List of usage examples for org.objectweb.asm Opcodes ARRAYLENGTH
int ARRAYLENGTH
To view the source code for org.objectweb.asm Opcodes ARRAYLENGTH.
Click Source Link
From source file:com.trigersoft.jaque.expression.ExpressionMethodVisitor.java
License:Apache License
@Override public void visitInsn(int opcode) { Expression e;/*from w w w . j a v a2 s. c o m*/ Expression first; Expression second; switch (opcode) { case Opcodes.ARRAYLENGTH: e = Expression.arrayLength(_exprStack.pop()); break; case Opcodes.ACONST_NULL: e = Expression.constant(null, Object.class); break; case Opcodes.IALOAD: case Opcodes.LALOAD: case Opcodes.FALOAD: case Opcodes.DALOAD: case Opcodes.AALOAD: case Opcodes.BALOAD: case Opcodes.CALOAD: case Opcodes.SALOAD: first = _exprStack.pop(); second = _exprStack.pop(); e = Expression.arrayIndex(second, first); break; case Opcodes.DCONST_0: e = Expression.constant(0d, Double.TYPE); break; case Opcodes.DCONST_1: e = Expression.constant(1d, Double.TYPE); break; case Opcodes.FCMPG: case Opcodes.FCMPL: case Opcodes.DCMPG: case Opcodes.DCMPL: case Opcodes.LCMP: first = _exprStack.pop(); second = _exprStack.pop(); e = Expression.subtract(second, first); break; case Opcodes.FCONST_0: e = Expression.constant(0f, Float.TYPE); break; case Opcodes.FCONST_1: e = Expression.constant(1f, Float.TYPE); break; case Opcodes.FCONST_2: e = Expression.constant(2f, Float.TYPE); break; case Opcodes.ICONST_M1: e = Expression.constant(-1, Integer.TYPE); break; case Opcodes.ICONST_0: e = Expression.constant(0, Integer.TYPE); break; case Opcodes.ICONST_1: e = Expression.constant(1, Integer.TYPE); break; case Opcodes.ICONST_2: e = Expression.constant(2, Integer.TYPE); break; case Opcodes.ICONST_3: e = Expression.constant(3, Integer.TYPE); break; case Opcodes.ICONST_4: e = Expression.constant(4, Integer.TYPE); break; case Opcodes.ICONST_5: e = Expression.constant(5, Integer.TYPE); break; case Opcodes.LCONST_0: e = Expression.constant(0l, Long.TYPE); break; case Opcodes.LCONST_1: e = Expression.constant(1l, Long.TYPE); break; case Opcodes.IADD: case Opcodes.LADD: case Opcodes.FADD: case Opcodes.DADD: first = _exprStack.pop(); second = _exprStack.pop(); e = Expression.add(second, first); break; case Opcodes.ISUB: case Opcodes.LSUB: case Opcodes.FSUB: case Opcodes.DSUB: first = _exprStack.pop(); second = _exprStack.pop(); e = Expression.subtract(second, first); break; case Opcodes.IMUL: case Opcodes.LMUL: case Opcodes.FMUL: case Opcodes.DMUL: first = _exprStack.pop(); second = _exprStack.pop(); e = Expression.multiply(second, first); break; case Opcodes.IDIV: case Opcodes.LDIV: case Opcodes.FDIV: case Opcodes.DDIV: first = _exprStack.pop(); second = _exprStack.pop(); e = Expression.divide(second, first); break; case Opcodes.IREM: case Opcodes.LREM: case Opcodes.FREM: case Opcodes.DREM: first = _exprStack.pop(); second = _exprStack.pop(); e = Expression.modulo(second, first); break; case Opcodes.INEG: case Opcodes.LNEG: case Opcodes.FNEG: case Opcodes.DNEG: first = _exprStack.pop(); e = Expression.negate(first); break; case Opcodes.ISHL: case Opcodes.LSHL: first = _exprStack.pop(); second = _exprStack.pop(); e = Expression.leftShift(second, first); break; case Opcodes.ISHR: case Opcodes.LSHR: first = _exprStack.pop(); second = _exprStack.pop(); e = Expression.rightShift(second, first); break; case Opcodes.IUSHR: case Opcodes.LUSHR: first = _exprStack.pop(); second = _exprStack.pop(); e = Expression.rightShift(second, first); break; case Opcodes.IAND: case Opcodes.LAND: first = _exprStack.pop(); second = _exprStack.pop(); e = Expression.bitwiseAnd(second, first); break; case Opcodes.IOR: case Opcodes.LOR: first = _exprStack.pop(); second = _exprStack.pop(); e = Expression.bitwiseOr(second, first); break; case Opcodes.IXOR: case Opcodes.LXOR: first = _exprStack.pop(); second = _exprStack.pop(); e = Expression.exclusiveOr(second, first); break; case Opcodes.I2B: case Opcodes.I2C: case Opcodes.I2S: first = _exprStack.pop(); e = Expression.convert(first, NumericTypeLookup2[opcode - Opcodes.I2B]); break; case Opcodes.I2L: case Opcodes.I2F: case Opcodes.I2D: first = _exprStack.pop(); e = Expression.convert(first, NumericTypeLookup[opcode - Opcodes.I2L + 1]); break; case Opcodes.L2I: case Opcodes.L2F: case Opcodes.L2D: int l2l = opcode > Opcodes.L2I ? 1 : 0; first = _exprStack.pop(); e = Expression.convert(first, NumericTypeLookup[opcode - Opcodes.L2I + l2l]); break; case Opcodes.F2I: case Opcodes.F2L: case Opcodes.F2D: int f2f = opcode == Opcodes.F2D ? 1 : 0; first = _exprStack.pop(); e = Expression.convert(first, NumericTypeLookup[opcode - Opcodes.F2I + f2f]); break; case Opcodes.D2I: case Opcodes.D2L: case Opcodes.D2F: first = _exprStack.pop(); e = Expression.convert(first, NumericTypeLookup[opcode - Opcodes.D2I]); break; case Opcodes.IRETURN: case Opcodes.LRETURN: case Opcodes.FRETURN: case Opcodes.DRETURN: case Opcodes.ARETURN: go(null); return; case Opcodes.SWAP: first = _exprStack.pop(); second = _exprStack.pop(); _exprStack.push(first); _exprStack.push(second); case Opcodes.DUP: case Opcodes.DUP_X1: case Opcodes.DUP_X2: case Opcodes.DUP2: case Opcodes.DUP2_X1: case Opcodes.DUP2_X2: // our stack is not divided to words int base = (opcode - Opcodes.DUP) % 3; base++; dup(_exprStack, base, base - 1); return; case Opcodes.NOP: return; case Opcodes.RETURN: default: throw notLambda(opcode); } _exprStack.push(e); }
From source file:com.yahoo.yqlplus.engine.internal.plan.types.base.ArrayIndexAdapter.java
@Override public BytecodeExpression length(final BytecodeExpression inputExpr) { return new BaseTypeExpression(BaseTypeAdapter.INT32) { @Override//from w w w . jav a2 s . c om public void generate(CodeEmitter code) { Label done = new Label(); Label isNull = new Label(); MethodVisitor mv = code.getMethodVisitor(); code.exec(inputExpr); boolean nullable = code.nullTest(inputExpr.getType(), isNull); mv.visitInsn(Opcodes.ARRAYLENGTH); if (nullable) { mv.visitJumpInsn(Opcodes.GOTO, done); mv.visitLabel(isNull); mv.visitInsn(Opcodes.ICONST_0); mv.visitLabel(done); } } }; }
From source file:com.yahoo.yqlplus.engine.internal.plan.types.base.ArrayIndexAdapter.java
@Override public BytecodeSequence iterate(final BytecodeExpression target, final AssignableValue item, final IterateLoop loop) { return new BytecodeSequence() { @Override//from ww w.j a va 2 s. co m public void generate(CodeEmitter start) { CodeEmitter code = start.createScope(); final AssignableValue count = code.allocate(BaseTypeAdapter.INT32); final AssignableValue idx = code.allocate(BaseTypeAdapter.INT32); Label done = new Label(); Label next = new Label(); MethodVisitor mv = code.getMethodVisitor(); BytecodeExpression tgt = code.evaluateOnce(target); code.exec(tgt); code.nullTest(tgt.getType(), done); mv.visitInsn(Opcodes.ARRAYLENGTH); code.exec(count.write(BaseTypeAdapter.INT32)); code.emitIntConstant(0); code.exec(idx.write(BaseTypeAdapter.INT32)); mv.visitLabel(next); code.exec(count.read()); mv.visitJumpInsn(Opcodes.IFEQ, done); code.inc(count, -1); code.exec(tgt); code.exec(idx.read()); code.getMethodVisitor().visitInsn(ownerType.getJVMType().getOpcode(Opcodes.IALOAD)); code.inc(idx, 1); code.nullTest(valueType, next); code.exec(item.write(item.getType())); loop.item(code, item.read(), done, next); mv.visitJumpInsn(Opcodes.GOTO, next); mv.visitLabel(done); code.endScope(); } }; }
From source file:com.yahoo.yqlplus.engine.internal.plan.types.base.ArrayIndexAdapter.java
@Override public BytecodeExpression first(final BytecodeExpression target) { // what should this return if the array is of length 0? return new BaseTypeExpression(NullableTypeWidget.create(valueType.boxed())) { @Override//w ww .ja v a2 s. c om public void generate(CodeEmitter start) { CodeEmitter code = start.createScope(); Label done = new Label(); Label isNull = new Label(); MethodVisitor mv = code.getMethodVisitor(); BytecodeExpression tgt = code.evaluateOnce(target); code.exec(tgt); code.nullTest(tgt.getType(), isNull); mv.visitInsn(Opcodes.ARRAYLENGTH); mv.visitJumpInsn(Opcodes.IFEQ, isNull); code.exec(tgt); code.emitIntConstant(0); mv.visitInsn(ownerType.getJVMType().getOpcode(Opcodes.IALOAD)); code.cast(valueType.boxed(), valueType, isNull); mv.visitJumpInsn(Opcodes.GOTO, done); mv.visitLabel(isNull); mv.visitInsn(Opcodes.ACONST_NULL); mv.visitLabel(done); code.endScope(); } }; }
From source file:de.dynamicfiles.projects.gradle.plugins.javafx.tasks.internal.MonkeyPatcher.java
License:Apache License
private static void doMonkeyPatchFileHandleLeak(ClassReader classReader, ClassWriter classWriter) { classReader.accept(new ClassVisitor(Opcodes.ASM5, classWriter) { @Override//from w w w . ja v a2 s. c om public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (!(name.equals(METHOD_TO_MONKEY_PATCH) && desc.equals(METHOD_SIGNATURE_TO_MONKEY_PATCH))) { return super.visitMethod(access, name, desc, signature, exceptions); } // helpful source: http://web.cs.ucla.edu/~msb/cs239-tutorial/ // "We will do this using the Adapter Pattern. Adapters wrap an object, overriding some of its methods, and delegating to the others." // ugly adapter-pattern ... took me more time than I really can tell here <.< return getMonkeyPatchedFileHandleLeakMethodVisitor(access, name, desc, signature, exceptions); } private MethodVisitor getMonkeyPatchedFileHandleLeakMethodVisitor(int access, String name, String desc, String signature, String[] exceptions) { return new MethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions)) { /* TODO improve detection of lambda-positions, numbers might vary on different compile-versions */ @Override public void visitCode() { // This mostly got generated from ASM itself, except some adjustments for lambda-IDs and removed "visitMaxs()"-call String javalangThrowable = "java/lang/Throwable"; String javaioFile = "java/io/File"; String javalangString = "java/lang/String"; Label l0 = new Label(); Label l1 = new Label(); Label l2 = new Label(); mv.visitTryCatchBlock(l0, l1, l2, javalangThrowable); Label l3 = new Label(); Label l4 = new Label(); Label l5 = new Label(); mv.visitTryCatchBlock(l3, l4, l5, javalangThrowable); Label l6 = new Label(); mv.visitTryCatchBlock(l3, l4, l6, null); Label l7 = new Label(); Label l8 = new Label(); Label l9 = new Label(); mv.visitTryCatchBlock(l7, l8, l9, javalangThrowable); Label l10 = new Label(); mv.visitTryCatchBlock(l5, l10, l6, null); mv.visitInsn(Opcodes.ACONST_NULL); mv.visitVarInsn(Opcodes.ASTORE, 3); mv.visitVarInsn(Opcodes.ALOAD, 2); Label l11 = new Label(); mv.visitJumpInsn(Opcodes.IFNULL, l11); mv.visitVarInsn(Opcodes.ALOAD, 2); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, javaioFile, "isDirectory", "()Z", false); Label l12 = new Label(); mv.visitJumpInsn(Opcodes.IFNE, l12); mv.visitLabel(l11); mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { javalangString }, 0, null); mv.visitTypeInsn(Opcodes.NEW, javaioFile); mv.visitInsn(Opcodes.DUP); mv.visitLdcInsn("java.home"); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/System", "getProperty", "(Ljava/lang/String;)Ljava/lang/String;", false); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, javaioFile, "<init>", "(Ljava/lang/String;)V", false); mv.visitVarInsn(Opcodes.ASTORE, 2); mv.visitLabel(l12); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitFieldInsn(Opcodes.GETSTATIC, "com/oracle/tools/packager/windows/WinAppBundler", "VS_VERS", "[Ljava/lang/String;"); mv.visitVarInsn(Opcodes.ASTORE, 4); mv.visitVarInsn(Opcodes.ALOAD, 4); mv.visitInsn(Opcodes.ARRAYLENGTH); mv.visitVarInsn(Opcodes.ISTORE, 5); mv.visitInsn(Opcodes.ICONST_0); mv.visitVarInsn(Opcodes.ISTORE, 6); Label l13 = new Label(); mv.visitLabel(l13); mv.visitFrame(Opcodes.F_APPEND, 3, new Object[] { "[Ljava/lang/String;", Opcodes.INTEGER, Opcodes.INTEGER }, 0, null); mv.visitVarInsn(Opcodes.ILOAD, 6); mv.visitVarInsn(Opcodes.ILOAD, 5); Label l14 = new Label(); mv.visitJumpInsn(Opcodes.IF_ICMPGE, l14); mv.visitVarInsn(Opcodes.ALOAD, 4); mv.visitVarInsn(Opcodes.ILOAD, 6); mv.visitInsn(Opcodes.AALOAD); mv.visitVarInsn(Opcodes.ASTORE, 7); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitVarInsn(Opcodes.ALOAD, 7); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/oracle/tools/packager/windows/WinAppBundler", "copyMSVCDLLs", "(Ljava/io/File;Ljava/lang/String;)Z", false); Label l15 = new Label(); mv.visitJumpInsn(Opcodes.IFEQ, l15); mv.visitVarInsn(Opcodes.ALOAD, 7); mv.visitVarInsn(Opcodes.ASTORE, 3); mv.visitJumpInsn(Opcodes.GOTO, l14); mv.visitLabel(l15); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitIincInsn(6, 1); mv.visitJumpInsn(Opcodes.GOTO, l13); mv.visitLabel(l14); mv.visitFrame(Opcodes.F_CHOP, 3, null, 0, null); mv.visitVarInsn(Opcodes.ALOAD, 3); Label l16 = new Label(); mv.visitJumpInsn(Opcodes.IFNONNULL, l16); mv.visitTypeInsn(Opcodes.NEW, "java/lang/RuntimeException"); mv.visitInsn(Opcodes.DUP); mv.visitLdcInsn("Not found MSVC dlls"); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V", false); mv.visitInsn(Opcodes.ATHROW); mv.visitLabel(l16); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitTypeInsn(Opcodes.NEW, "java/util/concurrent/atomic/AtomicReference"); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/concurrent/atomic/AtomicReference", "<init>", "()V", false); mv.visitVarInsn(Opcodes.ASTORE, 4); mv.visitVarInsn(Opcodes.ALOAD, 3); mv.visitVarInsn(Opcodes.ASTORE, 5); mv.visitVarInsn(Opcodes.ALOAD, 2); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, javaioFile, "toPath", "()Ljava/nio/file/Path;", false); mv.visitLdcInsn("bin"); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/nio/file/Path", "resolve", "(Ljava/lang/String;)Ljava/nio/file/Path;", true); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/nio/file/Files", "list", "(Ljava/nio/file/Path;)Ljava/util/stream/Stream;", false); mv.visitVarInsn(Opcodes.ASTORE, 6); mv.visitInsn(Opcodes.ACONST_NULL); mv.visitVarInsn(Opcodes.ASTORE, 7); mv.visitLabel(l3); mv.visitVarInsn(Opcodes.ALOAD, 6); mv.visitInvokeDynamicInsn("test", "()Ljava/util/function/Predicate;", new Handle( Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"), new Object[] { Type.getType("(Ljava/lang/Object;)Z"), new Handle(Opcodes.H_INVOKESTATIC, "com/oracle/tools/packager/windows/WinAppBundler", "lambda$copyMSVCDLLs$261", "(Ljava/nio/file/Path;)Z"), Type.getType("(Ljava/nio/file/Path;)Z") }); // modified lambda-name mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/stream/Stream", "filter", "(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;", true); mv.visitVarInsn(Opcodes.ALOAD, 5); mv.visitInvokeDynamicInsn("test", "(Ljava/lang/String;)Ljava/util/function/Predicate;", new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"), new Object[] { Type.getType("(Ljava/lang/Object;)Z"), new Handle( Opcodes.H_INVOKESTATIC, "com/oracle/tools/packager/windows/WinAppBundler", "lambda$copyMSVCDLLs$262", "(Ljava/lang/String;Ljava/nio/file/Path;)Z"), Type.getType("(Ljava/nio/file/Path;)Z") }); // modified lambda-name mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/stream/Stream", "filter", "(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;", true); mv.visitVarInsn(Opcodes.ALOAD, 1); mv.visitVarInsn(Opcodes.ALOAD, 4); mv.visitInvokeDynamicInsn("accept", "(Ljava/io/File;Ljava/util/concurrent/atomic/AtomicReference;)Ljava/util/function/Consumer;", new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;"), new Object[] { Type.getType("(Ljava/lang/Object;)V"), new Handle( Opcodes.H_INVOKESTATIC, "com/oracle/tools/packager/windows/WinAppBundler", "lambda$copyMSVCDLLs$263", "(Ljava/io/File;Ljava/util/concurrent/atomic/AtomicReference;Ljava/nio/file/Path;)V"), Type.getType("(Ljava/nio/file/Path;)V") }); // modified lambda-name mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/stream/Stream", "forEach", "(Ljava/util/function/Consumer;)V", true); mv.visitLabel(l4); mv.visitVarInsn(Opcodes.ALOAD, 6); Label l17 = new Label(); mv.visitJumpInsn(Opcodes.IFNULL, l17); mv.visitVarInsn(Opcodes.ALOAD, 7); Label l18 = new Label(); mv.visitJumpInsn(Opcodes.IFNULL, l18); mv.visitLabel(l0); mv.visitVarInsn(Opcodes.ALOAD, 6); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/stream/Stream", "close", "()V", true); mv.visitLabel(l1); mv.visitJumpInsn(Opcodes.GOTO, l17); mv.visitLabel(l2); mv.visitFrame(Opcodes.F_FULL, 8, new Object[] { "com/oracle/tools/packager/windows/WinAppBundler", javaioFile, javaioFile, javalangString, "java/util/concurrent/atomic/AtomicReference", javalangString, "java/util/stream/Stream", javalangThrowable }, 1, new Object[] { javalangThrowable }); mv.visitVarInsn(Opcodes.ASTORE, 8); mv.visitVarInsn(Opcodes.ALOAD, 7); mv.visitVarInsn(Opcodes.ALOAD, 8); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, javalangThrowable, "addSuppressed", "(Ljava/lang/Throwable;)V", false); mv.visitJumpInsn(Opcodes.GOTO, l17); mv.visitLabel(l18); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(Opcodes.ALOAD, 6); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/stream/Stream", "close", "()V", true); mv.visitJumpInsn(Opcodes.GOTO, l17); mv.visitLabel(l5); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { javalangThrowable }); mv.visitVarInsn(Opcodes.ASTORE, 8); mv.visitVarInsn(Opcodes.ALOAD, 8); mv.visitVarInsn(Opcodes.ASTORE, 7); mv.visitVarInsn(Opcodes.ALOAD, 8); mv.visitInsn(Opcodes.ATHROW); mv.visitLabel(l6); mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { javalangThrowable }); mv.visitVarInsn(Opcodes.ASTORE, 9); mv.visitLabel(l10); mv.visitVarInsn(Opcodes.ALOAD, 6); Label l19 = new Label(); mv.visitJumpInsn(Opcodes.IFNULL, l19); mv.visitVarInsn(Opcodes.ALOAD, 7); Label l20 = new Label(); mv.visitJumpInsn(Opcodes.IFNULL, l20); mv.visitLabel(l7); mv.visitVarInsn(Opcodes.ALOAD, 6); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/stream/Stream", "close", "()V", true); mv.visitLabel(l8); mv.visitJumpInsn(Opcodes.GOTO, l19); mv.visitLabel(l9); mv.visitFrame(Opcodes.F_FULL, 10, new Object[] { "com/oracle/tools/packager/windows/WinAppBundler", javaioFile, javaioFile, javalangString, "java/util/concurrent/atomic/AtomicReference", javalangString, "java/util/stream/Stream", javalangThrowable, Opcodes.TOP, javalangThrowable }, 1, new Object[] { javalangThrowable }); mv.visitVarInsn(Opcodes.ASTORE, 10); mv.visitVarInsn(Opcodes.ALOAD, 7); mv.visitVarInsn(Opcodes.ALOAD, 10); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, javalangThrowable, "addSuppressed", "(Ljava/lang/Throwable;)V", false); mv.visitJumpInsn(Opcodes.GOTO, l19); mv.visitLabel(l20); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(Opcodes.ALOAD, 6); mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/stream/Stream", "close", "()V", true); mv.visitLabel(l19); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitVarInsn(Opcodes.ALOAD, 9); mv.visitInsn(Opcodes.ATHROW); mv.visitLabel(l17); mv.visitFrame(Opcodes.F_FULL, 6, new Object[] { "com/oracle/tools/packager/windows/WinAppBundler", javaioFile, javaioFile, javalangString, "java/util/concurrent/atomic/AtomicReference", javalangString }, 0, new Object[] {}); mv.visitVarInsn(Opcodes.ALOAD, 4); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/concurrent/atomic/AtomicReference", "get", "()Ljava/lang/Object;", false); mv.visitTypeInsn(Opcodes.CHECKCAST, "java/io/IOException"); mv.visitVarInsn(Opcodes.ASTORE, 6); mv.visitVarInsn(Opcodes.ALOAD, 6); Label l21 = new Label(); mv.visitJumpInsn(Opcodes.IFNULL, l21); mv.visitVarInsn(Opcodes.ALOAD, 6); mv.visitInsn(Opcodes.ATHROW); mv.visitLabel(l21); mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] { "java/io/IOException" }, 0, null); mv.visitInsn(Opcodes.RETURN); } }; } }, ClassReader.EXPAND_FRAMES); // ClassReader.EXPAND_FRAMES required for Java 8 }
From source file:de.tuberlin.uebb.jbop.optimizer.array.FieldArrayLengthInlinerTest.java
License:Open Source License
/** * Tests that FieldArrayLengthInliner is working correctly. * // w w w .ja v a 2 s .com * @throws Exception * the exception */ @Test public void testFieldArrayLengthInliner() throws Exception { // INIT final String owner = "de.tuberlin.uebb.jbop.optimizer.array.FieldArrayLengthTestClass"; final ClassNodeBuilder builder = ClassNodeBuilder.createClass(owner).// addField("doubleArray", "[D").withModifiers(ACC_FINAL).initArray(15).// addField("objectArray", Type.getDescriptor(Object[].class)).withModifiers(ACC_FINAL).initArray(23).// addMethod("sumArrayLength", "()I").withAnnotation(Optimizable.class).// addGetClassField("doubleArray").// addInsn(new InsnNode(Opcodes.ARRAYLENGTH)).// addGetClassField("objectArray").// addInsn(new InsnNode(Opcodes.ARRAYLENGTH)).// addInsn(new InsnNode(Opcodes.IADD)).// addInsn(new InsnNode(Opcodes.IRETURN)); final FieldArrayLengthInliner inliner = new FieldArrayLengthInliner(); inliner.setClassNode(builder.getClassNode()); inliner.setInputObject(builder.toClass().instance()); // RUN STEP 1 final MethodNode method = builder.getMethod("sumArrayLength"); final InsnList optimized = inliner.optimize(method.instructions, method); // ASSERT STEP 2 assertEquals(4, optimized.size()); assertEquals(15, NodeHelper.getNumberValue(optimized.getFirst()).intValue()); assertEquals(23, NodeHelper.getNumberValue(optimized.getFirst().getNext()).intValue()); }
From source file:de.tuberlin.uebb.jbop.optimizer.array.LocalArrayLengthInlinerTest.java
License:Open Source License
/** * Tests that LocalArrayLengthInliner is working correctly. * /*w w w . java2 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.utils.NodeHelper.java
License:Open Source License
/** * Checks if node is array length.//from w w w . j a v a2 s . c o m * * @param node * the node * @return true if node is array length */ public static boolean isArrayLength(final AbstractInsnNode node) { if (node == null) { return false; } return node.getOpcode() == Opcodes.ARRAYLENGTH; }
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://ww w. j a v a2 s .c o m assert false; return "--ERROR--"; } }
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 av a 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(); }