{"record":{"id":"5ab7fe1a47a58269","repo":"oracle/graal","slug":"osr-with-locks-disabled","errorCode":null,"errorMessage":"OSR with locks disabled.","messagePattern":"OSR with locks disabled\\.","errorType":"exception","errorClass":"PermanentBailoutException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/phases/OnStackReplacementPhase.java","lineNumber":143,"sourceCode":"            return;\n        }\n        debug.dump(DebugContext.DETAILED_LEVEL, graph, \"OnStackReplacement initial at bci %d\", graph.getEntryBCI());\n\n        final EntryMarkerNode originalOSRNode = getEntryMarker(graph);\n        final LoopBeginNode originalOSRLoop = osrLoop(originalOSRNode, providers);\n        final boolean currentOSRWithLocks = osrWithLocks(originalOSRNode);\n\n        if (originalOSRLoop == null) {\n            /*\n             * OSR with Locks: We do not have an OSR loop for the original OSR bci. Therefore we\n             * cannot decide where to deopt and which framestate will be used. In the worst case the\n             * framestate of the OSR entry would be used.\n             */\n            throw new PermanentBailoutException(\"OSR compilation without OSR entry loop.\");\n        }\n\n        if (!supportOSRWithLocks(graph.getOptions()) && currentOSRWithLocks) {\n            throw new PermanentBailoutException(\"OSR with locks disabled.\");\n        }\n\n        EntryMarkerNode osr = OnStackReplacementUtils.peelEntryLoops(graph, providers.getLoopsDataProvider(), () -> getEntryMarker(graph), loop -> {\n        },\n                        (iterations, maxIterations) -> {\n                            throw GraalError.shouldNotReachHere(iterations + \" \" + maxIterations); // ExcludeFromJacocoGeneratedReport\n                        }, \"OnStackReplacement loop peeling result\");\n\n        StartNode start = graph.start();\n        FrameState osrState = osr.stateAfter();\n        OSRStartNode osrStart;\n        try (DebugCloseable context = osr.withNodeSourcePosition()) {\n            osr.setStateAfter(null);\n            osrStart = graph.add(new OSRStartNode());\n            FixedNode next = osr.next();\n            osr.setNext(null);\n            osrStart.setNext(next);\n            graph.setStart(osrStart);","sourceCodeStart":125,"sourceCodeEnd":161,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/hotspot/phases/OnStackReplacementPhase.java#L125-L161","documentation":"PermanentBailoutException thrown when an OSR compilation contains monitors (synchronized blocks on the OSR path) but the SupportOSRWithLocks option is disabled. OSR with locks requires reconstructing monitor state at the OSR entry, a feature gated behind an option; when off, Graal permanently bails out rather than emit incorrect lock state.","triggerScenarios":"OSR-compiling a method with a synchronized loop (or a loop containing monitorenter/monitorexit) while -Dgraal.SupportOSRWithLocks=false (its default in some configurations). osrWithLocks(entryMarker) reports the monitors and the option check fails.","commonSituations":"Benchmarks with synchronized hot loops running on configurations where OSR+locks support is disabled; explicitly turning the option off for determinism; older compiler builds where the feature was immature.","solutions":["Enable the feature: -Dgraal.SupportOSRWithLocks=true.","Refactor the hot loop out of the synchronized region so OSR sees no monitors.","Accept the bailout (interpretation continues) if OSR of that method is not performance-critical."],"exampleFix":"# before\n-XX:+UseJVMCICompiler  # SupportOSRWithLocks defaults off\n# PermanentBailoutException: OSR with locks disabled.\n\n# after\n-XX:+UseJVMCICompiler -Dgraal.SupportOSRWithLocks=true","handlingStrategy":"validation","validationCode":"// Before enabling Graal on workloads with synchronized hot loops\nboolean needsOsrLocks = workloadHasSynchronizedLoops;\nboolean osrLocksEnabled = Boolean.parseBoolean(System.getProperty(\"graal.SupportOSRWithLocks\", \"false\"));\nif (needsOsrLocks && !osrLocksEnabled) {\n    System.setProperty(\"graal.SupportOSRWithLocks\", \"true\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    // run workload under JVMCI\n} catch (PermanentBailoutException e) {\n    if (\"OSR with locks disabled.\".equals(e.getMessage())) {\n        // relaunch with -Dgraal.SupportOSRWithLocks=true\n    }\n}","preventionTips":["Include -Dgraal.SupportOSRWithLocks=true in flag sets for lock-heavy benchmarks.","Prefer hoisting synchronization out of hot loops so OSR never sees monitors."],"tags":["graalvm","osr","locks","compiler","bailout"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}