Skip to content

[codex] Implement frame-aware line instrumentation#49

Merged
hengyunabc merged 1 commit into
alibaba:masterfrom
hengyunabc:codex/frame-aware-line-instrumentation
Jun 7, 2026
Merged

[codex] Implement frame-aware line instrumentation#49
hengyunabc merged 1 commit into
alibaba:masterfrom
hengyunabc:codex/frame-aware-line-instrumentation

Conversation

@hengyunabc

Copy link
Copy Markdown
Collaborator

Summary

  • Add frame-aware @AtLine matching with operand stack spill/restore for line callbacks.
  • Add line mode and duplicate-line policies, including control-flow-aware duplicate handling.
  • Make line-local variable binding frame-aware so unreadable slots are skipped safely.
  • Add focused regression tests for stack preservation, local variables, concurrency, duplicate line handling, and analysis-limit restoration.

Root Cause

Line instrumentation could insert callbacks at source line markers without accounting for the current operand stack. That made some line locations unsafe when the original bytecode had live stack values at the line boundary, and it also made duplicate-line/control-flow cases ambiguous.

Validation

  • ./mvnw -pl bytekit-core test
    • 76 tests run, 0 failures, 0 errors, 1 skipped.
  • git diff --cached --check
    • no whitespace errors before commit.
  • Downstream verification in Arthas with local bytekit-core:0.1.6:
    • ./mvnw -pl core -am -Dtest=EnhancerTest,WatchCommandTest,OgnlTest -DfailIfNoTests=false -Dsurefire.failIfNoSpecifiedTests=false -DskipITs test
    • ./mvnw -pl packaging -am -DskipTests package
    • packaged watch demo.MathGame primeFactors --line 51 '{params, localVarMap}' -x 2 -n 1 hit AtLine:51 and printed expected locals.

@hengyunabc hengyunabc requested a review from Copilot June 7, 2026 15:16
@hengyunabc hengyunabc marked this pull request as ready for review June 7, 2026 15:16

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR upgrades @AtLine instrumentation to be frame-aware by analyzing ASM frames at each line marker, spilling/restoring the operand stack when needed, and introducing configurable behavior for duplicate line numbers. It also updates local-variable bindings to avoid reading slots that are not live/typed in the current frame, and adds targeted regression tests for stack/local handling and concurrency-related scenarios.

Changes:

  • Add frame-aware line matching (ASM analysis) and stack spill/restore support for line callbacks.
  • Introduce LineMode and LineDuplicatePolicy and wire them through @AtLine / LineLocationMatcher.
  • Make @Binding.LocalVars / @Binding.LocalVarNames frame-aware to skip unreadable locals; add comprehensive regression tests.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
bytekit-core/src/test/java/com/alibaba/bytekit/asm/interceptor/AtLineFrameAwareTest.java New regression tests covering stack preservation, frame-aware locals, duplicate-line policies, and concurrency scenarios.
bytekit-core/src/main/java/com/alibaba/bytekit/utils/AsmOpUtils.java Add frame-aware local variable filtering to avoid loading unreadable/uninitialized locals.
bytekit-core/src/main/java/com/alibaba/bytekit/asm/MethodProcessor.java Add initLineStackVariableNode helper for allocating locals used by line stack spilling.
bytekit-core/src/main/java/com/alibaba/bytekit/asm/location/Location.java Extend LineLocation with frame/stack metadata and a stack saver that spills/restores operand stack via temp locals.
bytekit-core/src/main/java/com/alibaba/bytekit/asm/location/LineMode.java New enum to select FRAME_AWARE vs LEGACY line matching behavior.
bytekit-core/src/main/java/com/alibaba/bytekit/asm/location/LineDuplicatePolicy.java New enum defining duplicate-line handling policies.
bytekit-core/src/main/java/com/alibaba/bytekit/asm/location/LineLocationMatcher.java Implement frame analysis, frame usability filtering, and duplicate-line policies; compute conservative analysis limits.
bytekit-core/src/main/java/com/alibaba/bytekit/asm/location/filter/GroupLocationFilter.java Refactor to extend AnyLocationFilter.
bytekit-core/src/main/java/com/alibaba/bytekit/asm/location/filter/AnyLocationFilter.java New “any-of” composite location filter implementation.
bytekit-core/src/main/java/com/alibaba/bytekit/asm/location/filter/AllLocationFilter.java New “all-of” composite location filter implementation.
bytekit-core/src/main/java/com/alibaba/bytekit/asm/interceptor/annotation/AtLine.java Add mode() and duplicatePolicy() options and pass them into LineLocationMatcher.
bytekit-core/src/main/java/com/alibaba/bytekit/asm/binding/LocalVarsBinding.java Use frame-aware valid-local filtering when the current location is a frame-aware LineLocation.
bytekit-core/src/main/java/com/alibaba/bytekit/asm/binding/LocalVarNamesBinding.java Same as above for local variable names binding.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +93 to +113
boolean rejectAfterControlFlow = effectivePolicy == LineDuplicatePolicy.REJECT_AFTER_CONTROL_FLOW
&& seenTargetLines.contains(lineNumberNode.line)
&& Boolean.TRUE.equals(controlFlowAfterLine.get(lineNumberNode.line));
if (!rejectAfterControlFlow
&& allowByDuplicatePolicy(effectivePolicy, matchedLines, lineNumberNode.line,
lineBlockBoundary)
&& locationFilter.allow(lineNumberNode, LocationType.LINE, false)) {
if (mode == LineMode.FRAME_AWARE) {
Frame<BasicValue> frame = frameOf(methodProcessor.getMethodNode(), lineFrames.frames,
lineNumberNode);
if (isFrameUsable(frame, lineFrames.precise)) {
locations.add(new LineLocation(lineNumberNode, lineNumberNode.line, frame,
locationIndex++));
}
} else {
locations.add(new LineLocation(lineNumberNode, lineNumberNode.line));
}
}
seenTargetLines.add(lineNumberNode.line);
controlFlowAfterLine.put(lineNumberNode.line, Boolean.FALSE);
}
Comment on lines +31 to +33
LineMode mode() default LineMode.FRAME_AWARE;

LineDuplicatePolicy duplicatePolicy() default LineDuplicatePolicy.DEFAULT;
}

start.countDown();
done.await();

private Object newInstance(String internalName, byte[] bytes) throws Exception {
Class<?> clazz = new TestClassLoader().define(internalName.replace('/', '.'), bytes);
return clazz.newInstance();
@hengyunabc hengyunabc merged commit 0698ea5 into alibaba:master Jun 7, 2026
3 checks passed
@hengyunabc hengyunabc deleted the codex/frame-aware-line-instrumentation branch June 7, 2026 15:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants