Mercurial > hg > truffle
comparison truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/Node.java @ 22219:1c0f490984d5
Merge with f47b601edbc626dcfe8b3636933b4834c89f7779
author | Michael Van De Vanter <michael.van.de.vanter@oracle.com> |
---|---|
date | Wed, 16 Sep 2015 15:36:22 -0700 |
parents | dc83cc1f94f2 3aad794eec0e |
children | 20380d1d41f2 |
comparison
equal
deleted
inserted
replaced
22160:0599e2df6a9f | 22219:1c0f490984d5 |
---|---|
22 * or visit www.oracle.com if you need additional information or have any | 22 * or visit www.oracle.com if you need additional information or have any |
23 * questions. | 23 * questions. |
24 */ | 24 */ |
25 package com.oracle.truffle.api.nodes; | 25 package com.oracle.truffle.api.nodes; |
26 | 26 |
27 import java.lang.annotation.ElementType; | |
28 import java.lang.annotation.Retention; | |
29 import java.lang.annotation.RetentionPolicy; | |
30 import java.lang.annotation.Target; | |
31 import java.util.HashMap; | |
32 import java.util.Iterator; | |
33 import java.util.Map; | |
34 import java.util.concurrent.Callable; | |
35 | |
27 import com.oracle.truffle.api.CallTarget; | 36 import com.oracle.truffle.api.CallTarget; |
28 import com.oracle.truffle.api.CompilerAsserts; | 37 import com.oracle.truffle.api.CompilerAsserts; |
29 import com.oracle.truffle.api.CompilerDirectives; | 38 import com.oracle.truffle.api.CompilerDirectives; |
30 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; | 39 import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; |
31 import com.oracle.truffle.api.ReplaceObserver; | 40 import com.oracle.truffle.api.ReplaceObserver; |
32 import com.oracle.truffle.api.TruffleLanguage; | 41 import com.oracle.truffle.api.TruffleLanguage; |
33 import com.oracle.truffle.api.TruffleOptions; | 42 import com.oracle.truffle.api.TruffleOptions; |
34 import com.oracle.truffle.api.impl.Accessor; | 43 import com.oracle.truffle.api.impl.Accessor; |
35 import com.oracle.truffle.api.instrument.Instrument; | 44 import com.oracle.truffle.api.instrument.Instrument; |
36 import com.oracle.truffle.api.instrument.Probe; | 45 import com.oracle.truffle.api.instrument.Probe; |
37 import com.oracle.truffle.api.instrument.ProbeException; | |
38 import com.oracle.truffle.api.instrument.ProbeFailure; | |
39 import com.oracle.truffle.api.instrument.ProbeNode; | |
40 import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; | 46 import com.oracle.truffle.api.instrument.ProbeNode.WrapperNode; |
41 import com.oracle.truffle.api.source.SourceSection; | 47 import com.oracle.truffle.api.source.SourceSection; |
42 import com.oracle.truffle.api.utilities.JSONHelper; | 48 import com.oracle.truffle.api.utilities.JSONHelper; |
43 import java.lang.annotation.ElementType; | |
44 import java.lang.annotation.Retention; | |
45 import java.lang.annotation.RetentionPolicy; | |
46 import java.lang.annotation.Target; | |
47 import java.util.HashMap; | |
48 import java.util.Iterator; | |
49 import java.util.Map; | |
50 import java.util.concurrent.Callable; | |
51 | 49 |
52 /** | 50 /** |
53 * Abstract base class for all Truffle nodes. | 51 * Abstract base class for all Truffle nodes. |
54 */ | 52 */ |
55 public abstract class Node implements NodeInterface, Cloneable { | 53 public abstract class Node implements NodeInterface, Cloneable { |
447 public WrapperNode createWrapperNode() { | 445 public WrapperNode createWrapperNode() { |
448 return null; | 446 return null; |
449 } | 447 } |
450 | 448 |
451 /** | 449 /** |
452 * Enables {@linkplain Instrument instrumentation} of a node, where the node is presumed to be | |
453 * part of a well-formed Truffle AST that is not being executed. If this node has not already | |
454 * been probed, modifies the AST by inserting a {@linkplain WrapperNode wrapper node} between | |
455 * the node and its parent; the wrapper node must be provided by implementations of | |
456 * {@link #createWrapperNode()}. No more than one {@link Probe} may be associated with a node, | |
457 * so a {@linkplain WrapperNode wrapper} may not wrap another {@linkplain WrapperNode wrapper}. | |
458 * | |
459 * @return a (possibly newly created) {@link Probe} associated with this node. | |
460 * @throws ProbeException (unchecked) when a probe cannot be created, leaving the AST unchanged | |
461 */ | |
462 public final Probe probe() { | |
463 | |
464 if (this instanceof WrapperNode) { | |
465 throw new ProbeException(ProbeFailure.Reason.WRAPPER_NODE, null, this, null); | |
466 } | |
467 | |
468 if (parent == null) { | |
469 throw new ProbeException(ProbeFailure.Reason.NO_PARENT, null, this, null); | |
470 } | |
471 | |
472 if (parent instanceof WrapperNode) { | |
473 return ((WrapperNode) parent).getProbe(); | |
474 } | |
475 | |
476 if (!isInstrumentable()) { | |
477 throw new ProbeException(ProbeFailure.Reason.NOT_INSTRUMENTABLE, parent, this, null); | |
478 } | |
479 | |
480 // Create a new wrapper/probe with this node as its child. | |
481 final WrapperNode wrapper = createWrapperNode(); | |
482 | |
483 if (wrapper == null || !(wrapper instanceof Node)) { | |
484 throw new ProbeException(ProbeFailure.Reason.NO_WRAPPER, parent, this, wrapper); | |
485 } | |
486 | |
487 final Node wrapperNode = (Node) wrapper; | |
488 | |
489 if (!this.isSafelyReplaceableBy(wrapperNode)) { | |
490 throw new ProbeException(ProbeFailure.Reason.WRAPPER_TYPE, parent, this, wrapper); | |
491 } | |
492 | |
493 // Connect it to a Probe | |
494 final Probe probe = ProbeNode.insertProbe(wrapper); | |
495 | |
496 // Replace this node in the AST with the wrapper | |
497 this.replace(wrapperNode); | |
498 | |
499 return probe; | |
500 } | |
501 | |
502 /** | |
503 * Converts this node to a textual representation useful for debugging. | 450 * Converts this node to a textual representation useful for debugging. |
504 */ | 451 */ |
505 @Override | 452 @Override |
506 public String toString() { | 453 public String toString() { |
507 StringBuilder sb = new StringBuilder(getClass().getSimpleName()); | 454 StringBuilder sb = new StringBuilder(getClass().getSimpleName()); |
574 return parent.getLanguage(); | 521 return parent.getLanguage(); |
575 } | 522 } |
576 return ""; | 523 return ""; |
577 } | 524 } |
578 | 525 |
526 protected void applyInstrumentation(Node node) { | |
527 ACCESSOR.applyInstrumentation(node); | |
528 } | |
529 | |
579 private static final Object GIL = new Object(); | 530 private static final Object GIL = new Object(); |
580 | 531 |
581 private static final ThreadLocal<Integer> IN_ATOMIC_BLOCK = new ThreadLocal<Integer>() { | 532 private static final ThreadLocal<Integer> IN_ATOMIC_BLOCK = new ThreadLocal<Integer>() { |
582 @Override | 533 @Override |
583 protected Integer initialValue() { | 534 protected Integer initialValue() { |
603 @SuppressWarnings("rawtypes") | 554 @SuppressWarnings("rawtypes") |
604 @Override | 555 @Override |
605 protected Class<? extends TruffleLanguage> findLanguage(RootNode n) { | 556 protected Class<? extends TruffleLanguage> findLanguage(RootNode n) { |
606 return n.language; | 557 return n.language; |
607 } | 558 } |
559 | |
560 @Override | |
561 protected void applyInstrumentation(Node node) { | |
562 super.applyInstrumentation(node); | |
563 } | |
608 } | 564 } |
609 | 565 |
610 // registers into Accessor.NODES | 566 // registers into Accessor.NODES |
611 @SuppressWarnings("unused") private static final AccessorNodes ACCESSOR = new AccessorNodes(); | 567 private static final AccessorNodes ACCESSOR = new AccessorNodes(); |
612 } | 568 } |