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 }