Class BytecodeRootNodes<T extends RootNode & BytecodeRootNode>

java.lang.Object
com.oracle.truffle.api.bytecode.BytecodeRootNodes<T>
Type Parameters:
T - the type of the bytecode root node

public abstract class BytecodeRootNodes<T extends RootNode & BytecodeRootNode> extends Object
A BytecodeRootNodes instance encapsulates one or more bytecode root nodes produced from a single parse. To reduce interpreter footprint, it supports on-demand reparsing to compute source and instrumentation metadata.

This class will be overridden by the Bytecode DSL. Do not override manually.

Since:
24.2
  • Field Details

    • TOKEN

      protected static final Object TOKEN
      A singleton object used to ensure certain Bytecode DSL APIs are only used by generated code.
      Since:
      24.2
    • nodes

      protected T extends RootNode & BytecodeRootNode[] nodes
      The array of parsed nodes.
      Since:
      24.2
  • Constructor Details

  • Method Details

    • getNodes

      public final List<T> getNodes()
      Returns the list of bytecode root nodes. The order of the list corresponds to the order of beginRoot(...) calls on the builder.
      Since:
      24.2
    • getNode

      public final T getNode(int i)
      Returns the bytecode root node at index i. The order of the list corresponds to the order of beginRoot(...) calls on the builder.
      Since:
      24.2
    • count

      public final int count()
      Returns the number of root nodes produced from the parse.
      Since:
      24.2
    • getParser

      protected final BytecodeParser<? extends BytecodeBuilder> getParser()
      Returns the parser used to parse the root nodes.
      Since:
      24.2
    • update

      public final boolean update(BytecodeConfig config)
      Updates the configuration for the given bytecode nodes. If the new configuration requires more information (e.g., sources, instrumentation or tags), this method may trigger a reparse to obtain it.

      Performance considerations: Updating and adding instrumentations or tags is a costly operation and requires reparsing all root nodes of a BytecodeRootNodes unit. Reparsing and modifying the generated bytecodes will also deoptimize and invalidate all currently optimized code of the reparsed root nodes. It also may or may not reset all profiling feedback gathered so far. Updating and adding just source information is a much less expensive operation and does not require any invalidation, but also requires to reparse all root nodes. Since compiled code is not invalidated when source information is added (and hence the BytecodeNode is not updated), lazily updated source information should not be accessed in compiled code.

      Usage in compiled code: This method may be used in compiled code, but the bytecode config must be a partial evaluation constant. If the bytecode config is changed in compiled code then deoptimization will be triggered. If an update does not require any changes then this operation will be a no-op in compiled code. In the interpreter it is also reasonably fast (a read and comparison of a volatile field), so it should reasonable to call this method on the fast path (e.g., in the prolog).

      Since:
      24.2
    • updateImpl

      protected abstract boolean updateImpl(BytecodeConfigEncoder encoder, long encoding)
      Implementation of reparse.

      This method will be generated by the Bytecode DSL. Do not override.

      Since:
      24.2
    • serialize

      public void serialize(DataOutput buffer, BytecodeSerializer callback) throws IOException
      Serializes the nodes to a byte buffer. This method will always fail unless serialization is enabled.

      Unlike the static serialize method defined on the generated root node, this method serializes the nodes using their current field values.

      This method will be overridden by the Bytecode DSL. Do not override.

      Parameters:
      buffer - The buffer to write the serialized bytes to.
      callback - A language-defined method for serializing language constants.
      Throws:
      IOException - if an I/O error occurs with the buffer.
    • ensureSourceInformation

      public final boolean ensureSourceInformation()
      Ensures that sources are available, reparsing if necessary.
      Since:
      24.2
    • ensureComplete

      public final boolean ensureComplete()
      Ensures that all sources and instrumentation metadata is available, reparsing if necessary.
      Since:
      24.2
    • addInstructionTracer

      public void addInstructionTracer(InstructionTracer tracer)
      Registers an InstructionTracer for this BytecodeRootNodes instance.

      This is a local variant of BytecodeDescriptor.addInstructionTracer(TruffleLanguage, InstructionTracer): it only affects the root nodes contained in this BytecodeRootNodes object, not all bytecode roots for the entire language.

      Tracer invocation happens on the language execution thread, at instruction granularity, and may run at very high frequency. Implementations should avoid unnecessary allocation or blocking.

      The same tracer instance can only be attached once. If the tracer is already installed for this BytecodeRootNodes instance, then this method has no effect. The order in which multiple tracers are invoked is unspecified.

      If this bytecode interpreter was generated without instruction tracing support (for example using @GenerateBytecode(enableInstructionTracing = false)), this method throws UnsupportedOperationException.

      Parameters:
      tracer - the tracer to install
      Throws:
      IllegalArgumentException - if tracer is exclusive to a different BytecodeDescriptor (see InstructionTracer.getExclusiveBytecodeDescriptor())
      UnsupportedOperationException - if instruction tracing is not enabled for this interpreter
      Since:
      25.1
    • removeInstructionTracer

      public void removeInstructionTracer(InstructionTracer tracer)
      Unregisters a previously installed InstructionTracer from this BytecodeRootNodes instance.

      Note that currently when all instruction tracers were removed, the trace instructions remain in the bytecode. This may be improved in the future.

      If this bytecode interpreter was generated without instruction tracing support (for example using @GenerateBytecode(enableInstructionTracing = false)), this method throws UnsupportedOperationException.

      Parameters:
      tracer - the tracer to remove
      Throws:
      IllegalArgumentException - if tracer is exclusive to a different BytecodeDescriptor (see InstructionTracer.getExclusiveBytecodeDescriptor())
      UnsupportedOperationException - if instruction tracing is not enabled for this interpreter
      Since:
      25.1
    • updateGlobalInstructionTracers

      protected void updateGlobalInstructionTracers(InstructionTracer[] tracers)
      Internal callback to the generated code to notify when global instruction tracers change.
      Since:
      25.1
    • toString

      public String toString()
      Returns a string representation of a BytecodeRootNodes.
      Overrides:
      toString in class Object
      Since:
      24.2