List of usage examples for org.objectweb.asm Opcodes MONITORENTER
int MONITORENTER
To view the source code for org.objectweb.asm Opcodes MONITORENTER.
Click Source Link
From source file:com.google.test.metric.asm.MethodVisitorBuilder.java
License:Apache License
public void visitInsn(final int opcode) { switch (opcode) { case Opcodes.ACONST_NULL: recorder.add(new Runnable() { public void run() { block.addOp(new Load(lineNumber, new Constant(null, JavaType.OBJECT))); }/*from w w w .j a va2 s . c om*/ }); break; case Opcodes.ICONST_M1: case Opcodes.ICONST_0: case Opcodes.ICONST_1: case Opcodes.ICONST_2: case Opcodes.ICONST_3: case Opcodes.ICONST_4: case Opcodes.ICONST_5: loadConstant(opcode - Opcodes.ICONST_M1 - 1, JavaType.INT); break; case Opcodes.LCONST_0: case Opcodes.LCONST_1: loadConstant(opcode - Opcodes.LCONST_0, JavaType.LONG); break; case Opcodes.FCONST_0: case Opcodes.FCONST_1: case Opcodes.FCONST_2: loadConstant(opcode - Opcodes.FCONST_0, JavaType.FLOAT); break; case Opcodes.DCONST_0: case Opcodes.DCONST_1: loadConstant(opcode - Opcodes.DCONST_0, JavaType.DOUBLE); break; case Opcodes.IALOAD: recordArrayLoad(JavaType.INT); break; case Opcodes.LALOAD: recordArrayLoad(JavaType.LONG); break; case Opcodes.FALOAD: recordArrayLoad(JavaType.FLOAT); break; case Opcodes.DALOAD: recordArrayLoad(JavaType.DOUBLE); break; case Opcodes.AALOAD: recordArrayLoad(JavaType.OBJECT); break; case Opcodes.BALOAD: recordArrayLoad(JavaType.BYTE); break; case Opcodes.CALOAD: recordArrayLoad(JavaType.CHAR); break; case Opcodes.SALOAD: recordArrayLoad(JavaType.SHORT); break; case Opcodes.IASTORE: recordArrayStore(JavaType.INT); break; case Opcodes.LASTORE: recordArrayStore(JavaType.LONG); break; case Opcodes.FASTORE: recordArrayStore(JavaType.FLOAT); break; case Opcodes.DASTORE: recordArrayStore(JavaType.DOUBLE); break; case Opcodes.AASTORE: recordArrayStore(JavaType.OBJECT); break; case Opcodes.BASTORE: recordArrayStore(JavaType.BYTE); break; case Opcodes.CASTORE: recordArrayStore(JavaType.CHAR); break; case Opcodes.SASTORE: recordArrayStore(JavaType.SHORT); break; case Opcodes.POP: case Opcodes.POP2: recorder.add(new Runnable() { public void run() { block.addOp(new Pop(lineNumber, opcode - Opcodes.POP + 1)); } }); break; case Opcodes.DUP: case Opcodes.DUP_X1: case Opcodes.DUP_X2: recorder.add(new Runnable() { public void run() { int offset = opcode - Opcodes.DUP; block.addOp(new Duplicate(lineNumber, offset)); } }); break; case Opcodes.DUP2: case Opcodes.DUP2_X1: case Opcodes.DUP2_X2: recorder.add(new Runnable() { public void run() { block.addOp(new Duplicate2(lineNumber, opcode - Opcodes.DUP2)); } }); break; case Opcodes.SWAP: recorder.add(new Runnable() { public void run() { block.addOp(new Swap(lineNumber)); } }); break; case Opcodes.IRETURN: _return(JavaType.INT); break; case Opcodes.FRETURN: _return(JavaType.FLOAT); break; case Opcodes.ARETURN: _return(JavaType.OBJECT); break; case Opcodes.LRETURN: _return(JavaType.LONG); break; case Opcodes.DRETURN: _return(JavaType.DOUBLE); break; case Opcodes.ATHROW: recorder.add(new Runnable() { public void run() { block.addOp(new Throw(lineNumber)); } }); break; case Opcodes.RETURN: _return(JavaType.VOID); break; case Opcodes.LCMP: operation("cmp", JavaType.LONG, JavaType.LONG, JavaType.INT); break; case Opcodes.FCMPL: operation("cmpl", JavaType.FLOAT, JavaType.FLOAT, JavaType.INT); break; case Opcodes.FCMPG: operation("cmpg", JavaType.FLOAT, JavaType.FLOAT, JavaType.INT); break; case Opcodes.DCMPL: operation("cmpl", JavaType.DOUBLE, JavaType.DOUBLE, JavaType.INT); break; case Opcodes.DCMPG: operation("cmpg", JavaType.DOUBLE, JavaType.DOUBLE, JavaType.INT); break; case Opcodes.LSHL: operation("shl", JavaType.LONG, JavaType.INT, JavaType.LONG); break; case Opcodes.LSHR: operation("shr", JavaType.LONG, JavaType.INT, JavaType.LONG); break; case Opcodes.LUSHR: operation("ushr", JavaType.LONG, JavaType.INT, JavaType.LONG); break; case Opcodes.LADD: operation("add", JavaType.LONG, JavaType.LONG, JavaType.LONG); break; case Opcodes.LSUB: operation("sub", JavaType.LONG, JavaType.LONG, JavaType.LONG); break; case Opcodes.LDIV: operation("div", JavaType.LONG, JavaType.LONG, JavaType.LONG); break; case Opcodes.LREM: operation("rem", JavaType.LONG, JavaType.LONG, JavaType.LONG); break; case Opcodes.LAND: operation("and", JavaType.LONG, JavaType.LONG, JavaType.LONG); break; case Opcodes.LOR: operation("or", JavaType.LONG, JavaType.LONG, JavaType.LONG); break; case Opcodes.LXOR: operation("xor", JavaType.LONG, JavaType.LONG, JavaType.LONG); break; case Opcodes.LMUL: operation("mul", JavaType.LONG, JavaType.LONG, JavaType.LONG); break; case Opcodes.FADD: operation("add", JavaType.FLOAT, JavaType.FLOAT, JavaType.FLOAT); break; case Opcodes.FSUB: operation("sub", JavaType.FLOAT, JavaType.FLOAT, JavaType.FLOAT); break; case Opcodes.FMUL: operation("mul", JavaType.FLOAT, JavaType.FLOAT, JavaType.FLOAT); break; case Opcodes.FREM: operation("rem", JavaType.FLOAT, JavaType.FLOAT, JavaType.FLOAT); break; case Opcodes.FDIV: operation("div", JavaType.FLOAT, JavaType.FLOAT, JavaType.FLOAT); break; case Opcodes.ISHL: operation("shl", JavaType.INT, JavaType.INT, JavaType.INT); break; case Opcodes.ISHR: operation("shr", JavaType.INT, JavaType.INT, JavaType.INT); break; case Opcodes.IUSHR: operation("ushr", JavaType.INT, JavaType.INT, JavaType.INT); break; case Opcodes.IADD: operation("add", JavaType.INT, JavaType.INT, JavaType.INT); break; case Opcodes.ISUB: operation("sub", JavaType.INT, JavaType.INT, JavaType.INT); break; case Opcodes.IMUL: operation("mul", JavaType.INT, JavaType.INT, JavaType.INT); break; case Opcodes.IDIV: operation("div", JavaType.INT, JavaType.INT, JavaType.INT); break; case Opcodes.IREM: operation("rem", JavaType.INT, JavaType.INT, JavaType.INT); break; case Opcodes.IAND: operation("and", JavaType.INT, JavaType.INT, JavaType.INT); break; case Opcodes.IOR: operation("or", JavaType.INT, JavaType.INT, JavaType.INT); break; case Opcodes.IXOR: operation("xor", JavaType.INT, JavaType.INT, JavaType.INT); break; case Opcodes.DSUB: operation("sub", JavaType.DOUBLE, JavaType.DOUBLE, JavaType.DOUBLE); break; case Opcodes.DADD: operation("add", JavaType.DOUBLE, JavaType.DOUBLE, JavaType.DOUBLE); break; case Opcodes.DMUL: operation("mul", JavaType.DOUBLE, JavaType.DOUBLE, JavaType.DOUBLE); break; case Opcodes.DDIV: operation("div", JavaType.DOUBLE, JavaType.DOUBLE, JavaType.DOUBLE); break; case Opcodes.DREM: operation("rem", JavaType.DOUBLE, JavaType.DOUBLE, JavaType.DOUBLE); break; case Opcodes.L2I: convert(JavaType.LONG, JavaType.INT); break; case Opcodes.L2F: convert(JavaType.LONG, JavaType.FLOAT); break; case Opcodes.L2D: convert(JavaType.LONG, JavaType.DOUBLE); break; case Opcodes.LNEG: operation("neg", JavaType.LONG, null, JavaType.LONG); break; case Opcodes.F2I: convert(JavaType.FLOAT, JavaType.INT); break; case Opcodes.F2L: convert(JavaType.FLOAT, JavaType.LONG); break; case Opcodes.FNEG: operation("neg", JavaType.FLOAT, null, JavaType.FLOAT); break; case Opcodes.F2D: convert(JavaType.FLOAT, JavaType.DOUBLE); break; case Opcodes.D2I: convert(JavaType.DOUBLE, JavaType.INT); break; case Opcodes.D2L: convert(JavaType.DOUBLE, JavaType.LONG); break; case Opcodes.D2F: convert(JavaType.DOUBLE, JavaType.FLOAT); break; case Opcodes.DNEG: operation("neg", JavaType.DOUBLE, null, JavaType.DOUBLE); break; case Opcodes.I2L: convert(JavaType.INT, JavaType.LONG); break; case Opcodes.I2F: convert(JavaType.INT, JavaType.FLOAT); break; case Opcodes.I2D: convert(JavaType.INT, JavaType.DOUBLE); break; case Opcodes.I2B: convert(JavaType.INT, JavaType.BYTE); break; case Opcodes.I2C: convert(JavaType.INT, JavaType.CHAR); break; case Opcodes.I2S: convert(JavaType.INT, JavaType.SHORT); break; case Opcodes.INEG: operation("neg", JavaType.INT, null, JavaType.INT); break; case Opcodes.ARRAYLENGTH: operation("arraylength", JavaType.OBJECT.toArray(), null, JavaType.INT); break; case Opcodes.MONITORENTER: recorder.add(new Runnable() { public void run() { block.addOp(new MonitorEnter(lineNumber)); } }); break; case Opcodes.MONITOREXIT: recorder.add(new Runnable() { public void run() { block.addOp(new MonitorExit(lineNumber)); } }); break; case Opcodes.NOP: recorder.add(new Runnable() { public void run() { block.addOp(new Transform(lineNumber, "NOP", null, null, null)); } }); } }
From source file:com.mebigfatguy.junitflood.jvm.OperandStack.java
License:Apache License
public void performInsn(int opcode) { switch (opcode) { case Opcodes.NOP: break;//w w w .j av a2 s. c o m case Opcodes.ACONST_NULL: { Operand op = new Operand(); op.setNull(true); push(op); } break; case Opcodes.ICONST_M1: { Operand op = new Operand(); op.setConstant(Integer.valueOf(-1)); push(op); } break; case Opcodes.ICONST_0: { Operand op = new Operand(); op.setConstant(Integer.valueOf(0)); push(op); } break; case Opcodes.ICONST_1: { Operand op = new Operand(); op.setConstant(Integer.valueOf(1)); push(op); } break; case Opcodes.ICONST_2: { Operand op = new Operand(); op.setConstant(Integer.valueOf(2)); push(op); } break; case Opcodes.ICONST_3: { Operand op = new Operand(); op.setConstant(Integer.valueOf(3)); push(op); } break; case Opcodes.ICONST_4: { Operand op = new Operand(); op.setConstant(Integer.valueOf(4)); push(op); } break; case Opcodes.ICONST_5: { Operand op = new Operand(); op.setConstant(Integer.valueOf(5)); push(op); } break; case Opcodes.LCONST_0: { Operand op = new Operand(); op.setConstant(Long.valueOf(0)); push(op); } break; case Opcodes.LCONST_1: { Operand op = new Operand(); op.setConstant(Long.valueOf(1)); push(op); } break; case Opcodes.FCONST_0: { Operand op = new Operand(); op.setConstant(Float.valueOf(0)); push(op); } break; case Opcodes.FCONST_1: { Operand op = new Operand(); op.setConstant(Float.valueOf(1)); push(op); } break; case Opcodes.FCONST_2: { Operand op = new Operand(); op.setConstant(Float.valueOf(2)); push(op); } break; case Opcodes.DCONST_0: { Operand op = new Operand(); op.setConstant(Double.valueOf(0)); push(op); } break; case Opcodes.DCONST_1: { Operand op = new Operand(); op.setConstant(Double.valueOf(1)); push(op); } break; case Opcodes.IALOAD: { pop2(); Operand op = new Operand(); op.setSignature("I"); push(op); } break; case Opcodes.LALOAD: { pop2(); Operand op = new Operand(); op.setSignature("J"); push(op); } break; case Opcodes.FALOAD: { pop2(); Operand op = new Operand(); op.setSignature("F"); push(op); } break; case Opcodes.DALOAD: { pop2(); Operand op = new Operand(); op.setSignature("D"); push(op); } break; case Opcodes.AALOAD: { pop2(); Operand op = new Operand(); op.setSignature("Ljava/lang/Object;"); push(op); } break; case Opcodes.BALOAD: { pop2(); Operand op = new Operand(); op.setSignature("B"); push(op); } break; case Opcodes.CALOAD: { pop2(); Operand op = new Operand(); op.setSignature("C"); push(op); } break; case Opcodes.SALOAD: { pop2(); Operand op = new Operand(); op.setSignature("S"); push(op); } break; case Opcodes.IASTORE: case Opcodes.LASTORE: case Opcodes.FASTORE: case Opcodes.DASTORE: case Opcodes.AASTORE: case Opcodes.BASTORE: case Opcodes.CASTORE: case Opcodes.SASTORE: if (stack.size() < 2) { stack.clear(); } else { Operand value = stack.remove(stack.size() - 1); Operand reg = stack.remove(stack.size() - 1); registers.put(Integer.valueOf(reg.getRegister()), value); } break; case Opcodes.POP: pop(); break; case Opcodes.POP2: pop2(); break; case Opcodes.DUP: if (!stack.isEmpty()) { Operand op = stack.get(stack.size() - 1); push(op); } break; case Opcodes.DUP_X1: if (stack.size() >= 2) { Operand op = stack.get(stack.size() - 1); stack.add(stack.size() - 2, op); } break; case Opcodes.DUP_X2: if (stack.size() >= 2) { Operand op = stack.get(stack.size() - 2); String sig = op.getSignature(); op = stack.get(stack.size() - 1); if ("J".equals(sig) || "D".equals(sig)) { stack.add(stack.size() - 2, op); } else if (stack.size() >= 3) { stack.add(stack.size() - 3, op); } } break; case Opcodes.DUP2: if (stack.size() >= 2) { stack.add(stack.get(stack.size() - 2)); stack.add(stack.get(stack.size() - 2)); } break; case Opcodes.DUP2_X1: if (stack.size() >= 1) { Operand op = stack.get(stack.size() - 1); String sig = op.getSignature(); if ("J".equals(sig) || "D".equals(sig)) { if (stack.size() >= 3) { stack.add(stack.size() - 3, op); op = stack.get(stack.size() - 2); stack.add(stack.size() - 4, op); } } else { if (stack.size() >= 2) { stack.add(stack.size() - 2, op); } } } break; case Opcodes.DUP2_X2: if (stack.size() >= 1) { Operand op = stack.get(stack.size() - 1); String sig = op.getSignature(); if ("J".equals(sig) || "D".equals(sig)) { if (stack.size() >= 2) { op = stack.get(stack.size() - 2); sig = op.getSignature(); if ("J".equals(sig) || "D".equals(sig)) { op = stack.get(stack.size() - 1); stack.add(stack.size() - 2, op); } else { if (stack.size() >= 3) { op = stack.get(stack.size() - 1); stack.add(stack.size() - 3, op); } } } } else { if (stack.size() >= 3) { op = stack.get(stack.size() - 3); sig = op.getSignature(); if ("J".equals(sig) || "D".equals(sig)) { op = stack.get(stack.size() - 2); stack.add(stack.size() - 3, op); op = stack.get(stack.size() - 1); stack.add(stack.size() - 3, op); } else { if (stack.size() >= 4) { op = stack.get(stack.size() - 2); stack.add(stack.size() - 4, op); op = stack.get(stack.size() - 1); stack.add(stack.size() - 4, op); } } } } } break; case Opcodes.SWAP: if (stack.size() >= 2) { Operand op = stack.remove(stack.size() - 1); stack.add(stack.size() - 1, op); } break; case Opcodes.IADD: { pop2(); Operand op = new Operand(); op.setSignature("I"); push(op); } break; case Opcodes.LADD: { pop2(); Operand op = new Operand(); op.setSignature("J"); push(op); } break; case Opcodes.FADD: { pop2(); Operand op = new Operand(); op.setSignature("F"); push(op); } break; case Opcodes.DADD: { pop2(); Operand op = new Operand(); op.setSignature("D"); push(op); } break; case Opcodes.ISUB: { pop2(); Operand op = new Operand(); op.setSignature("I"); push(op); } break; case Opcodes.LSUB: { pop2(); Operand op = new Operand(); op.setSignature("J"); push(op); } break; case Opcodes.FSUB: { pop2(); Operand op = new Operand(); op.setSignature("F"); push(op); } break; case Opcodes.DSUB: { pop2(); Operand op = new Operand(); op.setSignature("D"); push(op); } break; case Opcodes.IMUL: { pop2(); Operand op = new Operand(); op.setSignature("I"); push(op); } break; case Opcodes.LMUL: { pop2(); Operand op = new Operand(); op.setSignature("J"); push(op); } break; case Opcodes.FMUL: { pop2(); Operand op = new Operand(); op.setSignature("F"); push(op); } break; case Opcodes.DMUL: { pop2(); Operand op = new Operand(); op.setSignature("D"); push(op); } break; case Opcodes.IDIV: { pop2(); Operand op = new Operand(); op.setSignature("I"); push(op); } break; case Opcodes.LDIV: { pop2(); Operand op = new Operand(); op.setSignature("J"); push(op); } break; case Opcodes.FDIV: { pop2(); Operand op = new Operand(); op.setSignature("F"); push(op); } break; case Opcodes.DDIV: { pop2(); Operand op = new Operand(); op.setSignature("D"); push(op); } break; case Opcodes.IREM: { pop2(); Operand op = new Operand(); op.setSignature("I"); push(op); } break; case Opcodes.LREM: { pop2(); Operand op = new Operand(); op.setSignature("J"); push(op); } break; case Opcodes.FREM: { pop2(); Operand op = new Operand(); op.setSignature("F"); push(op); } break; case Opcodes.DREM: { pop2(); Operand op = new Operand(); op.setSignature("D"); push(op); } break; case Opcodes.INEG: { pop(); Operand op = new Operand(); op.setSignature("I"); push(op); } break; case Opcodes.LNEG: { pop(); Operand op = new Operand(); op.setSignature("J"); push(op); } break; case Opcodes.FNEG: { pop(); Operand op = new Operand(); op.setSignature("F"); push(op); } break; case Opcodes.DNEG: { pop(); Operand op = new Operand(); op.setSignature("D"); push(op); } break; case Opcodes.ISHL: { pop2(); Operand op = new Operand(); op.setSignature("I"); push(op); } break; case Opcodes.LSHL: { pop2(); Operand op = new Operand(); op.setSignature("J"); push(op); } break; case Opcodes.ISHR: { pop2(); Operand op = new Operand(); op.setSignature("I"); push(op); } break; case Opcodes.LSHR: { pop2(); Operand op = new Operand(); op.setSignature("J"); push(op); } break; case Opcodes.IUSHR: { pop2(); Operand op = new Operand(); op.setSignature("I"); push(op); } break; case Opcodes.LUSHR: { pop2(); Operand op = new Operand(); op.setSignature("J"); push(op); } break; case Opcodes.IAND: { pop2(); Operand op = new Operand(); op.setSignature("I"); push(op); } break; case Opcodes.LAND: { pop2(); Operand op = new Operand(); op.setSignature("J"); push(op); } break; case Opcodes.IOR: { pop2(); Operand op = new Operand(); op.setSignature("I"); push(op); } break; case Opcodes.LOR: { pop2(); Operand op = new Operand(); op.setSignature("J"); push(op); } break; case Opcodes.IXOR: { pop2(); Operand op = new Operand(); op.setSignature("I"); push(op); } break; case Opcodes.LXOR: { pop2(); Operand op = new Operand(); op.setSignature("J"); push(op); } break; case Opcodes.I2L: { Operand lop = new Operand(); lop.setSignature("J"); if (!stack.isEmpty()) { Operand op = stack.remove(stack.size() - 1); Object o = op.getConstant(); if (o != null) { lop.setConstant(Long.valueOf(((Integer) o).longValue())); } } push(lop); } break; case Opcodes.I2F: { Operand fop = new Operand(); fop.setSignature("F"); if (!stack.isEmpty()) { Operand op = stack.remove(stack.size() - 1); Object o = op.getConstant(); if (o != null) { fop.setConstant(Float.valueOf(((Integer) o).floatValue())); } } push(fop); } break; case Opcodes.I2D: { Operand dop = new Operand(); dop.setSignature("D"); if (!stack.isEmpty()) { Operand op = stack.remove(stack.size() - 1); Object o = op.getConstant(); if (o != null) { dop.setConstant(Double.valueOf(((Integer) o).doubleValue())); } } push(dop); } break; case Opcodes.L2I: { Operand iop = new Operand(); iop.setSignature("I"); if (!stack.isEmpty()) { Operand op = stack.remove(stack.size() - 1); Object o = op.getConstant(); if (o != null) { iop.setConstant(Integer.valueOf(((Long) o).intValue())); } } push(iop); } break; case Opcodes.L2F: { Operand fop = new Operand(); fop.setSignature("F"); if (!stack.isEmpty()) { Operand op = stack.remove(stack.size() - 1); Object o = op.getConstant(); if (o != null) { fop.setConstant(Float.valueOf(((Long) o).floatValue())); } } push(fop); } break; case Opcodes.L2D: { Operand dop = new Operand(); dop.setSignature("D"); if (!stack.isEmpty()) { Operand op = stack.remove(stack.size() - 1); Object o = op.getConstant(); if (o != null) { dop.setConstant(Double.valueOf(((Long) o).doubleValue())); } } push(dop); } break; case Opcodes.F2I: { Operand iop = new Operand(); iop.setSignature("I"); if (!stack.isEmpty()) { Operand op = stack.remove(stack.size() - 1); Object o = op.getConstant(); if (o != null) { iop.setConstant(Integer.valueOf(((Float) o).intValue())); } } push(iop); } break; case Opcodes.F2L: { Operand lop = new Operand(); lop.setSignature("J"); if (!stack.isEmpty()) { Operand op = stack.remove(stack.size() - 1); Object o = op.getConstant(); if (o != null) { lop.setConstant(Long.valueOf(((Float) o).longValue())); } } push(lop); } break; case Opcodes.F2D: { Operand dop = new Operand(); dop.setSignature("D"); if (!stack.isEmpty()) { Operand op = stack.remove(stack.size() - 1); Object o = op.getConstant(); if (o != null) { dop.setConstant(Double.valueOf(((Float) o).doubleValue())); } } push(dop); } break; case Opcodes.D2I: { Operand iop = new Operand(); iop.setSignature("I"); if (!stack.isEmpty()) { Operand op = stack.remove(stack.size() - 1); Object o = op.getConstant(); if (o != null) { iop.setConstant(Integer.valueOf(((Double) o).intValue())); } } push(iop); } break; case Opcodes.D2L: { Operand lop = new Operand(); lop.setSignature("J"); if (!stack.isEmpty()) { Operand op = stack.remove(stack.size() - 1); Object o = op.getConstant(); if (o != null) { lop.setConstant(Long.valueOf(((Double) o).longValue())); } } push(lop); } break; case Opcodes.D2F: { Operand fop = new Operand(); fop.setSignature("F"); if (!stack.isEmpty()) { Operand op = stack.remove(stack.size() - 1); Object o = op.getConstant(); if (o != null) { fop.setConstant(Float.valueOf(((Double) o).floatValue())); } } push(fop); } break; case Opcodes.I2B: { Operand bop = new Operand(); bop.setSignature("B"); if (!stack.isEmpty()) { Operand op = stack.remove(stack.size() - 1); Object o = op.getConstant(); if (o != null) { bop.setConstant(Byte.valueOf(((Integer) o).byteValue())); } } push(bop); } break; case Opcodes.I2C: { Operand cop = new Operand(); cop.setSignature("C"); if (!stack.isEmpty()) { Operand op = stack.remove(stack.size() - 1); Object o = op.getConstant(); if (o != null) { cop.setConstant(Character.valueOf((char) ((Integer) o).intValue())); } } push(cop); } break; case Opcodes.I2S: { Operand sop = new Operand(); sop.setSignature("S"); if (!stack.isEmpty()) { Operand op = stack.remove(stack.size() - 1); Object o = op.getConstant(); if (o != null) { sop.setConstant(Short.valueOf((short) ((Integer) o).intValue())); } } push(sop); } break; case Opcodes.LCMP: case Opcodes.FCMPL: case Opcodes.FCMPG: case Opcodes.DCMPL: case Opcodes.DCMPG: { pop2(); Operand op = new Operand(); op.setSignature("I"); push(op); } break; case Opcodes.IRETURN: case Opcodes.LRETURN: case Opcodes.FRETURN: case Opcodes.DRETURN: case Opcodes.ARETURN: pop(); break; case Opcodes.RETURN: //nop break; case Opcodes.ARRAYLENGTH: { pop(); Operand op = new Operand(); op.setSignature("I"); push(op); } break; case Opcodes.ATHROW: case Opcodes.MONITORENTER: case Opcodes.MONITOREXIT: pop(); break; } }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Clones a monitorenter/monitorexit node and returns it as an instruction list. * @param insnNode instruction to clone//www.j a v a 2 s. co m * @throws NullPointerException if any argument is {@code null} * @throws IllegalArgumentException if node isn't of invoke type * @return instruction list with cloned instruction */ public static InsnList cloneMonitorNode(AbstractInsnNode insnNode) { Validate.notNull(insnNode); Validate.isTrue(insnNode instanceof InsnNode); Validate.isTrue( insnNode.getOpcode() == Opcodes.MONITORENTER || insnNode.getOpcode() == Opcodes.MONITOREXIT); InsnList ret = new InsnList(); ret.add(insnNode.clone(new HashMap<>())); return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.InstructionUtils.java
License:Open Source License
/** * Generates a MONITORENTER instruction, which consumes an Object from the top of the stack. * @return instructions for a pop// ww w . j a v a 2 s .c o m */ public static InsnList monitorEnter() { InsnList ret = new InsnList(); ret.add(new InsnNode(Opcodes.MONITORENTER)); return ret; }
From source file:com.offbynull.coroutines.instrumenter.asm.SearchUtilsTest.java
License:Open Source License
@Test public void mustFindOpcodeWithinMethod() { MethodNode methodNode = findMethodsWithName(classNode.methods, "syncTest").get(0); List<AbstractInsnNode> insns = searchForOpcodes(methodNode.instructions, Opcodes.MONITORENTER, Opcodes.MONITOREXIT);// w ww .j av a2s.c o m assertEquals(3, insns.size()); assertEquals(Opcodes.MONITORENTER, insns.get(0).getOpcode()); assertEquals(Opcodes.MONITOREXIT, insns.get(1).getOpcode()); assertEquals(Opcodes.MONITOREXIT, insns.get(2).getOpcode()); // hidden trycatch block generated by compiler }
From source file:com.offbynull.coroutines.instrumenter.MethodAnalyzer.java
License:Open Source License
public MethodAttributes analyze(ClassNode classNode, MethodNode methodNode, InstrumentationSettings settings) { /////////////////////////////////////////////////////////////////////////////////////////// // VALIDATE INPUTS /////////////////////////////////////////////////////////////////////////////////////////// Validate.notNull(classNode);// w w w . ja v a 2 s . c om Validate.notNull(methodNode); Validate.notNull(settings); // Sanity check to make sure class Validate.isTrue(classNode.methods.contains(methodNode), "Method does not belong to class"); // Check if method is constructor -- we cannot instrument constructor Validate.isTrue(!"<init>".equals(methodNode.name), "Instrumentation of constructors not allowed"); // Check for JSR blocks -- Emitted for finally blocks in older versions of the JDK. Should never happen since we already inlined // these blocks before coming to this point. This is a sanity check. Validate.isTrue(searchForOpcodes(methodNode.instructions, Opcodes.JSR).isEmpty(), "JSR instructions not allowed"); /////////////////////////////////////////////////////////////////////////////////////////// // FIND SUSPEND / CONTINUATION INVOCATIONS + ALSO FIND SYNCHRONIZATION INSTRUCTIONS /////////////////////////////////////////////////////////////////////////////////////////// // Find invocations of continuation invocation/suspend List<AbstractInsnNode> suspendInvocationInsnNodes = findInvocationsOf(methodNode.instructions, CONTINUATION_SUSPEND_METHOD); List<AbstractInsnNode> contInvocationInsnNodes = findInvocationsWithParameter(methodNode.instructions, CONTINUATION_CLASS_TYPE); // If there are no continuation points, we don't need to instrument this method. It'll be like any other normal method // invocation because it won't have the potential to pause or call in to another method that may potentially pause. if (suspendInvocationInsnNodes.isEmpty() && contInvocationInsnNodes.isEmpty()) { return null; } // Check for continuation points that use invokedynamic instruction, which are currently only used by lambdas. See comments in // validateNoInvokeDynamic to see why we need to do this. validateNoInvokeDynamic(suspendInvocationInsnNodes); validateNoInvokeDynamic(contInvocationInsnNodes); // Find MONITORENTER/MONITOREXIT instructions List<AbstractInsnNode> monitorInsnNodes = searchForOpcodes(methodNode.instructions, Opcodes.MONITORENTER, Opcodes.MONITOREXIT); /////////////////////////////////////////////////////////////////////////////////////////// // COMPUTE FRAMES FOR INSTRUCTIONS /////////////////////////////////////////////////////////////////////////////////////////// // Compute frames for each instruction in the method Frame<BasicValue>[] frames; try { frames = new Analyzer<>(new SimpleVerifier(classInfoRepo)).analyze(classNode.name, methodNode); } catch (AnalyzerException ae) { throw new IllegalArgumentException("Analyzer failed to analyze method", ae); } /////////////////////////////////////////////////////////////////////////////////////////// // CREATE SUSPEND/CONTINUATION/SYNCHRONIZATION OBJECTS /////////////////////////////////////////////////////////////////////////////////////////// List<ContinuationPoint> continuationPoints = new LinkedList<>(); // Create SuspendContinuationPoint objects for suspend points for (AbstractInsnNode suspendInvocationInsnNode : suspendInvocationInsnNodes) { int instructionIndex = methodNode.instructions.indexOf(suspendInvocationInsnNode); Frame<BasicValue> frame = frames[instructionIndex]; LineNumberNode lineNumberNode = findLineNumberForInstruction(methodNode.instructions, suspendInvocationInsnNode); Integer lineNumber = lineNumberNode != null ? lineNumberNode.line : null; SuspendContinuationPoint suspendPoint = new SuspendContinuationPoint(lineNumber, (MethodInsnNode) suspendInvocationInsnNode, frame); continuationPoints.add(suspendPoint); } // Create NormalInvokeContinuationPoint / TryCatchInvokeContinuationPoint objects for suspend points for (AbstractInsnNode contInvocationInsnNode : contInvocationInsnNodes) { int instructionIndex = methodNode.instructions.indexOf(contInvocationInsnNode); boolean withinTryCatch = findTryCatchBlockNodesEncompassingInstruction(methodNode.instructions, methodNode.tryCatchBlocks, contInvocationInsnNode).size() > 0; Frame<BasicValue> frame = frames[instructionIndex]; LineNumberNode lineNumberNode = findLineNumberForInstruction(methodNode.instructions, contInvocationInsnNode); Integer lineNumber = lineNumberNode != null ? lineNumberNode.line : null; ContinuationPoint continuationPoint; if (withinTryCatch) { continuationPoint = new TryCatchInvokeContinuationPoint(lineNumber, (MethodInsnNode) contInvocationInsnNode, frame); } else { continuationPoint = new NormalInvokeContinuationPoint(lineNumber, (MethodInsnNode) contInvocationInsnNode, frame); } continuationPoints.add(continuationPoint); } // Create SynchronizationPoint objects for MONITORENTER/MONITOREXIT opcodes List<SynchronizationPoint> synchPoints = new LinkedList<>(); for (AbstractInsnNode monitorInsnNode : monitorInsnNodes) { int instructionIndex = methodNode.instructions.indexOf(monitorInsnNode); Frame<BasicValue> frame = frames[instructionIndex]; SynchronizationPoint synchPoint = new SynchronizationPoint((InsnNode) monitorInsnNode, frame); synchPoints.add(synchPoint); } /////////////////////////////////////////////////////////////////////////////////////////// // DETERMINE TYPES RETURNED FROM SUSPEND / CONTINUATION POINTS /////////////////////////////////////////////////////////////////////////////////////////// // For each non-suspend invocation node found, see what the return type is and figure out if it's in a try/catch block. // // The return type scanning is needed because the instrumenter needs to temporarily cache the results of the invocation. The // variable slots for these caches are assigned lower on in the code. // // The try/catch information is needed because the instrumenter needs to temporarily cache a throwable if the invocation throws one. // The variable slot for the throwable is assigned lower on in the code. TypeTracker invocationReturnTypes = new TypeTracker(); boolean invocationFoundWrappedInTryCatch = false; for (AbstractInsnNode invokeInsnNode : contInvocationInsnNodes) { if (findTryCatchBlockNodesEncompassingInstruction(methodNode.instructions, methodNode.tryCatchBlocks, invokeInsnNode).size() > 0) { invocationFoundWrappedInTryCatch = true; } Type returnType = getReturnTypeOfInvocation(invokeInsnNode); if (returnType.getSort() != Type.VOID) { invocationReturnTypes.trackType(returnType); } } /////////////////////////////////////////////////////////////////////////////////////////// // DETERMINE TYPES ON THE LOCAL VARIABLES TABE AT SUSPEND / CONTINUATION POINTS /////////////////////////////////////////////////////////////////////////////////////////// // For each invocation node found, see whats on the locals. // // We need on scan the types on the locals because the instrumenter needs to know which extra variable slots to allot to the // storage containers for those types. The variable slots for these storage containers are assigned lower on in the code. TypeTracker localsTypes = new TypeTracker(); for (AbstractInsnNode invokeInsnNode : union(contInvocationInsnNodes, suspendInvocationInsnNodes)) { int instructionIndex = methodNode.instructions.indexOf(invokeInsnNode); Frame<BasicValue> frame = frames[instructionIndex]; for (int i = 0; i < frame.getLocals(); i++) { BasicValue basicValue = frame.getLocal(i); Type type = basicValue.getType(); // If type == null, basicValue is pointing to uninitialized var -- basicValue.toString() will return '.'. This means that // this slot contains nothing to save. We don't store anything in this case so skip this slot if we encounter it. // // If type is 'Lnull;', this means that the slot has been assigned null and that "there has been no merge yet that would // 'raise' the type toward some class or interface type" (from ASM mailing list). We know this slot will always contain null // at this point in the code so we can avoid saving it. When we load it back up, we can simply push a null in to that slot, // thereby keeping the same 'Lnull;' type. if (type == null || "Lnull;".equals(type.getDescriptor())) { continue; } localsTypes.trackType(type); } } /////////////////////////////////////////////////////////////////////////////////////////// // DETERMINE TYPES ON THE OPERAND STACK AT SUSPEND / CONTINUATION POINTS /////////////////////////////////////////////////////////////////////////////////////////// // For each invocation node found, see whats on the operand stack. // // We need on scan the types on the operand stack because the instrumenter needs to know which extra variable slots to allot to the // storage containers for those types. The variable slots for these storage containers are assigned lower on in the code. TypeTracker operandStackTypes = new TypeTracker(); for (AbstractInsnNode invokeInsnNode : union(contInvocationInsnNodes, suspendInvocationInsnNodes)) { int instructionIndex = methodNode.instructions.indexOf(invokeInsnNode); Frame<BasicValue> frame = frames[instructionIndex]; for (int i = 0; i < frame.getStackSize(); i++) { BasicValue basicValue = frame.getStack(i); Type type = basicValue.getType(); // If type is 'Lnull;', this means that the slot has been assigned null and that "there has been no merge yet that would // 'raise' the type toward some class or interface type" (from ASM mailing list). We know this slot will always contain null // at this point in the code so we can avoid saving it. When we load it back up, we can simply push a null in to that slot, // thereby keeping the same 'Lnull;' type. if ("Lnull;".equals(type.getDescriptor())) { continue; } operandStackTypes.trackType(type); } } /////////////////////////////////////////////////////////////////////////////////////////// // DETERMINE WHICH INDEX IN LOCAL VARIABLE TABLE CONTAINS CONTINUATION OBJECT /////////////////////////////////////////////////////////////////////////////////////////// // Find index of continuation object int contArgIdx = getLocalVariableIndexOfContinuationParameter(methodNode); /////////////////////////////////////////////////////////////////////////////////////////// // CALCULATE EXTRA VARIABLES REQUIRED BY INSTRUMENTATION /////////////////////////////////////////////////////////////////////////////////////////// VariableTable varTable = new VariableTable(classNode, methodNode); // Create variable for the continuation object passed in as arg + variable for storing/loading method state Variable continuationArgVar = varTable.getArgument(contArgIdx); Variable methodStateVar = varTable.acquireExtra(MethodState.class); CoreVariables coreVars = new CoreVariables(continuationArgVar, methodStateVar); // Create variables for storing/loading locals -- only create ones we need StorageVariables localsStorageVars = allocateStorageVariableSlots(varTable, localsTypes); // Create variables for storing/loading operand stack -- only create ones we need StorageVariables stackStorageVars = allocateStorageVariableSlots(varTable, operandStackTypes); // Create variables to locals and operand stack storage containers -- these must exist StorageContainerVariables storageContainerVars = allocateStorageContainerVariableSlots(varTable); // Create variables to cache return values and thrown exceptions of invocations -- only create ones we need CacheVariables cacheVars = allocateCacheVariableSlots(varTable, invocationReturnTypes, invocationFoundWrappedInTryCatch); // Create variables to for holding on to monitors -- only create if we need them LockVariables lockVars = allocateLockVariableSlots(varTable, !synchPoints.isEmpty()); /////////////////////////////////////////////////////////////////////////////////////////// // RETURN RESULTS OF ANALYSIS /////////////////////////////////////////////////////////////////////////////////////////// MethodSignature signature = new MethodSignature(classNode.name, methodNode.name, Type.getMethodType(methodNode.desc)); return new MethodAttributes(signature, settings, continuationPoints, synchPoints, coreVars, cacheVars, storageContainerVars, localsStorageVars, stackStorageVars, lockVars); }
From source file:com.offbynull.coroutines.instrumenter.MethodInstrumenter.java
License:Open Source License
public void instrument(MethodNode methodNode, MethodAttributes attrs) { Validate.notNull(methodNode);// w ww .j a v a 2 s .c o m Validate.notNull(attrs); // These sanity checks need to exist. The methodNode.instructions.insertBefore/remove methods don't actually check to make sure the // instructions they're operating on belong to the method. This is here to make sure that the properties and methodNode match. attrs.getContinuationPoints().stream().map(x -> x.getInvokeInstruction()) .forEach(x -> methodNode.instructions.contains(x)); attrs.getSynchronizationPoints().stream().map(x -> x.getMonitorInstruction()) .forEach(x -> methodNode.instructions.contains(x)); // Add trycatch nodes attrs.getContinuationPoints().stream().filter(x -> x instanceof TryCatchInvokeContinuationPoint) .map(x -> (TryCatchInvokeContinuationPoint) x).map(x -> x.getTryCatchBlock()) .forEach(x -> methodNode.tryCatchBlocks.add(0, x)); // Add loading code (this includes continuation restore points) InsnList entryPoint = entryPointLoader(attrs); methodNode.instructions.insert(entryPoint); // Add continuation save points List<ContinuationPoint> continuationPoints = attrs.getContinuationPoints(); for (int i = 0; i < continuationPoints.size(); i++) { ContinuationPoint cp = continuationPoints.get(i); AbstractInsnNode nodeToReplace = cp.getInvokeInstruction(); InsnList insnsToReplaceWith = saveState(attrs, i); methodNode.instructions.insertBefore(nodeToReplace, insnsToReplaceWith); methodNode.instructions.remove(nodeToReplace); } // Add synchronization save points List<SynchronizationPoint> synchPoints = attrs.getSynchronizationPoints(); MarkerType markerType = attrs.getSettings().getMarkerType(); LockVariables lockVars = attrs.getLockVariables(); for (int i = 0; i < synchPoints.size(); i++) { SynchronizationPoint sp = synchPoints.get(i); InsnNode nodeToReplace = sp.getMonitorInstruction(); InsnList insnsToReplaceWith; switch (nodeToReplace.getOpcode()) { case Opcodes.MONITORENTER: insnsToReplaceWith = enterMonitorAndStore(markerType, lockVars); break; case Opcodes.MONITOREXIT: insnsToReplaceWith = exitMonitorAndDelete(markerType, lockVars); break; default: throw new IllegalStateException(); //should never happen } methodNode.instructions.insertBefore(nodeToReplace, insnsToReplaceWith); methodNode.instructions.remove(nodeToReplace); } }
From source file:com.offbynull.coroutines.instrumenter.MonitorInstrumentationGenerator.java
License:Open Source License
MonitorInstrumentationInstructions generate() { // Find monitorenter/monitorexit and create replacement instructions that keep track of which objects were entered/exited. ////from ww w . j a v a 2 s .c o m // // Check for synchronized code blocks. Synchronized methods and Java 5 locks are okay to ignore, but synchronized blocks need to // be instrumented. For every MONITORENTER instruction that's performed on an object, there needs to be an equivalent MONITOREXIT // before the method exits. Otherwise, the method throws an IllegalMonitorState exception when it exits. I've confirmed by making a // simple java class in JASMIN assembler that did 10 MONITORENTERs in a loop and returned. That code threw // IllegalMonitorStateException when it tried to return. This link seems to explain it pretty well: // http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2008-April/000118.html. // // So that means that if we're going to instrument the code to suspend and return in places, we need to make sure to exit all // monitors when we return and to re-enter those monitors when we come back in. We can't handle this via static analysis like we do // with inspecting the operand stack and local variables. It looks like static analysis is what Javaflow tries to do, which will // work in 99% of cases but won't in some edge cases like if the code was written in some JVM langauge other than Java. // // The following code creates replacements for every MONITORENTER and MONITOREXIT instruction such that those monitors get tracked // in a LockState object. List<AbstractInsnNode> monitorInsnNodes = searchForOpcodes(methodNode.instructions, Opcodes.MONITORENTER, Opcodes.MONITOREXIT); Map<AbstractInsnNode, InsnList> monitorInsnNodeReplacements = new HashMap<>(); // IMPORTANT NOTE: The following code only generates code if monitorInsnNodes is NOT empty. That means that there has to be at least // one MONITORENTER or one MONITOREXIT for this method to generate instructions. Otherwise, all instruction listings will be stubbed // out with empty instruction lists. for (AbstractInsnNode monitorInsnNode : monitorInsnNodes) { InsnNode insnNode = (InsnNode) monitorInsnNode; InsnList replacementLogic; switch (insnNode.getOpcode()) { case Opcodes.MONITORENTER: replacementLogic = merge(saveVar(tempObjVar), // enter monitor loadVar(tempObjVar), cloneMonitorNode(insnNode), call(LOCKSTATE_ENTER_METHOD, loadVar(lockStateVar), loadVar(tempObjVar)) // track after entered ); break; case Opcodes.MONITOREXIT: replacementLogic = merge(saveVar(tempObjVar), // exit monitor loadVar(tempObjVar), cloneMonitorNode(insnNode), call(LOCKSTATE_EXIT_METHOD, loadVar(lockStateVar), loadVar(tempObjVar)) // discard after exit ); break; default: throw new IllegalStateException(); // should never happen } monitorInsnNodeReplacements.put(monitorInsnNode, replacementLogic); } // Create code to create a new lockstate object InsnList createAndStoreLockStateInsnList; if (monitorInsnNodeReplacements.isEmpty()) { // if we don't have any MONITORENTER/MONITOREXIT, ignore this createAndStoreLockStateInsnList = empty(); } else { createAndStoreLockStateInsnList = merge(construct(LOCKSTATE_INIT_METHOD), saveVar(lockStateVar)); } // Create code to load lockstate object from methodstate InsnList loadAndStoreLockStateFromMethodStateInsnList; if (monitorInsnNodeReplacements.isEmpty()) { loadAndStoreLockStateFromMethodStateInsnList = empty(); } else { loadAndStoreLockStateFromMethodStateInsnList = merge( call(METHODSTATE_GETLOCKSTATE_METHOD, loadVar(methodStateVar)), saveVar(lockStateVar)); } // Create code to load lockstate object to the stack InsnList loadLockStateToStackInsnList; if (monitorInsnNodeReplacements.isEmpty()) { loadLockStateToStackInsnList = loadNull(); } else { loadLockStateToStackInsnList = loadVar(lockStateVar); } // Create code to enter all monitors in lockstate object InsnList enterMonitorsInLockStateInsnList; if (monitorInsnNodeReplacements.isEmpty()) { enterMonitorsInLockStateInsnList = empty(); } else { enterMonitorsInLockStateInsnList = forEach(counterVar, arrayLenVar, call(LOCKSTATE_TOARRAY_METHOD, loadVar(lockStateVar)), merge(monitorEnter() // temp monitor enter )); } // Create code to exit all monitors in lockstate object InsnList exitMonitorsInLockStateInsnList; if (monitorInsnNodeReplacements.isEmpty()) { exitMonitorsInLockStateInsnList = empty(); } else { exitMonitorsInLockStateInsnList = forEach(counterVar, arrayLenVar, call(LOCKSTATE_TOARRAY_METHOD, loadVar(lockStateVar)), merge(monitorExit() // temp monitor exit )); } return new MonitorInstrumentationInstructions(monitorInsnNodeReplacements, createAndStoreLockStateInsnList, loadAndStoreLockStateFromMethodStateInsnList, loadLockStateToStackInsnList, enterMonitorsInLockStateInsnList, exitMonitorsInLockStateInsnList); }
From source file:com.offbynull.coroutines.instrumenter.SynchronizationGenerators.java
License:Open Source License
/** * Generates instruction to enter all monitors in the {@link LockState} object sitting in the lockstate variable. * @param markerType debug marker type//from w w w. j av a2 s. co m * @param lockVars variables for lock/synchpoint functionality * @return instructions to enter all monitors in the {@link LockState} object * @throws NullPointerException if any argument is {@code null} * @throws IllegalArgumentException if lock variables aren't set (the method doesn't contain any monitorenter/monitorexit instructions) */ public static InsnList enterStoredMonitors(MarkerType markerType, LockVariables lockVars) { Validate.notNull(markerType); Validate.notNull(lockVars); Variable lockStateVar = lockVars.getLockStateVar(); Variable counterVar = lockVars.getCounterVar(); Variable arrayLenVar = lockVars.getArrayLenVar(); Validate.isTrue(lockStateVar != null); Validate.isTrue(counterVar != null); Validate.isTrue(arrayLenVar != null); return forEach(counterVar, arrayLenVar, merge(debugMarker(markerType, "Loading monitors to enter"), call(LOCKSTATE_TOARRAY_METHOD, loadVar(lockStateVar))), merge(debugMarker(markerType, "Entering monitor"), new InsnNode(Opcodes.MONITORENTER))); }
From source file:com.offbynull.coroutines.instrumenter.SynchronizationGenerators.java
License:Open Source License
/** * Generates instruction to enter a monitor (top item on the stack) and store it in the {@link LockState} object sitting in the * lockstate variable.// w w w . ja v a 2s . c o m * @param markerType debug marker type * @param lockVars variables for lock/synchpoint functionality * @return instructions to enter a monitor and store it in the {@link LockState} object * @throws NullPointerException if any argument is {@code null} * @throws IllegalArgumentException if lock variables aren't set (the method doesn't contain any monitorenter/monitorexit instructions) */ public static InsnList enterMonitorAndStore(MarkerType markerType, LockVariables lockVars) { Validate.notNull(markerType); Validate.notNull(lockVars); Variable lockStateVar = lockVars.getLockStateVar(); Validate.isTrue(lockStateVar != null); Type clsType = Type.getType(LOCKSTATE_ENTER_METHOD.getDeclaringClass()); Type methodType = Type.getType(LOCKSTATE_ENTER_METHOD); String clsInternalName = clsType.getInternalName(); String methodDesc = methodType.getDescriptor(); String methodName = LOCKSTATE_ENTER_METHOD.getName(); // NOTE: This adds to the lock state AFTER locking. return merge(debugMarker(markerType, "Entering monitor and storing"), // [obj] new InsnNode(Opcodes.DUP), // [obj, obj] new InsnNode(Opcodes.MONITORENTER), // [obj] new VarInsnNode(Opcodes.ALOAD, lockStateVar.getIndex()), // [obj, lockState] new InsnNode(Opcodes.SWAP), // [lockState, obj] new MethodInsnNode(Opcodes.INVOKEVIRTUAL, // [] clsInternalName, methodName, methodDesc, false)); }