KickJava   Java API By Example, From Geeks To Geeks.

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


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

4 package com.tc.object.bytecode;
5
6 import com.tc.asm.ClassAdapter;
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.asm.commons.LocalVariablesSorter;
13 import com.tc.object.lockmanager.api.LockLevel;
14
15 public class DSOUnsafeAdapter extends ClassAdapter implements Opcodes, ClassAdapterFactory {
16
17   public DSOUnsafeAdapter() {
18     super(null);
19   }
20   
21   private DSOUnsafeAdapter(ClassVisitor cv, ClassLoader JavaDoc loader) {
22     super(cv);
23   }
24
25   public ClassAdapter create(ClassVisitor visitor, ClassLoader JavaDoc loader) {
26     return new DSOUnsafeAdapter(visitor, loader);
27   }
28   
29   public final void visit(int version, int access, String JavaDoc name, String JavaDoc signature, String JavaDoc superName, String JavaDoc[] interfaces) {
30     superName = "sun/misc/Unsafe";
31     super.visit(version, access, name, signature, superName, interfaces);
32   }
33
34   public void visitEnd() {
35     MethodVisitor mv = super.visitMethod(ACC_PUBLIC, "compareAndSwapInt", "(Ljava/lang/Object;JII)Z", null, null);
36     addUnsafeWrapperMethodCode(mv, ACC_PUBLIC, "compareAndSwapInt", "(Ljava/lang/Object;JII)Z");
37
38     mv = super.visitMethod(ACC_PUBLIC, "compareAndSwapLong", "(Ljava/lang/Object;JJJ)Z", null, null);
39     addUnsafeWrapperMethodCode(mv, ACC_PUBLIC, "compareAndSwapLong", "(Ljava/lang/Object;JJJ)Z");
40
41
42     mv = super.visitMethod(ACC_PUBLIC, "compareAndSwapObject", "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z", null, null);
43     addUnsafeWrapperMethodCode(mv, ACC_PUBLIC, "compareAndSwapObject", "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z");
44
45     super.visitEnd();
46   }
47
48   private void addBeginVolatileInstrumentedCode(MethodVisitor mv, Type[] params) {
49     int pos = 0;
50     mv.visitVarInsn(params[0].getOpcode(ILOAD), pos+1);
51     pos += params[0].getSize();
52     mv.visitVarInsn(params[1].getOpcode(ILOAD), pos+1);
53     mv.visitIntInsn(BIPUSH, LockLevel.WRITE);
54     mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "beginVolatileByOffset",
55     "(Ljava/lang/Object;JI)V");
56   }
57
58   private void addCommitVolatileInstrumentedCode(MethodVisitor mv, Type[] params) {
59     int pos = 0;
60     mv.visitVarInsn(params[0].getOpcode(ILOAD), pos+1);
61     pos += params[0].getSize();
62     mv.visitVarInsn(params[1].getOpcode(ILOAD), pos+1);
63     mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "commitVolatileByOffset",
64     "(Ljava/lang/Object;J)V");
65   }
66
67   private void addCheckedManagedConditionCode(MethodVisitor mv, Type[] params, int objParamIndex,
68                                               Label nonSharedLabel, Label sharedLabel) {
69     mv.visitVarInsn(params[objParamIndex].getOpcode(ILOAD), objParamIndex + 1);
70     mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "isManaged",
71                        "(Ljava/lang/Object;)Z");
72     mv.visitJumpInsn(IFEQ, nonSharedLabel);
73     mv.visitJumpInsn(GOTO, sharedLabel);
74   }
75
76   private int getParameterPosition(Type[] params, int index) {
77     int pos = 0;
78     for (int i=0; i<index; i++) {
79       pos += params[i].getSize();
80     }
81     return pos;
82   }
83
84   private void addUnsafeWrapperMethodCode(MethodVisitor mv, int access, String JavaDoc methodName, String JavaDoc description) {
85     mv = new FieldMethodAdapter(access, description, mv);
86
87     Type[] params = Type.getArgumentTypes(description);
88     Type returnType = Type.getReturnType(description);
89
90     int newLocalVar1 = ((FieldMethodAdapter)mv).addNewVar(1);
91     int newLocalVar2 = ((FieldMethodAdapter)mv).addNewVar(1);
92     int newLocalVar3 = ((FieldMethodAdapter)mv).addNewVar(1);
93
94     mv.visitCode();
95
96     Label l0 = new Label();
97     Label l1 = new Label();
98     mv.visitTryCatchBlock(l0, l1, l1, null);
99     Label l2 = new Label();
100     Label l3 = new Label();
101     mv.visitTryCatchBlock(l2, l3, l1, null);
102     Label l4 = new Label();
103     mv.visitLabel(l4);
104     Label l5 = new Label();
105     Label l6 = new Label();
106     addCheckedManagedConditionCode(mv, params, 0, l6, l5);
107
108     mv.visitLabel(l6);
109     invokeSuperMethod(mv, methodName, description, params);
110     mv.visitInsn(returnType.getOpcode(IRETURN));
111
112     mv.visitLabel(l5);
113     mv.visitInsn(ICONST_0);
114     mv.visitVarInsn(ISTORE, newLocalVar1);
115
116     Label l7 = new Label();
117     mv.visitLabel(l7);
118     addBeginVolatileInstrumentedCode(mv, params);
119
120     mv.visitLabel(l0);
121     invokeSuperMethod(mv, methodName, description, params);
122     mv.visitVarInsn(ISTORE, newLocalVar1);
123
124     Label l8 = new Label();
125     mv.visitLabel(l8);
126     mv.visitVarInsn(ILOAD, newLocalVar1);
127     mv.visitJumpInsn(IFEQ, l2);
128
129     Label l9 = new Label();
130     mv.visitLabel(l9);
131     mv.visitVarInsn(params[0].getOpcode(ILOAD), getParameterPosition(params, 0)+1);
132     mv.visitVarInsn(params[1].getOpcode(ILOAD), getParameterPosition(params, 1)+1);
133     ByteCodeUtil.addTypeSpecificParameterLoad(mv, params[3], getParameterPosition(params, 3)+1);
134     mv.visitMethodInsn(INVOKESTATIC, "com/tc/util/UnsafeUtil", "updateDSOSharedField", "(Ljava/lang/Object;JLjava/lang/Object;)V");
135     mv.visitJumpInsn(GOTO, l2);
136
137     mv.visitLabel(l1);
138     mv.visitVarInsn(ASTORE, newLocalVar3);
139     Label l10 = new Label();
140     mv.visitJumpInsn(JSR, l10);
141     Label l11 = new Label();
142     mv.visitLabel(l11);
143     mv.visitVarInsn(ALOAD, newLocalVar3);
144     mv.visitInsn(ATHROW);
145     mv.visitLabel(l10);
146     mv.visitVarInsn(ASTORE, newLocalVar2);
147     Label l12 = new Label();
148     mv.visitLabel(l12);
149     addCommitVolatileInstrumentedCode(mv, params);
150     Label l13 = new Label();
151     mv.visitLabel(l13);
152     mv.visitVarInsn(RET, newLocalVar2);
153
154     mv.visitLabel(l2);
155     mv.visitJumpInsn(JSR, l10);
156     mv.visitLabel(l3);
157     mv.visitVarInsn(ILOAD, newLocalVar1);
158     mv.visitInsn(returnType.getOpcode(IRETURN));
159     Label l14 = new Label();
160     mv.visitLabel(l14);
161     mv.visitMaxs(0, 0);
162     mv.visitEnd();
163   }
164
165   protected void addCheckWriteAccessInstrumentedCode(MethodVisitor mv, Type[] params, int objParamIndex) {
166     mv.visitVarInsn(params[objParamIndex].getOpcode(ILOAD), objParamIndex + 1);
167     mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "checkWriteAccess",
168                        "(Ljava/lang/Object;)V");
169   }
170
171   private void invokeSuperMethod(MethodVisitor mv, String JavaDoc methodName, String JavaDoc description, Type[] params) {
172     ByteCodeUtil.pushThis(mv);
173     int pos = 0;
174     for (int i = 0; i < params.length; i++) {
175       mv.visitVarInsn(params[i].getOpcode(ILOAD), pos+1);
176       pos += params[i].getSize();
177     }
178     mv.visitMethodInsn(INVOKESPECIAL, "sun/misc/Unsafe", methodName, description);
179   }
180
181   private class FieldMethodAdapter extends LocalVariablesSorter implements Opcodes {
182     public FieldMethodAdapter(int access, String JavaDoc desc, MethodVisitor mv) {
183       super(access, desc, mv);
184     }
185
186     public int addNewVar(int size) {
187       return newLocal(size);
188     }
189   }
190
191 }
192
Popular Tags