{"record":{"id":"4517efb267920ef4","repo":"oracle/graal","slug":"out-of-registers-s","errorCode":null,"errorMessage":"out of registers%s","messagePattern":"out of registers(.+?)","errorType":"exception","errorClass":"GraalError","httpStatus":null,"severity":"critical","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/gen/LIRCompilerBackend.java","lineNumber":123,"sourceCode":"        } finally {\n            graph.checkCancellation();\n        }\n    }\n\n    @SuppressWarnings(\"try\")\n    public static LIRGenerationResult emitLIR(Backend backend, StructuredGraph graph, Object stub, RegisterConfig registerConfig, LIRSuites lirSuites,\n                    EntryPointDecorator entryPointDecorator) {\n        String registerPressure = GraalOptions.RegisterPressure.getValue(graph.getOptions());\n        String[] allocationRestrictedTo = registerPressure == null ? null : registerPressure.split(\",\");\n        try {\n            return emitLIR0(backend, graph, stub, registerConfig, lirSuites, allocationRestrictedTo, entryPointDecorator);\n        } catch (OutOfRegistersException e) {\n            if (allocationRestrictedTo != null && !GraalOptions.BailoutOnRegisterPressureFailure.getValue(graph.getOptions())) {\n                allocationRestrictedTo = null;\n                return emitLIR0(backend, graph, stub, registerConfig, lirSuites, allocationRestrictedTo, entryPointDecorator);\n            }\n            /* If the re-execution fails we convert the exception into a \"hard\" failure */\n            throw new GraalError(e, \"out of registers%s\", allocationRestrictedTo == null ? \"\" : \": \" + Arrays.toString(allocationRestrictedTo));\n        } finally {\n            graph.checkCancellation();\n        }\n    }\n\n    @SuppressWarnings(\"try\")\n    private static LIRGenerationResult emitLIR0(Backend backend,\n                    StructuredGraph graph,\n                    Object stub,\n                    RegisterConfig registerConfig,\n                    LIRSuites lirSuites,\n                    String[] allocationRestrictedTo, EntryPointDecorator entryPointDecorator) {\n        DebugContext debug = graph.getDebug();\n        try (DebugContext.Scope ds = debug.scope(\"EmitLIR\"); DebugCloseable a = EmitLIR.start(debug)) {\n            assert graph.isAfterStage(StageFlag.VALUE_PROXY_REMOVAL);\n\n            ScheduleResult schedule = graph.getLastSchedule();\n            HIRBlock[] blocks = schedule.getCFG().getBlocks();","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/gen/LIRCompilerBackend.java#L105-L141","documentation":"LIRCompilerBackend.emitLIR catches OutOfRegistersException from LIR generation/register allocation. If allocation was restricted via -Dgraal.RegisterPressure and BailoutOnRegisterPressureFailure is false, it retries unrestricted; otherwise (or if the retry itself fails) it converts the failure into a hard GraalError('out of registers...') listing the restriction. This is an internal compiler error, not a normal bailout — the compilation cannot proceed at all.","triggerScenarios":"Setting -Dgraal.RegisterPressure to too few registers for the LIR's needs (e.g. a single register for code containing 64-bit operations needing scratch registers), together with -Dgraal.BailoutOnRegisterPressureFailure=true, which skips the unrestricted retry. Also thrown when even unrestricted allocation runs out of registers, which normally indicates a backend bug.","commonSituations":"Register-allocation experiments and CI fuzzing configurations using RegisterPressure; AArch64/x86 lists that omit mandatory registers needed by specific LIR instructions; changes in LIR instruction constraints after a Graal upgrade making an old restriction list impossible to satisfy.","solutions":["Remove or widen the -Dgraal.RegisterPressure restriction — the message lists the exact restricted set that failed.","If you intentionally restrict allocation, drop -Dgraal.BailoutOnRegisterPressureFailure=true so the compiler can retry with all registers as the fallback.","If no RegisterPressure was set (message shows no register list), this is a compiler/backend bug — report it with the graph dump and stack trace."],"exampleFix":"# before\n-Dgraal.RegisterPressure=rax,rbx -Dgraal.BailoutOnRegisterPressureFailure=true\n\n# after\n-Dgraal.RegisterPressure=rax,rbx,rcx,rdx  # or remove the option entirely","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    LIRGenerationResult lir = LIRCompilerBackend.emitLIR(backend, graph, stub, registerConfig, lirSuites, decorator);\n} catch (GraalError e) {\n    if (e.getMessage().startsWith(\"out of registers\")) {\n        // retry without RegisterPressure restriction\n        LIRGenerationResult lir = LIRCompilerBackend.emitLIR(backend, graph, stub, registerConfig, lirSuites, decorator); // with unrestricted config\n    } else {\n        throw e;\n    }\n}","preventionTips":["Never enable RegisterPressure restrictions without also leaving BailoutOnRegisterPressureFailure=false so the unrestricted retry remains possible.","Smoke-test restricted-register configurations per backend after every Graal upgrade — LIR constraints change."],"tags":["register-allocation","lir","compiler-backend","options","graal-error"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}