CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-graalvm-truffle--truffle-api

A multi-language framework for executing dynamic languages that achieves high performance when combined with Graal.

Pending
Overview
Eval results
Files

instrumentation.mddocs/

Instrumentation and Debugging

Truffle's instrumentation framework provides comprehensive debugging, profiling, and tooling infrastructure for language development and runtime analysis. It enables dynamic attachment of execution listeners, breakpoints, and profiling tools without modifying language implementations.

Capabilities

Instrument Implementation

Core framework for implementing debugging and profiling tools.

/**
 * Base class for implementing Truffle instruments
 */
public abstract class TruffleInstrument {
    
    /**
     * Called when instrument is created
     * @param env Instrument environment
     */
    protected abstract void onCreate(Env env);
    
    /**
     * Called when instrument is finalized
     * @param env Instrument environment
     */
    protected void onFinalize(Env env) {
        // Default implementation
    }
    
    /**
     * Called when instrument is disposed
     * @param env Instrument environment
     */
    protected void onDispose(Env env) {
        // Default implementation
    }
    
    /**
     * Instrument registration annotation
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface Registration {
        
        /**
         * Instrument identifier
         * @return Instrument ID
         */
        String id();
        
        /**
         * Instrument name
         * @return Display name
         */
        String name();
        
        /**
         * Instrument version
         * @return Version string
         */
        String version() default "";
        
        /**
         * Whether instrument is internal
         * @return true if internal
         */
        boolean internal() default false;
        
        /**
         * Services provided by instrument
         * @return Array of service classes
         */
        Class<?>[] services() default {};
    }
    
    /**
     * Instrument environment providing access to instrumentation services
     */
    public static final class Env {
        
        /**
         * Get instrumenter for attaching listeners
         * @return Instrumenter instance
         */
        public Instrumenter getInstrumenter();
        
        /**
         * Get logger for this instrument
         * @param loggerName Logger name
         * @return TruffleLogger instance
         */
        public TruffleLogger getLogger(String loggerName);
        
        /**
         * Register service for other instruments/languages
         * @param service Service object
         */
        public void registerService(Object service);
        
        /**
         * Look up service from other instruments/languages
         * @param type Service type
         * @return Service instance or null
         */
        public <T> T lookup(Class<T> type);
        
        /**
         * Get instrument options
         * @return OptionValues instance
         */
        public OptionValues getOptions();
        
        /**
         * Get input stream for instrument
         * @return InputStream
         */
        public InputStream in();
        
        /**
         * Get output stream for instrument
         * @return OutputStream
         */
        public OutputStream out();
        
        /**
         * Get error stream for instrument
         * @return OutputStream
         */
        public OutputStream err();
    }
}

Usage Example:

@TruffleInstrument.Registration(
    id = "myProfiler", 
    name = "My Profiler",
    version = "1.0"
)
public class MyProfiler extends TruffleInstrument {
    
    @Override
    protected void onCreate(Env env) {
        Instrumenter instrumenter = env.getInstrumenter();
        
        // Attach execution listener to all source sections
        instrumenter.attachExecutionEventListener(
            SourceSectionFilter.ANY,
            new ExecutionEventListener() {
                @Override
                public void onEnter(EventContext context, VirtualFrame frame) {
                    // Record entry time
                    recordEntry(context.getInstrumentedSourceSection());
                }
                
                @Override
                public void onReturnValue(EventContext context, VirtualFrame frame, Object result) {
                    // Record exit time and result
                    recordExit(context.getInstrumentedSourceSection(), result);
                }
            }
        );
    }
    
    private void recordEntry(SourceSection section) {
        // Profiling logic
    }
    
    private void recordExit(SourceSection section, Object result) {
        // Profiling logic
    }
}

Execution Event System

Framework for monitoring and intercepting AST node execution.

/**
 * Main interface for attaching execution listeners and instruments
 */
public abstract class Instrumenter {
    
    /**
     * Attach execution event listener
     * @param filter Filter for source sections to instrument
     * @param listener Execution event listener
     * @return Event binding for management
     */
    public abstract EventBinding<ExecutionEventListener> attachExecutionEventListener(
        SourceSectionFilter filter, ExecutionEventListener listener);
    
    /**
     * Attach execution event factory
     * @param filter Filter for source sections to instrument
     * @param factory Factory for creating event nodes
     * @return Event binding for management
     */
    public abstract <T extends ExecutionEventNodeFactory> EventBinding<T> attachExecutionEventFactory(
        SourceSectionFilter filter, T factory);
    
    /**
     * Attach load source listener
     * @param filter Filter for sources to monitor
     * @param listener Source load listener
     * @param includeExistingSources Whether to notify for existing sources
     * @return Event binding for management
     */
    public abstract EventBinding<LoadSourceListener> attachLoadSourceListener(
        SourceFilter filter, LoadSourceListener listener, boolean includeExistingSources);
    
    /**
     * Attach load source section listener
     * @param filter Filter for source sections to monitor
     * @param listener Source section load listener
     * @param includeExistingSections Whether to notify for existing sections
     * @return Event binding for management
     */
    public abstract EventBinding<LoadSourceSectionListener> attachLoadSourceSectionListener(
        SourceSectionFilter filter, LoadSourceSectionListener listener, boolean includeExistingSections);
    
    /**
     * Get allocation reporter for memory tracking
     * @return AllocationReporter instance
     */
    public abstract AllocationReporter getAllocationReporter();
    
    /**
     * Visit loaded source sections
     * @param filter Filter for sections to visit
     * @param visitor Section visitor
     */
    public abstract void visitLoadedSourceSections(SourceSectionFilter filter, LoadSourceSectionListener visitor);
}

/**
 * Listener interface for execution events
 */
public interface ExecutionEventListener {
    
    /**
     * Called when entering instrumented node
     * @param context Event context
     * @param frame Execution frame
     */
    default void onEnter(EventContext context, VirtualFrame frame) {
        // Default implementation
    }
    
    /**
     * Called when exiting with return value
     * @param context Event context
     * @param frame Execution frame
     * @param result Return value
     */
    default void onReturnValue(EventContext context, VirtualFrame frame, Object result) {
        // Default implementation
    }
    
    /**
     * Called when exiting with exception
     * @param context Event context
     * @param frame Execution frame
     * @param exception Exception thrown
     */
    default void onReturnExceptional(EventContext context, VirtualFrame frame, Throwable exception) {
        // Default implementation
    }
}

/**
 * Factory interface for creating execution event nodes
 */
public interface ExecutionEventNodeFactory {
    
    /**
     * Create execution event node
     * @param context Event context
     * @return ExecutionEventNode instance
     */
    ExecutionEventNode create(EventContext context);
}

/**
 * Base class for execution event nodes
 */
public abstract class ExecutionEventNode extends Node {
    
    /**
     * Called when entering instrumented node
     * @param frame Execution frame
     */
    protected void onEnter(VirtualFrame frame) {
        // Default implementation
    }
    
    /**
     * Called when exiting with return value
     * @param frame Execution frame
     * @param result Return value
     */
    protected void onReturnValue(VirtualFrame frame, Object result) {
        // Default implementation
    }
    
    /**
     * Called when exiting with exception
     * @param frame Execution frame
     * @param exception Exception thrown
     */
    protected void onReturnExceptional(VirtualFrame frame, Throwable exception) {
        // Default implementation
    }
    
    /**
     * Called when node is disposed
     */
    protected void onDispose(VirtualFrame frame) {
        // Default implementation
    }
    
    /**
     * Get event context
     * @return EventContext instance
     */
    protected final EventContext getEventContext() {
        // Implementation details
        return null;
    }
}

/**
 * Context information for execution events
 */
public abstract class EventContext {
    
    /**
     * Get instrumented source section
     * @return SourceSection instance
     */
    public abstract SourceSection getInstrumentedSourceSection();
    
    /**
     * Get instrumented node
     * @return Node instance
     */
    public abstract Node getInstrumentedNode();
    
    /**
     * Check if node has tag
     * @param tag Tag class to check
     * @return true if node has tag
     */
    public abstract boolean hasTag(Class<? extends Tag> tag);
    
    /**
     * Get node object for debugging
     * @param frame Execution frame
     * @return Debug node object
     */
    public abstract Object getNodeObject(VirtualFrame frame);
    
    /**
     * Create unwind throwable for non-local control flow
     * @param info Unwind information
     * @return Unwind throwable
     */
    public abstract RuntimeException createUnwind(Object info);
    
    /**
     * Create error throwable
     * @param exception Exception to wrap
     * @return Error throwable
     */
    public abstract RuntimeException createError(RuntimeException exception);
}

Source Filtering System

Comprehensive filtering system for targeting specific source code regions for instrumentation.

/**
 * Filter for selecting source sections to instrument
 */
public final class SourceSectionFilter {
    
    /**
     * Filter matching any source section
     */
    public static final SourceSectionFilter ANY = newBuilder().build();
    
    /**
     * Create new filter builder
     * @return Builder instance
     */
    public static Builder newBuilder() {
        return new Builder();
    }
    
    /**
     * Builder for creating source section filters
     */
    public static final class Builder {
        
        /**
         * Filter by tag classes
         * @param tags Tag classes to match
         * @return Builder instance
         */
        public Builder tagIs(Class<?>... tags) {
            return this;
        }
        
        /**
         * Filter by tag classes (any match)
         * @param tags Tag classes to match
         * @return Builder instance
         */
        public Builder tagIsOneOf(Class<?>... tags) {
            return this;
        }
        
        /**
         * Filter by source sections
         * @param sections Source sections to match
         * @return Builder instance
         */
        public Builder sourceSectionEquals(SourceSection... sections) {
            return this;
        }
        
        /**
         * Filter by line range
         * @param startLine Start line (inclusive)
         * @param endLine End line (inclusive)
         * @return Builder instance
         */
        public Builder lineIn(int startLine, int endLine) {
            return this;
        }
        
        /**
         * Filter by specific line
         * @param line Line number
         * @return Builder instance
         */
        public Builder lineIs(int line) {
            return this;
        }
        
        /**
         * Filter by column range
         * @param startColumn Start column (inclusive)
         * @param endColumn End column (inclusive)
         * @return Builder instance
         */
        public Builder columnIn(int startColumn, int endColumn) {
            return this;
        }
        
        /**
         * Filter by MIME type
         * @param mimeTypes MIME types to match
         * @return Builder instance
         */
        public Builder mimeTypeIs(String... mimeTypes) {
            return this;
        }
        
        /**
         * Filter by source name pattern
         * @param namePattern Name pattern (regex)
         * @return Builder instance
         */
        public Builder sourceIs(String namePattern) {
            return this;
        }
        
        /**
         * Filter by root name pattern
         * @param namePattern Root name pattern (regex)
         * @return Builder instance
         */
        public Builder rootNameIs(String namePattern) {
            return this;
        }
        
        /**
         * Include internal sources
         * @return Builder instance
         */
        public Builder includeInternal(boolean includeInternal) {
            return this;
        }
        
        /**
         * Build the filter
         * @return SourceSectionFilter instance
         */
        public SourceSectionFilter build() {
            return new SourceSectionFilter();
        }
    }
}

/**
 * Filter for selecting sources to monitor
 */
public final class SourceFilter {
    
    /**
     * Filter matching any source
     */
    public static final SourceFilter ANY = newBuilder().build();
    
    /**
     * Create new filter builder
     * @return Builder instance
     */
    public static Builder newBuilder() {
        return new Builder();
    }
    
    /**
     * Builder for creating source filters
     */
    public static final class Builder {
        
        /**
         * Filter by MIME type
         * @param mimeTypes MIME types to match
         * @return Builder instance
         */
        public Builder mimeTypeIs(String... mimeTypes) {
            return this;
        }
        
        /**
         * Filter by source name pattern
         * @param namePattern Name pattern (regex)
         * @return Builder instance
         */
        public Builder sourceIs(String namePattern) {
            return this;
        }
        
        /**
         * Include internal sources
         * @return Builder instance
         */
        public Builder includeInternal(boolean includeInternal) {
            return this;
        }
        
        /**
         * Build the filter
         * @return SourceFilter instance
         */
        public SourceFilter build() {
            return new SourceFilter();
        }
    }
}

Allocation Tracking

System for monitoring memory allocations in Truffle languages.

/**
 * Reports memory allocations to registered listeners
 */
public abstract class AllocationReporter {
    
    /**
     * Add allocation listener
     * @param listener Allocation listener
     */
    public abstract void addListener(AllocationListener listener);
    
    /**
     * Remove allocation listener
     * @param listener Allocation listener
     */
    public abstract void removeListener(AllocationListener listener);
    
    /**
     * Report object allocation
     * @param newObject Newly allocated object
     */
    public abstract void onEnter(Object newObject);
    
    /**
     * Report allocation with size
     * @param newObject Newly allocated object
     * @param size Allocation size in bytes
     */
    public abstract void onEnter(Object newObject, long size);
    
    /**
     * Report allocation with language and size
     * @param newObject Newly allocated object
     * @param size Allocation size in bytes
     * @param language Allocating language
     */
    public abstract void onEnter(Object newObject, long size, TruffleLanguage<?> language);
}

/**
 * Listener interface for allocation events
 */
public interface AllocationListener {
    
    /**
     * Called when object is allocated
     * @param event Allocation event
     */
    void onAllocation(AllocationEvent event);
}

/**
 * Event representing an object allocation
 */
public abstract class AllocationEvent {
    
    /**
     * Get allocated object
     * @return Allocated object
     */
    public abstract Object getAllocatedObject();
    
    /**
     * Get allocation size
     * @return Size in bytes
     */
    public abstract long getSize();
    
    /**
     * Get allocating language
     * @return TruffleLanguage instance
     */
    public abstract TruffleLanguage<?> getLanguage();
    
    /**
     * Get allocation stack trace
     * @return Array of stack trace elements
     */
    public abstract StackTraceElement[] getStackTrace();
}

Event Binding Management

System for managing and controlling instrumentation bindings.

/**
 * Represents a binding between instrument and instrumented code
 * @param <T> Bound element type
 */
public abstract class EventBinding<T> {
    
    /**
     * Check if binding is disposed
     * @return true if disposed
     */
    public abstract boolean isDisposed();
    
    /**
     * Dispose this binding
     */
    public abstract void dispose();
    
    /**
     * Get bound element
     * @return Bound element
     */
    public abstract T getElement();
    
    /**
     * Check if binding is attached to specific instrumented node
     * @param node Node to check
     * @return true if attached
     */
    public abstract boolean isAttached(Node node);
}

Node Tagging System

System for marking AST nodes with semantic tags for targeted instrumentation.

/**
 * Base class for node tags
 */
public abstract class Tag {
    // Base tag class
}

/**
 * Standard tags for common language constructs
 */
public final class StandardTags {
    
    /**
     * Tag for expression nodes
     */
    public static final class ExpressionTag extends Tag {
        private ExpressionTag() {}
    }
    
    /**
     * Tag for statement nodes
     */
    public static final class StatementTag extends Tag {
        private StatementTag() {}
    }
    
    /**
     * Tag for function call nodes
     */
    public static final class CallTag extends Tag {
        private CallTag() {}
    }
    
    /**
     * Tag for root nodes
     */
    public static final class RootTag extends Tag {
        private RootTag() {}
    }
    
    /**
     * Tag for root body nodes
     */
    public static final class RootBodyTag extends Tag {
        private RootBodyTag() {}
    }
    
    /**
     * Tag for read variable nodes
     */
    public static final class ReadVariableTag extends Tag {
        private ReadVariableTag() {}
    }
    
    /**
     * Tag for write variable nodes
     */
    public static final class WriteVariableTag extends Tag {
        private WriteVariableTag() {}
    }
}

/**
 * Marks nodes as instrumentable
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Instrumentable {
    
    /**
     * Factory class for creating wrappers
     * @return Wrapper factory class
     */
    Class<? extends ProvidedTags> factory();
}

/**
 * Tags provided by an instrumentable node
 */
public abstract class ProvidedTags {
    
    /**
     * Get provided tag classes
     * @return Array of tag classes
     */
    public abstract Class<?>[] getProvidedTags();
}

/**
 * Generates wrapper nodes for instrumentation
 */
@Retention(RetentionPolicy.CLASS)
@Target(ElementType.TYPE)
public @interface GenerateWrapper {
    
    /**
     * Delegate factory class
     * @return Factory class
     */
    Class<?> delegateTo();
}

Source Load Monitoring

System for monitoring source code loading and compilation.

/**
 * Listener interface for source loading events
 */
public interface LoadSourceListener {
    
    /**
     * Called when source is loaded
     * @param event Source load event
     */
    void onLoad(LoadSourceEvent event);
}

/**
 * Listener interface for source section loading events
 */
public interface LoadSourceSectionListener {
    
    /**
     * Called when source section is loaded
     * @param event Source section load event
     */
    void onLoad(LoadSourceSectionEvent event);
}

/**
 * Event representing source loading
 */
public abstract class LoadSourceEvent {
    
    /**
     * Get loaded source
     * @return Source instance
     */
    public abstract Source getSource();
}

/**
 * Event representing source section loading
 */
public abstract class LoadSourceSectionEvent {
    
    /**
     * Get loaded source section
     * @return SourceSection instance
     */
    public abstract SourceSection getSourceSection();
    
    /**
     * Get associated node
     * @return Node instance
     */
    public abstract Node getNode();
}

Types

Debugging Infrastructure Types

/**
 * Options for instrumentation configuration
 */
public final class OptionValues {
    
    /**
     * Get option value
     * @param key Option key
     * @return Option value
     */
    public <T> T get(OptionKey<T> key) {
        return null;
    }
    
    /**
     * Check if option has value
     * @param key Option key
     * @return true if has value
     */
    public boolean hasBeenSet(OptionKey<?> key) {
        return false;
    }
}

/**
 * Key for accessing option values
 * @param <T> Option value type
 */
public final class OptionKey<T> {
    
    /**
     * Get default value
     * @return Default value
     */
    public T getDefaultValue() {
        return null;
    }
}

/**
 * Descriptor for option definitions
 */
public final class OptionDescriptor {
    
    /**
     * Get option name
     * @return Option name
     */
    public String getName() {
        return null;
    }
    
    /**
     * Get option help text
     * @return Help text
     */
    public String getHelp() {
        return null;
    }
    
    /**
     * Get option key
     * @return OptionKey instance
     */
    public OptionKey<?> getKey() {
        return null;
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-graalvm-truffle--truffle-api

docs

advanced.md

core-api.md

data-types.md

dsl.md

index.md

instrumentation.md

interop.md

tile.json