comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/Instrument.java @ 21356:e34bc00733d1

Truffle/Instrumentation: an Advanced Instrument can now be created that requires the evaluation result be of a specified type, reporting a failure if not
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Tue, 12 May 2015 17:29:49 -0700
parents 442b57a7f208
children 19801a65cf57
comparison
equal deleted inserted replaced
21355:442b57a7f208 21356:e34bc00733d1
131 * full Truffle optimization, a client-provided AST fragment every time the Probed node is 131 * full Truffle optimization, a client-provided AST fragment every time the Probed node is
132 * entered. 132 * entered.
133 * 133 *
134 * @param resultListener optional client callback for results/failure notification 134 * @param resultListener optional client callback for results/failure notification
135 * @param rootFactory provider of AST fragments on behalf of the client 135 * @param rootFactory provider of AST fragments on behalf of the client
136 * @param requiredResultType optional requirement, any non-assignable result is reported to the
137 * the listener, if any, as a failure
136 * @param instrumentInfo optional description of the instrument's role, intended for debugging. 138 * @param instrumentInfo optional description of the instrument's role, intended for debugging.
137 * @return a new instrument, ready for attachment at a probe 139 * @return a new instrument, ready for attachment at a probe
138 */ 140 */
139 public static Instrument create(AdvancedInstrumentResultListener resultListener, AdvancedInstrumentRootFactory rootFactory, String instrumentInfo) { 141 public static Instrument create(AdvancedInstrumentResultListener resultListener, AdvancedInstrumentRootFactory rootFactory, Class<?> requiredResultType, String instrumentInfo) {
140 return new AdvancedInstrument(resultListener, rootFactory, instrumentInfo); 142 return new AdvancedInstrument(resultListener, rootFactory, requiredResultType, instrumentInfo);
141 } 143 }
142 144
143 // TODO (mlvdv) experimental 145 // TODO (mlvdv) experimental
144 /** 146 /**
145 * For implementation testing. 147 * For implementation testing.
381 * AST with potential for full optimization. 383 * AST with potential for full optimization.
382 */ 384 */
383 private static final class AdvancedInstrument extends Instrument { 385 private static final class AdvancedInstrument extends Instrument {
384 386
385 private final AdvancedInstrumentResultListener resultListener; 387 private final AdvancedInstrumentResultListener resultListener;
386 /**
387 * Client-provided supplier of new node instances to attach.
388 */
389 private final AdvancedInstrumentRootFactory rootFactory; 388 private final AdvancedInstrumentRootFactory rootFactory;
390 389 private final Class<?> requiredResultType;
391 private AdvancedInstrument(AdvancedInstrumentResultListener resultListener, AdvancedInstrumentRootFactory rootFactory, String instrumentInfo) { 390
391 private AdvancedInstrument(AdvancedInstrumentResultListener resultListener, AdvancedInstrumentRootFactory rootFactory, Class<?> requiredResultType, String instrumentInfo) {
392 super(instrumentInfo); 392 super(instrumentInfo);
393 this.resultListener = resultListener; 393 this.resultListener = resultListener;
394 this.rootFactory = rootFactory; 394 this.rootFactory = rootFactory;
395 395 this.requiredResultType = requiredResultType;
396 } 396 }
397 397
398 @Override 398 @Override
399 AbstractInstrumentNode addToChain(AbstractInstrumentNode nextNode) { 399 AbstractInstrumentNode addToChain(AbstractInstrumentNode nextNode) {
400 return new AdvancedInstrumentNode(nextNode); 400 return new AdvancedInstrumentNode(nextNode);
446 } 446 }
447 if (instrumentRoot != null) { 447 if (instrumentRoot != null) {
448 try { 448 try {
449 final Object result = instrumentRoot.executeRoot(node, vFrame); 449 final Object result = instrumentRoot.executeRoot(node, vFrame);
450 if (resultListener != null) { 450 if (resultListener != null) {
451 checkResultType(result);
451 resultListener.notifyResult(node, vFrame, result); 452 resultListener.notifyResult(node, vFrame, result);
452 } 453 }
453 } catch (RuntimeException ex) { 454 } catch (RuntimeException ex) {
454 if (resultListener != null) { 455 if (resultListener != null) {
455 resultListener.notifyFailure(node, vFrame, ex); 456 resultListener.notifyFailure(node, vFrame, ex);
456 } 457 }
457 } 458 }
458 } 459 }
459 if (nextInstrumentNode != null) { 460 if (nextInstrumentNode != null) {
460 nextInstrumentNode.enter(node, vFrame); 461 nextInstrumentNode.enter(node, vFrame);
462 }
463 }
464
465 private void checkResultType(Object result) {
466 if (requiredResultType == null) {
467 return;
468 }
469 if (result == null || !(requiredResultType.isAssignableFrom(result.getClass()))) {
470 throw new RuntimeException("Instrument result " + result.toString() + " not assignable to " + requiredResultType.getSimpleName());
461 } 471 }
462 } 472 }
463 473
464 public void returnVoid(Node node, VirtualFrame vFrame) { 474 public void returnVoid(Node node, VirtualFrame vFrame) {
465 if (nextInstrumentNode != null) { 475 if (nextInstrumentNode != null) {