com.oracle.truffle.api.instrument

## Class Instrument

- java.lang.Object
- - com.oracle.truffle.api.instrument.Instrument

    public final class Instrument
    extends java.lang.Object

A dynamically added/removed binding between a `Probe`, which provides notification of execution events taking place at a `Node` in a Guest Language (GL) Truffle AST, and a receiver, which consumes notifications on behalf of an external tool.

#### Summary: How to "instrument" an AST location:

1. Create an implementation of `TruffleEventReceiver` that responds to events on behalf of a tool.
2. Create an Instrument via factory method `create(TruffleEventReceiver)`.
3. "Attach" the Instrument to a Probe via `Probe.attach(Instrument)`, at which point event notifications begin to arrive at the receiver.
4. When no longer needed, "detach" the Instrument via `dispose()`, at which point event notifications to the receiver cease, and the Instrument becomes unusable.

#### Options for creating receivers:

1. Implement the interface `TruffleEventReceiver`. The event handling methods account for both the entry into an AST node (about to call) and several possible kinds of exit from an AST node (just returned).
2. Extend `DefaultEventReceiver`, which provides a no-op implementation of every `TruffleEventReceiver` method; override the methods of interest.
3. Extend `SimpleEventReceiver`, where return values are ignored so only two methods (for "enter" and "return") will notify all events.

#### General guidelines for receiver implementation:

When an Instrument is attached to a Probe, the receiver effectively becomes part of the executing GL program; performance can be affected by the receiver's implementation.

- Do not store `Frame` or `Node` references in fields.
- Prefer `final` fields and (where performance is important) short methods.
- If needed, pass along the `VirtualFrame` reference from an event notification as far as possible through code that is expected to be inlined, since this incurs no runtime overhead. When access to frame data is needed, substitute a more expensive materialized representation of the frame.
- If a receiver calls back to its tool during event handling, and if performance is an issue, then this should be through a final "callback" field in the instrument, and the called methods should be minimal.
- On the other hand, implementations should prevent Truffle from inlining beyond a reasonable point with the method annotation `CompilerDirectives.TruffleBoundary`.
- The implicit "outer" pointer in a non-static inner class is a useful way to implement callbacks to owner tools.
- Primitive-valued return events are boxed for notification, but Truffle will eliminate the boxing if they are cast back to their primitive values quickly (in particular before crossing any `CompilerDirectives.TruffleBoundary` annotations).

#### Allowing for AST cloning:

Truffle routinely clones ASTs, which has consequences for receiver implementation.

- Even though a `Probe` is uniquely associated with a particular location in the executing Guest Language program, execution events at that location will in general be implemented by different `Node` instances, i.e. clones of the originally probed node.
- Because of cloning the `Node` supplied with notifications to a particular receiver will vary, but because they all represent the same GL program location the events should be treated as equivalent for most purposes.

#### Access to execution state:

- Event notification arguments provide primary access to the GL program's execution states:
  - `Node`: the concrete node (in one of the AST's clones) from which the event originated.
  - `VirtualFrame`: the current execution frame.
- Some global information is available, for example the execution stack.
- Additional information needed by a receiver could be stored when created, preferably `final` of course. For example, a reference to the `Probe` to which the receiver's Instrument has been attached would give access to its corresponding source location or to the collection of tags currently applied to the Probe.

#### Activating and deactivating Instruments:

Instruments are single-use:

- An instrument becomes active only when attached to a Probe via `Probe.attach(Instrument)`, and it may only be attached to a single Probe. It is a runtime error to attempt attaching a previously attached instrument.
- Attaching an instrument modifies every existing clone of the AST to which it is being attached, which can trigger deoptimization.
- The method `dispose()` makes an instrument inactive by removing it from the Probe to which it was attached and rendering it permanently inert.
- Disposal removes the implementation of an instrument from all ASTs to which it was attached, which can trigger deoptimization.

#### Sharing receivers:

Although an Instrument may only be attached to a single Probe, a receiver can be shared among multiple Instruments. This can be useful for observing events that might happen at different locations in a single AST, for example all assignments to a particular variable. In this case a new Instrument would be created and attached at each assignment node, but all the Instruments would be created with the same receiver.

Disclaimer: experimental; under development.

See Also:
  `Probe`, `TruffleEventReceiver`

### Method Summary

Methods
`static Instrument` `create(TruffleEventReceiver receiver)` Creates an instrument that will route execution events to a receiver.
`static Instrument` `create(TruffleEventReceiver receiver, java.lang.String instrumentInfo)` Creates an instrument that will route execution events to a receiver.
`void` `dispose()` Removes this instrument (and any clones) from the probe to which it attached and renders the instrument inert.

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Method Detail

#### create

    public static Instrument create(TruffleEventReceiver receiver,
                    java.lang.String instrumentInfo)

Creates an instrument that will route execution events to a receiver.

Parameters:
  `receiver` - a receiver for event generated by the instrument
  `instrumentInfo` - optional description of the instrument's role
Returns:
  a new instrument, ready for attachment at a probe

#### create

    public static Instrument create(TruffleEventReceiver receiver)

Creates an instrument that will route execution events to a receiver.

#### dispose

    public void dispose()
                 throws java.lang.IllegalStateException

Removes this instrument (and any clones) from the probe to which it attached and renders the instrument inert.

Throws:
  `java.lang.IllegalStateException` - if this instrument has already been disposed