Class EncapsulatingNodeReference

java.lang.Object
com.oracle.truffle.api.nodes.EncapsulatingNodeReference

public final class EncapsulatingNodeReference extends Object
Thread local reference class to remember the current encapsulating node of an interpreter on the stack. The current encapsulating node is used whenever the code transitions from cached to uncached cases. This typically happens when the maximum limit for an inline cache was reached and the uncached version of a node will be used behind a CompilerDirectives.TruffleBoundary. To correctly produce exception stack traces it is necessary to remember the node that transitioned to the uncached case. Uncached calls to CallTarget will automatically use the value of the encapsulating node. Truffle DSL produces such transitions automatically if Truffle libraries are used and they transition to uncached.

Usage example for pushing and restoring the current node to the stack.

 EncapsulatingNodeReference encapsulating = EncapsulatingNodeReference.getCurrent();
 Node encapsulatingNode = encapsulating.set(currentNode);
 try {
     // follow uncached path
 } finally {
     encapsulating.set(encapsulatingNode);
 }
 

The current encapsulating node can also be useful when constructing guest exceptions in slow-paths and the location of the error needs to be found out reliably. Usage example:

 final class LanguageException extends AbstractTruffleException {

     private LanguageException(Node locationNode) {
         super(locationNode);
     }

     static LanguageException create(Node locationNode) {
         CompilerAsserts.partialEvaluationConstant(locationNode);
         if (locationNode == null || !locationNode.isAdoptable()) {
             return new LanguageException(EncapsulatingNodeReference.getCurrent().get());
         } else {
             return new LanguageException(locationNode);
         }
     }

     // ...
 }
 
Note that Node.isAdoptable() is a way to find out whether a node was used in an uncached scenario or not.
Since:
20.2
  • Method Details

    • set

      public Node set(Node node)
      Sets the current encapsulating node for the current thread and returns its previous value. The passed node may be null. The set node must be adoptable and be adopted by a RootNode otherwise an AssertionError is thrown. This method must only be used from the thread it was requested for. This method is safe to be called from compiled code paths.
      Since:
      20.2
    • get

      public Node get()
      Returns the current encapsulating node for the current thread. Returned node may be null. If the returned node is non-null then it is guaranteed to be adoptable and adopted by a RootNode. This method must only be used from the thread it was requested for. This method is safe to be called from compiled code paths.
      Since:
      20.2
    • getCurrent

      public static EncapsulatingNodeReference getCurrent()
      Returns the encapsulating node reference of the current thread. The returned value is never null. This method is safe to be called from compiled code paths.
      Since:
      20.2