l1a/l1b: PASS; l2: FAIL (missing 2nd slot copy)#565
Open
opencode-agent[bot] wants to merge 1 commit into
Open
Conversation
Co-authored-by: LSantha <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Spec compliance report for
lload_0(JVM Spec: https://docs.oracle.com/javase/specs/jvms/se6/html/Instructions2.doc8.html)Details
l1a Implementation
core/src/core/org/jnode/vm/x86/compiler/l1a/X86BytecodeVisitor.java:3232(visit_lload)core/src/core/org/jnode/vm/x86/compiler/l1a/X86StackFrame.java:351(getWideEbpOffset)core/src/core/org/jnode/vm/bytecode/BytecodeParser.java:276(opcode 0x1e dispatch)lload_0) →handler.visit_lload(0)visit_lload(int index)creates aLocalitem viaifac.createLocal(JvmType.LONG, stackFrame.getWideEbpOffset(typeSizeInfo, index))getWideEbpOffset(index)returnsgetEbpOffset(index + 1), correctly computing the EBP-relative offset for the high 32-bit slot of the long (JVM locals: index=low, index+1=high)VirtualStackpushes aLongItem(category-2), which occupies one virtual stack entry but represents 64 bitsDoubleWordItemloads both halves: 32-bit mode uses twoMOVinstructions (LSB fromdisp+4, MSB fromdisp); 64-bit mode uses singleMOV BITS64BytecodeParser.java:840-841for 16-bit indexindex
l1b Implementation
core/src/core/org/jnode/vm/x86/compiler/l1b/X86BytecodeVisitor.java:4035(visit_lload)core/src/core/org/jnode/vm/x86/compiler/l1b/X86StackFrame.java:343(getWideEbpOffset)core/src/core/org/jnode/vm/bytecode/BytecodeParser.java:276(shared parser)visit_lloadcreatesLocalitem with wide offset fromgetWideEbpOffsetVirtualStack/DoubleWordItemmechanism for category-2 valuesl2 Implementation
Status: ❌ FAIL
Files:
core/src/core/org/jnode/vm/compiler/ir/IRGenerator.java:323(visit_lload)core/src/core/org/jnode/vm/x86/compiler/l2/GenericX86CodeGenerator.java:278(generateCodeFor(VariableRefAssignQuad))core/src/core/org/jnode/vm/x86/compiler/l2/L2ByteCodeSupportChecker.java(no override → implicitly supported)core/src/core/org/jnode/vm/bytecode/BytecodeParser.java:276(shared parser)Issues:
IRGenerator.visit_lload (line 323-330) — Missing second slot copy:
Per JVM spec,
lloadloads from two consecutive local slots (index and index+1) and pushes to two consecutive stack slots (stackOffset and stackOffset+1). The IR only generates oneVariableRefAssignQuadforindex → stackOffset. The second slot (index+1 → stackOffset+1) is never copied. This leaves the high 32 bits of the long uninitialized on the operand stack.GenericX86CodeGenerator.generateCodeFor(VariableRefAssignQuad) (line 332-338) — Single-word move for category-2:
When LHS and RHS are both stack-frame locations (local → stack), the code emits a single
PUSH/POPpair (32-bit in 32-bit mode, 64-bit in 64-bit mode). For aLONGin 32-bit mode, this moves only 32 bits instead of the required 64 bits (two 32-bit words). The code lacks any handling forOperand.LONG/Operand.DOUBLEcategory-2 types in variable-to-variable moves.L2ByteCodeSupportChecker does not override
visit_lload, so the checker returnssupported=trueand L2 attempts compilation, but the generated code is incorrect.Local variable offset calculation: L2 uses
X86StackFrame.getEbpOffsetdirectly (viainitMethodArgumentsatX86Level2Compiler.java:220), which returns per-slot offsets. For a long at indexi, the low slot is atgetEbpOffset(i)and high slot atgetEbpOffset(i+1). The IR treats each JVM local slot as a separateVariable, but thevisit_lloadonly referencesindex(low slot), neverindex+1(high slot).Impact: Any method using
lload_0,lload_1,lload_2,lload_3,lload, orwide lloadcompiled by L2 will produce incorrect results — the high 32 bits of the loaded long will be garbage (uninitialized stack memory).JVM Spec References
From https://docs.oracle.com/javase/specs/jvms/se6/html/Instructions2.doc8.html:
Key requirements verified:
visit_lload(0)in all compilers (BytecodeParser.java:276)lload(BytecodeParser.java:840)DoubleWordItem; l2 marks two slots but fails to copy both)getWideEbpOffset; l2 fails to reference index+1)long(category 2) (all compilers)Summary
getWideEbpOffset)getWideEbpOffset)Recommendation: L2 requires fixes in both
IRGenerator.visit_lload(emit twoVariableRefAssignQuadfor index→stackOffset and index+1→stackOffset+1) andGenericX86CodeGenerator.generateCodeFor(VariableRefAssignQuad)(handle category-2 moves with two 32-bit operations in 32-bit mode).Closes #343
opencode session | github run