comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java @ 20892:73b1844b5b14

Truffle/Instrumentation: rename InstrumentListener to SimpleInstrumentListener
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Fri, 10 Apr 2015 21:00:26 -0700
parents e7ece52e1ff3
children 263ab98b3bf0
comparison
equal deleted inserted replaced
20891:0f3d81231ecb 20892:73b1844b5b14
39 * A dynamically added/removed binding between a {@link Probe}, which provides notification of 39 * A dynamically added/removed binding between a {@link Probe}, which provides notification of
40 * <em>execution events</em> taking place at a {@link Node} in a Guest Language (GL) Truffle AST, 40 * <em>execution events</em> taking place at a {@link Node} in a Guest Language (GL) Truffle AST,
41 * and a <em>listener</em>, which consumes notifications on behalf of an external tool. There are at 41 * and a <em>listener</em>, which consumes notifications on behalf of an external tool. There are at
42 * present two kinds of listeners that be used: 42 * present two kinds of listeners that be used:
43 * <ol> 43 * <ol>
44 * <li>{@link InstrumentListener} is the simplest and is intended for tools that require no access 44 * <li>{@link SimpleInstrumentListener} is the simplest and is intended for tools that require no access
45 * to the <em>internal execution state</em> of the Truffle execution, only that execution has passed 45 * to the <em>internal execution state</em> of the Truffle execution, only that execution has passed
46 * through a particular location in the program. Information about that location is made available 46 * through a particular location in the program. Information about that location is made available
47 * via the {@link Probe} argument in notification methods, including the {@linkplain SourceSection 47 * via the {@link Probe} argument in notification methods, including the {@linkplain SourceSection
48 * source location} of the node and any {@linkplain SyntaxTag tags} that have been applied to the 48 * source location} of the node and any {@linkplain SyntaxTag tags} that have been applied to the
49 * node.</li> 49 * node.</li>
55 * <h4>Summary: How to "instrument" an AST location:</h4> 55 * <h4>Summary: How to "instrument" an AST location:</h4>
56 * <p> 56 * <p>
57 * <ol> 57 * <ol>
58 * <li>Create an implementation of a <em>listener</em> interface.</li> 58 * <li>Create an implementation of a <em>listener</em> interface.</li>
59 * <li>Create an Instrument via factory methods 59 * <li>Create an Instrument via factory methods
60 * {@link Instrument#create(InstrumentListener, String)} or 60 * {@link Instrument#create(SimpleInstrumentListener, String)} or
61 * {@link Instrument#create(ASTInstrumentListener, String)}.</li> 61 * {@link Instrument#create(ASTInstrumentListener, String)}.</li>
62 * <li>"Attach" the Instrument to a Probe via {@link Probe#attach(Instrument)}, at which point event 62 * <li>"Attach" the Instrument to a Probe via {@link Probe#attach(Instrument)}, at which point event
63 * notifications begin to arrive at the listener.</li> 63 * notifications begin to arrive at the listener.</li>
64 * <li>When no longer needed, "detach" the Instrument via {@link ASTInstrument#dispose()}, at which 64 * <li>When no longer needed, "detach" the Instrument via {@link ASTInstrument#dispose()}, at which
65 * point event notifications to the listener cease, and the Instrument becomes unusable.</li> 65 * point event notifications to the listener cease, and the Instrument becomes unusable.</li>
66 * </ol> 66 * </ol>
67 * <p> 67 * <p>
68 * <h4>Options for creating listeners:</h4> 68 * <h4>Options for creating listeners:</h4>
69 * <p> 69 * <p>
70 * <ol> 70 * <ol>
71 * <li>Implement one of the <em>listener interfaces</em>: {@link InstrumentListener} or 71 * <li>Implement one of the <em>listener interfaces</em>: {@link SimpleInstrumentListener} or
72 * {@link ASTInstrumentListener} . Their event handling methods account for both the entry into an 72 * {@link ASTInstrumentListener} . Their event handling methods account for both the entry into an
73 * AST node (about to call) and three possible kinds of <em>execution return</em> from an AST node.</li> 73 * AST node (about to call) and three possible kinds of <em>execution return</em> from an AST node.</li>
74 * <li>Extend one of the <em>helper implementations</em>: {@link DefaultInstrumentListener} or 74 * <li>Extend one of the <em>helper implementations</em>: {@link DefaultSimpleInstrumentListener} or
75 * {@link DefaultASTInstrumentListener}. These provide no-op implementation of every listener 75 * {@link DefaultASTInstrumentListener}. These provide no-op implementation of every listener
76 * method, so only the methods of interest need to be overridden.</li> 76 * method, so only the methods of interest need to be overridden.</li>
77 * </ol> 77 * </ol>
78 * <p> 78 * <p>
79 * <h4>General guidelines for {@link ASTInstrumentListener} implementation:</h4> 79 * <h4>General guidelines for {@link ASTInstrumentListener} implementation:</h4>
80 * <p> 80 * <p>
81 * Unlike the listener interface {@link InstrumentListener}, which isolates implementations 81 * Unlike the listener interface {@link SimpleInstrumentListener}, which isolates implementations
82 * completely from Truffle internals (and is thus <em>Truffle-safe</em>), implementations of 82 * completely from Truffle internals (and is thus <em>Truffle-safe</em>), implementations of
83 * {@link ASTInstrumentListener} can interact directly with (and potentially affect) Truffle 83 * {@link ASTInstrumentListener} can interact directly with (and potentially affect) Truffle
84 * execution in general and Truffle optimization in particular. For example, it is possible to 84 * execution in general and Truffle optimization in particular. For example, it is possible to
85 * implement a debugger with this interface. 85 * implement a debugger with this interface.
86 * </p> 86 * </p>
108 * </ul> 108 * </ul>
109 * <p> 109 * <p>
110 * <h4>Allowing for AST cloning:</h4> 110 * <h4>Allowing for AST cloning:</h4>
111 * <p> 111 * <p>
112 * Truffle routinely <em>clones</em> ASTs, which has consequences for implementations of 112 * Truffle routinely <em>clones</em> ASTs, which has consequences for implementations of
113 * {@link ASTInstrumentListener} (but not for implementations of {@link InstrumentListener}, from 113 * {@link ASTInstrumentListener} (but not for implementations of {@link SimpleInstrumentListener}, from
114 * which cloning is hidden). 114 * which cloning is hidden).
115 * <ul> 115 * <ul>
116 * <li>Even though a {@link Probe} is uniquely associated with a particular location in the 116 * <li>Even though a {@link Probe} is uniquely associated with a particular location in the
117 * executing Guest Language program, execution events at that location will in general be 117 * executing Guest Language program, execution events at that location will in general be
118 * implemented by different {@link Node} instances, i.e. <em>clones</em> of the originally probed 118 * implemented by different {@link Node} instances, i.e. <em>clones</em> of the originally probed
171 * 171 *
172 * @param listener a minimal listener for event generated by the instrument. 172 * @param listener a minimal listener for event generated by the instrument.
173 * @param instrumentInfo optional description of the instrument's role, useful for debugging. 173 * @param instrumentInfo optional description of the instrument's role, useful for debugging.
174 * @return a new instrument, ready for attachment at a probe 174 * @return a new instrument, ready for attachment at a probe
175 */ 175 */
176 public static Instrument create(InstrumentListener listener, String instrumentInfo) { 176 public static Instrument create(SimpleInstrumentListener listener, String instrumentInfo) {
177 return new BasicInstrument(listener, instrumentInfo); 177 return new SimpleInstrument(listener, instrumentInfo);
178 } 178 }
179 179
180 /** 180 /**
181 * Creates an instrument that will route execution events to a listener, along with access to 181 * Creates an instrument that will route execution events to a listener, along with access to
182 * internal execution state. 182 * internal execution state.
260 } 260 }
261 261
262 abstract AbstractInstrumentNode addToChain(AbstractInstrumentNode nextNode); 262 abstract AbstractInstrumentNode addToChain(AbstractInstrumentNode nextNode);
263 263
264 /** 264 /**
265 * An instrument that propagates events to an instance of {@link InstrumentListener}. 265 * An instrument that propagates events to an instance of {@link SimpleInstrumentListener}.
266 */ 266 */
267 private static final class BasicInstrument extends Instrument { 267 private static final class SimpleInstrument extends Instrument {
268 268
269 /** 269 /**
270 * Tool-supplied listener for events. 270 * Tool-supplied listener for events.
271 */ 271 */
272 private final InstrumentListener instrumentListener; 272 private final SimpleInstrumentListener simpleListener;
273 273
274 private BasicInstrument(InstrumentListener basicListener, String instrumentInfo) { 274 private SimpleInstrument(SimpleInstrumentListener simpleListener, String instrumentInfo) {
275 super(instrumentInfo); 275 super(instrumentInfo);
276 this.instrumentListener = basicListener; 276 this.simpleListener = simpleListener;
277 } 277 }
278 278
279 @Override 279 @Override
280 AbstractInstrumentNode addToChain(AbstractInstrumentNode nextNode) { 280 AbstractInstrumentNode addToChain(AbstractInstrumentNode nextNode) {
281 return new BasicInstrumentNode(nextNode); 281 return new SimpleInstrumentNode(nextNode);
282 } 282 }
283 283
284 @Override 284 @Override
285 AbstractInstrumentNode removeFromChain(AbstractInstrumentNode instrumentNode) { 285 AbstractInstrumentNode removeFromChain(AbstractInstrumentNode instrumentNode) {
286 boolean found = false; 286 boolean found = false;
288 if (instrumentNode.getInstrument() == this) { 288 if (instrumentNode.getInstrument() == this) {
289 // Found the match at the head of the chain 289 // Found the match at the head of the chain
290 return instrumentNode.nextInstrumentNode; 290 return instrumentNode.nextInstrumentNode;
291 } 291 }
292 // Match not at the head of the chain; remove it. 292 // Match not at the head of the chain; remove it.
293 found = instrumentNode.removeFromChain(BasicInstrument.this); 293 found = instrumentNode.removeFromChain(SimpleInstrument.this);
294 } 294 }
295 if (!found) { 295 if (!found) {
296 throw new IllegalStateException("Couldn't find instrument node to remove: " + this); 296 throw new IllegalStateException("Couldn't find instrument node to remove: " + this);
297 } 297 }
298 return instrumentNode; 298 return instrumentNode;
299 } 299 }
300 300
301 @NodeInfo(cost = NodeCost.NONE) 301 @NodeInfo(cost = NodeCost.NONE)
302 private final class BasicInstrumentNode extends AbstractInstrumentNode { 302 private final class SimpleInstrumentNode extends AbstractInstrumentNode {
303 303
304 private BasicInstrumentNode(AbstractInstrumentNode nextNode) { 304 private SimpleInstrumentNode(AbstractInstrumentNode nextNode) {
305 super(nextNode); 305 super(nextNode);
306 } 306 }
307 307
308 public void enter(Node node, VirtualFrame vFrame) { 308 public void enter(Node node, VirtualFrame vFrame) {
309 BasicInstrument.this.instrumentListener.enter(BasicInstrument.this.probe); 309 SimpleInstrument.this.simpleListener.enter(SimpleInstrument.this.probe);
310 if (nextInstrumentNode != null) { 310 if (nextInstrumentNode != null) {
311 nextInstrumentNode.enter(node, vFrame); 311 nextInstrumentNode.enter(node, vFrame);
312 } 312 }
313 } 313 }
314 314
315 public void returnVoid(Node node, VirtualFrame vFrame) { 315 public void returnVoid(Node node, VirtualFrame vFrame) {
316 BasicInstrument.this.instrumentListener.returnVoid(BasicInstrument.this.probe); 316 SimpleInstrument.this.simpleListener.returnVoid(SimpleInstrument.this.probe);
317 if (nextInstrumentNode != null) { 317 if (nextInstrumentNode != null) {
318 nextInstrumentNode.returnVoid(node, vFrame); 318 nextInstrumentNode.returnVoid(node, vFrame);
319 } 319 }
320 } 320 }
321 321
322 public void returnValue(Node node, VirtualFrame vFrame, Object result) { 322 public void returnValue(Node node, VirtualFrame vFrame, Object result) {
323 BasicInstrument.this.instrumentListener.returnValue(BasicInstrument.this.probe, result); 323 SimpleInstrument.this.simpleListener.returnValue(SimpleInstrument.this.probe, result);
324 if (nextInstrumentNode != null) { 324 if (nextInstrumentNode != null) {
325 nextInstrumentNode.returnValue(node, vFrame, result); 325 nextInstrumentNode.returnValue(node, vFrame, result);
326 } 326 }
327 } 327 }
328 328
329 public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) { 329 public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) {
330 BasicInstrument.this.instrumentListener.returnExceptional(BasicInstrument.this.probe, exception); 330 SimpleInstrument.this.simpleListener.returnExceptional(SimpleInstrument.this.probe, exception);
331 if (nextInstrumentNode != null) { 331 if (nextInstrumentNode != null) {
332 nextInstrumentNode.returnExceptional(node, vFrame, exception); 332 nextInstrumentNode.returnExceptional(node, vFrame, exception);
333 } 333 }
334 } 334 }
335 335
336 public String instrumentationInfo() { 336 public String instrumentationInfo() {
337 final String info = getInstrumentInfo(); 337 final String info = getInstrumentInfo();
338 return info != null ? info : instrumentListener.getClass().getSimpleName(); 338 return info != null ? info : simpleListener.getClass().getSimpleName();
339 } 339 }
340 } 340 }
341 } 341 }
342 342
343 /** 343 /**