The community edition of the Truffle runtime providing execution engine and optimization support for dynamic programming languages built with the Truffle framework
—
Compilation infrastructure providing optimized call targets, compiler directives, assumption-based optimizations, and performance profiling.
Represents a compiled and optimized executable unit that can be invoked with high performance.
/**
* Optimized implementation of CallTarget that provides compilation
* and performance monitoring capabilities
*/
public abstract class OptimizedCallTarget implements CallTarget, ReplaceObserver {
/** Executes the call target with given arguments */
public final Object call(Object... arguments);
/** Checks if this call target's compiled code is still valid */
public abstract boolean isValid();
/** Invalidates the compiled code, forcing recompilation */
public abstract void invalidate();
/** Invalidates with a specific reason for debugging */
public abstract void invalidate(String reason);
/** Returns the number of times this call target has been invoked */
public abstract int getCallCount();
/** Returns the time spent compiling this call target (in nanoseconds) */
public abstract long getCompilationTime();
/** Checks if this call target is currently being compiled */
public abstract boolean isCompiling();
/** Checks if this call target has been compiled */
public abstract boolean isCompiled();
/** Forces compilation of this call target */
public abstract void compile();
/** Returns compilation metadata and statistics */
public abstract CompilationResult getCompilationResult();
/** Returns the root node associated with this call target */
public final RootNode getRootNode();
/** Sets a custom name for this call target */
public final void setName(String name);
/** Returns the name of this call target */
public final String getName();
}Usage Examples:
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.runtime.OptimizedCallTarget;
// Create an optimized call target
RootNode rootNode = new MyLanguageRootNode();
OptimizedCallTarget callTarget = (OptimizedCallTarget) Truffle.getRuntime()
.createCallTarget(rootNode);
// Monitor compilation status
if (!callTarget.isCompiled()) {
System.out.println("Call count: " + callTarget.getCallCount());
// Force compilation if needed
callTarget.compile();
}
// Check if optimizations are still valid
if (!callTarget.isValid()) {
System.out.println("Call target was invalidated, will recompile");
}Static utility methods that provide hints and directives to the optimizing compiler.
/**
* Compiler optimization directives and hints for the Graal compiler
*/
public final class CompilerDirectives {
/** Forces transfer from compiled code to interpreter */
public static void transferToInterpreter();
/** Forces transfer to interpreter and invalidates compiled code */
public static void transferToInterpreterAndInvalidate();
/** Checks if currently executing in interpreter mode */
public static boolean inInterpreter();
/** Checks if currently executing in compiled code */
public static boolean inCompiledCode();
/** Hints that a value should be treated as compilation constant */
public static boolean isCompilationConstant(Object value);
/** Hints that a condition is likely to be true */
public static boolean injectBranchProbability(double probability, boolean condition);
/** Marks a code path as unlikely to be executed */
public static void bailout(String reason);
/** Ensures a value is not optimized away */
public static <T> T blackhole(T value);
/** Hints that a method call should be inlined */
public static void ensureVirtualized(Object object);
/** Hints that an exception path is slow */
public static RuntimeException shouldNotReachHere();
/** Hints that an exception path is slow with message */
public static RuntimeException shouldNotReachHere(String message);
/** Hints that an exception path is slow with cause */
public static RuntimeException shouldNotReachHere(Throwable cause);
}Usage Examples:
public class MyLanguageNode extends Node {
@CompilerDirectives.CompilationFinal
private int constantValue = 42;
public Object execute(VirtualFrame frame) {
if (CompilerDirectives.inInterpreter()) {
// This code only runs in interpreter
collectProfile();
}
// Provide branch probability hint
if (CompilerDirectives.injectBranchProbability(0.9, isCommonCase())) {
return fastPath();
} else {
// Unlikely path - may cause deoptimization
CompilerDirectives.transferToInterpreterAndInvalidate();
return slowPath();
}
}
}Represents an assumption that enables aggressive optimizations but can be invalidated when conditions change.
/**
* Optimized implementation of Assumption that enables aggressive
* compiler optimizations based on runtime assumptions
*/
public final class OptimizedAssumption implements Assumption {
/** Checks if this assumption is still valid */
public boolean isValid();
/** Invalidates this assumption and all dependent compiled code */
public void invalidate();
/** Invalidates this assumption with a specific message */
public void invalidate(String message);
/** Returns the name of this assumption */
public String getName();
/** Checks the assumption and throws exception if invalid */
public void check() throws InvalidAssumptionException;
/** Checks if the assumption has been checked in compiled code */
public boolean isValidAssumption();
}Usage Examples:
import com.oracle.truffle.api.Assumption;
import com.oracle.truffle.api.Truffle;
public class ClassLayout {
private final Assumption stableLayout;
public ClassLayout() {
this.stableLayout = Truffle.getRuntime()
.createAssumption("Stable class layout");
}
public Object getProperty(String name) {
try {
// Check assumption before using cached layout
stableLayout.check();
return getCachedProperty(name);
} catch (InvalidAssumptionException e) {
// Layout changed, update cache
updateLayout();
return getProperty(name);
}
}
public void addProperty(String name) {
// Adding property invalidates layout assumption
stableLayout.invalidate("Property added: " + name);
updateLayout();
}
}Information about compilation process and results.
/**
* Result of a compilation attempt
*/
public interface CompilationResult {
/** Returns the target that was compiled */
OptimizedCallTarget getTarget();
/** Checks if compilation was successful */
boolean isSuccess();
/** Returns the compilation failure reason if any */
String getFailureReason();
/** Returns compilation time in nanoseconds */
long getTimeCompilationFinished();
/** Returns the number of nodes in compiled code */
int getNodeCount();
/** Returns the size of generated code in bytes */
int getCodeSize();
}
/**
* Actions to take when compilation fails
*/
public enum CompilationFailureAction {
/** Silently continue with interpreter */
Silent,
/** Print compilation failure to console */
Print,
/** Throw exception on compilation failure */
Throw,
/** Exit the VM on compilation failure */
ExitVM,
/** Perform detailed diagnostics */
Diagnose
}Specialized nodes for optimized loop execution and On-Stack Replacement (OSR).
/**
* Optimized loop node that supports OSR compilation
*/
public abstract class OptimizedLoopNode extends Node implements LoopNode {
/** Executes the loop with given frame */
public abstract void execute(VirtualFrame frame);
/** Returns the repeating node inside this loop */
public abstract RepeatingNode getRepeatingNode();
/** Checks if OSR is enabled for this loop */
public abstract boolean isOSREnabled();
/** Returns OSR compilation metadata */
public abstract OSRMetadata getOSRMetadata();
}
/**
* OSR (On-Stack Replacement) optimized loop node
*/
public final class OptimizedOSRLoopNode extends OptimizedLoopNode {
/** Creates a new OSR loop node */
public static OptimizedOSRLoopNode create(RepeatingNode repeatingNode);
/** Executes the loop with OSR support */
public void execute(VirtualFrame frame);
/** Forces OSR compilation */
public void forceOSR();
/** Returns the OSR call target */
public CallTarget getOSRCallTarget();
}Usage Examples:
// Creating an optimized loop
RepeatingNode repeatingNode = new MyRepeatingNode();
OptimizedLoopNode loopNode = OptimizedOSRLoopNode.create(repeatingNode);
// The runtime automatically handles OSR compilation
// when the loop runs for a long timepublic interface Assumption {
/** Checks if the assumption is still valid */
boolean isValid();
/** Invalidates the assumption */
void invalidate();
/** Invalidates the assumption with a message */
void invalidate(String message);
/** Returns the assumption name */
String getName();
/** Checks the assumption, throwing exception if invalid */
void check() throws InvalidAssumptionException;
}
public final class InvalidAssumptionException extends SlowPathException {
/** Creates exception for invalid assumption */
public InvalidAssumptionException(Assumption assumption);
/** Returns the invalidated assumption */
public Assumption getAssumption();
}
public interface RepeatingNode extends Node.Child {
/** Executes one iteration of the repeating node */
boolean executeRepeating(VirtualFrame frame);
}
public interface LoopNode extends Node.Child {
/** Executes the entire loop */
void execute(VirtualFrame frame);
/** Returns the repeating node */
RepeatingNode getRepeatingNode();
}Install with Tessl CLI
npx tessl i tessl/maven-org-graalvm-truffle--truffle-runtime