Example usage for org.objectweb.asm MethodVisitor visitMaxs

List of usage examples for org.objectweb.asm MethodVisitor visitMaxs

Introduction

In this page you can find the example usage for org.objectweb.asm MethodVisitor visitMaxs.

Prototype

public void visitMaxs(final int maxStack, final int maxLocals) 

Source Link

Document

Visits the maximum stack size and the maximum number of local variables of the method.

Usage

From source file:de.javanarior.vo.generator.ByteCodeGenerator.java

License:Apache License

/**
 * Generate a implementation of a value object.
 *
 * @param valueType//from  w  w w . j a  v a  2s.  co m
 *            - value object type
 * @param technicalType
 *            - to which the value object is mapped
 * @param wrapperClass
 *            - abstract wrapper class, correspond to the technical type
 * @return class name and byte code in a container
 */
/* CHECKSTYLE:OFF */
public static ByteCodeContainer generate(Class<?> valueType, Class<? extends Comparable<?>> technicalType,
        @SuppressWarnings("rawtypes") Class<? extends AbstractValue> wrapperClass) {
    /* CHECKSTYLE:ON */

    if (!isInterface(valueType)) {
        throw new IllegalArgumentException("Could not generate implementation for class " + valueType.getName()
                + ". Please provide interface");
    }

    ClassWriter classWriter = new ClassWriter(0);
    MethodVisitor methodVisitor;

    classWriter.visit(Opcodes.V1_7, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, implementationClassName(valueType),
            "L" + parentClassName(wrapperClass) + "<" + addTypeDiscriptor(valueType) + ">;"
                    + addTypeDiscriptor(valueType),
            parentClassName(wrapperClass), implementedInterfaces(valueType));

    methodVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC, CONSTRUCTOR, methodDescriptor(technicalType),
            null, null);
    methodVisitor.visitCode();
    Label label0 = new Label();
    methodVisitor.visitLabel(label0);
    /* CHECKSTYLE:OFF */
    methodVisitor.visitLineNumber(8, label0);
    /* CHECKSTYLE:ON */
    methodVisitor.visitVarInsn(Opcodes.ALOAD, 0);
    methodVisitor.visitVarInsn(getILOADOpCode(technicalType), 1);
    methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, parentClassName(wrapperClass), CONSTRUCTOR,
            methodDescriptor(technicalType), false);
    Label label1 = new Label();
    methodVisitor.visitLabel(label1);
    /* CHECKSTYLE:OFF */
    methodVisitor.visitLineNumber(9, label1);
    /* CHECKSTYLE:ON */
    methodVisitor.visitInsn(Opcodes.RETURN);
    Label label2 = new Label();
    methodVisitor.visitLabel(label2);
    methodVisitor.visitLocalVariable("this", addTypeSignature(implementationClassName(valueType)), null, label0,
            label2, 0);
    methodVisitor.visitLocalVariable("value", getType(technicalType), null, label0, label2, 1);
    int stackSize = getStackSize(Type.getDescriptor(technicalType));
    methodVisitor.visitMaxs(stackSize, stackSize);
    methodVisitor.visitEnd();
    classWriter.visitEnd();

    return new ByteCodeContainer(binaryClassName(valueType), classWriter.toByteArray());
}

From source file:de.kandid.model.Emitter.java

License:Apache License

/**
 * Assembles a class that implements the given interface by generating the byte code.
 * @param interfaze the interface to implement
 * @return the class/*  w w  w.  j  ava2 s  .  c o  m*/
 */
private static Class<? extends Emitter<?>> makeClass(Class<?> interfaze) {
    String nameClass = _nameEmitter + '$' + interfaze.getName().replace('.', '$');
    String nameInterface = Type.getInternalName(interfaze);
    // ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
    ClassWriter cw = new ClassWriter(0);
    cw.visit(V1_4, ACC_PUBLIC + ACC_SUPER, nameClass, null, _nameEmitter, new String[] { name(interfaze) });

    // Generate default construcotor
    MethodVisitor cv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    cv.visitVarInsn(ALOAD, 0);
    cv.visitMethodInsn(INVOKESPECIAL, _nameEmitter, "<init>", "()V");
    cv.visitInsn(RETURN);
    cv.visitMaxs(1, 1);

    // Generate methods
    Method[] methods = interfaze.getMethods();
    for (int i = 0; i < methods.length; ++i) {
        final Method m = methods[i];
        if (m.getReturnType() != void.class)
            throw new IllegalArgumentException("Method " + m.toGenericString() + " must not return a value");
        final String descMethod = Type.getMethodDescriptor(m);
        final MethodVisitor mw = cw.visitMethod(ACC_PUBLIC + ACC_SYNCHRONIZED, m.getName(), descMethod, null,
                null);
        final Type[] argTypes = Type.getArgumentTypes(m);

        // for (int i = 0; i < _end; i += 2)
        //    ((Listener) _listeners[i]).send(...);

        int localStart = 1; // give one for "this"
        for (Type at : argTypes)
            localStart += at.getSize();
        Label entry = new Label();
        Label exit = new Label();
        mw.visitLabel(entry);

        // _isFiring = true;
        mw.visitVarInsn(ALOAD, 0);
        mw.visitInsn(Opcodes.ICONST_1);
        mw.visitFieldInsn(Opcodes.PUTFIELD, nameClass, "_isFiring", Type.BOOLEAN_TYPE.getDescriptor());

        // setup local variables: i, _listeners, _end
        mw.visitLocalVariable("i", Type.INT_TYPE.getDescriptor(), null, entry, exit, localStart);
        mw.visitInsn(Opcodes.ICONST_0);
        mw.visitIntInsn(Opcodes.ISTORE, localStart);

        mw.visitLocalVariable("listeners", _descObjectArray, null, entry, exit, localStart + 1);
        mw.visitVarInsn(ALOAD, 0);
        mw.visitFieldInsn(GETFIELD, nameClass, "_listeners", _descObjectArray);
        mw.visitIntInsn(Opcodes.ASTORE, localStart + 1);

        mw.visitLocalVariable("end", Type.INT_TYPE.getDescriptor(), null, entry, exit, localStart + 2);
        mw.visitVarInsn(ALOAD, 0);
        mw.visitFieldInsn(GETFIELD, nameClass, "_end", Type.INT_TYPE.getDescriptor());
        mw.visitIntInsn(Opcodes.ISTORE, localStart + 2);

        final Label condition = new Label();
        mw.visitJumpInsn(GOTO, condition);

        final Label loop = new Label();
        mw.visitLabel(loop);

        //((Listener) _listeners[i]).doSomething()
        mw.visitIntInsn(Opcodes.ALOAD, localStart + 1);
        mw.visitIntInsn(Opcodes.ILOAD, localStart);
        mw.visitInsn(Opcodes.AALOAD);
        mw.visitTypeInsn(CHECKCAST, nameInterface);
        int offs = 1; // give one for "this"
        for (Type at : argTypes) {
            mw.visitVarInsn(at.getOpcode(ILOAD), offs);
            offs += at.getSize();
        }
        mw.visitMethodInsn(INVOKEINTERFACE, nameInterface, m.getName(), descMethod);

        // i += 2
        mw.visitIincInsn(localStart, 2);

        // if (i < end) goto loop
        mw.visitLabel(condition);
        mw.visitIntInsn(Opcodes.ILOAD, localStart);
        mw.visitIntInsn(Opcodes.ILOAD, localStart + 2);
        mw.visitJumpInsn(Opcodes.IF_ICMPLT, loop);

        // _isFiring = false;
        mw.visitVarInsn(ALOAD, 0);
        mw.visitInsn(Opcodes.ICONST_0);
        mw.visitFieldInsn(Opcodes.PUTFIELD, nameClass, "_isFiring", Type.BOOLEAN_TYPE.getDescriptor());

        mw.visitLabel(exit);
        mw.visitInsn(RETURN);
        mw.visitMaxs(localStart + 2, localStart + 3);
        mw.visitEnd();
    }
    cw.visitEnd();
    return _loader.loadClass(cw, nameClass.replace('/', '.'));
}

From source file:de.topicmapslab.aranuka.proxy.ProxyAdapter.java

License:Apache License

@Override
public void visitEnd() {
    MethodVisitor visitMethod = super.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
    visitMethod.visitCode();//from w w  w .j a  v  a  2 s. c o  m
    visitMethod.visitVarInsn(ALOAD, 0);
    visitMethod.visitMethodInsn(INVOKESPECIAL, oldName, "<init>", "()V");
    visitMethod.visitInsn(RETURN);
    visitMethod.visitMaxs(1, 1);
    visitMethod.visitEnd();

    super.visitField(ACC_PRIVATE, "methodInterceptor", "Lde/topicmapslab/aranuka/proxy/IMethodInterceptor;",
            null, null).visitEnd();

    visitMethod = super.visitMethod(ACC_PRIVATE, "setMethodInterceptor",
            "(Lde/topicmapslab/aranuka/proxy/IMethodInterceptor;)V", null, null);
    visitMethod.visitCode();
    visitMethod.visitVarInsn(ALOAD, 0);
    visitMethod.visitVarInsn(ALOAD, 1);
    visitMethod.visitFieldInsn(PUTFIELD, newName, "methodInterceptor",
            "Lde/topicmapslab/aranuka/proxy/IMethodInterceptor;");
    visitMethod.visitInsn(RETURN);
    visitMethod.visitMaxs(2, 2);
    visitMethod.visitEnd();

    super.visitEnd();
}

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) {/* w  w  w.  j av  a2s .c o 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();
}

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

License:BSD License

@Override
public void visitEnd() {
    // public void setInstrumentationActive(boolean instrumentationActive) {
    MethodVisitor setInstrumentationActiveMV = this.cv.visitMethod(Opcodes.ACC_PUBLIC,
            "setInstrumentationActive", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE), null,
            null);//  w  w w.  jav  a  2 s  .c  o m
    setInstrumentationActiveMV.visitCode();

    // this.instrumentationActive.setInstrumentationActive(instrumentationActive);
    setInstrumentationActiveMV.visitVarInsn(Opcodes.ALOAD, 0);
    setInstrumentationActiveMV.visitFieldInsn(Opcodes.GETFIELD, this.instrumentedTypeInternalName,
            "instrumentationActive", Type.getDescriptor(InstrumentationActive.class));
    setInstrumentationActiveMV.visitVarInsn(Opcodes.ILOAD, 1);
    setInstrumentationActiveMV.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
            Type.getInternalName(InstrumentationActive.class), "setInstrumentationActive",
            Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE), false);

    // }
    setInstrumentationActiveMV.visitInsn(Opcodes.RETURN);
    setInstrumentationActiveMV.visitMaxs(0, 0);
    setInstrumentationActiveMV.visitEnd();

    // public boolean isInstrumentationActive() {
    MethodVisitor isInstrumentationActiveMV = this.cv.visitMethod(Opcodes.ACC_PUBLIC, "isInstrumentationActive",
            Type.getMethodDescriptor(Type.BOOLEAN_TYPE), null, null);
    isInstrumentationActiveMV.visitCode();

    // return instrumentationActive.isInstrumentationActive();
    // }
    isInstrumentationActiveMV.visitVarInsn(Opcodes.ALOAD, 0);
    isInstrumentationActiveMV.visitFieldInsn(Opcodes.GETFIELD, this.instrumentedTypeInternalName,
            "instrumentationActive", Type.getDescriptor(InstrumentationActive.class));
    isInstrumentationActiveMV.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
            Type.getInternalName(InstrumentationActive.class), "isInstrumentationActive",
            Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false);
    isInstrumentationActiveMV.visitInsn(Opcodes.IRETURN);
    isInstrumentationActiveMV.visitMaxs(0, 0);
    isInstrumentationActiveMV.visitEnd();

    appendWrappedMethods(this.cv);

    this.cv.visitEnd();
}

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

License:BSD License

@Override
protected void appendWrappedMethods(ClassVisitor visitor) {
    // override from MappedByteBuffer so we can re-init the callback
    // properly// w w  w  .  j a  v a  2s  .co  m

    // public void setFileDescriptor(FileDescriptor fileDescriptor) {
    MethodVisitor settFileDescriptorMV = visitor.visitMethod(Opcodes.ACC_PUBLIC, "setFileDescriptor",
            Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(FileDescriptor.class)), null, null);
    settFileDescriptorMV.visitCode();

    // this.fileDescriptor = fileDescriptor;
    settFileDescriptorMV.visitVarInsn(Opcodes.ALOAD, 0);
    settFileDescriptorMV.visitVarInsn(Opcodes.ALOAD, 1);
    settFileDescriptorMV.visitFieldInsn(Opcodes.PUTFIELD, Type.getInternalName(MappedByteBuffer.class),
            "fileDescriptor", Type.getDescriptor(FileDescriptor.class));

    // callback.openCallback(this.fileDescriptor);
    settFileDescriptorMV.visitVarInsn(Opcodes.ALOAD, 0);
    settFileDescriptorMV.visitFieldInsn(Opcodes.GETFIELD, this.instrumentedTypeInternalName, "callback",
            this.callbackTypeDescriptor);
    settFileDescriptorMV.visitVarInsn(Opcodes.ALOAD, 0);
    settFileDescriptorMV.visitFieldInsn(Opcodes.GETFIELD, Type.getInternalName(MappedByteBuffer.class),
            "fileDescriptor", Type.getDescriptor(FileDescriptor.class));
    settFileDescriptorMV.visitMethodInsn(Opcodes.INVOKEVIRTUAL, this.callbackTypeInternalName, "openCallback",
            Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(FileDescriptor.class)), false);

    // }
    settFileDescriptorMV.visitInsn(Opcodes.RETURN);
    settFileDescriptorMV.visitMaxs(0, 0);
    settFileDescriptorMV.visitEnd();

    // also override from MappedByteBuffer

    // protected FileDescriptor getFileDescriptorImpl() {
    MethodVisitor getFileDescriptorImplMV = visitor.visitMethod(Opcodes.ACC_PROTECTED, "getFileDescriptorImpl",
            Type.getMethodDescriptor(Type.getType(FileDescriptor.class)), null, null);
    getFileDescriptorImplMV.visitCode();

    // return fileDescriptor;
    // }
    getFileDescriptorImplMV.visitVarInsn(Opcodes.ALOAD, 0);
    getFileDescriptorImplMV.visitFieldInsn(Opcodes.GETFIELD, Type.getInternalName(MappedByteBuffer.class),
            "fileDescriptor", Type.getDescriptor(FileDescriptor.class));
    getFileDescriptorImplMV.visitInsn(Opcodes.ARETURN);
    getFileDescriptorImplMV.visitMaxs(0, 0);
    getFileDescriptorImplMV.visitEnd();

    if (!skipReads()) {
        wrapMethod(Opcodes.ACC_PUBLIC, "get", Type.getType(ByteBuffer.class),
                new Type[] { Type.getType(byte[].class), Type.INT_TYPE, Type.INT_TYPE }, null, null,
                "getCallback", Type.INT_TYPE, new ParameterResultPasser(3));
    }

    if (!skipWrites()) {
        wrapMethod(Opcodes.ACC_PUBLIC, "put", Type.getType(ByteBuffer.class),
                new Type[] { Type.getType(byte[].class), Type.INT_TYPE, Type.INT_TYPE }, null, null,
                "putCallback", Type.INT_TYPE, new ParameterResultPasser(3));
    }

    if (!skipWrites()) {
        // public ByteBuffer put(ByteBuffer src) {
        MethodVisitor bulkPutMV = visitor.visitMethod(Opcodes.ACC_PUBLIC, "put",
                Type.getMethodDescriptor(Type.getType(ByteBuffer.class), Type.getType(ByteBuffer.class)), null,
                null);
        bulkPutMV.visitCode();

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

        // return nativeMethodPrefixput(src);
        bulkPutMV.visitVarInsn(Opcodes.ALOAD, 0);
        bulkPutMV.visitVarInsn(Opcodes.ALOAD, 1);
        bulkPutMV.visitMethodInsn(Opcodes.INVOKESPECIAL, this.instrumentedTypeInternalName,
                this.methodPrefix + "put",
                Type.getMethodDescriptor(Type.getType(ByteBuffer.class), Type.getType(ByteBuffer.class)),
                false);
        bulkPutMV.visitInsn(Opcodes.ARETURN);

        // }
        bulkPutMV.visitLabel(instrumentationActiveLabel);

        // setInstrumentationActive(fromFileChannel);
        bulkPutMV.visitVarInsn(Opcodes.ALOAD, 0);
        bulkPutMV.visitVarInsn(Opcodes.ALOAD, 0);
        bulkPutMV.visitFieldInsn(Opcodes.GETFIELD, this.instrumentedTypeInternalName, "fromFileChannel",
                Type.getDescriptor(Boolean.TYPE));
        bulkPutMV.visitMethodInsn(Opcodes.INVOKEVIRTUAL, this.instrumentedTypeInternalName,
                "setInstrumentationActive", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE), false);

        // boolean srcInstrumentationActive = false;
        bulkPutMV.visitInsn(Opcodes.ICONST_0);
        bulkPutMV.visitVarInsn(Opcodes.ISTORE, 2);

        // if (src instanceof MappedByteBuffer) {
        bulkPutMV.visitVarInsn(Opcodes.ALOAD, 1);
        bulkPutMV.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName(MappedByteBuffer.class));
        Label srcInstanceofMappedByteBufferLabel = new Label();
        bulkPutMV.visitJumpInsn(Opcodes.IFEQ, srcInstanceofMappedByteBufferLabel);

        // srcInstrumentationActive = src.isFromFileChannel();
        bulkPutMV.visitVarInsn(Opcodes.ALOAD, 1);
        bulkPutMV.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                "isFromFileChannel", Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false);
        bulkPutMV.visitVarInsn(Opcodes.ISTORE, 2);

        // src.setInstrumentationActive(true);
        bulkPutMV.visitVarInsn(Opcodes.ALOAD, 1);
        bulkPutMV.visitInsn(Opcodes.ICONST_1);
        bulkPutMV.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                "setInstrumentationActive", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE), false);

        // }
        bulkPutMV.visitLabel(srcInstanceofMappedByteBufferLabel);

        // int length = src.remaining();
        bulkPutMV.visitVarInsn(Opcodes.ALOAD, 1);
        bulkPutMV.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(Buffer.class), "remaining",
                Type.getMethodDescriptor(Type.INT_TYPE), false);
        bulkPutMV.visitVarInsn(Opcodes.ISTORE, 4);

        // long startTime = System.nanoTime();
        bulkPutMV.visitMethodInsn(Opcodes.INVOKESTATIC, this.systemInternalName, "nanoTime",
                this.nanoTimeDescriptor, false);
        bulkPutMV.visitVarInsn(Opcodes.LSTORE, 5);

        // ByteBuffer result = nativeMethodPrefixput(src);
        bulkPutMV.visitVarInsn(Opcodes.ALOAD, 0);
        bulkPutMV.visitVarInsn(Opcodes.ALOAD, 1);
        bulkPutMV.visitMethodInsn(Opcodes.INVOKESPECIAL, this.instrumentedTypeInternalName,
                this.methodPrefix + "put",
                Type.getMethodDescriptor(Type.getType(ByteBuffer.class), Type.getType(ByteBuffer.class)),
                false);
        bulkPutMV.visitVarInsn(Opcodes.ASTORE, 7);

        // long endTime = System.nanoTime();
        bulkPutMV.visitMethodInsn(Opcodes.INVOKESTATIC, this.systemInternalName, "nanoTime",
                this.nanoTimeDescriptor, false);
        bulkPutMV.visitVarInsn(Opcodes.LSTORE, 8);

        // if (isInstrumentationActive()) {
        isInstrumentationActive(bulkPutMV);
        Label instrumentationStillActiveLabel = new Label();
        bulkPutMV.visitJumpInsn(Opcodes.IFEQ, instrumentationStillActiveLabel);

        // callback.putCallback(startTime, endTime, length);
        bulkPutMV.visitVarInsn(Opcodes.ALOAD, 0);
        bulkPutMV.visitFieldInsn(Opcodes.GETFIELD, this.instrumentedTypeInternalName, "callback",
                this.callbackTypeDescriptor);
        bulkPutMV.visitVarInsn(Opcodes.LLOAD, 5);
        bulkPutMV.visitVarInsn(Opcodes.LLOAD, 8);
        bulkPutMV.visitVarInsn(Opcodes.ILOAD, 4);
        bulkPutMV.visitMethodInsn(Opcodes.INVOKEVIRTUAL, this.callbackTypeInternalName, "putCallback",
                Type.getMethodDescriptor(Type.VOID_TYPE, Type.LONG_TYPE, Type.LONG_TYPE, Type.INT_TYPE), false);

        // setInstrumentationActive(false);
        setInstrumentationActive(bulkPutMV, false);

        // }
        bulkPutMV.visitLabel(instrumentationStillActiveLabel);

        // if (srcInstrumentationActive) {
        bulkPutMV.visitVarInsn(Opcodes.ILOAD, 2);
        Label srcInstrumentationActiveLabel = new Label();
        bulkPutMV.visitJumpInsn(Opcodes.IFEQ, srcInstrumentationActiveLabel);

        // callback.onGetEnd(src.getFileDescriptor(), startTime, endTime,
        // length);
        bulkPutMV.visitVarInsn(Opcodes.ALOAD, 1);
        bulkPutMV.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                "getFileDescriptor", Type.getMethodDescriptor(Type.getType(FileDescriptor.class)), false);
        bulkPutMV.visitVarInsn(Opcodes.LLOAD, 5);
        bulkPutMV.visitVarInsn(Opcodes.LLOAD, 8);
        bulkPutMV.visitVarInsn(Opcodes.ILOAD, 4);
        bulkPutMV.visitMethodInsn(Opcodes.INVOKESTATIC, this.callbackTypeInternalName, "getCallback",
                Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(FileDescriptor.class), Type.LONG_TYPE,
                        Type.LONG_TYPE, Type.INT_TYPE),
                false);

        // src.setInstrumentationActive(false);
        bulkPutMV.visitVarInsn(Opcodes.ALOAD, 1);
        bulkPutMV.visitInsn(Opcodes.ICONST_0);
        bulkPutMV.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                "setInstrumentationActive", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE), false);

        // }
        bulkPutMV.visitLabel(srcInstrumentationActiveLabel);

        // return result;
        // }
        bulkPutMV.visitVarInsn(Opcodes.ALOAD, 7);
        bulkPutMV.visitInsn(Opcodes.ARETURN);
        bulkPutMV.visitMaxs(0, 0);
        bulkPutMV.visitEnd();
    }

    ResultPasser resultDiscarder = new DiscardResultPasser();

    // regular gets and puts
    for (Map.Entry<String, Type> type : TYPES.entrySet()) {
        if (!skipReads()) {
            // public TYPE getTYPE() { ... }
            wrapMethod(Opcodes.ACC_PUBLIC, "get" + type.getKey(), type.getValue(), null, null, null,
                    "get" + type.getKey() + "Callback", null, resultDiscarder);

            // public TYPE getTYPE(int index) { ... }
            wrapMethod(Opcodes.ACC_PUBLIC, "get" + type.getKey(), type.getValue(), new Type[] { Type.INT_TYPE },
                    null, null, "get" + type.getKey() + "Callback", null, resultDiscarder);
        }

        if (!skipWrites()) {
            // public ByteBuffer putTYPE(TYPE value) { ... }
            wrapMethod(Opcodes.ACC_PUBLIC, "put" + type.getKey(), Type.getType(ByteBuffer.class),
                    new Type[] { type.getValue() }, null, null, "put" + type.getKey() + "Callback", null,
                    resultDiscarder);

            // public ByteBuffer putTYPE(int index, TYPE value) { ... }
            wrapMethod(Opcodes.ACC_PUBLIC, "put" + type.getKey(), Type.getType(ByteBuffer.class),
                    new Type[] { Type.INT_TYPE, type.getValue() }, null, null,
                    "put" + type.getKey() + "Callback", null, resultDiscarder);
        }
    }

    visitor.visitEnd();
}

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

License:BSD License

@Override
protected void wrapMethod(int access, String name, Type returnType, Type[] argumentTypes, String signature,
        String[] exceptions, String callbackName, Type additionalCallbackArgumentType,
        ResultPasser resultPasser) {/*from www.  j  av a  2 s  .  c  o  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() || !fromFileChannel) {
    isInstrumentationActive(mv);
    Label instrumentationActiveLabel = new Label();
    mv.visitJumpInsn(Opcodes.IFNE, instrumentationActiveLabel);

    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, this.instrumentedTypeInternalName, "fromFileChannel",
            Type.getDescriptor(Boolean.TYPE));
    Label fromFileChannelLabel = new Label();
    mv.visitJumpInsn(Opcodes.IFNE, fromFileChannelLabel);

    mv.visitLabel(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(Opcodes.INVOKESPECIAL, 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(fromFileChannelLabel);

    // 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(Opcodes.INVOKESPECIAL, 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();
}

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

License:BSD License

@Override
protected void appendWrappedMethods(ClassVisitor visitor) {
    // public FileDescriptor getFileDescriptor() {
    MethodVisitor getFileDescriptorMV = visitor.visitMethod(Opcodes.ACC_PUBLIC, "getFileDescriptor",
            Type.getMethodDescriptor(Type.getType(FileDescriptor.class)), null, null);
    getFileDescriptorMV.visitCode();/* w w  w  .  ja v a2s  . c  o  m*/

    // return fileDescriptor;
    // }
    getFileDescriptorMV.visitVarInsn(Opcodes.ALOAD, 0);
    getFileDescriptorMV.visitFieldInsn(Opcodes.GETFIELD, Type.getInternalName(FileChannelImpl.class), "fd",
            Type.getDescriptor(FileDescriptor.class));
    getFileDescriptorMV.visitInsn(Opcodes.ARETURN);
    getFileDescriptorMV.visitMaxs(0, 0);
    getFileDescriptorMV.visitEnd();

    if (!skipReads()) {
        wrapFileChannelImplMethod(Opcodes.ACC_PUBLIC, "read", Type.INT_TYPE,
                new Type[] { Type.getType(ByteBuffer.class) }, null,
                new String[] { Type.getInternalName(IOException.class) }, "readCallback", "writeCallback",
                Type.INT_TYPE, 0, false);

        wrapFileChannelImplMethod(Opcodes.ACC_PUBLIC, "read", Type.INT_TYPE,
                new Type[] { Type.getType(ByteBuffer.class), Type.LONG_TYPE }, null,
                new String[] { Type.getInternalName(IOException.class) }, "readCallback", "writeCallback",
                Type.INT_TYPE, 0, false);

        wrapFileChannelImplMethod(Opcodes.ACC_PUBLIC, "read", Type.LONG_TYPE,
                new Type[] { Type.getType(ByteBuffer[].class), Type.INT_TYPE, Type.INT_TYPE }, null,
                new String[] { Type.getInternalName(IOException.class) }, "readCallback", "writeCallback",
                Type.LONG_TYPE, 0, false);

        // transferTo is basically a read

        wrapFileChannelImplMethod(Opcodes.ACC_PUBLIC, "transferTo", Type.LONG_TYPE,
                new Type[] { Type.LONG_TYPE, Type.LONG_TYPE, Type.getType(WritableByteChannel.class) }, null,
                new String[] { Type.getInternalName(IOException.class) }, "readCallback", "writeCallback",
                Type.LONG_TYPE, 2, true);
    }

    // repeat for write methods

    if (!skipWrites()) {
        wrapFileChannelImplMethod(Opcodes.ACC_PUBLIC, "write", Type.INT_TYPE,
                new Type[] { Type.getType(ByteBuffer.class) }, null,
                new String[] { Type.getInternalName(IOException.class) }, "writeCallback", "readCallback",
                Type.INT_TYPE, 0, false);

        wrapFileChannelImplMethod(Opcodes.ACC_PUBLIC, "write", Type.INT_TYPE,
                new Type[] { Type.getType(ByteBuffer.class), Type.LONG_TYPE }, null,
                new String[] { Type.getInternalName(IOException.class) }, "writeCallback", "readCallback",
                Type.INT_TYPE, 0, false);

        wrapFileChannelImplMethod(Opcodes.ACC_PUBLIC, "write", Type.LONG_TYPE,
                new Type[] { Type.getType(ByteBuffer[].class), Type.INT_TYPE, Type.INT_TYPE }, null,
                new String[] { Type.getInternalName(IOException.class) }, "writeCallback", "readCallback",
                Type.LONG_TYPE, 0, false);

        // transferFrom is basically a write

        wrapFileChannelImplMethod(Opcodes.ACC_PUBLIC, "transferFrom", Type.LONG_TYPE,
                new Type[] { Type.getType(ReadableByteChannel.class), Type.LONG_TYPE, Type.LONG_TYPE }, null,
                new String[] { Type.getInternalName(IOException.class) }, "writeCallback", "readCallback",
                Type.LONG_TYPE, 0, true);
    }

    String mapMethodDescriptor = Type.getMethodDescriptor(Type.getType(MappedByteBuffer.class),
            Type.getType(MapMode.class), Type.LONG_TYPE, Type.LONG_TYPE);

    // public MappedByteBuffer map(MapMode mode, long position, long size)
    // throws IOException {
    MethodVisitor mapMV = visitor.visitMethod(Opcodes.ACC_PUBLIC, "map", mapMethodDescriptor, null,
            new String[] { Type.getInternalName(IOException.class) });
    mapMV.visitCode();

    // MappedByteBuffer mbb = nativeMethodPrefixmap(mode, position, size);
    mapMV.visitVarInsn(Opcodes.ALOAD, 0);
    mapMV.visitVarInsn(Opcodes.ALOAD, 1);
    mapMV.visitVarInsn(Opcodes.LLOAD, 2);
    mapMV.visitVarInsn(Opcodes.LLOAD, 4);
    mapMV.visitMethodInsn(Opcodes.INVOKESPECIAL, this.instrumentedTypeInternalName, this.methodPrefix + "map",
            mapMethodDescriptor, false);
    mapMV.visitVarInsn(Opcodes.ASTORE, 6);

    // mbb.setFromFileChannel(true);
    mapMV.visitVarInsn(Opcodes.ALOAD, 6);
    mapMV.visitInsn(Opcodes.ICONST_1);
    mapMV.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
            "setFromFileChannel", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE), false);

    // mbb.setFileDescriptor(fd);
    mapMV.visitVarInsn(Opcodes.ALOAD, 6);
    mapMV.visitVarInsn(Opcodes.ALOAD, 0);
    mapMV.visitFieldInsn(Opcodes.GETFIELD, this.instrumentedTypeInternalName, "fd",
            Type.getDescriptor(FileDescriptor.class));
    mapMV.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
            "setFileDescriptor", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(FileDescriptor.class)),
            false);

    // if we don't want to trace mmap calls, then map needs to reset the
    // instrumentationActive flag
    if (!this.traceMmap) {
        // setInstrumentationActive(false);
        setInstrumentationActive(mapMV, false);
    }

    // return mbb;
    // }
    mapMV.visitVarInsn(Opcodes.ALOAD, 6);
    mapMV.visitInsn(Opcodes.ARETURN);
    mapMV.visitMaxs(0, 0);
    mapMV.visitEnd();
}

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

License:BSD License

protected void wrapFileChannelImplMethod(int access, String name, Type returnType, Type[] argumentTypes,
        String signature, String[] exceptions, String callbackName, String oppositeCallbackName,
        Type additionalCallbackArgumentType, int bufferArgumentTypeIndex, boolean isTransferMethod) {
    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();//from   w  w  w . j  a  v a 2  s.c o  m

    // 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(Opcodes.INVOKESPECIAL, this.instrumentedTypeInternalName, this.methodPrefix + name,
            methodDescriptor, false);
    mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN));

    // }
    mv.visitLabel(instrumentationActiveLabel);

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

    // we need to set the instrumentation flag for the source/destination
    // buffer(s) as well

    // boolean bufferInstrumentationActive = false;
    int bufferInstrumentationActiveIndex = 1;
    for (Type argument : argumentTypes) {
        bufferInstrumentationActiveIndex += argument.getSize();
    }
    mv.visitInsn(Opcodes.ICONST_0);
    mv.visitVarInsn(Opcodes.ISTORE, bufferInstrumentationActiveIndex);

    // obtain actual index of the buffer(s) in the argument list
    int bufferArgumentIndex = 1;
    for (int i = 0; i < bufferArgumentTypeIndex; ++i) {
        bufferArgumentIndex += argumentTypes[i].getSize();
    }

    if (argumentTypes[bufferArgumentTypeIndex].getSort() == Type.ARRAY) {
        // If the first buffer in the array is a MappedByteBuffer, assume
        // they all are. If not, this will crash the users' program.

        // if (<buffers>[0] instanceof MappedByteBuffer) {
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitInsn(Opcodes.AALOAD);
        mv.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName(MappedByteBuffer.class));
        Label bufferInstanceofMappedByteBufferLabel = new Label();
        mv.visitJumpInsn(Opcodes.IFEQ, bufferInstanceofMappedByteBufferLabel);

        // only trace mmapped file channels if desired
        if (this.traceMmap) {
            // if (<buffers>[0].isFromFileChannel()) {
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitInsn(Opcodes.ICONST_0);
            mv.visitInsn(Opcodes.AALOAD);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                    "isFromFileChannel", Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false);
            Label fromFileChannelLabel = new Label();
            mv.visitJumpInsn(Opcodes.IFEQ, fromFileChannelLabel);

            int iIndex = bufferInstrumentationActiveIndex + 1;

            // for (int i = 0; i < <buffers>.length; ++i) {
            // <buffers>[i].setInstrumentationActive(true);
            // }
            mv.visitInsn(Opcodes.ICONST_0);
            mv.visitVarInsn(Opcodes.ISTORE, iIndex);
            Label loopConditionLabel = new Label();
            mv.visitJumpInsn(Opcodes.GOTO, loopConditionLabel);
            Label loopStartLabel = new Label();
            mv.visitLabel(loopStartLabel);
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitVarInsn(Opcodes.ILOAD, iIndex);
            mv.visitInsn(Opcodes.AALOAD);
            mv.visitInsn(Opcodes.ICONST_1);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                    "setInstrumentationActive", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE),
                    false);
            mv.visitIincInsn(iIndex, 1);
            mv.visitLabel(loopConditionLabel);
            mv.visitVarInsn(Opcodes.ILOAD, iIndex);
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitInsn(Opcodes.ARRAYLENGTH);
            mv.visitJumpInsn(Opcodes.IF_ICMPLT, loopStartLabel);

            // bufferInstrumentationActive = true;
            mv.visitInsn(Opcodes.ICONST_1);
            mv.visitVarInsn(Opcodes.ISTORE, bufferInstrumentationActiveIndex);

            // }
            mv.visitLabel(fromFileChannelLabel);
        }

        // }
        mv.visitLabel(bufferInstanceofMappedByteBufferLabel);
    } else {
        // We need to handle the transferFrom/transferTo methods a little
        // differently. Their "buffers" only need to be FileChannelImpls,
        // the rest remains the same.

        // if (buffer instanceof MappedByteBuffer) {
        // if (buffer instanceof FileChannelImpl) {
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        if (!isTransferMethod) {
            mv.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName(MappedByteBuffer.class));
        } else {
            mv.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName(FileChannelImpl.class));
        }
        Label bufferInstanceofMappedByteBufferLabel = new Label();
        mv.visitJumpInsn(Opcodes.IFEQ, bufferInstanceofMappedByteBufferLabel);

        // additional check required if the buffer is a MappedByteBuffer,
        // and we want to trace those
        Label fromFileChannelLabel = new Label();
        if (!isTransferMethod && this.traceMmap) {
            // if (buffer.isFromFileChannel()) {
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                    "isFromFileChannel", Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false);
            mv.visitJumpInsn(Opcodes.IFEQ, fromFileChannelLabel);
        }

        // either we're dealing with a FileChannelImpl (in a
        // transferTo/transferFrom method), or this is a regular read or
        // write and we want to count in mmapped buffers
        if (isTransferMethod || this.traceMmap) {
            // buffer.setInstrumentationActive(true);
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitInsn(Opcodes.ICONST_1);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                    !isTransferMethod ? Type.getInternalName(MappedByteBuffer.class)
                            : Type.getInternalName(FileChannelImpl.class),
                    "setInstrumentationActive", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE),
                    false);

            // bufferInstrumentationActive = true;
            mv.visitInsn(Opcodes.ICONST_1);
            mv.visitVarInsn(Opcodes.ISTORE, bufferInstrumentationActiveIndex);
        }

        if (!isTransferMethod && this.traceMmap) {
            // }
            mv.visitLabel(fromFileChannelLabel);
        }

        // }
        mv.visitLabel(bufferInstanceofMappedByteBufferLabel);
    }

    // long startTime = System.nanoTime();
    int startTimeIndex = bufferInstrumentationActiveIndex + 1;
    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(Opcodes.INVOKESPECIAL, this.instrumentedTypeInternalName, this.methodPrefix + name,
            methodDescriptor, false);
    int resultIndex = startTimeIndex + 2;
    mv.visitVarInsn(returnType.getOpcode(Opcodes.ISTORE), resultIndex);
    int endTimeIndex = resultIndex + returnType.getSize();

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

    // if map(...) was involved in this, then it may have reset the
    // instrumentationActive flag if we don't trace mmap calls, so we need
    // to check again whether instrumentation is still active, and only
    // report the data then

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

    // callback.<callbackName>(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);
    mv.visitVarInsn(returnType.getOpcode(Opcodes.ILOAD), resultIndex);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, this.callbackTypeInternalName, callbackName,
            Type.getMethodDescriptor(Type.VOID_TYPE, Type.LONG_TYPE, Type.LONG_TYPE,
                    additionalCallbackArgumentType),
            false);

    // }
    mv.visitLabel(instrumentationStillActiveLabel);

    // same for the buffer

    if (argumentTypes[bufferArgumentTypeIndex].getSort() != Type.ARRAY) {
        // if (buffer instanceof MappedByteBuffer) {
        // if (buffer instanceof FileChannelImpl) {
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        if (!isTransferMethod) {
            mv.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName(MappedByteBuffer.class));
        } else {
            mv.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName(FileChannelImpl.class));
        }
        Label bufferInstanceofMappedByteBufferLabel = new Label();
        mv.visitJumpInsn(Opcodes.IFEQ, bufferInstanceofMappedByteBufferLabel);

        // additional check required if the buffer is a MappedByteBuffer,
        // and we want to trace those
        Label fromFileChannelLabel = new Label();
        if (!isTransferMethod && this.traceMmap) {
            // if (buffer.isFromFileChannel()) {
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                    "isFromFileChannel", Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false);
            mv.visitJumpInsn(Opcodes.IFEQ, fromFileChannelLabel);
        }

        // either we're dealing with a FileChannelImpl (in a
        // transferTo/transferFrom method), which might have flipped its
        // instrumentationActive flag because mmap was used, or this is a
        // regular read or write and we want to count in mmapped buffers
        if (isTransferMethod || this.traceMmap) {
            // if traceMmap is true, then we could actually just set
            // bufferInstrumentationActive to true

            // bufferInstrumentationActive =
            // buffer.isInstrumentationActive();
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                    !isTransferMethod ? Type.getInternalName(MappedByteBuffer.class)
                            : Type.getInternalName(FileChannelImpl.class),
                    "isInstrumentationActive", Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false);
            mv.visitVarInsn(Opcodes.ISTORE, bufferInstrumentationActiveIndex);
        }

        if (!isTransferMethod && this.traceMmap) {
            // }
            mv.visitLabel(fromFileChannelLabel);
        }

        // }
        mv.visitLabel(bufferInstanceofMappedByteBufferLabel);
    }

    // if (bufferInstrumentationActive) {
    mv.visitVarInsn(Opcodes.ILOAD, bufferInstrumentationActiveIndex);
    Label bufferInstrumentationActiveLabel = new Label();
    mv.visitJumpInsn(Opcodes.IFEQ, bufferInstrumentationActiveLabel);

    // callback.<oppositeCallbackName>(buffer.getFileDescriptor(),
    // startTime, endTime, result);
    if (!isTransferMethod) {
        if (argumentTypes[bufferArgumentTypeIndex].getSort() == Type.ARRAY) {
            // TODO this calls the opposite callback only on the first
            // element in the buffer array, but there is not really a way to
            // tell which buffer has received how many bytes, and thus which
            // file
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitInsn(Opcodes.ICONST_0);
            mv.visitInsn(Opcodes.AALOAD);
        } else {
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        }
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                "getFileDescriptor", Type.getMethodDescriptor(Type.getType(FileDescriptor.class)), false);
    } else {
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(FileChannelImpl.class),
                "getFileDescriptor", Type.getMethodDescriptor(Type.getType(FileDescriptor.class)), false);
    }
    mv.visitVarInsn(Opcodes.LLOAD, startTimeIndex);
    mv.visitVarInsn(Opcodes.LLOAD, endTimeIndex);
    mv.visitVarInsn(returnType.getOpcode(Opcodes.ILOAD), resultIndex);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, this.callbackTypeInternalName, oppositeCallbackName,
            Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(FileDescriptor.class), Type.LONG_TYPE,
                    Type.LONG_TYPE, additionalCallbackArgumentType),
            false);

    // revert the active instrumentation flag for the buffer
    if (argumentTypes[bufferArgumentTypeIndex].getSort() == Type.ARRAY) {
        int iIndex = bufferInstrumentationActiveIndex + 1;

        // for (int i = 0; i < <buffers>.length; ++i) {
        // <buffers>[i].setInstrumentationActive(false);
        // }
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitVarInsn(Opcodes.ISTORE, iIndex);
        Label loopConditionLabel = new Label();
        mv.visitJumpInsn(Opcodes.GOTO, loopConditionLabel);
        Label loopStartLabel = new Label();
        mv.visitLabel(loopStartLabel);
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        mv.visitVarInsn(Opcodes.ILOAD, iIndex);
        mv.visitInsn(Opcodes.AALOAD);
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                "setInstrumentationActive", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE), false);
        mv.visitIincInsn(iIndex, 1);
        mv.visitLabel(loopConditionLabel);
        mv.visitVarInsn(Opcodes.ILOAD, iIndex);
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        mv.visitInsn(Opcodes.ARRAYLENGTH);
        mv.visitJumpInsn(Opcodes.IF_ICMPLT, loopStartLabel);
    } else {
        // buffer.setInstrumentationActive(false);
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                !isTransferMethod ? Type.getInternalName(MappedByteBuffer.class)
                        : Type.getInternalName(FileChannelImpl.class),
                "setInstrumentationActive", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE), false);
    }

    // }
    mv.visitLabel(bufferInstrumentationActiveLabel);

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

    // return result;
    // }
    mv.visitVarInsn(returnType.getOpcode(Opcodes.ILOAD), resultIndex);
    mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

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

License:BSD License

@Override
protected void appendWrappedMethods(ClassVisitor visitor) {
    // public void setFromFileChannel(boolean fromFileChannel) {
    MethodVisitor setFromFileChannelMV = visitor.visitMethod(Opcodes.ACC_PUBLIC, "setFromFileChannel",
            Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE), null, null);
    setFromFileChannelMV.visitCode();//from  w ww .jav  a  2s . co  m

    // this.fromFileChannel = fromFileChannel;
    setFromFileChannelMV.visitVarInsn(Opcodes.ALOAD, 0);
    setFromFileChannelMV.visitVarInsn(Opcodes.ILOAD, 1);
    setFromFileChannelMV.visitFieldInsn(Opcodes.PUTFIELD, Type.getInternalName(MappedByteBuffer.class),
            "fromFileChannel", Type.getDescriptor(Boolean.TYPE));

    // }
    setFromFileChannelMV.visitInsn(Opcodes.RETURN);
    setFromFileChannelMV.visitMaxs(0, 0);
    setFromFileChannelMV.visitEnd();

    // public boolean isFromFileChannel() {
    MethodVisitor isFromFileChannelMV = visitor.visitMethod(Opcodes.ACC_PUBLIC, "isFromFileChannel",
            Type.getMethodDescriptor(Type.BOOLEAN_TYPE), null, null);
    isFromFileChannelMV.visitCode();

    // return fromFileChannel;
    // }
    isFromFileChannelMV.visitVarInsn(Opcodes.ALOAD, 0);
    isFromFileChannelMV.visitFieldInsn(Opcodes.GETFIELD, Type.getInternalName(MappedByteBuffer.class),
            "fromFileChannel", Type.getDescriptor(Boolean.TYPE));
    isFromFileChannelMV.visitInsn(Opcodes.IRETURN);
    isFromFileChannelMV.visitMaxs(0, 0);
    isFromFileChannelMV.visitEnd();

    // public void setFileDescriptor(FileDescriptor fileDescriptor) {
    MethodVisitor settFileDescriptorMV = visitor.visitMethod(Opcodes.ACC_PUBLIC, "setFileDescriptor",
            Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(FileDescriptor.class)), null, null);
    settFileDescriptorMV.visitCode();

    // this.fileDescriptor = fileDescriptor;
    settFileDescriptorMV.visitVarInsn(Opcodes.ALOAD, 0);
    settFileDescriptorMV.visitVarInsn(Opcodes.ALOAD, 1);
    settFileDescriptorMV.visitFieldInsn(Opcodes.PUTFIELD, Type.getInternalName(MappedByteBuffer.class),
            "fileDescriptor", Type.getDescriptor(FileDescriptor.class));

    // }
    settFileDescriptorMV.visitInsn(Opcodes.RETURN);
    settFileDescriptorMV.visitMaxs(0, 0);
    settFileDescriptorMV.visitEnd();

    // public FileDescriptor getFileDescriptor() {
    MethodVisitor getFileDescriptorMV = visitor.visitMethod(Opcodes.ACC_PUBLIC, "getFileDescriptor",
            Type.getMethodDescriptor(Type.getType(FileDescriptor.class)), null, null);
    getFileDescriptorMV.visitCode();

    // return getFileDescriptorImpl();
    // }
    getFileDescriptorMV.visitVarInsn(Opcodes.ALOAD, 0);
    getFileDescriptorMV.visitMethodInsn(Opcodes.INVOKESPECIAL, this.instrumentedTypeInternalName,
            "getFileDescriptorImpl", Type.getMethodDescriptor(Type.getType(FileDescriptor.class)), false);
    getFileDescriptorMV.visitInsn(Opcodes.ARETURN);
    getFileDescriptorMV.visitMaxs(0, 0);
    getFileDescriptorMV.visitEnd();

    // protected FileDescriptor getFileDescriptorImpl() {
    MethodVisitor getFileDescriptorImplMV = visitor.visitMethod(Opcodes.ACC_PROTECTED, "getFileDescriptorImpl",
            Type.getMethodDescriptor(Type.getType(FileDescriptor.class)), null, null);
    getFileDescriptorImplMV.visitCode();

    // return fileDescriptor;
    // }
    getFileDescriptorImplMV.visitVarInsn(Opcodes.ALOAD, 0);
    getFileDescriptorImplMV.visitFieldInsn(Opcodes.GETFIELD, Type.getInternalName(MappedByteBuffer.class),
            "fileDescriptor", Type.getDescriptor(FileDescriptor.class));
    getFileDescriptorImplMV.visitInsn(Opcodes.ARETURN);
    getFileDescriptorImplMV.visitMaxs(0, 0);
    getFileDescriptorImplMV.visitEnd();

    visitor.visitEnd();
}