or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced.mdcore-api.mddata-types.mddsl.mdindex.mdinstrumentation.mdinterop.md

instrumentation.mddocs/

0

# Instrumentation and Debugging

1

2

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.

3

4

## Capabilities

5

6

### Instrument Implementation

7

8

Core framework for implementing debugging and profiling tools.

9

10

```java { .api }

11

/**

12

* Base class for implementing Truffle instruments

13

*/

14

public abstract class TruffleInstrument {

15

16

/**

17

* Called when instrument is created

18

* @param env Instrument environment

19

*/

20

protected abstract void onCreate(Env env);

21

22

/**

23

* Called when instrument is finalized

24

* @param env Instrument environment

25

*/

26

protected void onFinalize(Env env) {

27

// Default implementation

28

}

29

30

/**

31

* Called when instrument is disposed

32

* @param env Instrument environment

33

*/

34

protected void onDispose(Env env) {

35

// Default implementation

36

}

37

38

/**

39

* Instrument registration annotation

40

*/

41

@Retention(RetentionPolicy.RUNTIME)

42

@Target(ElementType.TYPE)

43

public @interface Registration {

44

45

/**

46

* Instrument identifier

47

* @return Instrument ID

48

*/

49

String id();

50

51

/**

52

* Instrument name

53

* @return Display name

54

*/

55

String name();

56

57

/**

58

* Instrument version

59

* @return Version string

60

*/

61

String version() default "";

62

63

/**

64

* Whether instrument is internal

65

* @return true if internal

66

*/

67

boolean internal() default false;

68

69

/**

70

* Services provided by instrument

71

* @return Array of service classes

72

*/

73

Class<?>[] services() default {};

74

}

75

76

/**

77

* Instrument environment providing access to instrumentation services

78

*/

79

public static final class Env {

80

81

/**

82

* Get instrumenter for attaching listeners

83

* @return Instrumenter instance

84

*/

85

public Instrumenter getInstrumenter();

86

87

/**

88

* Get logger for this instrument

89

* @param loggerName Logger name

90

* @return TruffleLogger instance

91

*/

92

public TruffleLogger getLogger(String loggerName);

93

94

/**

95

* Register service for other instruments/languages

96

* @param service Service object

97

*/

98

public void registerService(Object service);

99

100

/**

101

* Look up service from other instruments/languages

102

* @param type Service type

103

* @return Service instance or null

104

*/

105

public <T> T lookup(Class<T> type);

106

107

/**

108

* Get instrument options

109

* @return OptionValues instance

110

*/

111

public OptionValues getOptions();

112

113

/**

114

* Get input stream for instrument

115

* @return InputStream

116

*/

117

public InputStream in();

118

119

/**

120

* Get output stream for instrument

121

* @return OutputStream

122

*/

123

public OutputStream out();

124

125

/**

126

* Get error stream for instrument

127

* @return OutputStream

128

*/

129

public OutputStream err();

130

}

131

}

132

```

133

134

**Usage Example:**

135

136

```java

137

@TruffleInstrument.Registration(

138

id = "myProfiler",

139

name = "My Profiler",

140

version = "1.0"

141

)

142

public class MyProfiler extends TruffleInstrument {

143

144

@Override

145

protected void onCreate(Env env) {

146

Instrumenter instrumenter = env.getInstrumenter();

147

148

// Attach execution listener to all source sections

149

instrumenter.attachExecutionEventListener(

150

SourceSectionFilter.ANY,

151

new ExecutionEventListener() {

152

@Override

153

public void onEnter(EventContext context, VirtualFrame frame) {

154

// Record entry time

155

recordEntry(context.getInstrumentedSourceSection());

156

}

157

158

@Override

159

public void onReturnValue(EventContext context, VirtualFrame frame, Object result) {

160

// Record exit time and result

161

recordExit(context.getInstrumentedSourceSection(), result);

162

}

163

}

164

);

165

}

166

167

private void recordEntry(SourceSection section) {

168

// Profiling logic

169

}

170

171

private void recordExit(SourceSection section, Object result) {

172

// Profiling logic

173

}

174

}

175

```

176

177

### Execution Event System

178

179

Framework for monitoring and intercepting AST node execution.

180

181

```java { .api }

182

/**

183

* Main interface for attaching execution listeners and instruments

184

*/

185

public abstract class Instrumenter {

186

187

/**

188

* Attach execution event listener

189

* @param filter Filter for source sections to instrument

190

* @param listener Execution event listener

191

* @return Event binding for management

192

*/

193

public abstract EventBinding<ExecutionEventListener> attachExecutionEventListener(

194

SourceSectionFilter filter, ExecutionEventListener listener);

195

196

/**

197

* Attach execution event factory

198

* @param filter Filter for source sections to instrument

199

* @param factory Factory for creating event nodes

200

* @return Event binding for management

201

*/

202

public abstract <T extends ExecutionEventNodeFactory> EventBinding<T> attachExecutionEventFactory(

203

SourceSectionFilter filter, T factory);

204

205

/**

206

* Attach load source listener

207

* @param filter Filter for sources to monitor

208

* @param listener Source load listener

209

* @param includeExistingSources Whether to notify for existing sources

210

* @return Event binding for management

211

*/

212

public abstract EventBinding<LoadSourceListener> attachLoadSourceListener(

213

SourceFilter filter, LoadSourceListener listener, boolean includeExistingSources);

214

215

/**

216

* Attach load source section listener

217

* @param filter Filter for source sections to monitor

218

* @param listener Source section load listener

219

* @param includeExistingSections Whether to notify for existing sections

220

* @return Event binding for management

221

*/

222

public abstract EventBinding<LoadSourceSectionListener> attachLoadSourceSectionListener(

223

SourceSectionFilter filter, LoadSourceSectionListener listener, boolean includeExistingSections);

224

225

/**

226

* Get allocation reporter for memory tracking

227

* @return AllocationReporter instance

228

*/

229

public abstract AllocationReporter getAllocationReporter();

230

231

/**

232

* Visit loaded source sections

233

* @param filter Filter for sections to visit

234

* @param visitor Section visitor

235

*/

236

public abstract void visitLoadedSourceSections(SourceSectionFilter filter, LoadSourceSectionListener visitor);

237

}

238

239

/**

240

* Listener interface for execution events

241

*/

242

public interface ExecutionEventListener {

243

244

/**

245

* Called when entering instrumented node

246

* @param context Event context

247

* @param frame Execution frame

248

*/

249

default void onEnter(EventContext context, VirtualFrame frame) {

250

// Default implementation

251

}

252

253

/**

254

* Called when exiting with return value

255

* @param context Event context

256

* @param frame Execution frame

257

* @param result Return value

258

*/

259

default void onReturnValue(EventContext context, VirtualFrame frame, Object result) {

260

// Default implementation

261

}

262

263

/**

264

* Called when exiting with exception

265

* @param context Event context

266

* @param frame Execution frame

267

* @param exception Exception thrown

268

*/

269

default void onReturnExceptional(EventContext context, VirtualFrame frame, Throwable exception) {

270

// Default implementation

271

}

272

}

273

274

/**

275

* Factory interface for creating execution event nodes

276

*/

277

public interface ExecutionEventNodeFactory {

278

279

/**

280

* Create execution event node

281

* @param context Event context

282

* @return ExecutionEventNode instance

283

*/

284

ExecutionEventNode create(EventContext context);

285

}

286

287

/**

288

* Base class for execution event nodes

289

*/

290

public abstract class ExecutionEventNode extends Node {

291

292

/**

293

* Called when entering instrumented node

294

* @param frame Execution frame

295

*/

296

protected void onEnter(VirtualFrame frame) {

297

// Default implementation

298

}

299

300

/**

301

* Called when exiting with return value

302

* @param frame Execution frame

303

* @param result Return value

304

*/

305

protected void onReturnValue(VirtualFrame frame, Object result) {

306

// Default implementation

307

}

308

309

/**

310

* Called when exiting with exception

311

* @param frame Execution frame

312

* @param exception Exception thrown

313

*/

314

protected void onReturnExceptional(VirtualFrame frame, Throwable exception) {

315

// Default implementation

316

}

317

318

/**

319

* Called when node is disposed

320

*/

321

protected void onDispose(VirtualFrame frame) {

322

// Default implementation

323

}

324

325

/**

326

* Get event context

327

* @return EventContext instance

328

*/

329

protected final EventContext getEventContext() {

330

// Implementation details

331

return null;

332

}

333

}

334

335

/**

336

* Context information for execution events

337

*/

338

public abstract class EventContext {

339

340

/**

341

* Get instrumented source section

342

* @return SourceSection instance

343

*/

344

public abstract SourceSection getInstrumentedSourceSection();

345

346

/**

347

* Get instrumented node

348

* @return Node instance

349

*/

350

public abstract Node getInstrumentedNode();

351

352

/**

353

* Check if node has tag

354

* @param tag Tag class to check

355

* @return true if node has tag

356

*/

357

public abstract boolean hasTag(Class<? extends Tag> tag);

358

359

/**

360

* Get node object for debugging

361

* @param frame Execution frame

362

* @return Debug node object

363

*/

364

public abstract Object getNodeObject(VirtualFrame frame);

365

366

/**

367

* Create unwind throwable for non-local control flow

368

* @param info Unwind information

369

* @return Unwind throwable

370

*/

371

public abstract RuntimeException createUnwind(Object info);

372

373

/**

374

* Create error throwable

375

* @param exception Exception to wrap

376

* @return Error throwable

377

*/

378

public abstract RuntimeException createError(RuntimeException exception);

379

}

380

```

381

382

### Source Filtering System

383

384

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

385

386

```java { .api }

387

/**

388

* Filter for selecting source sections to instrument

389

*/

390

public final class SourceSectionFilter {

391

392

/**

393

* Filter matching any source section

394

*/

395

public static final SourceSectionFilter ANY = newBuilder().build();

396

397

/**

398

* Create new filter builder

399

* @return Builder instance

400

*/

401

public static Builder newBuilder() {

402

return new Builder();

403

}

404

405

/**

406

* Builder for creating source section filters

407

*/

408

public static final class Builder {

409

410

/**

411

* Filter by tag classes

412

* @param tags Tag classes to match

413

* @return Builder instance

414

*/

415

public Builder tagIs(Class<?>... tags) {

416

return this;

417

}

418

419

/**

420

* Filter by tag classes (any match)

421

* @param tags Tag classes to match

422

* @return Builder instance

423

*/

424

public Builder tagIsOneOf(Class<?>... tags) {

425

return this;

426

}

427

428

/**

429

* Filter by source sections

430

* @param sections Source sections to match

431

* @return Builder instance

432

*/

433

public Builder sourceSectionEquals(SourceSection... sections) {

434

return this;

435

}

436

437

/**

438

* Filter by line range

439

* @param startLine Start line (inclusive)

440

* @param endLine End line (inclusive)

441

* @return Builder instance

442

*/

443

public Builder lineIn(int startLine, int endLine) {

444

return this;

445

}

446

447

/**

448

* Filter by specific line

449

* @param line Line number

450

* @return Builder instance

451

*/

452

public Builder lineIs(int line) {

453

return this;

454

}

455

456

/**

457

* Filter by column range

458

* @param startColumn Start column (inclusive)

459

* @param endColumn End column (inclusive)

460

* @return Builder instance

461

*/

462

public Builder columnIn(int startColumn, int endColumn) {

463

return this;

464

}

465

466

/**

467

* Filter by MIME type

468

* @param mimeTypes MIME types to match

469

* @return Builder instance

470

*/

471

public Builder mimeTypeIs(String... mimeTypes) {

472

return this;

473

}

474

475

/**

476

* Filter by source name pattern

477

* @param namePattern Name pattern (regex)

478

* @return Builder instance

479

*/

480

public Builder sourceIs(String namePattern) {

481

return this;

482

}

483

484

/**

485

* Filter by root name pattern

486

* @param namePattern Root name pattern (regex)

487

* @return Builder instance

488

*/

489

public Builder rootNameIs(String namePattern) {

490

return this;

491

}

492

493

/**

494

* Include internal sources

495

* @return Builder instance

496

*/

497

public Builder includeInternal(boolean includeInternal) {

498

return this;

499

}

500

501

/**

502

* Build the filter

503

* @return SourceSectionFilter instance

504

*/

505

public SourceSectionFilter build() {

506

return new SourceSectionFilter();

507

}

508

}

509

}

510

511

/**

512

* Filter for selecting sources to monitor

513

*/

514

public final class SourceFilter {

515

516

/**

517

* Filter matching any source

518

*/

519

public static final SourceFilter ANY = newBuilder().build();

520

521

/**

522

* Create new filter builder

523

* @return Builder instance

524

*/

525

public static Builder newBuilder() {

526

return new Builder();

527

}

528

529

/**

530

* Builder for creating source filters

531

*/

532

public static final class Builder {

533

534

/**

535

* Filter by MIME type

536

* @param mimeTypes MIME types to match

537

* @return Builder instance

538

*/

539

public Builder mimeTypeIs(String... mimeTypes) {

540

return this;

541

}

542

543

/**

544

* Filter by source name pattern

545

* @param namePattern Name pattern (regex)

546

* @return Builder instance

547

*/

548

public Builder sourceIs(String namePattern) {

549

return this;

550

}

551

552

/**

553

* Include internal sources

554

* @return Builder instance

555

*/

556

public Builder includeInternal(boolean includeInternal) {

557

return this;

558

}

559

560

/**

561

* Build the filter

562

* @return SourceFilter instance

563

*/

564

public SourceFilter build() {

565

return new SourceFilter();

566

}

567

}

568

}

569

```

570

571

### Allocation Tracking

572

573

System for monitoring memory allocations in Truffle languages.

574

575

```java { .api }

576

/**

577

* Reports memory allocations to registered listeners

578

*/

579

public abstract class AllocationReporter {

580

581

/**

582

* Add allocation listener

583

* @param listener Allocation listener

584

*/

585

public abstract void addListener(AllocationListener listener);

586

587

/**

588

* Remove allocation listener

589

* @param listener Allocation listener

590

*/

591

public abstract void removeListener(AllocationListener listener);

592

593

/**

594

* Report object allocation

595

* @param newObject Newly allocated object

596

*/

597

public abstract void onEnter(Object newObject);

598

599

/**

600

* Report allocation with size

601

* @param newObject Newly allocated object

602

* @param size Allocation size in bytes

603

*/

604

public abstract void onEnter(Object newObject, long size);

605

606

/**

607

* Report allocation with language and size

608

* @param newObject Newly allocated object

609

* @param size Allocation size in bytes

610

* @param language Allocating language

611

*/

612

public abstract void onEnter(Object newObject, long size, TruffleLanguage<?> language);

613

}

614

615

/**

616

* Listener interface for allocation events

617

*/

618

public interface AllocationListener {

619

620

/**

621

* Called when object is allocated

622

* @param event Allocation event

623

*/

624

void onAllocation(AllocationEvent event);

625

}

626

627

/**

628

* Event representing an object allocation

629

*/

630

public abstract class AllocationEvent {

631

632

/**

633

* Get allocated object

634

* @return Allocated object

635

*/

636

public abstract Object getAllocatedObject();

637

638

/**

639

* Get allocation size

640

* @return Size in bytes

641

*/

642

public abstract long getSize();

643

644

/**

645

* Get allocating language

646

* @return TruffleLanguage instance

647

*/

648

public abstract TruffleLanguage<?> getLanguage();

649

650

/**

651

* Get allocation stack trace

652

* @return Array of stack trace elements

653

*/

654

public abstract StackTraceElement[] getStackTrace();

655

}

656

```

657

658

### Event Binding Management

659

660

System for managing and controlling instrumentation bindings.

661

662

```java { .api }

663

/**

664

* Represents a binding between instrument and instrumented code

665

* @param <T> Bound element type

666

*/

667

public abstract class EventBinding<T> {

668

669

/**

670

* Check if binding is disposed

671

* @return true if disposed

672

*/

673

public abstract boolean isDisposed();

674

675

/**

676

* Dispose this binding

677

*/

678

public abstract void dispose();

679

680

/**

681

* Get bound element

682

* @return Bound element

683

*/

684

public abstract T getElement();

685

686

/**

687

* Check if binding is attached to specific instrumented node

688

* @param node Node to check

689

* @return true if attached

690

*/

691

public abstract boolean isAttached(Node node);

692

}

693

```

694

695

### Node Tagging System

696

697

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

698

699

```java { .api }

700

/**

701

* Base class for node tags

702

*/

703

public abstract class Tag {

704

// Base tag class

705

}

706

707

/**

708

* Standard tags for common language constructs

709

*/

710

public final class StandardTags {

711

712

/**

713

* Tag for expression nodes

714

*/

715

public static final class ExpressionTag extends Tag {

716

private ExpressionTag() {}

717

}

718

719

/**

720

* Tag for statement nodes

721

*/

722

public static final class StatementTag extends Tag {

723

private StatementTag() {}

724

}

725

726

/**

727

* Tag for function call nodes

728

*/

729

public static final class CallTag extends Tag {

730

private CallTag() {}

731

}

732

733

/**

734

* Tag for root nodes

735

*/

736

public static final class RootTag extends Tag {

737

private RootTag() {}

738

}

739

740

/**

741

* Tag for root body nodes

742

*/

743

public static final class RootBodyTag extends Tag {

744

private RootBodyTag() {}

745

}

746

747

/**

748

* Tag for read variable nodes

749

*/

750

public static final class ReadVariableTag extends Tag {

751

private ReadVariableTag() {}

752

}

753

754

/**

755

* Tag for write variable nodes

756

*/

757

public static final class WriteVariableTag extends Tag {

758

private WriteVariableTag() {}

759

}

760

}

761

762

/**

763

* Marks nodes as instrumentable

764

*/

765

@Retention(RetentionPolicy.RUNTIME)

766

@Target(ElementType.TYPE)

767

public @interface Instrumentable {

768

769

/**

770

* Factory class for creating wrappers

771

* @return Wrapper factory class

772

*/

773

Class<? extends ProvidedTags> factory();

774

}

775

776

/**

777

* Tags provided by an instrumentable node

778

*/

779

public abstract class ProvidedTags {

780

781

/**

782

* Get provided tag classes

783

* @return Array of tag classes

784

*/

785

public abstract Class<?>[] getProvidedTags();

786

}

787

788

/**

789

* Generates wrapper nodes for instrumentation

790

*/

791

@Retention(RetentionPolicy.CLASS)

792

@Target(ElementType.TYPE)

793

public @interface GenerateWrapper {

794

795

/**

796

* Delegate factory class

797

* @return Factory class

798

*/

799

Class<?> delegateTo();

800

}

801

```

802

803

### Source Load Monitoring

804

805

System for monitoring source code loading and compilation.

806

807

```java { .api }

808

/**

809

* Listener interface for source loading events

810

*/

811

public interface LoadSourceListener {

812

813

/**

814

* Called when source is loaded

815

* @param event Source load event

816

*/

817

void onLoad(LoadSourceEvent event);

818

}

819

820

/**

821

* Listener interface for source section loading events

822

*/

823

public interface LoadSourceSectionListener {

824

825

/**

826

* Called when source section is loaded

827

* @param event Source section load event

828

*/

829

void onLoad(LoadSourceSectionEvent event);

830

}

831

832

/**

833

* Event representing source loading

834

*/

835

public abstract class LoadSourceEvent {

836

837

/**

838

* Get loaded source

839

* @return Source instance

840

*/

841

public abstract Source getSource();

842

}

843

844

/**

845

* Event representing source section loading

846

*/

847

public abstract class LoadSourceSectionEvent {

848

849

/**

850

* Get loaded source section

851

* @return SourceSection instance

852

*/

853

public abstract SourceSection getSourceSection();

854

855

/**

856

* Get associated node

857

* @return Node instance

858

*/

859

public abstract Node getNode();

860

}

861

```

862

863

## Types

864

865

### Debugging Infrastructure Types

866

867

```java { .api }

868

/**

869

* Options for instrumentation configuration

870

*/

871

public final class OptionValues {

872

873

/**

874

* Get option value

875

* @param key Option key

876

* @return Option value

877

*/

878

public <T> T get(OptionKey<T> key) {

879

return null;

880

}

881

882

/**

883

* Check if option has value

884

* @param key Option key

885

* @return true if has value

886

*/

887

public boolean hasBeenSet(OptionKey<?> key) {

888

return false;

889

}

890

}

891

892

/**

893

* Key for accessing option values

894

* @param <T> Option value type

895

*/

896

public final class OptionKey<T> {

897

898

/**

899

* Get default value

900

* @return Default value

901

*/

902

public T getDefaultValue() {

903

return null;

904

}

905

}

906

907

/**

908

* Descriptor for option definitions

909

*/

910

public final class OptionDescriptor {

911

912

/**

913

* Get option name

914

* @return Option name

915

*/

916

public String getName() {

917

return null;

918

}

919

920

/**

921

* Get option help text

922

* @return Help text

923

*/

924

public String getHelp() {

925

return null;

926

}

927

928

/**

929

* Get option key

930

* @return OptionKey instance

931

*/

932

public OptionKey<?> getKey() {

933

return null;

934

}

935

}

936

```