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

Reviewed-by: jlahoda
This commit is contained in:
Vicente Romero 2024-04-22 16:31:32 +00:00
parent 20be5e095f
commit 0b9350e8b6
2 changed files with 1214 additions and 18 deletions

View File

@ -1074,29 +1074,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