Example usage for org.objectweb.asm Opcodes IRETURN

List of usage examples for org.objectweb.asm Opcodes IRETURN

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes IRETURN.

Prototype

int IRETURN

To view the source code for org.objectweb.asm Opcodes IRETURN.

Click Source Link

Usage

From source file:de.tuberlin.uebb.jbop.optimizer.array.LocalArrayLengthInlinerTest.java

License:Open Source License

/**
 * Tests that LocalArrayLengthInliner is working correctly.
 * /*  w ww  . j av a 2  s.c  o m*/
 * @throws Exception
 *           the exception
 */
@Test
public void test_newarrayAndSubarray() throws Exception {
    // INIT
    final String owner = "de.tuberlin.uebb.jbop.optimizer.array.LocalArrayLengthTestClass";
    final ClassNodeBuilder builder = ClassNodeBuilder.createClass(owner).//
            addField("doubleArray", "[[D").initArray(15, 42)
            .withModifiers(Opcodes.ACC_PRIVATE, Opcodes.ACC_FINAL).//
            addMethod("getArrayLength", "()I").withAnnotation(Optimizable.class).//
            addArray("[D", 15).// 3 -> 3
            addInsn(new VarInsnNode(Opcodes.ALOAD, 1)).// 1 -> 0|
            addInsn(new InsnNode(Opcodes.ARRAYLENGTH)).// 1 -> 0|1
            addGetClassField("doubleArray").// 2 -> 2
            addInsn(new InsnNode(Opcodes.ICONST_0)).// 1 -> 1
            addInsn(new InsnNode(Opcodes.AALOAD)).// 1 -> 1
            addInsn(new VarInsnNode(Opcodes.ASTORE, 2)).// 1 -> 1
            addInsn(new VarInsnNode(Opcodes.ALOAD, 2)).// 1 -> 0|
            addInsn(new InsnNode(Opcodes.ARRAYLENGTH)).// 1 -> 0|1
            addInsn(new InsnNode(Opcodes.IADD)).// 1 -> 1
            addInsn(new InsnNode(Opcodes.IRETURN));// 1 -> 1
    // 14 -> 12
    final LocalArrayLengthInliner inliner = new LocalArrayLengthInliner();
    inliner.setInputObject(builder.toClass().instance());

    // RUN STEP 1
    final MethodNode method = builder.getMethod("getArrayLength");
    assertEquals(14, method.instructions.size());
    final InsnList optimized = inliner.optimize(method.instructions, method);
    method.instructions = optimized;

    // ASSERT STEP 1
    assertEquals(12, optimized.size());
    assertEquals(15, NodeHelper.getNumberValue(optimized.get(3)).intValue());
    assertEquals(42, NodeHelper.getNumberValue(optimized.get(9)).intValue());

    // RUN STEP 2
    final InsnList optimized2 = inliner.optimize(method.instructions, method);

    // ASSERT STEP 2
    assertEquals(12, optimized2.size());
}

From source file:de.tuberlin.uebb.jbop.optimizer.ClassNodeBuilder.java

License:Open Source License

/**
 * Creates a getter for the last added field.
 * /* w w w . j  a  v  a  2  s  .  c  om*/
 * @return the class node builder
 */
public ClassNodeBuilder withGetter() {
    if (isInterface) {
        return this;
    }
    final String name = lastField.name;
    final String desc = lastField.desc;
    addMethod("get" + Character.toUpperCase(name.charAt(0)) + name.substring(1), "()" + desc);
    final Type type = Type.getType(desc);
    addInsn(new VarInsnNode(Opcodes.ALOAD, 0));
    addInsn(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, name, desc));
    addInsn(new InsnNode(type.getOpcode(Opcodes.IRETURN)));
    return this;
}

From source file:de.tuberlin.uebb.jbop.optimizer.methodsplitter.Block.java

License:Open Source License

private Type getTypeIfSimpleType(final AbstractInsnNode node) {
    final int opcode = node.getOpcode();
    if ((opcode == Opcodes.ILOAD) || (opcode == Opcodes.ISTORE) || (opcode == Opcodes.IRETURN)) {
        return Type.INT_TYPE;
    }/*from  w  ww .  ja  va 2 s.co  m*/
    if ((opcode == Opcodes.FLOAD) || (opcode == Opcodes.FSTORE) || (opcode == Opcodes.FRETURN)) {
        return Type.FLOAT_TYPE;
    }
    if ((opcode == Opcodes.LLOAD) || (opcode == Opcodes.LSTORE) || (opcode == Opcodes.LRETURN)) {
        return Type.LONG_TYPE;
    }
    if ((opcode == Opcodes.DLOAD) || (opcode == Opcodes.DSTORE) || (opcode == Opcodes.DRETURN)) {
        return Type.DOUBLE_TYPE;
    }
    return null;
}

From source file:de.tuberlin.uebb.jbop.optimizer.methodsplitter.Block.java

License:Open Source License

private static boolean isStore(final AbstractInsnNode currentNode) {
    if (currentNode == null) {
        return false;
    }//w w  w.j av a2s  . c  o m
    if ((currentNode.getOpcode() >= Opcodes.ISTORE) && (currentNode.getOpcode() <= Opcodes.ASTORE)) {
        return true;
    }
    if ((currentNode.getOpcode() >= Opcodes.IRETURN) && (currentNode.getOpcode() <= Opcodes.RETURN)) {
        return true;
    }
    return false;
}

From source file:de.unisb.cs.st.javalanche.coverage.CoverageMethodAdapter.java

License:Open Source License

public void visitInsn(int inst) {
    if (!methodName.equals("<clinit>") && instrumentReturns) {
        switch (inst) {
        case Opcodes.IRETURN:
            callLogIReturn();// w w  w  .  j  a va 2 s.c  om
            callEnd();
            break;
        case Opcodes.ARETURN:
            callLogAReturn();
            callEnd();
            break;
        case Opcodes.ATHROW:
            callEnd();
            break;
        case Opcodes.DRETURN:
            callLogDReturn();
            callEnd();
            break;
        case Opcodes.FRETURN:
            callLogFReturn();
            callEnd();
            break;
        case Opcodes.LRETURN:
            callLogLReturn();
            callEnd();
            break;
        case Opcodes.RETURN:
            callEnd();
            break;
        default:
            break;
        }
    }
    super.visitInsn(inst);
}

From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.SimpleInstruction.java

License:Open Source License

@Override
public String toString() {
    switch (getOpcode()) {
    // the not interesting ones:
    case Opcodes.NOP:
        return "NOP";
    // constants:
    case Opcodes.ACONST_NULL:
        return "ACONST_NULL";
    case Opcodes.ICONST_M1:
        return "ICONST_M1";
    case Opcodes.ICONST_0:
        return "ICONST_0";
    case Opcodes.ICONST_1:
        return "ICONST_1";
    case Opcodes.ICONST_2:
        return "ICONST_2";
    case Opcodes.ICONST_3:
        return "ICONST_3";
    case Opcodes.ICONST_4:
        return "ICONST_4";
    case Opcodes.ICONST_5:
        return "ICONST_5";
    case Opcodes.LCONST_0:
        return "LCONST_0";
    case Opcodes.LCONST_1:
        return "LCONST_1";
    case Opcodes.FCONST_0:
        return "FCONST_0";
    case Opcodes.FCONST_1:
        return "FCONST_1";
    case Opcodes.FCONST_2:
        return "FCONST_2";
    case Opcodes.DCONST_0:
        return "DCONST_0";
    case Opcodes.DCONST_1:
        return "DCONST_1";

    // array load:
    case Opcodes.IALOAD:
        return "IALOAD";
    case Opcodes.LALOAD:
        return "LALOAD";
    case Opcodes.FALOAD:
        return "FALOAD";
    case Opcodes.DALOAD:
        return "DALOAD";
    case Opcodes.AALOAD:
        return "AALOAD";
    case Opcodes.BALOAD:
        return "BALOAD";
    case Opcodes.CALOAD:
        return "CALOAD";
    case Opcodes.SALOAD:
        return "SALOAD";

    // array store:
    case Opcodes.IASTORE:
        return "IASTORE";
    case Opcodes.LASTORE:
        return "LASTORE";
    case Opcodes.FASTORE:
        return "FASTORE";
    case Opcodes.DASTORE:
        return "DASTORE";
    case Opcodes.AASTORE:
        return "AASTORE";
    case Opcodes.BASTORE:
        return "BASTORE";
    case Opcodes.CASTORE:
        return "CASTORE";
    case Opcodes.SASTORE:
        return "SASTORE";

    // stack manipulation:
    case Opcodes.POP:
        return "POP";
    case Opcodes.POP2:
        return "POP2";
    case Opcodes.DUP:
        return "DUP";
    case Opcodes.DUP_X1:
        return "DUP_X1";
    case Opcodes.DUP_X2:
        return "DUP_X2";
    case Opcodes.DUP2:
        return "DUP2";
    case Opcodes.DUP2_X1:
        return "DUP2_X1";
    case Opcodes.DUP2_X2:
        return "DUP2_X2";
    case Opcodes.SWAP:
        return "SWAP";

    // arithmetic:
    case Opcodes.IADD:
        return "IADD";
    case Opcodes.LADD:
        return "LADD";
    case Opcodes.FADD:
        return "FADD";
    case Opcodes.DADD:
        return "DADD";
    case Opcodes.ISUB:
        return "ISUB";
    case Opcodes.LSUB:
        return "LSUB";
    case Opcodes.FSUB:
        return "FSUB";
    case Opcodes.DSUB:
        return "DSUB";
    case Opcodes.IMUL:
        return "IMUL";
    case Opcodes.LMUL:
        return "LMUL";
    case Opcodes.FMUL:
        return "FMUL";
    case Opcodes.DMUL:
        return "DMUL";
    case Opcodes.IDIV:
        return "IDIV";
    case Opcodes.LDIV:
        return "LDIV";
    case Opcodes.FDIV:
        return "FDIV";
    case Opcodes.DDIV:
        return "DDIV";
    case Opcodes.IREM:
        return "IREM";
    case Opcodes.LREM:
        return "LREM";
    case Opcodes.FREM:
        return "FREM";
    case Opcodes.DREM:
        return "DREM";
    case Opcodes.INEG:
        return "INEG";
    case Opcodes.LNEG:
        return "LNEG";
    case Opcodes.FNEG:
        return "FNEG";
    case Opcodes.DNEG:
        return "DNEG";
    case Opcodes.ISHL:
        return "ISHL";
    case Opcodes.LSHL:
        return "LSHL";
    case Opcodes.ISHR:
        return "ISHR";
    case Opcodes.LSHR:
        return "LSHR";
    case Opcodes.IUSHR:
        return "IUSHR";
    case Opcodes.LUSHR:
        return "LUSHR";
    case Opcodes.IAND:
        return "IAND";
    case Opcodes.LAND:
        return "LAND";
    case Opcodes.IOR:
        return "IOR";
    case Opcodes.LOR:
        return "LOR";
    case Opcodes.IXOR:
        return "IXOR";
    case Opcodes.LXOR:
        return "LXOR";

    // type conversions:
    case Opcodes.I2L:
        return "I2L";
    case Opcodes.I2F:
        return "I2F";
    case Opcodes.I2D:
        return "I2D";
    case Opcodes.L2I:
        return "L2I";
    case Opcodes.L2F:
        return "L2F";
    case Opcodes.L2D:
        return "L2D";
    case Opcodes.F2I:
        return "F2I";
    case Opcodes.F2L:
        return "F2L";
    case Opcodes.F2D:
        return "F2D";
    case Opcodes.D2I:
        return "D2I";
    case Opcodes.D2L:
        return "D2L";
    case Opcodes.D2F:
        return "D2F";
    case Opcodes.I2B:
        return "I2B";
    case Opcodes.I2C:
        return "I2C";
    case Opcodes.I2S:
        return "I2S";

    // comparison:
    case Opcodes.LCMP:
        return "LCMP";
    case Opcodes.FCMPL:
        return "FCMPL";
    case Opcodes.FCMPG:
        return "FCMPG";
    case Opcodes.DCMPL:
        return "DCMPL";
    case Opcodes.DCMPG:
        return "DCMPG";

    // control-flow statements:
    case Opcodes.IRETURN:
        return "IRETURN";
    case Opcodes.LRETURN:
        return "LRETURN";
    case Opcodes.FRETURN:
        return "FRETURN";
    case Opcodes.DRETURN:
        return "DRETURN";
    case Opcodes.ARETURN:
        return "ARETURN";
    case Opcodes.RETURN:
        return "RETURN";

    // special things
    case Opcodes.ARRAYLENGTH:
        return "ARRAYLENGTH";
    case Opcodes.ATHROW:
        return "ATHROW";
    case Opcodes.MONITORENTER:
        return "MONITORENTER";
    case Opcodes.MONITOREXIT:
        return "MONITOREXIT";

    default://from w  ww.j a va 2s .c  om
        assert false;
        return "--ERROR--";
    }
}

From source file:de.unisb.cs.st.javaslicer.controlflowanalysis.ControlFlowGraph.java

License:Open Source License

private static Collection<Instruction> getSuccessors(Instruction instruction) {
    int opcode = instruction.getOpcode();
    Instruction nextInstruction = instruction.getNext();
    switch (instruction.getType()) {
    case JUMP:/*  w w  w .  java 2  s .c om*/
        // GOTO and JSR are not conditional
        if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
            return Collections.singleton((Instruction) ((JumpInstruction) instruction).getLabel());
        }
        assert nextInstruction != null;
        return Arrays.asList(((JumpInstruction) instruction).getLabel(), nextInstruction);
    case LOOKUPSWITCH: {
        LookupSwitchInstruction lsi = (LookupSwitchInstruction) instruction;
        Instruction[] successors = new AbstractInstruction[lsi.getHandlers().size() + 1];
        successors[0] = lsi.getDefaultHandler();
        int i = 1;
        for (LabelMarker lm : lsi.getHandlers().values())
            successors[i++] = lm;
        return Arrays.asList(successors);
    }
    case TABLESWITCH: {
        TableSwitchInstruction tsi = (TableSwitchInstruction) instruction;
        Instruction[] successors = new AbstractInstruction[tsi.getHandlers().length + 1];
        successors[0] = tsi.getDefaultHandler();
        System.arraycopy(tsi.getHandlers(), 0, successors, 1, tsi.getHandlers().length);
        return Arrays.asList(successors);
    }
    case SIMPLE:
        switch (opcode) {
        case Opcodes.IRETURN:
        case Opcodes.LRETURN:
        case Opcodes.FRETURN:
        case Opcodes.DRETURN:
        case Opcodes.ARETURN:
        case Opcodes.RETURN:
            return Collections.emptySet();

        default:
            break;
        }
        break;
    case VAR:
        if (opcode == Opcodes.RET) {
            List<JumpInstruction> callingInstructions = getJsrInstructions((VarInstruction) instruction);
            Instruction[] successors = new AbstractInstruction[callingInstructions.size()];
            int i = 0;
            for (JumpInstruction instr : callingInstructions)
                successors[i++] = instr.getNext();
            return Arrays.asList(successors);
        }
        break;
    case LABEL:
        if (instruction == instruction.getMethod().getAbnormalTerminationLabel())
            return Collections.emptySet();
        break;
    default:
        break;
    }
    assert nextInstruction != null;
    return Collections.singleton(nextInstruction);
}

From source file:de.unisb.cs.st.javaslicer.controlflowanalysis.ControlFlowGraph2.java

License:Open Source License

public Collection<Instruction> getSuccessors(Instruction instruction) {
    int opcode = instruction.getOpcode();
    // index??? getnextindex+1?
    Instruction nextInstruction = instruction.getNext();
    switch (instruction.getType()) {
    case JUMP://w w w  .j av  a2  s  .  c  o  m
        // GOTO and JSR are not conditional
        // ????
        if (opcode == Opcodes.GOTO || opcode == Opcodes.JSR) {
            List<AbstractInstruction> instrs = this.method.instructions;
            Iterator<AbstractInstruction> iter = instrs.iterator();
            Instruction temp = null;
            while (iter.hasNext()) {
                temp = iter.next();
                if (temp.getIndex() == ((JumpInstruction2) instruction).getTarget())
                    break;
            }
            return Collections.singleton(temp);
        }
        assert nextInstruction != null;
        // ?nextInstruction, ?label!
        List<AbstractInstruction> instrs = this.method.instructions;
        Iterator<AbstractInstruction> iter = instrs.iterator();
        Instruction temp = null;
        while (iter.hasNext()) {
            temp = iter.next();
            if (temp.getIndex() == ((JumpInstruction2) instruction).getTarget())
                break;
        }
        return Arrays.asList(temp, nextInstruction);
    // switch 
    case LOOKUPSWITCH: {
        LookupSwitchInstruction2 lsi = (LookupSwitchInstruction2) instruction;
        List<AbstractInstruction> instrs4 = this.method.instructions;
        List<AbstractInstruction> instrs5 = this.method.instructions;
        Iterator<AbstractInstruction> iter4 = instrs4.iterator();
        Instruction temp2 = null;
        Instruction[] successors = new AbstractInstruction[lsi.getHandlers().size() + 1];
        // find the default
        while (iter4.hasNext()) {
            temp2 = iter4.next();
            if (temp2.getIndex() == lsi.getDefaultHandler()) {
                successors[0] = temp2;
                break;
            }
        }
        // find the handlers
        int index = 0;
        for (Integer lm : lsi.getHandlers().values()) {
            Iterator<AbstractInstruction> iter5 = instrs5.iterator();
            while (iter5.hasNext()) {
                temp2 = iter5.next();
                if (temp2.getIndex() == lm) {
                    successors[index + 1] = temp2;
                    index++;
                    break;
                }
            }
        }
        return Arrays.asList(successors);
    }
    // switch ?
    case TABLESWITCH: {
        TableSwitchInstruction2 tsi = (TableSwitchInstruction2) instruction;
        List<AbstractInstruction> instrs2 = this.method.instructions;
        List<AbstractInstruction> instrs3 = this.method.instructions;
        Iterator<AbstractInstruction> iter2 = instrs2.iterator();
        //Iterator<AbstractInstruction> iter3=instrs3.iterator();
        Instruction temp2 = null;
        Instruction[] successors = new AbstractInstruction[tsi.getHandlers().length + 1];
        // get the default target
        while (iter2.hasNext()) {
            temp2 = iter2.next();
            if (tsi.getDefaultHandler() == temp2.getIndex()) {
                successors[0] = temp2;
                break;
            }
        }
        // get the target from min to max! 
        for (int i = 0; i < tsi.getHandlers().length; i++) {
            Iterator<AbstractInstruction> iter3 = instrs3.iterator();
            while (iter3.hasNext()) {
                temp2 = iter3.next();
                if (temp2.getIndex() == (tsi.getHandlers()[i])) {
                    successors[i + 1] = temp2;
                    break;
                }
            }
        }
        return Arrays.asList(successors);
        /*
         TableSwitchInstruction tsi = (TableSwitchInstruction) instruction;
         Instruction[] successors = new AbstractInstruction[tsi.getHandlers().length+1];
         successors[0] = tsi.getDefaultHandler();
         System.arraycopy(tsi.getHandlers(), 0, successors, 1, tsi.getHandlers().length);
         return Arrays.asList(successors);*/
    }
    // ???return??nextInstruction!
    case SIMPLE:
        switch (opcode) {
        case Opcodes.IRETURN:
        case Opcodes.LRETURN:
        case Opcodes.FRETURN:
        case Opcodes.DRETURN:
        case Opcodes.ARETURN:
        case Opcodes.RETURN:
            return Collections.emptySet();

        default:
            break;
        }
        break;
    // ??ret 
    case VAR:
        if (opcode == Opcodes.RET) {
            List<JumpInstruction2> callingInstructions = getJsrInstructions((VarInstruction) instruction);
            Instruction[] successors = new AbstractInstruction[callingInstructions.size()];
            int i = 0;
            for (JumpInstruction2 instr : callingInstructions)
                successors[i++] = instr.getNext();
            return Arrays.asList(successors);
        }
        break;
    // label abnormalTermination?nextInstruction!
    case LABEL:
        if (instruction == instruction.getMethod().getAbnormalTerminationLabel())
            return Collections.emptySet();
        break;
    default:
        break;
    }
    // ?index+1??
    assert nextInstruction != null;
    return Collections.singleton(nextInstruction);
}

From source file:de.unisb.cs.st.javaslicer.traceResult.BackwardTraceIterator.java

License:Open Source License

private InstanceType getNextInstruction(final int nextIndex) throws TracerException {
    int index = nextIndex;
    while (true) {
        if (WRITE_ITERATION_DEBUG_FILE) {
            this.debugFileWriter.println(index);
        }//from w  ww .ja va 2  s  .c o m
        final Instruction backwardInstruction = this.threadTraceResult.findInstruction(index);
        if (backwardInstruction == null) {
            assert index == -1;
            return null;
        }
        assert backwardInstruction.getIndex() == index;
        int tmpStackDepth = this.stackDepth;
        int opcode;
        if (backwardInstruction == backwardInstruction.getMethod().getMethodEntryLabel()) {
            --this.stackDepth;
            assert this.stackDepth >= 0 : "enter method occured more often than leave method";
        } else if (backwardInstruction == backwardInstruction.getMethod().getAbnormalTerminationLabel()
                || ((opcode = backwardInstruction.getOpcode()) >= Opcodes.IRETURN
                        && opcode <= Opcodes.RETURN)) {
            // info: the return statements opcodes lie between 172 (IRETURN) and 177 (RETURN)
            this.stackDepth = ++tmpStackDepth;
        }
        final InstanceType instance = backwardInstruction.getNextInstance(this, tmpStackDepth,
                this.instancesCount, this.instanceFactory);
        assert instance != null;

        ++this.instancesCount;
        if (this.filter != null && this.filter.filterInstance(instance)) {
            ++this.filteredInstancesCount;
        } else {
            return instance;
        }
        index = backwardInstruction.getBackwardInstructionIndex(this);
    }
}

From source file:de.zib.sfs.instrument.AbstractSfsAdapter.java

License:BSD License

protected void wrapMethod(int access, String name, Type returnType, Type[] argumentTypes, String signature,
        String[] exceptions, String callbackName, Type additionalCallbackArgumentType,
        ResultPasser resultPasser) {/*from   w w w.  ja  v  a 2  s  . co m*/
    argumentTypes = argumentTypes == null ? new Type[] {} : argumentTypes;
    String methodDescriptor = Type.getMethodDescriptor(returnType, argumentTypes);

    // <access> <returnType> <name>(<argumentTypes> arguments) throws
    // <exceptions> {
    MethodVisitor mv = this.cv.visitMethod(access, name, methodDescriptor, signature, exceptions);
    mv.visitCode();

    // if (isInstrumentationActive()) {
    isInstrumentationActive(mv);
    Label instrumentationActiveLabel = new Label();
    mv.visitJumpInsn(Opcodes.IFEQ, instrumentationActiveLabel);

    // return? methodPrefix<name>(arguments);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    int argumentIndex = 1;
    for (Type argument : argumentTypes) {
        mv.visitVarInsn(argument.getOpcode(Opcodes.ILOAD), argumentIndex);
        argumentIndex += argument.getSize();
    }
    mv.visitMethodInsn((access & Opcodes.ACC_STATIC) == 0 ? Opcodes.INVOKESPECIAL : Opcodes.INVOKESTATIC,
            this.instrumentedTypeInternalName, this.methodPrefix + name, methodDescriptor, false);
    if (!Type.VOID_TYPE.equals(returnType)) {
        mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
    } else {
        mv.visitInsn(Opcodes.RETURN);
    }

    // }
    mv.visitLabel(instrumentationActiveLabel);

    // setInstrumentationActive(true);
    setInstrumentationActive(mv, true);

    // long startTime = System.nanoTime();
    int startTimeIndex = 1;
    for (Type argument : argumentTypes) {
        startTimeIndex += argument.getSize();
    }
    storeTime(mv, startTimeIndex);

    // <returnType> result =? methodPrefix<name>(arguments);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    argumentIndex = 1;
    for (Type argument : argumentTypes) {
        mv.visitVarInsn(argument.getOpcode(Opcodes.ILOAD), argumentIndex);
        argumentIndex += argument.getSize();
    }
    mv.visitMethodInsn((access & Opcodes.ACC_STATIC) == 0 ? Opcodes.INVOKESPECIAL : Opcodes.INVOKESTATIC,
            this.instrumentedTypeInternalName, this.methodPrefix + name, methodDescriptor, false);
    int endTimeIndex = startTimeIndex + 2;
    if (!Type.VOID_TYPE.equals(returnType)) {
        mv.visitVarInsn(returnType.getOpcode(Opcodes.ISTORE), startTimeIndex + 2);
        endTimeIndex += returnType.getSize();
    }

    // long endTime = System.nanoTime();
    storeTime(mv, endTimeIndex);

    // callback.<callbackMethod>(startTime, endTime, result?);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, this.instrumentedTypeInternalName, "callback",
            this.callbackTypeDescriptor);
    mv.visitVarInsn(Opcodes.LLOAD, startTimeIndex);
    mv.visitVarInsn(Opcodes.LLOAD, endTimeIndex);

    // -1 indicates no result should be passed
    int resultIndex = resultPasser.getResultIndex();
    if (resultIndex != -1) {
        // result of the actual operation requested
        if (resultIndex == 0) {
            mv.visitVarInsn(returnType.getOpcode(Opcodes.ILOAD), startTimeIndex + 2);
            resultPasser.passResult(mv);
        } else {
            // some parameter requested
            mv.visitVarInsn(argumentTypes[resultIndex - 1].getOpcode(Opcodes.ILOAD), resultIndex);
            resultPasser.passResult(mv);
        }
    }

    Type[] callbackArgumentTypes;
    if (additionalCallbackArgumentType == null) {
        callbackArgumentTypes = new Type[] { Type.LONG_TYPE, Type.LONG_TYPE };
    } else {
        callbackArgumentTypes = new Type[] { Type.LONG_TYPE, Type.LONG_TYPE, additionalCallbackArgumentType };
    }
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, this.callbackTypeInternalName, callbackName,
            Type.getMethodDescriptor(Type.VOID_TYPE, callbackArgumentTypes), false);

    // setInstrumentationActive(false);
    setInstrumentationActive(mv, false);

    // return result;?
    // }
    if (!Type.VOID_TYPE.equals(returnType)) {
        mv.visitVarInsn(returnType.getOpcode(Opcodes.ILOAD), startTimeIndex + 2);
        mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
    } else {
        mv.visitInsn(Opcodes.RETURN);
    }
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}