List of usage examples for org.objectweb.asm Opcodes INSTANCEOF
int INSTANCEOF
To view the source code for org.objectweb.asm Opcodes INSTANCEOF.
Click Source Link
From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.TypeInstruction.java
License:Open Source License
public TypeInstruction(final ReadMethod readMethod, final int opcode, final int lineNumber, final String className, int newObjIdSeqIndex) { super(readMethod, opcode, lineNumber); assert opcode == Opcodes.NEW || opcode == Opcodes.ANEWARRAY || opcode == Opcodes.CHECKCAST || opcode == Opcodes.INSTANCEOF; assert ((opcode == Opcodes.CHECKCAST || opcode == Opcodes.INSTANCEOF) && newObjIdSeqIndex == -1) || ((opcode == Opcodes.NEW || opcode == Opcodes.ANEWARRAY) && newObjIdSeqIndex != -1); this.className = className; this.newObjectIdentifierSeqIndex = newObjIdSeqIndex; }
From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.TypeInstruction.java
License:Open Source License
private TypeInstruction(final ReadMethod readMethod, final int lineNumber, final int opcode, final String typeDesc, final int index, int newObjIdSeqIndex) { super(readMethod, opcode, lineNumber, index); assert opcode == Opcodes.NEW || opcode == Opcodes.ANEWARRAY || opcode == Opcodes.CHECKCAST || opcode == Opcodes.INSTANCEOF; assert ((opcode == Opcodes.CHECKCAST || opcode == Opcodes.INSTANCEOF) && newObjIdSeqIndex == -1) || ((opcode == Opcodes.NEW || opcode == Opcodes.ANEWARRAY) && newObjIdSeqIndex != -1); this.className = typeDesc; this.newObjectIdentifierSeqIndex = newObjIdSeqIndex; }
From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.TypeInstruction.java
License:Open Source License
@Override public String toString() { String instruction;//from w w w .ja va 2 s.c o m switch (getOpcode()) { case Opcodes.NEW: instruction = "NEW"; break; case Opcodes.ANEWARRAY: instruction = "ANEWARRAY"; break; case Opcodes.CHECKCAST: instruction = "CHECKCAST"; break; case Opcodes.INSTANCEOF: instruction = "INSTANCEOF"; break; default: instruction = "-ERROR-"; } return new StringBuilder(instruction.length() + this.className.length() + 1).append(instruction).append(' ') .append(this.className).toString(); }
From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.TypeInstruction2.java
License:Open Source License
public TypeInstruction2(final ReadMethod readMethod, final int opcode, final int lineNumber, final String className, long newObjIdSeqIndex) { super(readMethod, opcode, lineNumber); assert opcode == Opcodes.NEW || opcode == Opcodes.ANEWARRAY || opcode == Opcodes.CHECKCAST || opcode == Opcodes.INSTANCEOF; assert ((opcode == Opcodes.CHECKCAST || opcode == Opcodes.INSTANCEOF) && newObjIdSeqIndex == -1) || ((opcode == Opcodes.NEW || opcode == Opcodes.ANEWARRAY) && newObjIdSeqIndex != -1); this.className = className; this.newObjectIdentifier = newObjIdSeqIndex; }
From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.TypeInstruction2.java
License:Open Source License
public TypeInstruction2(final ReadMethod readMethod, final int lineNumber, final int opcode, final String typeDesc, final int index, long newObjIdSeqIndex) { super(readMethod, opcode, lineNumber, index); assert opcode == Opcodes.NEW || opcode == Opcodes.ANEWARRAY || opcode == Opcodes.CHECKCAST || opcode == Opcodes.INSTANCEOF; assert ((opcode == Opcodes.CHECKCAST || opcode == Opcodes.INSTANCEOF) && newObjIdSeqIndex == -1) || ((opcode == Opcodes.NEW || opcode == Opcodes.ANEWARRAY) && newObjIdSeqIndex != -1); this.className = typeDesc; this.newObjectIdentifier = newObjIdSeqIndex; }
From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.TypeInstruction2.java
License:Open Source License
@Override public <InstanceType> InstanceType getNextInstance(TraceIterator infoProv, int stackDepth, long instanceNr, InstructionInstanceFactory<InstanceType> instanceFactory) throws TracerException { long newobjIndentifier = this.newObjectIdentifier; TypeInstrInstanceInfo info;// www . ja va 2s .c o m if (this.getOpcode() == Opcodes.CHECKCAST || this.getOpcode() == Opcodes.INSTANCEOF) info = TypeInstrInstanceInfo.NO_INFO; else info = new TypeInstrInstanceInfo(newobjIndentifier); return instanceFactory.createInstructionInstance(this, infoProv.getNextInstructionOccurenceNumber(getIndex()), stackDepth, instanceNr, info); }
From source file:de.unisb.cs.st.javaslicer.instructionSimulation.Simulator.java
License:Open Source License
private DynamicInformation simulateTypeInsn(InstructionInstance inst, SimulationEnvironment simEnv) { assert inst.getInstruction().getType() == InstructionType.TYPE; TypeInstrInstanceInfo info = (TypeInstrInstanceInfo) inst.getAdditionalInfo(); int stackDepth = inst.getStackDepth(); switch (inst.getInstruction().getOpcode()) { case Opcodes.NEW: return new SimpleVariableUsage(DynamicInformation.EMPTY_VARIABLE_SET, Collections.<Variable>singleton( simEnv.getOpStackEntry(stackDepth, simEnv.decAndGetOpStack(stackDepth))), Collections.<Long, Collection<? extends Variable>>singletonMap(info.getNewObjectIdentifier(), getAllFields(((TypeInstruction) inst.getInstruction()).getJavaClassName(), info.getNewObjectIdentifier()))); case Opcodes.ANEWARRAY: int stackSize = simEnv.getOpStack(stackDepth) - 1; IntHolder h = this.maxArrayElem.remove(info.getNewObjectIdentifier()); Collection<Variable> stackEntryColl = Collections .<Variable>singleton(simEnv.getOpStackEntry(stackDepth, stackSize)); return new SimpleVariableUsage(stackEntryColl, stackEntryColl, Collections.<Long, Collection<? extends Variable>>singletonMap(info.getNewObjectIdentifier(), new ArrayElementsList(h == null ? 0 : (h.get() + 1), info.getNewObjectIdentifier()))); case Opcodes.CHECKCAST: return new SimpleVariableUsage(simEnv.getOpStackEntry(stackDepth, simEnv.getOpStack(stackDepth) - 1), DynamicInformation.EMPTY_VARIABLE_SET); case Opcodes.INSTANCEOF: return stackManipulation(simEnv, stackDepth, 1, 1); default:// w ww . j a v a 2 s.c om assert false; return null; } }
From source file:de.zib.sfs.instrument.DirectByteBufferAdapter.java
License:BSD License
@Override protected void initializeFields(MethodVisitor constructorMV, String constructorDesc) { if ("(Lsun/nio/ch/DirectBuffer;IIIII)V".equals(constructorDesc)) { // if we're constructed from another buffer, make sure we're from a // file too if the other buffer is too // if (db instanceof MappedByteBuffer) { constructorMV.visitVarInsn(Opcodes.ALOAD, 1); constructorMV.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName(MappedByteBuffer.class)); Label memoryMappedBufferLabel = new Label(); constructorMV.visitJumpInsn(Opcodes.IFEQ, memoryMappedBufferLabel); // setFromFileChannel(db.isFromFileChannel()); constructorMV.visitVarInsn(Opcodes.ALOAD, 0); constructorMV.visitVarInsn(Opcodes.ALOAD, 1); constructorMV.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class), "isFromFileChannel", Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false); constructorMV.visitMethodInsn(Opcodes.INVOKESPECIAL, this.instrumentedTypeInternalName, "setFromFileChannel", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE), false); // callback.openCallback(db.fileDescriptor); constructorMV.visitVarInsn(Opcodes.ALOAD, 0); constructorMV.visitFieldInsn(Opcodes.GETFIELD, this.instrumentedTypeInternalName, "callback", this.callbackTypeDescriptor); constructorMV.visitVarInsn(Opcodes.ALOAD, 1); constructorMV.visitFieldInsn(Opcodes.GETFIELD, Type.getInternalName(MappedByteBuffer.class), "fileDescriptor", Type.getDescriptor(FileDescriptor.class)); constructorMV.visitMethodInsn(Opcodes.INVOKEVIRTUAL, this.callbackTypeInternalName, "openCallback", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(FileDescriptor.class)), false); // }/*from w w w. j av a2 s . co m*/ constructorMV.visitLabel(memoryMappedBufferLabel); } }
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 ww .j a v a 2 s . 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.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 ava 2s . co 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(); }