KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > object > bytecode > DistributedMethodCallAdapter


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

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 JavaDoc className;
18   private String JavaDoc methodName;
19   private String JavaDoc description;
20   private String JavaDoc[] exceptions;
21   private String JavaDoc 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 JavaDoc newMethodName = ByteCodeUtil.DMI_METHOD_RENAME_PREFIX + methodName;
33     MethodVisitor codeVisitor = classVisitor.visitMethod(access, newMethodName, description, signature, exceptions);
34     addDmiMethodWrapper(classVisitor, newMethodName);
35     // addDistributedCall(codeVisitor, newMethodName, description);
36
return codeVisitor;
37   }
38
39   private void addDmiMethodWrapper(ClassVisitor classVisitor, String JavaDoc 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     // call the renamed method and store it's return value
57
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 JavaDoc name, String JavaDoc 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 JavaDoc 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 JavaDoc aClassName, String JavaDoc aMethodName,
106                          String JavaDoc aOriginalMethodName, String JavaDoc aDescription, String JavaDoc sig, String JavaDoc[] 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