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;
/**
* The predecessors of this opcode, including the prevByAddr, if
* that does not alwaysJump.
* The predecessors of this opcode, orthogonal to the succs array.
* This must be null or a non empty array.
*/
public Vector preds = new Vector();
public Instruction[] preds;
/**
* The next instruction in code order.
*/
@ -97,6 +97,36 @@ public class Instruction implements Opcodes{
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() {
Instruction newInstr = new Instruction(codeinfo);
newInstr.addr = addr;
@ -110,40 +140,26 @@ public class Instruction implements Opcodes{
prevByAddr = newInstr;
/* promote the predecessors to newInstr */
Enumeration enum = preds.elements();
while (enum.hasMoreElements()) {
Instruction pred = (Instruction) enum.nextElement();
if (pred.succs != null)
for (int i=0; i < pred.succs.length; i++)
if (pred.succs[i] == this)
pred.succs[i] = newInstr;
if (preds != null) {
for (int j=0; j < preds.length; j++)
for (int i=0; i < preds[j].succs.length; i++)
if (preds[j].succs[i] == this)
preds[j].succs[i] = newInstr;
newInstr.preds = preds;
preds = null;
}
newInstr.preds = preds;
preds = new Vector();
preds.addElement(newInstr);
return newInstr;
}
public Instruction appendInstruction(boolean nextAlwaysJumps) {
public Instruction appendInstruction() {
Instruction newInstr = new Instruction(codeinfo);
newInstr.addr = addr;
newInstr.nextByAddr = nextByAddr;
if (nextByAddr != null)
nextByAddr.prevByAddr = newInstr;
newInstr.prevByAddr = this;
newInstr.alwaysJumps = nextAlwaysJumps;
if (nextByAddr != null) {
if (!this.alwaysJumps)
nextByAddr.preds.removeElement(this);
if (!nextAlwaysJumps)
nextByAddr.preds.addElement(newInstr);
}
nextByAddr = newInstr;
if (!this.alwaysJumps)
newInstr.preds.addElement(this);
return newInstr;
}
@ -151,6 +167,7 @@ public class Instruction implements Opcodes{
* Removes this instruction (as if it would be replaced by a nop).
*/
public void removeInstruction() {
try{
/* remove from chained list */
if (prevByAddr != null)
prevByAddr.nextByAddr = nextByAddr;
@ -161,23 +178,30 @@ public class Instruction implements Opcodes{
nextByAddr.prevByAddr = prevByAddr;
/* remove predecessors of successors */
if (!alwaysJumps && nextByAddr != null)
nextByAddr.preds.removeElement(this);
if (succs != null) {
for (int i=0; i < succs.length; i++)
succs[i].preds.removeElement(this);
succs[i].removePredecessor(this);
succs = null;
}
/* promote the predecessors to nextByAddr */
Enumeration enum = preds.elements();
while (enum.hasMoreElements()) {
Instruction pred = (Instruction) enum.nextElement();
if (pred.succs != null)
for (int i=0; i < pred.succs.length; i++)
if (pred.succs[i] == this)
pred.succs[i] = nextByAddr;
if (nextByAddr != null)
nextByAddr.preds.addElement(pred);
Instruction alternative = nextByAddr != null ? nextByAddr : prevByAddr;
/* remove the predecessors to alternative */
if (preds != null) {
for (int j=0; j < preds.length; j++)
for (int i=0; i < preds[j].succs.length; i++)
if (preds[j].succs[i] == this)
preds[j].succs[i] = alternative;
if (alternative.preds == null)
alternative.preds = preds;
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 */
@ -204,16 +228,76 @@ public class Instruction implements Opcodes{
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() {
String result = ""+addr+"_"+Integer.toHexString(hashCode());
for (Instruction instr = codeinfo.firstInstr;
instr != null; instr = instr.nextByAddr) {
if (instr == this)
return result;
public String getDescription() {
StringBuffer result = new StringBuffer(String.valueOf(addr))
.append('_').append(Integer.toHexString(hashCode()))
.append(": ").append(opcodeString[opcode]);
switch (opcode) {
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+"*";
return result.toString();
}
public String toString() {
return ""+addr+"_"+Integer.toHexString(hashCode());
}
}

Loading…
Cancel
Save