preds is no longer a vector, but an array

getDescription


git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@527 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 26 years ago
parent 38e5046902
commit 8f11aef005
  1. 174
      jode/jode/bytecode/Instruction.java

@ -73,10 +73,10 @@ public class Instruction implements Opcodes{
*/ */
public Instruction[] succs; public Instruction[] succs;
/** /**
* The predecessors of this opcode, including the prevByAddr, if * The predecessors of this opcode, orthogonal to the succs array.
* that does not alwaysJump. * This must be null or a non empty array.
*/ */
public Vector preds = new Vector(); public Instruction[] preds;
/** /**
* The next instruction in code order. * The next instruction in code order.
*/ */
@ -97,6 +97,36 @@ public class Instruction implements Opcodes{
this.codeinfo = ci; this.codeinfo = ci;
} }
public void addPredecessor(Instruction pred) {
if (preds == null) {
preds = new Instruction[] { pred };
return;
}
int predsLength = preds.length;
Instruction[] newPreds = new Instruction[predsLength+1];
System.arraycopy(preds, 0, newPreds, 0, predsLength);
newPreds[predsLength] = pred;
preds = newPreds;
}
public void removePredecessor(Instruction pred) {
/* Hopefully it doesn't matter if this is slow */
int predLength = preds.length;
if (predLength == 1) {
if (preds[0] != pred)
throw new jode.AssertError
("removing not existing predecessor");
preds = null;
} else {
Instruction[] newPreds = new Instruction[predLength-1];
int j;
for (j = 0; preds[j] != pred; j++)
newPreds[j] = preds[j];
System.arraycopy(preds, j+1, newPreds, j, predLength - j - 1);
preds = newPreds;
}
}
public Instruction insertInstruction() { public Instruction insertInstruction() {
Instruction newInstr = new Instruction(codeinfo); Instruction newInstr = new Instruction(codeinfo);
newInstr.addr = addr; newInstr.addr = addr;
@ -110,40 +140,26 @@ public class Instruction implements Opcodes{
prevByAddr = newInstr; prevByAddr = newInstr;
/* promote the predecessors to newInstr */ /* promote the predecessors to newInstr */
Enumeration enum = preds.elements(); if (preds != null) {
while (enum.hasMoreElements()) { for (int j=0; j < preds.length; j++)
Instruction pred = (Instruction) enum.nextElement(); for (int i=0; i < preds[j].succs.length; i++)
if (pred.succs != null) if (preds[j].succs[i] == this)
for (int i=0; i < pred.succs.length; i++) preds[j].succs[i] = newInstr;
if (pred.succs[i] == this)
pred.succs[i] = newInstr;
}
newInstr.preds = preds; newInstr.preds = preds;
preds = new Vector(); preds = null;
preds.addElement(newInstr); }
return newInstr; return newInstr;
} }
public Instruction appendInstruction(boolean nextAlwaysJumps) { public Instruction appendInstruction() {
Instruction newInstr = new Instruction(codeinfo); Instruction newInstr = new Instruction(codeinfo);
newInstr.addr = addr; newInstr.addr = addr;
newInstr.nextByAddr = nextByAddr; newInstr.nextByAddr = nextByAddr;
if (nextByAddr != null) if (nextByAddr != null)
nextByAddr.prevByAddr = newInstr; nextByAddr.prevByAddr = newInstr;
newInstr.prevByAddr = this; newInstr.prevByAddr = this;
newInstr.alwaysJumps = nextAlwaysJumps;
if (nextByAddr != null) {
if (!this.alwaysJumps)
nextByAddr.preds.removeElement(this);
if (!nextAlwaysJumps)
nextByAddr.preds.addElement(newInstr);
}
nextByAddr = newInstr; nextByAddr = newInstr;
if (!this.alwaysJumps)
newInstr.preds.addElement(this);
return newInstr; return newInstr;
} }
@ -151,6 +167,7 @@ public class Instruction implements Opcodes{
* Removes this instruction (as if it would be replaced by a nop). * Removes this instruction (as if it would be replaced by a nop).
*/ */
public void removeInstruction() { public void removeInstruction() {
try{
/* remove from chained list */ /* remove from chained list */
if (prevByAddr != null) if (prevByAddr != null)
prevByAddr.nextByAddr = nextByAddr; prevByAddr.nextByAddr = nextByAddr;
@ -161,23 +178,30 @@ public class Instruction implements Opcodes{
nextByAddr.prevByAddr = prevByAddr; nextByAddr.prevByAddr = prevByAddr;
/* remove predecessors of successors */ /* remove predecessors of successors */
if (!alwaysJumps && nextByAddr != null)
nextByAddr.preds.removeElement(this);
if (succs != null) { if (succs != null) {
for (int i=0; i < succs.length; i++) for (int i=0; i < succs.length; i++)
succs[i].preds.removeElement(this); succs[i].removePredecessor(this);
succs = null;
} }
/* promote the predecessors to nextByAddr */ Instruction alternative = nextByAddr != null ? nextByAddr : prevByAddr;
Enumeration enum = preds.elements(); /* remove the predecessors to alternative */
while (enum.hasMoreElements()) { if (preds != null) {
Instruction pred = (Instruction) enum.nextElement(); for (int j=0; j < preds.length; j++)
if (pred.succs != null) for (int i=0; i < preds[j].succs.length; i++)
for (int i=0; i < pred.succs.length; i++) if (preds[j].succs[i] == this)
if (pred.succs[i] == this) preds[j].succs[i] = alternative;
pred.succs[i] = nextByAddr; if (alternative.preds == null)
if (nextByAddr != null) alternative.preds = preds;
nextByAddr.preds.addElement(pred); else {
Instruction[] newPreds
= new Instruction[alternative.preds.length + preds.length];
System.arraycopy(preds, 0, newPreds, 0, preds.length);
System.arraycopy(alternative.preds, 0, newPreds, preds.length,
alternative.preds.length);
alternative.preds = newPreds;
}
preds = null;
} }
/* adjust exception handlers */ /* adjust exception handlers */
@ -204,16 +228,76 @@ public class Instruction implements Opcodes{
i--; i--;
} }
} }
} catch (Exception ex) {
ex.printStackTrace();
System.err.println(getDescription()+ " "
+ Integer.toHexString(hashCode()));
if (succs != null) {
System.err.print("\tsuccs: "+succs[0]);
for (int i = 1; i < succs.length; i++)
System.err.print(", "+succs[i]);
System.err.println();
}
if (preds != null) {
System.err.print("\tpreds: " + preds[0]);
for (int i=1; i < preds.length; i++)
System.err.print(", " + preds[i]);
System.err.println();
}
codeinfo.dumpCode(System.err);
}
} }
public String toString() { public String getDescription() {
String result = ""+addr+"_"+Integer.toHexString(hashCode()); StringBuffer result = new StringBuffer(String.valueOf(addr))
for (Instruction instr = codeinfo.firstInstr; .append('_').append(Integer.toHexString(hashCode()))
instr != null; instr = instr.nextByAddr) { .append(": ").append(opcodeString[opcode]);
if (instr == this) switch (opcode) {
return result; case opc_iload: case opc_lload:
case opc_fload: case opc_dload: case opc_aload:
case opc_istore: case opc_lstore:
case opc_fstore: case opc_dstore: case opc_astore:
case opc_ret:
result.append(" ").append(localSlot);
break;
case opc_iinc:
result.append(" ").append(localSlot).append(" ").append(intData);
break;
case opc_ldc: case opc_ldc2_w:
case opc_getstatic: case opc_getfield:
case opc_putstatic: case opc_putfield:
case opc_invokespecial: case opc_invokestatic: case opc_invokevirtual:
case opc_new:
case opc_checkcast:
case opc_instanceof:
result.append(" ").append(objData);
break;
case opc_anewarray:
case opc_newarray:
result.append(" ").append(((String)objData).substring(1));
break;
case opc_multianewarray:
case opc_invokeinterface:
result.append(" ").append(objData).append(" ").append(intData);
break;
case opc_ifeq: case opc_ifne:
case opc_iflt: case opc_ifge:
case opc_ifgt: case opc_ifle:
case opc_if_icmpeq: case opc_if_icmpne:
case opc_if_icmplt: case opc_if_icmpge:
case opc_if_icmpgt: case opc_if_icmple:
case opc_if_acmpeq: case opc_if_acmpne:
case opc_ifnull: case opc_ifnonnull:
case opc_goto:
case opc_jsr:
result.append(" ").append(succs[0].addr);
break;
}
return result.toString();
} }
return result+"*";
public String toString() {
return ""+addr+"_"+Integer.toHexString(hashCode());
} }
} }

Loading…
Cancel
Save