@Override public Size apply( MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) { StackManipulation thisReference = MethodVariableAccess.REFERENCE.loadOffset(0); FieldList<?> fieldList = instrumentedType.getDeclaredFields(); StackManipulation[] fieldLoading = new StackManipulation[fieldList.size()]; int index = 0; for (FieldDescription fieldDescription : fieldList) { fieldLoading[index] = new StackManipulation.Compound( thisReference, MethodVariableAccess.forType(fieldDescription.getType().asErasure()) .loadOffset(instrumentedMethod.getParameters().get(index).getOffset()), FieldAccess.forField(fieldDescription).putter()); index++; } StackManipulation.Size stackSize = new StackManipulation.Compound( thisReference, MethodInvocation.invoke(ConstructorCall.INSTANCE.objectTypeDefaultConstructor), new StackManipulation.Compound(fieldLoading), MethodReturn.VOID) .apply(methodVisitor, implementationContext); return new Size(stackSize.getMaximalSize(), instrumentedMethod.getStackSize()); }
@Override public Size apply( MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) { StackManipulation thisReference = MethodVariableAccess.forType(instrumentedType).loadOffset(0); FieldList<?> fieldList = instrumentedType.getDeclaredFields(); StackManipulation[] fieldLoading = new StackManipulation[fieldList.size()]; int index = 0; for (FieldDescription fieldDescription : fieldList) { fieldLoading[index++] = new StackManipulation.Compound( thisReference, FieldAccess.forField(fieldDescription).getter()); } StackManipulation.Size stackSize = new StackManipulation.Compound( new StackManipulation.Compound(fieldLoading), MethodInvocation.invoke(accessorMethod), assigner.assign( accessorMethod.getReturnType().asErasure(), instrumentedMethod.getReturnType().asErasure(), Assigner.Typing.DYNAMIC), MethodReturn.returning(instrumentedMethod.getReturnType().asErasure())) .apply(methodVisitor, implementationContext); return new Size(stackSize.getMaximalSize(), instrumentedMethod.getStackSize()); }
private void buildCopyStack( List<StackManipulation> stack, int iterations, Method getMethod, Method putMethod, long stride) throws NoSuchFieldException, NoSuchMethodException { final Field unsafeField = UnsafeCopier.class.getDeclaredField("unsafe"); final StackManipulation copyStack = new StackManipulation.Compound( // unsafe.putLong(dest, destOffset, unsafe.getLong(src)); MethodVariableAccess.REFERENCE.loadOffset(0), // ALOAD 0 this FieldAccess.forField(new FieldDescription.ForLoadedField(unsafeField)) .getter(), // GETFIELD MethodVariableAccess.REFERENCE.loadOffset(1), // ALOAD 1 dest MethodVariableAccess.LONG.loadOffset(4), // LLOAD 4 destOffset MethodVariableAccess.REFERENCE.loadOffset(0), // ALOAD 0 this FieldAccess.forField(new FieldDescription.ForLoadedField(unsafeField)) .getter(), // GETFIELD MethodVariableAccess.LONG.loadOffset(2), // LLOAD 2 src MethodInvocation.invoke(new MethodDescription.ForLoadedMethod(getMethod)), MethodInvocation.invoke(new MethodDescription.ForLoadedMethod(putMethod))); final StackManipulation incrementStack = new StackManipulation.Compound( // destOffset += 8; src += 8; MethodVariableAccess.LONG.loadOffset(4), // LLOAD 4 destOffset LongConstant.forValue(stride), // LDC 8 strideWidth LongAdd.INSTANCE, // LADD MethodVariableStore.LONG.storeOffset(4), // LSTORE 4 MethodVariableAccess.LONG.loadOffset(2), // LLOAD 2 src LongConstant.forValue(stride), // LDC 8 strideWidth LongAdd.INSTANCE, // LADD MethodVariableStore.LONG.storeOffset(2) // LSTORE 2 ); for (int i = 0; i < iterations; i++) { stack.add(copyStack); stack.add(incrementStack); } }
@Override public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext) { TypeDescription auxiliaryType = implementationContext.register( new MethodCallProxy(specialMethodInvocation, serializable)); return new Compound( TypeCreation.forType(auxiliaryType), Duplication.SINGLE, MethodVariableAccess.allArgumentsOf(specialMethodInvocation.getMethodDescription()) .prependThisReference(), MethodInvocation.invoke( auxiliaryType.getDeclaredMethods().filter(isConstructor()).getOnly())) .apply(methodVisitor, implementationContext); }