{"record":{"id":"4a4a083ab48763be","repo":"oracle/graal","slug":"cannot-handle-d-variables-in-d-loops","errorCode":null,"errorMessage":"Cannot handle %d variables in %d loops","messagePattern":"Cannot handle (.+?) variables in (.+?) loops","errorType":"exception","errorClass":"PermanentBailoutException","httpStatus":null,"severity":"warning","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java","lineNumber":186,"sourceCode":"    }\n\n    /**\n     * Computes local live sets (i.e. {@link BlockData#liveGen} and {@link BlockData#liveKill})\n     * separately for each block.\n     */\n    @SuppressWarnings(\"try\")\n    void computeLocalLiveSets() {\n        int liveSize = allocator.liveSetSize();\n        int variables = allocator.operandSize();\n        int loops = allocator.numLoops();\n        long nBits = (long) variables * loops;\n        try {\n            if (nBits > Integer.MAX_VALUE) {\n                throw new OutOfMemoryError();\n            }\n            intervalInLoop = new BitMap2D(variables, loops);\n        } catch (OutOfMemoryError e) {\n            throw new PermanentBailoutException(e, \"Cannot handle %d variables in %d loops\", variables, loops);\n        }\n\n        try {\n            final SparseBitSet liveGenScratch = new SparseBitSet();\n            final SparseBitSet liveKillScratch = new SparseBitSet();\n            // iterate all blocks\n            for (int blockId : allocator.sortedBlocks()) {\n                BasicBlock<?> block = allocator.getLIR().getBlockById(blockId);\n                try (Indent indent = debug.logAndIndent(\"compute local live sets for block %s\", block)) {\n\n                    liveGenScratch.clear();\n                    liveKillScratch.clear();\n\n                    ArrayList<LIRInstruction> instructions = allocator.getLIR().getLIRforBlock(block);\n                    int numInst = instructions.size();\n\n                    ValueConsumer useConsumer = (operand, mode, flags) -> {\n                        if (LIRValueUtil.isVariable(operand)) {","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java#L168-L204","documentation":"Thrown by LinearScanLifetimeAnalysisPhase.computeLocalLiveSets when allocating the per-variable/per-loop BitMap2D (variables x loops bits) fails: either the bit count exceeds Integer.MAX_VALUE or the allocation throws OutOfMemoryError. The linear-scan allocator cannot track loop membership for such a huge variable/loop product, so the compilation permanently bails out wrapping the OOM.","triggerScenarios":"new BitMap2D(variables, loops) throwing OutOfMemoryError (or nBits > Integer.MAX_VALUE throwing it explicitly) — a method with an enormous number of LIR variables (many virtual registers after register allocation setup) multiplied by many loops, e.g. tens of thousands of variables times thousands of loops.","commonSituations":"Machine-generated mega-methods (query compilers, state machines, shader-like kernels); methods whose inlining exploded variable counts; memory-constrained containers where even a legal-size allocation fails — the message reports the exact variables/loops counts to distinguish a real limit breach from a tight -Xmx/-XX:MaxHeapSizeForCompilation.","solutions":["If variables*loops is genuinely near Integer.MAX_VALUE, refactor the method (split it, reduce loop count) — no flag fixes the structural limit.","If the container is merely low on memory, raise the JVM's heap budget so the bit set allocation succeeds.","Check -XX:CompileCommand filtering for the offending mega-method to exclude it from Graal compilation."],"exampleFix":null,"handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// permanent bailout; if caused by heap pressure rather than the 2^31 limit,\n// raising -Xmx lets the same method compile on retry.","preventionTips":["Keep generated mega-methods under control (split by region/statement batches).","Size the JVM heap for JIT compilation load, not just application load."],"tags":["graalvm","register-allocation","lsra","out-of-memory","bailout"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}