You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@flink.apache.org by "Moses (Jira)" <ji...@apache.org> on 2026/09/09 03:41:00 UTC

[jira] [Created] (FLINK-40605) Code splitting still exceeds 64 KB for large if blocks containing loops with break or continue

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)