Moses created FLINK-40605:
-----------------------------

             Summary: Code splitting still exceeds 64 KB for large if blocks 
containing loops with break or continue
                 Key: FLINK-40605
                 URL: https://issues.apache.org/jira/browse/FLINK-40605
             Project: Flink
          Issue Type: Bug
          Components: Table SQL / Runtime
    Affects Versions: 2.4.0
         Environment: Apache Flink master / 2.4-SNAPSHOT at 
4e9d5412d3dcd4776b750e8a94ba6e86d2b409c6; JDK 17; Janino 3.1.12; repository 
Maven wrapper 3.9.16. Reproduced on 9 September 2026.
            Reporter: Moses


h2. Problem

A large generated {{if}} block can still fail Janino compilation with {{Code 
grows beyond 64 KB}} when it contains a small, self-contained loop with 
{{break}} or {{continue}}, even after the full {{JavaCodeSplitter.split(...)}} 
pipeline has run.

This is a remaining code-splitting corner case, rather than a request to reopen 
FLINK-23007. FLINK-23007 introduced the splitter, and FLINK-27246 subsequently 
added block rewriting. The current implementation still conservatively rejects 
an enclosing statement whenever any descendant contains a jump.

h2. Reproduction

Reproduced on Apache Flink {{master}} / {{2.4-SNAPSHOT}} at commit 
{{4e9d5412d3dcd4776b750e8a94ba6e86d2b409c6}} on 9 September 2026, with JDK 17 
and Janino 3.1.12. Released versions have not been tested for this specific 
reproduction.

Run the following with {{JavaCodeSplitter}} and Janino on the classpath. Repeat 
with {{jump = "continue"}} to reproduce the second case.

{code:java}
import org.apache.flink.table.codesplit.JavaCodeSplitter;
import org.codehaus.janino.SimpleCompiler;

public class CodeSplitReproducer {
    public static void main(String[] args) throws Exception {
        String jump = "break";
        String code =
                "public class Generated { public void run(int[] a) {"
                        + "if (a[0] >= 0) {"
                        + "a[1] += 1;".repeat(15000)
                        + "for (int i = 0; i < 5; i++) {"
                        + "a[2]++; if (i == 2) { " + jump + "; } a[3]++;"
                        + "}} a[4] = 1; }}";

        String split = JavaCodeSplitter.split(code, 4000, 10000);
        SimpleCompiler compiler = new SimpleCompiler();
        compiler.cook(split);

        Class<?> generated = compiler.getClassLoader().loadClass("Generated");
        Object instance = generated.getDeclaredConstructor().newInstance();
        int[] result = {0, 0, 0, 0, 0};
        generated.getMethod("run", int[].class).invoke(instance, result);
        System.out.println(java.util.Arrays.toString(result));
    }
}
{code}

*Actual:* compilation of the transformed code fails with:
{noformat}
Caused by: org.codehaus.commons.compiler.InternalCompilerException: Code grows 
beyond 64 KB
{noformat}

*Expected:* the large enclosing block is split into compilable methods without 
changing control flow. The result is {{[0, 15000, 3, 2, 1]}} for {{break}} and 
{{[0, 15000, 5, 4, 1]}} for {{continue}}. For an input of {{[-1, 0, 0, 0, 0]}}, 
the branch is skipped and the result is {{[-1, 0, 0, 0, 1]}}.

h2. Cause and proposed fix

{{BlockStatementSplitter.BlockStatementVisitor.visitStatement}} currently 
returns early when {{getNumOfReturnOrJumpStatements(ctx) != 0}}. Counting every 
nested {{break}}/{{continue}} prevents splitting the entire enclosing {{if}}, 
even though the loop and its jump targets can remain together inside an 
extracted method.

Track returns separately, retain the conservative return guard and the jump 
guard when traversing loop bodies, and allow enclosing blocks containing 
complete loops to be extracted. This does not attempt to support arbitrary 
oversized loop bodies containing jumps.

h2. Patch and verification

A candidate fix with regression tests is available in [this fork 
commit|https://github.com/ChaomingZhangCN/flink/commit/12da06a50a0e7fe321560b28c9ab1b65f4fd9a53]
 (branch {{codex/fix-code-splitter-nested-jumps}}).

* Both oversized-branch regression cases fail on the unmodified base commit 
with the 64 KB error and pass with the fix.
* Execution assertions cover {{break}}, {{continue}}, skipped branches, labeled 
jumps and early returns.
* The complete code-splitter module suite passes against its {{2.4-SNAPSHOT}} 
reactor dependencies: 54 tests, 0 failures, 0 errors and 1 pre-existing skipped 
test.
* Spotless, Checkstyle and a module-scoped RAT check pass. The full repository 
test suite has not been run.

Related: FLINK-23007 and FLINK-27246.




--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to