{"record":{"id":"f88cc8f1b96769ff","repo":"oracle/graal","slug":"at-s-bci-s-opcode-s-s-has-a-stack-effect-o","errorCode":null,"errorMessage":"At %s, bci %s: opcode %s (%s) has a stack effect of %s, the stack size is %s + %s, this will underflow the bytecode stack.","messagePattern":"At (.+?), bci (.+?): opcode (.+?) \\((.+?)\\) has a stack effect of (.+?), the stack size is (.+?) \\+ (.+?), this will underflow the bytecode stack\\.","errorType":"exception","errorClass":"PermanentBailoutException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/java/FrameStateBuilder.java","lineNumber":440,"sourceCode":"            return;\n        }\n        if (rethrowException) {\n            /*\n             * We seem to be inside explicit exception handling code, with the operation's inputs\n             * already popped off the stack and an exception pushed instead. We can't recover the\n             * original stack size for verification.\n             */\n            return;\n        }\n\n        int pushedSlotCount = 0;\n        if (pushedSlotKinds != null) {\n            for (JavaKind pushedKind : pushedSlotKinds) {\n                pushedSlotCount += pushedKind.getSlotCount();\n            }\n        }\n        if (stackSize + pushedSlotCount + Bytecodes.stackEffectOf(opcode) < 0) {\n            throw new PermanentBailoutException(\"At %s, bci %s: opcode %s (%s) has a stack effect of %s, the stack size is %s + %s, this will underflow the bytecode stack.\",\n                            code, bci, opcode & 0xff, Bytecodes.nameOf(opcode), Bytecodes.stackEffectOf(opcode), stackSize, pushedSlotCount);\n        }\n    }\n\n    public NodeSourcePosition createBytecodePosition(int bci) {\n        BytecodeParser parent = parser.getParent();\n        NodeSourcePosition position = create(bci, parent);\n        return position;\n    }\n\n    private NodeSourcePosition create(int bci, BytecodeParser parent) {\n        if (outerSourcePosition == null && parent != null) {\n            outerSourcePosition = parent.getFrameStateBuilder().createBytecodePosition(parent.bci());\n        }\n        if (bci == BytecodeFrame.AFTER_EXCEPTION_BCI && parent != null) {\n            return FrameState.toSourcePosition(outerFrameState);\n        }\n        if (bci == BytecodeFrame.INVALID_FRAMESTATE_BCI) {","sourceCodeStart":422,"sourceCodeEnd":458,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/java/FrameStateBuilder.java#L422-L458","documentation":"FrameStateBuilder.check JDK26-style stack-usage verifier: before an opcode is processed, it computes stackSize + pushedSlotCount + stackEffectOf(opcode) and permanently bails out if the result is negative — the instruction would pop more values than exist on the operand stack (stack underflow). Well-formed, verified bytecode never triggers this; hitting it means the bytecode is malformed or the frame state tracking diverged from reality.","triggerScenarios":"FrameStateBuilder stack check firing for an opcode at a bci where the tracked stack size plus the values pushed by the current operation is smaller than the opcode's pop count — typical of hand-written/modified bytecode that fails verification, or of long/complex values (TWO_SLOT_MARKER handling) confusing the slot accounting.","commonSituations":"Malformed class files from broken generators or aggressive obfuscators; instrumentation agents inserting pops/branches that leave the stack inconsistent; rare Graal frame-state bugs after unusual store/load sequences — the message includes code, bci, opcode, stack effect and sizes to pinpoint it.","solutions":["Run the class through a strict verifier (`java -Xverify:all -Xshare:off`) or a bytecode checker to confirm and locate the malformed method.","Fix or regenerate the bytecode so each branch target has a consistent stack shape.","If verification passes, capture the bci/opcode from the message and report a Graal compiler issue with the reproducing class."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// verify stack consistency at every branch target before shipping the class file\n// tools: `java -Xverify:all`, ASM CheckClassAdapter, or jacoco/spotbugs bytecode checks","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Run strict bytecode verification on all generated classes in CI.","When writing ASM transformers, recompute stack-map frames and test on both int and long paths (TWO_SLOT handling)."],"tags":["graalvm","bytecode-verification","stack-underflow","frame-state","bailout"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}