8037937: javac: AssertionError during LVT generation, wrong variable ranges

Reviewed-by: mcimadamore
This commit is contained in:
Vicente Romero 2014-05-29 15:28:01 +01:00
parent e0f4450825
commit 92e2e96714
4 changed files with 33 additions and 16 deletions
langtools
src/share/classes/com/sun/tools/javac/jvm
test/tools/javac/flow

@ -1925,6 +1925,13 @@ public class Code {
return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1); return aliveRanges.isEmpty() ? null : aliveRanges.get(aliveRanges.size() - 1);
} }
void removeLastRange() {
Range lastRange = lastRange();
if (lastRange != null) {
aliveRanges.remove(lastRange);
}
}
@Override @Override
public String toString() { public String toString() {
if (aliveRanges == null) { if (aliveRanges == null) {
@ -1955,9 +1962,7 @@ public class Code {
} }
} }
} else { } else {
if (!aliveRanges.isEmpty()) { removeLastRange();
aliveRanges.remove(aliveRanges.size() - 1);
}
} }
} }
@ -1965,16 +1970,14 @@ public class Code {
if (aliveRanges.isEmpty()) { if (aliveRanges.isEmpty()) {
return false; return false;
} }
Range range = lastRange(); return lastRange().length == Character.MAX_VALUE;
return range.length == Character.MAX_VALUE;
} }
public boolean isLastRangeInitialized() { public boolean isLastRangeInitialized() {
if (aliveRanges.isEmpty()) { if (aliveRanges.isEmpty()) {
return false; return false;
} }
Range range = lastRange(); return lastRange().start_pc != Character.MAX_VALUE;
return range.start_pc != Character.MAX_VALUE;
} }
public Range getWidestRange() { public Range getWidestRange() {
@ -2095,7 +2098,7 @@ public class Code {
v.closeRange(length); v.closeRange(length);
putVar(v); putVar(v);
} else { } else {
v.lastRange().start_pc = Character.MAX_VALUE; v.removeLastRange();
} }
} }
} }

@ -1800,8 +1800,7 @@ public class Gen extends JCTree.Visitor {
genStat(tree.thenpart, env, CRT_STATEMENT | CRT_FLOW_TARGET); genStat(tree.thenpart, env, CRT_STATEMENT | CRT_FLOW_TARGET);
thenExit = code.branch(goto_); thenExit = code.branch(goto_);
if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.thenpart)) { if (varDebugInfo && lvtRanges.containsKey(code.meth, tree.thenpart)) {
code.closeAliveRanges(tree.thenpart, code.closeAliveRanges(tree.thenpart, code.cp);
thenExit != null && tree.elsepart == null ? thenExit.pc : code.cp);
} }
} }
if (elseChain != null) { if (elseChain != null) {

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,8 +23,8 @@
/* /*
* @test * @test
* @bug 7047734 8027660 * @bug 7047734 8027660 8037937
* @summary The LVT is not generated correctly during some try/catch scenarios; * @summary The LVT is not generated correctly during some try/catch scenarios
* javac crash while creating LVT entry for a local variable defined in * javac crash while creating LVT entry for a local variable defined in
* an inner block * an inner block
* @library /tools/javac/lib * @library /tools/javac/lib
@ -120,7 +120,7 @@ public class LVTHarness {
for (Map.Entry<ElementKey, AliveRanges> entry : aliveRangeMap.entrySet()) { for (Map.Entry<ElementKey, AliveRanges> entry : aliveRangeMap.entrySet()) {
if (!seenAliveRanges.contains(entry.getKey())) { if (!seenAliveRanges.contains(entry.getKey())) {
error("Redundant @AliveRanges annotation on method " + error("Redundant @AliveRanges annotation on method " +
entry.getKey().elem); entry.getKey().elem + " with key " + entry.getKey());
} }
} }
} }
@ -134,7 +134,7 @@ public class LVTHarness {
for (Method method : classFile.methods) { for (Method method : classFile.methods) {
for (ElementKey elementKey: aliveRangeMap.keySet()) { for (ElementKey elementKey: aliveRangeMap.keySet()) {
String methodDesc = method.getName(constantPool) + String methodDesc = method.getName(constantPool) +
method.descriptor.getParameterTypes(constantPool); method.descriptor.getParameterTypes(constantPool).replace(" ", "");
if (methodDesc.equals(elementKey.elem.toString())) { if (methodDesc.equals(elementKey.elem.toString())) {
checkMethod(constantPool, method, aliveRangeMap.get(elementKey)); checkMethod(constantPool, method, aliveRangeMap.get(elementKey));
seenAliveRanges.add(elementKey); seenAliveRanges.add(elementKey);

@ -33,7 +33,7 @@ public class TestCaseIfElse {
@AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8) @AliveRange(varName="o", bytecodeStart=10, bytecodeLength=8)
@AliveRange(varName="o", bytecodeStart=21, bytecodeLength=9) @AliveRange(varName="o", bytecodeStart=21, bytecodeLength=9)
void m2(String[] args) { void m2() {
Object o; Object o;
int i = 5; int i = 5;
if (i != 5) { if (i != 5) {
@ -45,4 +45,19 @@ public class TestCaseIfElse {
} }
o = "finish"; o = "finish";
} }
@AliveRange(varName="o", bytecodeStart=11, bytecodeLength=3)
@AliveRange(varName="o", bytecodeStart=17, bytecodeLength=2)
Object m3(boolean cond1, boolean cond2) {
Object o;
if (cond1) {
if (cond2) {
o = "then";
} else {
o = "else";
return null;
}
}
return null;
}
} }