comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java @ 20909:f96165ecb6f1

Truffle/Instrumentation: rename the most recently created kind of Instrument, formerly "ToolNodeblahblah...". It is now defined by SpliceInstrumentListener. This listener allows the client to create an instrument that will *splied* a client-supplied AST fragment directly into a Probe's "instrumentation chain", and this directly into the flow of Truffle execution (with full optimization).
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Mon, 13 Apr 2015 15:33:45 -0700
parents f166d264af9f
children 78a4b44420cf
comparison
equal deleted inserted replaced
20908:f166d264af9f 20909:f96165ecb6f1
126 return new StandardInstrument(standardListener, instrumentInfo); 126 return new StandardInstrument(standardListener, instrumentInfo);
127 } 127 }
128 128
129 /** 129 /**
130 * Creates an instrument that, when executed the first time in any particular AST location, 130 * Creates an instrument that, when executed the first time in any particular AST location,
131 * invites the tool to provide an AST fragment for attachment/adoption into the running AST. 131 * invites the tool to provide an AST fragment for <em>splicing</em> directly into the running
132 * AST.
132 * 133 *
133 * @param toolNodeListener a listener for the tool that can request an AST fragment 134 * @param spliceListener a callback to the client that requests an AST node to be splice.
134 * @param instrumentInfo instrumentInfo optional description of the instrument's role, useful 135 * @param instrumentInfo instrumentInfo optional description of the instrument's role, useful
135 * for debugging. 136 * for debugging.
136 * @return a new instrument, ready for attachment at a probe. 137 * @return a new instrument, ready for attachment at a probe.
137 */ 138 */
138 public static Instrument create(ToolNodeInstrumentListener toolNodeListener, String instrumentInfo) { 139 public static Instrument create(SpliceInstrumentListener spliceListener, String instrumentInfo) {
139 return new ToolNodeInstrument(toolNodeListener, instrumentInfo); 140 return new SpliceInstrument(spliceListener, instrumentInfo);
140 } 141 }
141 142
142 // TODO (mlvdv) experimental 143 // TODO (mlvdv) experimental
143 /** 144 /**
144 * For implementation testing. 145 * For implementation testing.
193 boolean isDisposed() { 194 boolean isDisposed() {
194 return isDisposed; 195 return isDisposed;
195 } 196 }
196 197
197 abstract AbstractInstrumentNode addToChain(AbstractInstrumentNode nextNode); 198 abstract AbstractInstrumentNode addToChain(AbstractInstrumentNode nextNode);
199
200 /**
201 * Removes this instrument from an instrument chain.
202 */
203 abstract AbstractInstrumentNode removeFromChain(AbstractInstrumentNode instrumentNode);
198 204
199 /** 205 /**
200 * An instrument that propagates events to an instance of {@link SimpleInstrumentListener}. 206 * An instrument that propagates events to an instance of {@link SimpleInstrumentListener}.
201 */ 207 */
202 private static final class SimpleInstrument extends Instrument { 208 private static final class SimpleInstrument extends Instrument {
274 } 280 }
275 } 281 }
276 } 282 }
277 283
278 /** 284 /**
279 * Removes this instrument from an instrument chain.
280 */
281 abstract AbstractInstrumentNode removeFromChain(AbstractInstrumentNode instrumentNode);
282
283 /**
284 * An instrument that propagates events to an instance of {@link StandardInstrumentListener}. 285 * An instrument that propagates events to an instance of {@link StandardInstrumentListener}.
285 */ 286 */
286 private static final class StandardInstrument extends Instrument { 287 private static final class StandardInstrument extends Instrument {
287 288
288 /** 289 /**
359 } 360 }
360 } 361 }
361 362
362 // TODO (mlvdv) EXPERIMENTAL- UNDER DEVELOPMENT 363 // TODO (mlvdv) EXPERIMENTAL- UNDER DEVELOPMENT
363 /** 364 /**
364 * An instrument that propagates events to an instance of {@link StandardInstrumentListener}. 365 * An instrument that allows clients to "splice" an AST fragment directly into a Probe's
365 */ 366 * <em>instrumentation chain</em>, and thus directly into the executing Truffle AST.
366 private static final class ToolNodeInstrument extends Instrument { 367 */
368 private static final class SpliceInstrument extends Instrument {
367 369
368 /** 370 /**
369 * Tool-supplied listener for AST events. 371 * Tool-supplied listener for AST events.
370 */ 372 */
371 private final ToolNodeInstrumentListener toolNodeListener; 373 private final SpliceInstrumentListener spliceListener;
372 374
373 private ToolNodeInstrument(ToolNodeInstrumentListener toolNodeListener, String instrumentInfo) { 375 private SpliceInstrument(SpliceInstrumentListener spliceListener, String instrumentInfo) {
374 super(instrumentInfo); 376 super(instrumentInfo);
375 this.toolNodeListener = toolNodeListener; 377 this.spliceListener = spliceListener;
376 } 378 }
377 379
378 @Override 380 @Override
379 AbstractInstrumentNode addToChain(AbstractInstrumentNode nextNode) { 381 AbstractInstrumentNode addToChain(AbstractInstrumentNode nextNode) {
380 return new ToolInstrumentNode(nextNode); 382 return new SpliceInstrumentNode(nextNode);
381 } 383 }
382 384
383 @Override 385 @Override
384 AbstractInstrumentNode removeFromChain(AbstractInstrumentNode instrumentNode) { 386 AbstractInstrumentNode removeFromChain(AbstractInstrumentNode instrumentNode) {
385 boolean found = false; 387 boolean found = false;
387 if (instrumentNode.getInstrument() == this) { 389 if (instrumentNode.getInstrument() == this) {
388 // Found the match at the head of the chain 390 // Found the match at the head of the chain
389 return instrumentNode.nextInstrumentNode; 391 return instrumentNode.nextInstrumentNode;
390 } 392 }
391 // Match not at the head of the chain; remove it. 393 // Match not at the head of the chain; remove it.
392 found = instrumentNode.removeFromChain(ToolNodeInstrument.this); 394 found = instrumentNode.removeFromChain(SpliceInstrument.this);
393 } 395 }
394 if (!found) { 396 if (!found) {
395 throw new IllegalStateException("Couldn't find instrument node to remove: " + this); 397 throw new IllegalStateException("Couldn't find instrument node to remove: " + this);
396 } 398 }
397 return instrumentNode; 399 return instrumentNode;
398 } 400 }
399 401
400 @NodeInfo(cost = NodeCost.NONE) 402 @NodeInfo(cost = NodeCost.NONE)
401 private final class ToolInstrumentNode extends AbstractInstrumentNode { 403 private final class SpliceInstrumentNode extends AbstractInstrumentNode {
402 404
403 @Child ToolNode toolNode; 405 @Child SplicedNode splicedNode;
404 406
405 private ToolInstrumentNode(AbstractInstrumentNode nextNode) { 407 private SpliceInstrumentNode(AbstractInstrumentNode nextNode) {
406 super(nextNode); 408 super(nextNode);
407 } 409 }
408 410
409 public void enter(Node node, VirtualFrame vFrame) { 411 public void enter(Node node, VirtualFrame vFrame) {
410 if (toolNode == null) { 412 if (splicedNode == null) {
411 final ToolNode newToolNode = ToolNodeInstrument.this.toolNodeListener.getToolNode(ToolNodeInstrument.this.probe); 413 final SplicedNode newSplicedNode = SpliceInstrument.this.spliceListener.getSpliceNode(SpliceInstrument.this.probe);
412 if (newToolNode != null) { 414 if (newSplicedNode != null) {
413 toolNode = newToolNode; 415 splicedNode = newSplicedNode;
414 adoptChildren(); 416 adoptChildren();
415 ToolNodeInstrument.this.probe.invalidateProbeUnchanged(); 417 SpliceInstrument.this.probe.invalidateProbeUnchanged();
416 } 418 }
417 } 419 }
418 if (toolNode != null) { 420 if (splicedNode != null) {
419 toolNode.enter(node, vFrame); 421 splicedNode.enter(node, vFrame);
420 } 422 }
421 if (nextInstrumentNode != null) { 423 if (nextInstrumentNode != null) {
422 nextInstrumentNode.enter(node, vFrame); 424 nextInstrumentNode.enter(node, vFrame);
423 } 425 }
424 } 426 }
425 427
426 public void returnVoid(Node node, VirtualFrame vFrame) { 428 public void returnVoid(Node node, VirtualFrame vFrame) {
427 if (toolNode != null) { 429 if (splicedNode != null) {
428 toolNode.returnVoid(node, vFrame); 430 splicedNode.returnVoid(node, vFrame);
429 } 431 }
430 if (nextInstrumentNode != null) { 432 if (nextInstrumentNode != null) {
431 nextInstrumentNode.returnVoid(node, vFrame); 433 nextInstrumentNode.returnVoid(node, vFrame);
432 } 434 }
433 } 435 }
434 436
435 public void returnValue(Node node, VirtualFrame vFrame, Object result) { 437 public void returnValue(Node node, VirtualFrame vFrame, Object result) {
436 if (toolNode != null) { 438 if (splicedNode != null) {
437 toolNode.returnValue(node, vFrame, result); 439 splicedNode.returnValue(node, vFrame, result);
438 } 440 }
439 if (nextInstrumentNode != null) { 441 if (nextInstrumentNode != null) {
440 nextInstrumentNode.returnValue(node, vFrame, result); 442 nextInstrumentNode.returnValue(node, vFrame, result);
441 } 443 }
442 } 444 }
443 445
444 public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) { 446 public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) {
445 if (toolNode != null) { 447 if (splicedNode != null) {
446 toolNode.returnExceptional(node, vFrame, exception); 448 splicedNode.returnExceptional(node, vFrame, exception);
447 } 449 }
448 if (nextInstrumentNode != null) { 450 if (nextInstrumentNode != null) {
449 nextInstrumentNode.returnExceptional(node, vFrame, exception); 451 nextInstrumentNode.returnExceptional(node, vFrame, exception);
450 } 452 }
451 } 453 }
452 454
453 public String instrumentationInfo() { 455 public String instrumentationInfo() {
454 final String info = getInstrumentInfo(); 456 final String info = getInstrumentInfo();
455 return info != null ? info : toolNodeListener.getClass().getSimpleName(); 457 return info != null ? info : spliceListener.getClass().getSimpleName();
456 } 458 }
457 } 459 }
458 } 460 }
459 461
460 public interface TruffleOptListener { 462 public interface TruffleOptListener {