/* This file is part of the db4o object database http://www.db4o.com Copyright (C) 2004 - 2011 Versant Corporation http://www.versant.com db4o is free software; you can redistribute it and/or modify it under the terms of version 3 of the GNU General Public License as published by the Free Software Foundation. db4o is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. */ package EDU.purdue.cs.bloat.trans; import EDU.purdue.cs.bloat.editor.*; public class StackOpt extends InstructionAdapter implements Opcode { int stackHeight; int minStackHeight; UseMap uMap; static final boolean DEBUG = false; public void transform(final MethodEditor method) { uMap = method.uMap(); for (int i = method.codeLength() - 1; i > 0; i--) { Instruction inst; boolean isWide; final Object codeEl = method.codeElementAt(i); if ((codeEl instanceof Instruction) && ((Instruction) codeEl).isLoad()) { inst = (Instruction) codeEl; } else { continue; } switch (inst.opcodeClass()) { case opcx_iload: case opcx_fload: case opcx_aload: case opcx_iaload: case opcx_faload: case opcx_aaload: case opcx_baload: case opcx_caload: case opcx_saload: isWide = false; break; case opcx_lload: case opcx_dload: case opcx_laload: case opcx_daload: default: isWide = true; } stackHeight = 0; for (int j = i - 1;; j--) { // stop at the begining of the code or a basic block. if ((j <= 0) || // this should be redundant, but to be safe (method.codeElementAt(j) instanceof Label)) { break; } if ((stackHeight == -1) && ((uMap.hasSameDef(inst, ((Instruction) method .codeElementAt(j))) && ((Instruction) method .codeElementAt(j)).isLoad()) || dupRun(method, j, inst))) { if (forwardCountCheck(method, j, i, -1)) { // found a type 0 relation with a load if (StackOpt.DEBUG) { System.err .println("load type 0: " + ((Instruction) method .codeElementAt(j)) .toString() + " " + inst.toString()); } if (isWide) { method.insertCodeAt( new Instruction(Opcode.opc_dup2), j + 1); } else { method.insertCodeAt( new Instruction(Opcode.opc_dup), j + 1); // add // dup } i++; // code has changed; why don't method editors // have iterators? method.removeCodeAt(i); // remove load } break; // done, even if final check failed. } else if ((stackHeight == 0) && uMap.hasSameDef(inst, ((Instruction) method .codeElementAt(j)))) { if (((Instruction) method.codeElementAt(j)).isStore()) { if (forwardCountCheck(method, j, i, 0)) { // found a type 0 with a store if (StackOpt.DEBUG) { System.err.println("store type 0: " + ((Instruction) method .codeElementAt(j)).toString() + " " + inst.toString()); } if (isWide) { method.insertCodeAt(new Instruction( Opcode.opc_dup2), j); } else { method.insertCodeAt(new Instruction( Opcode.opc_dup), j); } i++; method.removeCodeAt(i); } break; } else if (((Instruction) method.codeElementAt(j)).isLoad() && !isWide) { // can't do type 1s with wides. if (forwardCountCheck(method, j, i, -1)) { // found a type 1 with a load if (StackOpt.DEBUG) { System.err.println("load type 1: " + ((Instruction) method .codeElementAt(j)).toString() + " " + inst.toString()); } method.insertCodeAt( new Instruction(Opcode.opc_dup), j + 1); i++; method.replaceCodeAt(new Instruction( Opcode.opc_swap), i); } break; } } else if ((stackHeight == 1) && uMap.hasSameDef(inst, ((Instruction) method .codeElementAt(j)))) { if (((Instruction) method.codeElementAt(j)).isStore() && !isWide) { // can't do type 1 with wides if (forwardCountCheck(method, j, i, 0)) { // type 1 for stores if (StackOpt.DEBUG) { System.err.println("store type 1: " + ((Instruction) method .codeElementAt(j)).toString() + " " + inst.toString()); } method.insertCodeAt( new Instruction(Opcode.opc_dup), j); i++; method.replaceCodeAt(new Instruction( Opcode.opc_swap), i); } break; } } heightChange(method.codeElementAt(j)); // System.err.print(stackHeight + ";"); } } } boolean forwardCountCheck(final MethodEditor m, final int j, final int i, final int bound) { stackHeight = 0; minStackHeight = 0; for (int k = j + 1; k < i; k++) { heightChange(m.codeElementAt(k)); if (minStackHeight < bound) { return false; } } return true; } boolean dupRun(final MethodEditor m, final int j, final Instruction inst) { if (((Instruction) m.codeElementAt(j)).opcodeClass() == Opcode.opcx_dup) { for (int k = j - 1;; k--) { if (m.codeElementAt(k) instanceof Instruction) { if (((Instruction) m.codeElementAt(k)).opcodeClass() == Opcode.opcx_dup) { continue; } else if (((Instruction) m.codeElementAt(k)).isLoad() && uMap.hasSameDef(inst, ((Instruction) m .codeElementAt(k)))) { return true; } } break; } } return false; } void heightChange(final Object inst) { if (inst instanceof Instruction) { ((Instruction) inst).visit(this); } } public void visit_nop(final Instruction inst) { stackHeight += 0; } public void visit_ldc(final Instruction inst) { final Object operand = inst.operand(); if ((operand instanceof Long) || (operand instanceof Double)) { stackHeight += 2; } else { stackHeight += 1; } } public void visit_iload(final Instruction inst) { stackHeight += 1; } public void visit_lload(final Instruction inst) { stackHeight += 2; } public void visit_fload(final Instruction inst) { stackHeight += 1; } public void visit_dload(final Instruction inst) { stackHeight += 2; } public void visit_aload(final Instruction inst) { stackHeight += 1; } public void visit_iaload(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_laload(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_faload(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_daload(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_aaload(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_baload(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_caload(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_saload(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_istore(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_lstore(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_fstore(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_dstore(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_astore(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_iastore(final Instruction inst) { stackHeight -= 3; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_lastore(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_fastore(final Instruction inst) { stackHeight -= 3; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_dastore(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_aastore(final Instruction inst) { stackHeight -= 3; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_bastore(final Instruction inst) { stackHeight -= 3; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_castore(final Instruction inst) { stackHeight -= 3; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_sastore(final Instruction inst) { stackHeight -= 3; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_pop(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_pop2(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_dup(final Instruction inst) { stackHeight += 1; } public void visit_dup_x1(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 3; } public void visit_dup_x2(final Instruction inst) { stackHeight -= 3; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 4; } public void visit_dup2(final Instruction inst) { stackHeight += 2; } public void visit_dup2_x1(final Instruction inst) { stackHeight -= 3; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 5; } public void visit_dup2_x2(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 6; } public void visit_swap(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_iadd(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_ladd(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_fadd(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_dadd(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_isub(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_lsub(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_fsub(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_dsub(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_imul(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_lmul(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_fmul(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_dmul(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_idiv(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_ldiv(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_fdiv(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_ddiv(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_irem(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_lrem(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_frem(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_drem(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_ineg(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_lneg(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_fneg(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_dneg(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_ishl(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_lshl(final Instruction inst) { stackHeight -= 3; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_ishr(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_lshr(final Instruction inst) { stackHeight -= 3; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_iushr(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_lushr(final Instruction inst) { stackHeight -= 3; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_iand(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_land(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_ior(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_lor(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_ixor(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_lxor(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_iinc(final Instruction inst) { } public void visit_i2l(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_i2f(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_i2d(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_l2i(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_l2f(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_l2d(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_f2i(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_f2l(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_f2d(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_d2i(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_d2l(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 2; } public void visit_d2f(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_i2b(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_i2c(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_i2s(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_lcmp(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_fcmpl(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_fcmpg(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_dcmpl(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_dcmpg(final Instruction inst) { stackHeight -= 4; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_ifeq(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_ifne(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_iflt(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_ifge(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_ifgt(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_ifle(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_if_icmpeq(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_if_icmpne(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_if_icmplt(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_if_icmpge(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_if_icmpgt(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_if_icmple(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_if_acmpeq(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_if_acmpne(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_goto(final Instruction inst) { } public void visit_jsr(final Instruction inst) { stackHeight += 1; } public void visit_ret(final Instruction inst) { } public void visit_switch(final Instruction inst) { stackHeight -= 1; } public void visit_ireturn(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_lreturn(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_freturn(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_dreturn(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_areturn(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_return(final Instruction inst) { } public void visit_getstatic(final Instruction inst) { final Type type = ((MemberRef) inst.operand()).nameAndType().type(); stackHeight += type.stackHeight(); } public void visit_putstatic(final Instruction inst) { final Type type = ((MemberRef) inst.operand()).nameAndType().type(); stackHeight -= type.stackHeight(); if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_putstatic_nowb(final Instruction inst) { final Type type = ((MemberRef) inst.operand()).nameAndType().type(); stackHeight -= type.stackHeight(); if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_getfield(final Instruction inst) { final Type type = ((MemberRef) inst.operand()).nameAndType().type(); stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += type.stackHeight(); } public void visit_putfield(final Instruction inst) { final Type type = ((MemberRef) inst.operand()).nameAndType().type(); stackHeight -= type.stackHeight() + 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_putfield_nowb(final Instruction inst) { final Type type = ((MemberRef) inst.operand()).nameAndType().type(); stackHeight -= type.stackHeight() + 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_invokevirtual(final Instruction inst) { final MemberRef method = (MemberRef) inst.operand(); final Type type = method.nameAndType().type(); stackHeight -= type.stackHeight() + 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += type.returnType().stackHeight(); } public void visit_invokespecial(final Instruction inst) { final MemberRef method = (MemberRef) inst.operand(); final Type type = method.nameAndType().type(); stackHeight -= type.stackHeight() + 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += type.returnType().stackHeight(); } public void visit_invokestatic(final Instruction inst) { final MemberRef method = (MemberRef) inst.operand(); final Type type = method.nameAndType().type(); stackHeight -= type.stackHeight(); if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += type.returnType().stackHeight(); } public void visit_invokeinterface(final Instruction inst) { final MemberRef method = (MemberRef) inst.operand(); final Type type = method.nameAndType().type(); stackHeight -= type.stackHeight() + 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += type.returnType().stackHeight(); } public void visit_new(final Instruction inst) { stackHeight += 1; } public void visit_newarray(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_arraylength(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_athrow(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_checkcast(final Instruction inst) { } public void visit_instanceof(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_monitorenter(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_monitorexit(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_multianewarray(final Instruction inst) { final MultiArrayOperand operand = (MultiArrayOperand) inst.operand(); final int dim = operand.dimensions(); stackHeight -= dim; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } stackHeight += 1; } public void visit_ifnull(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_ifnonnull(final Instruction inst) { stackHeight -= 1; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_rc(final Instruction inst) { } public void visit_aupdate(final Instruction inst) { } public void visit_supdate(final Instruction inst) { } public void visit_aswizzle(final Instruction inst) { stackHeight -= 2; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } public void visit_aswrange(final Instruction inst) { stackHeight -= 3; if (stackHeight < minStackHeight) { minStackHeight = stackHeight; } } }