oracle/graal · warning · PermanentBailoutException

Non-reducible loop requires too much duplication. Setting %s

Error message

Non-reducible loop requires too much duplication. Setting %s to a value higher than %s may resolve this.

What it means

Thrown when making an irreducible loop reducible would require duplicating more blocks than -Dgraal.MaxDuplicationFactor allows. The mapping pass tracks duplicateBlocks versus postJSRBlockCount * factor; exceeding the budget bails out permanently and the message explicitly tells you which flag to raise.

Source

Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/java/BciBlockMapping.java:1887

                    }
                } else if (step instanceof DuplicationTraversalStep) {
                    workStack.push(new DuplicationTraversalStep((DuplicationTraversalStep) step, successor));
                } else {
                    workStack.push(new TraversalStep(step, successor));
                }
                step.currentSuccessorIndex++;
            } else {
                // We processed all the successors of this block.
                block.active = false;
                assert checkBlocks(blocksNotYetAssignedId, block);
                blocksNotYetAssignedId--;
                if (blocksNotYetAssignedId < 0) {
                    // this should only happen if duplication is active
                    OptionValues options = debug.getOptions();
                    double factor = MaxDuplicationFactor.getValue(options);
                    duplicateBlocks += newDuplicateBlocks;
                    if (duplicateBlocks > postJsrBlockCount * factor) {
                        throw new PermanentBailoutException("Non-reducible loop requires too much duplication. " +
                                        "Setting " + MaxDuplicationFactor.getName() + " to a value higher than " + factor + " may resolve this.");
                    }
                    // there are new duplicate blocks, re-number
                    debug.log(DebugContext.INFO_LEVEL, "Re-numbering blocks to make room for duplicates (old length: %d; new blocks: %d)", blocks.length, newDuplicateBlocks);
                    BciBlock[] newBlocks = new BciBlock[blocks.length + newDuplicateBlocks];
                    for (int i = 0; i < blocks.length; i++) {
                        newBlocks[i + newDuplicateBlocks] = blocks[i];
                        int id = blocks[i].id;
                        assert id == UNASSIGNED_ID : id;
                    }
                    blocksNotYetAssignedId += newDuplicateBlocks;
                    assert NumUtil.assertNonNegativeInt(blocksNotYetAssignedId);
                    newDuplicateBlocks = 0;
                    blocks = newBlocks;
                }
                blocks[blocksNotYetAssignedId] = block;
                debug.log("computeBlockOrder(%s) -> %s", block, block.loops);
                debug.dump(DebugContext.DETAILED_LEVEL, this, "After adding %s", block);

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Increase -Dgraal.MaxDuplicationFactor (e.g. from 2 to 4 or 8) as the message suggests, mindful of compile-time and memory growth.
  2. Recompile/regenerate the class with reducible control flow so no duplication is needed.
  3. If duplication keeps exploding, exclude the method from Graal compilation (-XX:CompileCommand=exclude) as a last resort.

Example fix

# before
java -Dgraal.MaxDuplicationFactor=2 MyApp
# throws: Non-reducible loop requires too much duplication. Setting MaxDuplicationFactor to a value higher than 2.0 may resolve this.

# after
java -Dgraal.MaxDuplicationFactor=6 MyApp
Defensive patterns

Strategy: fallback

Try / catch

// permanent bailout by design; HotSpot falls back. Adjust the flag or the bytecode.

Prevention

When it happens

Trigger: Compiling a method with a non-reducible loop where the duplication pass (enabled because MaxDuplicationFactor > 1.0) generates more duplicate blocks than postJsrBlockCount * MaxDuplicationFactor before all blocks are assigned IDs (blocksNotYetAssignedId < 0).

Common situations: Obfuscated or generated bytecode with large irreducible regions; a MaxDuplicationFactor raised from the default (to fix error 168) but still too small for the amount of duplication the method needs; pathological CFGs where duplication cascades.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/6f5b22cf8a200339. Report an issue: GitHub.