8322992: Javac fails with StackOverflowError when compiling deeply nested synchronized blocks

Backport-of: 0b9350e8b6
This commit is contained in:
Goetz Lindenmaier
2025-07-22 11:25:01 +00:00
committed by Vitaly Provodin
parent 16ada2c662
commit ebe16df56a
2 changed files with 1214 additions and 18 deletions

View File

@@ -1100,29 +1100,38 @@ public class Gen extends JCTree.Visitor {
}
public void visitBlock(JCBlock tree) {
/* this method is heavily invoked, as expected, for deeply nested blocks, if blocks doesn't happen to have
* patterns there will be an unnecessary tax on memory consumption every time this method is executed, for this
* reason we have created helper methods and here at a higher level we just discriminate depending on the
* presence, or not, of patterns in a given block
*/
if (tree.patternMatchingCatch != null) {
Set<JCMethodInvocation> prevInvocationsWithPatternMatchingCatch = invocationsWithPatternMatchingCatch;
ListBuffer<int[]> prevRanges = patternMatchingInvocationRanges;
State startState = code.state.dup();
try {
invocationsWithPatternMatchingCatch = tree.patternMatchingCatch.calls2Handle();
patternMatchingInvocationRanges = new ListBuffer<>();
doVisitBlock(tree);
} finally {
Chain skipCatch = code.branch(goto_);
JCCatch handler = tree.patternMatchingCatch.handler();
code.entryPoint(startState, handler.param.sym.type);
genPatternMatchingCatch(handler, env, patternMatchingInvocationRanges.toList());
code.resolve(skipCatch);
invocationsWithPatternMatchingCatch = prevInvocationsWithPatternMatchingCatch;
patternMatchingInvocationRanges = prevRanges;
}
visitBlockWithPatterns(tree);
} else {
doVisitBlock(tree);
internalVisitBlock(tree);
}
}
private void doVisitBlock(JCBlock tree) {
private void visitBlockWithPatterns(JCBlock tree) {
Set<JCMethodInvocation> prevInvocationsWithPatternMatchingCatch = invocationsWithPatternMatchingCatch;
ListBuffer<int[]> prevRanges = patternMatchingInvocationRanges;
State startState = code.state.dup();
try {
invocationsWithPatternMatchingCatch = tree.patternMatchingCatch.calls2Handle();
patternMatchingInvocationRanges = new ListBuffer<>();
internalVisitBlock(tree);
} finally {
Chain skipCatch = code.branch(goto_);
JCCatch handler = tree.patternMatchingCatch.handler();
code.entryPoint(startState, handler.param.sym.type);
genPatternMatchingCatch(handler, env, patternMatchingInvocationRanges.toList());
code.resolve(skipCatch);
invocationsWithPatternMatchingCatch = prevInvocationsWithPatternMatchingCatch;
patternMatchingInvocationRanges = prevRanges;
}
}
private void internalVisitBlock(JCBlock tree) {
int limit = code.nextreg;
Env<GenContext> localEnv = env.dup(tree, new GenContext());
genStats(tree.stats, localEnv);

File diff suppressed because it is too large Load Diff