1 5 package com.tc.object.bytecode; 6 7 import com.tc.asm.ClassVisitor; 8 import com.tc.asm.Label; 9 import com.tc.asm.MethodVisitor; 10 import com.tc.asm.Opcodes; 11 import com.tc.asm.Type; 12 import com.tc.object.logging.InstrumentationLogger; 13 14 public class DistributedMethodCallAdapter implements MethodAdapter, Opcodes { 15 private ManagerHelper managerHelper; 16 private int access; 17 private String className; 18 private String methodName; 19 private String description; 20 private String [] exceptions; 21 private String signature; 22 private InstrumentationLogger instrumentationLogger; 23 24 private final boolean runOnAllNodes; 25 26 public DistributedMethodCallAdapter(boolean runOnAllNodes) { 27 super(); 28 this.runOnAllNodes = runOnAllNodes; 29 } 30 31 public MethodVisitor adapt(ClassVisitor classVisitor) { 32 final String newMethodName = ByteCodeUtil.DMI_METHOD_RENAME_PREFIX + methodName; 33 MethodVisitor codeVisitor = classVisitor.visitMethod(access, newMethodName, description, signature, exceptions); 34 addDmiMethodWrapper(classVisitor, newMethodName); 35 return codeVisitor; 37 } 38 39 private void addDmiMethodWrapper(ClassVisitor classVisitor, String newMethodName) { 40 MethodVisitor mv = classVisitor.visitMethod(access, methodName, description, signature, exceptions); 41 final int boolPos = ByteCodeUtil.getFirstLocalVariableOffset(access, description); 42 final int exceptionPos = boolPos + 1; 43 final int pcPos = exceptionPos + 1; 44 final int rvPos = pcPos + 1; 45 46 mv.visitCode(); 47 Label l0 = new Label(); 48 Label l1 = new Label(); 49 Label l2 = new Label(); 50 mv.visitTryCatchBlock(l0, l1, l2, null); 51 52 addDistributedCall(mv, methodName, description); 53 mv.visitVarInsn(ISTORE, boolPos); 54 mv.visitLabel(l0); 55 56 mv.visitVarInsn(ALOAD, 0); 58 ByteCodeUtil.pushMethodArguments(access, description, mv); 59 mv.visitMethodInsn(INVOKEVIRTUAL, className.replace('.', '/'), newMethodName, description); 60 final Type rvType = Type.getReturnType(description); 61 final boolean returnVoid = rvType == Type.VOID_TYPE; 62 if (!returnVoid) mv.visitVarInsn(rvType.getOpcode(ISTORE), rvPos); 63 64 Label l4 = new Label(); 65 mv.visitJumpInsn(JSR, l4); 66 mv.visitLabel(l1); 67 if (!returnVoid) mv.visitVarInsn(rvType.getOpcode(ILOAD), rvPos); 68 mv.visitInsn(rvType.getOpcode(IRETURN)); 69 70 mv.visitLabel(l2); 71 mv.visitVarInsn(ASTORE, exceptionPos); 72 mv.visitJumpInsn(JSR, l4); 73 74 mv.visitVarInsn(ALOAD, exceptionPos); 75 mv.visitInsn(ATHROW); 76 mv.visitLabel(l4); 77 mv.visitVarInsn(ASTORE, pcPos); 78 79 mv.visitVarInsn(ILOAD, boolPos); 80 Label l7 = new Label(); 81 mv.visitJumpInsn(IFEQ, l7); 82 managerHelper.callManagerMethod("distributedMethodCallCommit", mv); 83 mv.visitLabel(l7); 84 mv.visitVarInsn(RET, pcPos); 85 mv.visitMaxs(0, 0); 86 mv.visitEnd(); 87 } 88 89 private void addDistributedCall(MethodVisitor mv, String name, String desc) { 90 if (instrumentationLogger.distMethodCallInsertion()) { 91 instrumentationLogger.distMethodCallInserted(className, name, desc); 92 } 93 94 ByteCodeUtil.pushThis(mv); 95 mv.visitLdcInsn(name + desc); 96 ByteCodeUtil.createParametersToArrayByteCode(mv, Type.getArgumentTypes(desc)); 97 final String managerMethodName = (runOnAllNodes) ? "distributedMethodCall" : "prunedDistributedMethodCall"; 98 managerHelper.callManagerMethod(managerMethodName, mv); 99 } 100 101 public boolean doesOriginalNeedAdapting() { 102 return true; 103 } 104 105 public void initialize(ManagerHelper aManagerHelper, int anAccess, String aClassName, String aMethodName, 106 String aOriginalMethodName, String aDescription, String sig, String [] anExceptions, 107 InstrumentationLogger logger) { 108 this.managerHelper = aManagerHelper; 109 this.access = anAccess; 110 this.className = aClassName; 111 this.methodName = aMethodName; 112 this.description = aDescription; 113 this.exceptions = anExceptions; 114 this.instrumentationLogger = logger; 115 this.signature = sig; 116 } 117 118 } 119 | Popular Tags |