Here is a new patch to replace the former one on variable backpropagation. Previously
I missed an occurence of addMonitorVariable in JTryFinallyStatement.java. Again the
former code could mess up the variables and be the source of really strange NullPointerException.
The test case, contributed by Helmer, is given in attachment. My new patch is also attached
the this e-mail.
Helmer, could you test Eclipse with this new patch ?
Cheers,
Guilhem.
P.S.: Jim, your patch to KJC seems to pose problems when I run "javac test.java" (or anything other program)
To be able to compile a Java file you need now to always provide "-d ."
public class test
{
public static void main (String args[])
{
try { }
finally {
synchronized (new Object()) {
int i = 0;
}
}
}
}
diff -ur kopi-2.1B.orig/src/bytecode/ssa/LivenessComputer.java
kopi-2.1B/src/bytecode/ssa/LivenessComputer.java
--- kopi-2.1B.orig/src/bytecode/ssa/LivenessComputer.java 2002-07-15
20:53:29.000000000 +0200
+++ kopi-2.1B/src/bytecode/ssa/LivenessComputer.java 2003-07-31 09:00:34.000000000
+0200
@@ -334,7 +334,7 @@
if (phi instanceof QPhiCatch) {
//compute temp = (use[ij] - def[i1i2..i(j-1)]).
- temp.clear();
+ for (int u=0;u<temp.size();u++) temp.clear(u);;
QOperandBox[] operands = phi.getUses();
for (int u = 0; u < operands.length; ++u) {
if (operands[u].getOperand() instanceof QSSAVar) {
@@ -360,7 +360,7 @@
while (insts.hasNext()) {
//compute temp = (use[ij] - def[i1i2..i(j-1)]).
- temp.clear();
+ for (int u=0;u<temp.size();u++) temp.clear(u);;
QInst inst = (QInst) insts.next();
QOperandBox[] operands = inst.getUses();
for (int u = 0; u < operands.length; ++u) {
@@ -434,7 +434,7 @@
//out[n] = union {s in succ[n]} in[s]
- out.clear();
+ for (int u=0;u<out.size();u++) out.clear(u);
Iterator succs = nodes[nodeIndex].getSuccessors();
while (succs.hasNext()) {
out.or(ins[((Node)succs.next()).getIndex()]);
@@ -491,7 +491,7 @@
while (insts.hasNext()) {
//compute temp = (use[ij] - def[i1i2..i(j-1)]).
- temp.clear();
+ for (int u=0;u<temp.size();u++) temp.clear(u);
QInst inst = (QInst) insts.next();
QOperandBox[] operands = inst.getUses();
for (int u = 0; u < operands.length; ++u) {
@@ -530,7 +530,7 @@
//out[n] = union {s in succ[n]} in[s]
- out.clear();
+ for (int u=0;u<out.size();u++) out.clear(u);
Iterator succs = nodes[nodeIndex].getSuccessors();
while (succs.hasNext()) {
out.or(ins[((Node)succs.next()).getIndex()]);
diff -ur kopi-2.1B.orig/src/kjc/CBlockContext.java kopi-2.1B/src/kjc/CBlockContext.java
--- kopi-2.1B.orig/src/kjc/CBlockContext.java 2002-07-15 20:53:32.000000000 +0200
+++ kopi-2.1B/src/kjc/CBlockContext.java 2003-07-31 09:26:59.000000000 +0200
@@ -59,6 +59,8 @@
this.localVars = localVars == 0 ? null : new ArrayList(localVars);
this.localsPosition = 0;
this.parentIndex = 0;
+ this.localsIndex = 0;
+ this.childrenBlock = null;
}
/**
@@ -81,11 +83,15 @@
super(parent, environment);
this.localVars = new ArrayList(predictedVars);
+ this.childrenBlock = null;
CBlockContext parentBlock = parent.getBlockContext();
this.localsPosition = parentBlock.localsPosition();
+ this.localsIndex = 0;
this.parentIndex = parentBlock.localsIndex();
+
+ parentBlock.registerChildBlock(this);
}
// ----------------------------------------------------------------------
@@ -165,6 +171,61 @@
localsPosition += var.getType().getSize();
}
+ public void registerChildBlock(CBlockContext child) {
+ if (childrenBlock == null) {
+ childrenBlock = new ArrayList();
+ }
+ childrenBlock.add(child);
+ }
+
+ /**
+ * Fix the position of local variables as a monitor variable has been
+ * added to the stack.
+ *
+ * @param incr the update increment for local variables
+ */
+ public void fixVariablePositions(int increment) throws UnpositionedError {
+ localsPosition += increment;
+ parentIndex++;
+ for (int i=0; i < localVars.size(); i++) {
+ JLocalVariable localVar = (JLocalVariable) localVars.get(i);
+
+ localVar.setPosition(localVar.getPosition()+increment);
+ // fix 27.03.02 lackner
+ // synthetic variable has no entry in CVariableInfo
+ // not necessary think
+ // localVar.setIndex(localVar.getIndex()+1);
+ }
+
+ if (childrenBlock != null) {
+ for (int i=0; i < childrenBlock.size(); i++) {
+ CBlockContext child = (CBlockContext)childrenBlock.get(i);
+
+ child.fixVariablePositions(increment);
+ }
+ }
+ }
+
+ /**
+ * Adds a variable and fix the position of the current children block. This
+ * function is principally used by addMonitorVariable because child blocks
+ * may want to add some variable to the top of the analyse tree.
+ *
+ * @param var variable to insert
+ */
+ public void addVariableWithFix(JLocalVariable var) throws UnpositionedError {
+ int increment = var.getType().getSize();
+
+ addVariable(var);
+ if (childrenBlock != null) {
+ for (int i=0; i < childrenBlock.size(); i++) {
+ CBlockContext child = (CBlockContext)childrenBlock.get(i);
+
+ child.fixVariablePositions(increment);
+ }
+ }
+ }
+
/**
* Adds the variable for the monitor of the synchronized statement to the
* correct context.
@@ -173,23 +234,9 @@
*/
public void addMonitorVariable(JLocalVariable var) throws UnpositionedError {
if (parent instanceof CMethodContext) {
- addVariable(var);
+ addVariableWithFix(var);
} else {
parent.addMonitorVariable(var);
- // correct index
- int size = var.getType().getSize();
-
- localsPosition += size;
- parentIndex++;
- for (int i=0; i < localVars.size(); i++) {
- JLocalVariable localVar = (JLocalVariable) localVars.get(i);
-
- localVar.setPosition(localVar.getPosition()+size);
- // fix 27.03.02 lackner
- // synthetic variable has no entry in CVariableInfo
- // not necessary think
- // localVar.setIndex(localVar.getIndex()+1);
- }
}
}
/**
@@ -287,6 +334,7 @@
private Hashtable localClasses;
private ArrayList localVars;
+ private ArrayList childrenBlock;
private /*final*/ int parentIndex;
private int localsIndex;
diff -ur kopi-2.1B.orig/src/kjc/JTryFinallyStatement.java
kopi-2.1B/src/kjc/JTryFinallyStatement.java
--- kopi-2.1B.orig/src/kjc/JTryFinallyStatement.java 2002-07-15 20:53:32.000000000
+0200
+++ kopi-2.1B/src/kjc/JTryFinallyStatement.java 2003-07-31 09:27:44.000000000 +0200
@@ -78,7 +78,7 @@
public void analyse(CBodyContext context) throws PositionedError {
CBlockContext self = new CBlockContext(context, context.getEnvironment()){
public void addMonitorVariable(JLocalVariable var) throws UnpositionedError {
- addVariable(var);
+ addVariableWithFix(var);
}
};
CType integerType =
context.getTypeFactory().getPrimitiveType(TypeFactory.PRM_INT);
