private void computeUsage(CodeIterator ci, TypedBlock[] blocks, int maxLocals) throws BadBytecode { int n = blocks.length; for (int i = 0; i < n; i++) { TypedBlock tb = blocks[i]; localsUsage = tb.localsUsage = new byte[maxLocals]; int pos = tb.position; analyze(ci, pos, pos + tb.length); localsUsage = null; } }
public void compute(CodeIterator ci, TypedBlock[] blocks, int maxLocals, TypeData[] args) throws BadBytecode { computeUsage(ci, blocks, maxLocals); if (useArgs) useAllArgs(blocks, args); computeLiveness1(blocks[0]); while (hasChanged(blocks)) computeLiveness2(blocks[0]); }
for (int i = 0; i < tb.exit.length; i++) { TypedBlock e = (TypedBlock)tb.exit[i]; computeLiveness2(e); if (e.status != DONE) changed = true; if (computeLiveness2except(tb)) tb.status = CHANGED_NOW;
protected void analyze(CodeIterator ci, int begin, int end) throws BadBytecode { ci.begin(); ci.move(begin); while (ci.hasNext()) { int index = ci.next(); if (index >= end) break; int op = ci.byteAt(index); if (op < 96) if (op < 54) doOpcode0_53(ci, index, op); else doOpcode54_95(ci, index, op); else if (op == Opcode.IINC) { // this does not call writeLocal(). readLocal(ci.byteAt(index + 1)); } else if (op == Opcode.WIDE) doWIDE(ci, index); } }
/** * Divides the method body into basic blocks. * The type information of the first block is initialized. * * @param optmize if it is true and the method does not include * branches, this method returns null. */ public static TypedBlock[] makeBlocks(MethodInfo minfo, CodeAttribute ca, boolean optimize) throws BadBytecode { TypedBlock[] blocks = (TypedBlock[])new Maker().make(minfo); if (optimize && blocks.length < 2) if (blocks.length == 0 || blocks[0].incoming == 0) return null; ConstPool pool = minfo.getConstPool(); boolean isStatic = (minfo.getAccessFlags() & AccessFlag.STATIC) != 0; blocks[0].initFirstBlock(ca.getMaxStack(), ca.getMaxLocals(), pool.getClassName(), minfo.getDescriptor(), isStatic, minfo.isConstructor()); new Liveness().compute(ca.iterator(), blocks, ca.getMaxLocals(), blocks[0].localsTypes); return blocks; }
private void computeLiveness1(TypedBlock tb) { if (tb.updating) { computeLiveness1u(tb); return; while (handlers != null) { TypedBlock h = (TypedBlock)handlers.body; computeLiveness1(h); for (int k = 0; k < n; k++) if (h.inputs[k]) for (int i = 0; i < tb.exit.length; i++) { TypedBlock e = (TypedBlock)tb.exit[i]; computeLiveness1(e); for (int k = 0; k < n; k++) if (!in[k])
private boolean computeLiveness2except(TypedBlock tb) { BasicBlock.Catch handlers = tb.toCatch; boolean changed = false; while (handlers != null) { TypedBlock h = (TypedBlock)handlers.body; computeLiveness2(h); if (h.status != DONE) { boolean[] in = tb.inputs; int n = in.length; for (int k = 0; k < n; k++) if (!in[k] && h.inputs[k]) { in[k] = true; changed = true; } } handlers = handlers.next; } return changed; }
protected void analyze(CodeIterator ci, int begin, int end) throws BadBytecode { ci.begin(); ci.move(begin); while (ci.hasNext()) { int index = ci.next(); if (index >= end) break; int op = ci.byteAt(index); if (op < 96) if (op < 54) doOpcode0_53(ci, index, op); else doOpcode54_95(ci, index, op); else if (op == Opcode.IINC) { // this does not call writeLocal(). readLocal(ci.byteAt(index + 1)); } else if (op == Opcode.WIDE) doWIDE(ci, index); } }
/** * Divides the method body into basic blocks. * The type information of the first block is initialized. * * @param optmize if it is true and the method does not include * branches, this method returns null. */ public static TypedBlock[] makeBlocks(MethodInfo minfo, CodeAttribute ca, boolean optimize) throws BadBytecode { TypedBlock[] blocks = (TypedBlock[])new Maker().make(minfo); if (optimize && blocks.length < 2) if (blocks.length == 0 || blocks[0].incoming == 0) return null; ConstPool pool = minfo.getConstPool(); boolean isStatic = (minfo.getAccessFlags() & AccessFlag.STATIC) != 0; blocks[0].initFirstBlock(ca.getMaxStack(), ca.getMaxLocals(), pool.getClassName(), minfo.getDescriptor(), isStatic, minfo.isConstructor()); new Liveness().compute(ca.iterator(), blocks, ca.getMaxLocals(), blocks[0].localsTypes); return blocks; }
private void computeLiveness1(TypedBlock tb) { if (tb.updating) { computeLiveness1u(tb); return; while (handlers != null) { TypedBlock h = (TypedBlock)handlers.body; computeLiveness1(h); for (int k = 0; k < n; k++) if (h.inputs[k]) for (int i = 0; i < tb.exit.length; i++) { TypedBlock e = (TypedBlock)tb.exit[i]; computeLiveness1(e); for (int k = 0; k < n; k++) if (!in[k])
private boolean computeLiveness2except(TypedBlock tb) { BasicBlock.Catch handlers = tb.toCatch; boolean changed = false; while (handlers != null) { TypedBlock h = (TypedBlock)handlers.body; computeLiveness2(h); if (h.status != DONE) { boolean[] in = tb.inputs; int n = in.length; for (int k = 0; k < n; k++) if (!in[k] && h.inputs[k]) { in[k] = true; changed = true; } } handlers = handlers.next; } return changed; }
public void compute(CodeIterator ci, TypedBlock[] blocks, int maxLocals, TypeData[] args) throws BadBytecode { computeUsage(ci, blocks, maxLocals); if (useArgs) useAllArgs(blocks, args); computeLiveness1(blocks[0]); while (hasChanged(blocks)) computeLiveness2(blocks[0]); }
for (int i = 0; i < tb.exit.length; i++) { TypedBlock e = (TypedBlock)tb.exit[i]; computeLiveness2(e); if (e.status != DONE) changed = true; if (computeLiveness2except(tb)) tb.status = CHANGED_NOW;
private void computeUsage(CodeIterator ci, TypedBlock[] blocks, int maxLocals) throws BadBytecode { int n = blocks.length; for (int i = 0; i < n; i++) { TypedBlock tb = blocks[i]; localsUsage = tb.localsUsage = new byte[maxLocals]; int pos = tb.position; analyze(ci, pos, pos + tb.length); localsUsage = null; } }