8322992: Javac fails with StackOverflowError when compiling deeply nested synchronized blocks
Reviewed-by: jlahoda
This commit is contained in:
parent
20be5e095f
commit
0b9350e8b6
@ -1074,29 +1074,38 @@ public class Gen extends JCTree.Visitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void visitBlock(JCBlock tree) {
|
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) {
|
if (tree.patternMatchingCatch != null) {
|
||||||
Set<JCMethodInvocation> prevInvocationsWithPatternMatchingCatch = invocationsWithPatternMatchingCatch;
|
visitBlockWithPatterns(tree);
|
||||||
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;
|
|
||||||
}
|
|
||||||
} else {
|
} 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;
|
int limit = code.nextreg;
|
||||||
Env<GenContext> localEnv = env.dup(tree, new GenContext());
|
Env<GenContext> localEnv = env.dup(tree, new GenContext());
|
||||||
genStats(tree.stats, localEnv);
|
genStats(tree.stats, localEnv);
|
||||||
|
1187
test/langtools/tools/javac/patterns/SOEDeeplyNestedBlocksTest.java
Normal file
1187
test/langtools/tools/javac/patterns/SOEDeeplyNestedBlocksTest.java
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user