KickJava   Java API By Example, From Geeks To Geeks.

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


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
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.config.MethodSpec;
13 import com.tc.object.logging.InstrumentationLogger;
14 import com.tcclient.util.MapEntrySetWrapper;
15 import com.tcclient.util.SortedViewSetWrapper;
16
17 import java.lang.reflect.Modifier JavaDoc;
18
19 /**
20  * Used to create wrappers for logical methods
21  */

22 public class LogicalMethodAdapter implements MethodAdapter, Opcodes {
23   private String JavaDoc ownerSlashes;
24   private String JavaDoc methodName;
25   private String JavaDoc originalMethodName;
26   private ManagerHelper managerHelper;
27   private String JavaDoc description;
28   private int access;
29   private String JavaDoc[] exceptions;
30   private String JavaDoc signature;
31   private int instrumentationType;
32   private int wrapperAccess;
33
34   public LogicalMethodAdapter() {
35     // When using this as a Method creator it doesn't need any of that stuff. yuck :-)
36
}
37
38   public LogicalMethodAdapter(String JavaDoc methodName, int instrumentationType) {
39     this.methodName = methodName;
40     this.instrumentationType = instrumentationType;
41   }
42
43   public void initialize(ManagerHelper aManagerHelper, int anAccess, String JavaDoc aClassName, String JavaDoc aMethodName,
44                          String JavaDoc aOriginalMethodName, String JavaDoc aDescription, String JavaDoc sig, String JavaDoc[] anExceptions,
45                          InstrumentationLogger logger) {
46     this.managerHelper = aManagerHelper;
47     this.ownerSlashes = aClassName.replace('.', '/');
48     this.methodName = aMethodName;
49     this.originalMethodName = aOriginalMethodName;
50     this.description = aDescription;
51     this.wrapperAccess = anAccess & (~Modifier.SYNCHRONIZED); // wrapper method should have synch removed
52
this.access = anAccess;
53     this.exceptions = anExceptions;
54     this.signature = sig;
55   }
56
57   public MethodVisitor adapt(ClassVisitor classVisitor) {
58     createWrapperMethod(classVisitor);
59     return classVisitor.visitMethod(access, getNewName(), description, signature, exceptions);
60   }
61
62   public boolean doesOriginalNeedAdapting() {
63     return true;
64   }
65
66   protected String JavaDoc getNewName() {
67     return ByteCodeUtil.TC_METHOD_PREFIX + methodName;
68   }
69
70   protected void createWrapperMethod(ClassVisitor classVisitor) {
71     switch (instrumentationType) {
72       case MethodSpec.ALWAYS_LOG:
73         createAlwaysLogWrapperMethod(classVisitor, true);
74         break;
75       case MethodSpec.HASHMAP_REMOVE_LOG:
76         createHashMapRemoveWrapperMethod(classVisitor, true);
77         break;
78       case MethodSpec.HASHTABLE_REMOVE_LOG:
79         createHashMapRemoveWrapperMethod(classVisitor, false);
80         break;
81       case MethodSpec.THASH_REMOVE_AT_LOG:
82         createTHashRemoveAtWrapperMethod(classVisitor);
83         break;
84       case MethodSpec.HASHMAP_PUT_LOG:
85         createHashPutWrapperMethod(classVisitor, true);
86         break;
87       case MethodSpec.HASHTABLE_PUT_LOG:
88         createHashPutWrapperMethod(classVisitor, false);
89         break;
90       case MethodSpec.HASHTABLE_CLEAR_LOG:
91         createAlwaysLogWrapperMethod(classVisitor, false);
92         break;
93       case MethodSpec.THASHSET_ADD_LOG:
94         createTHashSetAddWrapperMethod(classVisitor);
95         break;
96       case MethodSpec.THASHMAP_PUT_LOG:
97         createTHashMapPutWrapperMethod(classVisitor);
98         break;
99       case MethodSpec.IF_TRUE_LOG:
100         createIfTrueLogWrapperMethod(classVisitor);
101         break;
102       case MethodSpec.LIST_REMOVE_LOG:
103         createListRemoveWrapperMethod(classVisitor);
104         break;
105       case MethodSpec.SET_ITERATOR_WRAPPER_LOG:
106         createSetIteratorWrapper(classVisitor);
107         break;
108       case MethodSpec.ENTRY_SET_WRAPPER_LOG:
109         createEntrySetWrapper(classVisitor);
110         break;
111       case MethodSpec.KEY_SET_WRAPPER_LOG:
112         createKeySetWrapper(classVisitor);
113         break;
114       case MethodSpec.VALUES_WRAPPER_LOG:
115         createValuesWrapper(classVisitor);
116         break;
117       case MethodSpec.SORTED_SET_VIEW_WRAPPER_LOG:
118         createSortedViewSetWrapper(classVisitor);
119         break;
120       default:
121         throw new AssertionError JavaDoc("illegal instrumentationType:" + instrumentationType);
122     }
123
124   }
125
126   private void createTHashRemoveAtWrapperMethod(ClassVisitor classVisitor) {
127     MethodVisitor mv = classVisitor.visitMethod(wrapperAccess, methodName, description, signature, exceptions);
128     addCheckWriteAccessInstrumentedCode(mv, true);
129     mv.visitInsn(ACONST_NULL);
130     mv.visitVarInsn(ASTORE, 2);
131     ByteCodeUtil.pushThis(mv);
132     mv.visitFieldInsn(GETFIELD, ownerSlashes, "_set", "[Ljava/lang/Object;");
133     mv.visitVarInsn(ILOAD, 1);
134     mv.visitInsn(AALOAD);
135     mv.visitVarInsn(ASTORE, 2);
136     ByteCodeUtil.pushThis(mv);
137     Type[] params = Type.getArgumentTypes(description);
138     for (int i = 0; i < params.length; i++) {
139       mv.visitVarInsn(params[i].getOpcode(ILOAD), i + 1);
140     }
141     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, getNewName(), description);
142
143     ByteCodeUtil.pushThis(mv);
144
145     mv.visitLdcInsn(methodName + description);
146     mv.visitLdcInsn(new Integer JavaDoc(1));
147     mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
148     mv.visitInsn(DUP);
149     mv.visitLdcInsn(new Integer JavaDoc(0));
150     mv.visitVarInsn(ALOAD, 2);
151     mv.visitInsn(AASTORE);
152     managerHelper.callManagerMethod("logicalInvoke", mv);
153
154     mv.visitInsn(RETURN);
155     mv.visitMaxs(0, 0);
156   }
157
158   private void createSortedViewSetWrapper(ClassVisitor classVisitor) {
159     MethodVisitor mv = classVisitor.visitMethod(wrapperAccess, methodName, description, signature, exceptions);
160     mv.visitTypeInsn(NEW, SortedViewSetWrapper.CLASS_SLASH);
161     mv.visitInsn(DUP);
162     ByteCodeUtil.pushThis(mv);
163     ByteCodeUtil.pushThis(mv);
164     Type[] params = Type.getArgumentTypes(description);
165     for (int i = 0; i < params.length; i++) {
166       mv.visitVarInsn(params[i].getOpcode(ILOAD), i + 1);
167     }
168     mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/TreeSet", getNewName(), description);
169     for (int i = 0; i < params.length; i++) {
170       mv.visitVarInsn(params[i].getOpcode(ILOAD), i + 1);
171     }
172     if ("headSet".equals(methodName)) {
173       mv.visitInsn(ICONST_1);
174       mv.visitMethodInsn(INVOKESPECIAL, SortedViewSetWrapper.CLASS_SLASH, "<init>",
175                          "(Ljava/util/SortedSet;Ljava/util/SortedSet;Ljava/lang/Object;Z)V");
176     } else if ("tailSet".equals(methodName)) {
177       mv.visitInsn(ICONST_0);
178       mv.visitMethodInsn(INVOKESPECIAL, SortedViewSetWrapper.CLASS_SLASH, "<init>",
179                          "(Ljava/util/SortedSet;Ljava/util/SortedSet;Ljava/lang/Object;Z)V");
180     } else {
181       mv.visitMethodInsn(INVOKESPECIAL, SortedViewSetWrapper.CLASS_SLASH, "<init>",
182                          "(Ljava/util/SortedSet;Ljava/util/SortedSet;Ljava/lang/Object;Ljava/lang/Object;)V");
183     }
184
185     mv.visitInsn(ARETURN);
186     mv.visitMaxs(0, 0);
187   }
188
189   private void createSetIteratorWrapper(ClassVisitor classVisitor) {
190     MethodVisitor mv = classVisitor.visitMethod(wrapperAccess, methodName, description, signature, exceptions);
191     mv.visitTypeInsn(NEW, "com/tc/util/SetIteratorWrapper");
192     mv.visitInsn(DUP);
193     mv.visitVarInsn(ALOAD, 0);
194     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, getNewName(), "()Ljava/util/Iterator;");
195     mv.visitVarInsn(ALOAD, 0);
196     mv.visitMethodInsn(INVOKESPECIAL, "com/tc/util/SetIteratorWrapper", "<init>",
197                        "(Ljava/util/Iterator;Ljava/util/Set;)V");
198     mv.visitInsn(ARETURN);
199     mv.visitMaxs(0, 0);
200   }
201
202   private void createEntrySetWrapper(ClassVisitor classVisitor) {
203     MethodVisitor mv = classVisitor.visitMethod(wrapperAccess, methodName, description, signature, exceptions);
204     Label l0 = new Label();
205     mv.visitLabel(l0);
206     mv.visitTypeInsn(NEW, MapEntrySetWrapper.CLASS_SLASH);
207     mv.visitInsn(DUP);
208     mv.visitVarInsn(ALOAD, 0);
209     mv.visitInsn(DUP);
210     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, getNewName(), "()Ljava/util/Set;");
211     mv.visitMethodInsn(INVOKESPECIAL, MapEntrySetWrapper.CLASS_SLASH, "<init>", "(Ljava/util/Map;Ljava/util/Set;)V");
212     mv.visitInsn(ARETURN);
213     Label l1 = new Label();
214     mv.visitLabel(l1);
215     mv.visitLocalVariable("this", "Ljava/util/Map;", null, l0, l1, 0);
216     mv.visitMaxs(5, 1);
217   }
218
219   private void createKeySetWrapper(ClassVisitor classVisitor) {
220     MethodVisitor mv = classVisitor.visitMethod(wrapperAccess, methodName, description, signature, exceptions);
221     Label l0 = new Label();
222     mv.visitLabel(l0);
223     mv.visitTypeInsn(NEW, "com/tc/util/THashMapCollectionWrapper");
224     mv.visitInsn(DUP);
225     mv.visitVarInsn(ALOAD, 0);
226     mv.visitInsn(DUP);
227     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, getNewName(), "()Ljava/util/Set;");
228     mv.visitMethodInsn(INVOKESPECIAL, "com/tc/util/THashMapCollectionWrapper", "<init>",
229                        "(Ljava/util/Map;Ljava/util/Collection;)V");
230     mv.visitInsn(ARETURN);
231     Label l1 = new Label();
232     mv.visitLabel(l1);
233     mv.visitLocalVariable("this", "Ljava/util/Map;", null, l0, l1, 0);
234     mv.visitMaxs(5, 1);
235   }
236
237   private void createValuesWrapper(ClassVisitor classVisitor) {
238     MethodVisitor mv = classVisitor.visitMethod(wrapperAccess, methodName, description, signature, exceptions);
239     Label l0 = new Label();
240     mv.visitLabel(l0);
241     mv.visitTypeInsn(NEW, "com/tc/util/THashMapCollectionWrapper");
242     mv.visitInsn(DUP);
243     mv.visitVarInsn(ALOAD, 0);
244     mv.visitInsn(DUP);
245     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, getNewName(), "()Ljava/util/Collection;");
246     mv.visitMethodInsn(INVOKESPECIAL, "com/tc/util/THashMapCollectionWrapper", "<init>",
247                        "(Ljava/util/Map;Ljava/util/Collection;)V");
248     mv.visitInsn(ARETURN);
249     Label l1 = new Label();
250     mv.visitLabel(l1);
251     mv.visitLocalVariable("this", "Ljava/util/Map;", null, l0, l1, 0);
252     mv.visitMaxs(5, 1);
253   }
254
255   private void createListRemoveWrapperMethod(ClassVisitor classVisitor) {
256     MethodVisitor mv = classVisitor.visitMethod(wrapperAccess, methodName, description, signature, exceptions);
257     Type[] params = Type.getArgumentTypes("(Ljava/lang/Object;)");
258     Type returnType = Type.getReturnType(description);
259     // get the index of what is getting removed
260
mv.visitVarInsn(ALOAD, 1);
261     mv.visitFieldInsn(GETFIELD, "java/util/LinkedList$Entry", "element", "Ljava/lang/Object;");
262     Label l2 = new Label();
263     mv.visitJumpInsn(IFNULL, l2);
264     ByteCodeUtil.pushThis(mv);
265     mv.visitLdcInsn(methodName + description);
266     mv.visitLdcInsn(new Integer JavaDoc(params.length));
267     mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
268     mv.visitInsn(DUP);
269     mv.visitLdcInsn(new Integer JavaDoc(0));
270     mv.visitVarInsn(ALOAD, 1);
271     mv.visitFieldInsn(GETFIELD, "java/util/LinkedList$Entry", "element", "Ljava/lang/Object;");
272     mv.visitInsn(AASTORE);
273     managerHelper.callManagerMethod("logicalInvoke", mv);
274     mv.visitLabel(l2);
275     ByteCodeUtil.pushThis(mv);
276     mv.visitVarInsn(ALOAD, 1);
277     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, getNewName(), description);
278     mv.visitInsn(returnType.getOpcode(IRETURN));
279     mv.visitMaxs(0, 0);
280   }
281
282   private void createTHashSetAddWrapperMethod(ClassVisitor classVisitor) {
283     createTHashSetRemoveMethod(classVisitor);
284     MethodVisitor mv = classVisitor.visitMethod(wrapperAccess, methodName, description, signature, exceptions);
285     addCheckWriteAccessInstrumentedCode(mv, true);
286     mv.visitInsn(ACONST_NULL);
287     mv.visitVarInsn(ASTORE, 2);
288
289     ByteCodeUtil.pushThis(mv);
290     mv.visitVarInsn(ALOAD, 1);
291     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, "contains", "(Ljava/lang/Object;)Z");
292     Label l2 = new Label();
293     mv.visitJumpInsn(IFEQ, l2);
294     ByteCodeUtil.pushThis(mv);
295     mv.visitFieldInsn(GETFIELD, ownerSlashes, "_set", "[Ljava/lang/Object;");
296     ByteCodeUtil.pushThis(mv);
297     mv.visitVarInsn(ALOAD, 1);
298     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, "index", "(Ljava/lang/Object;)I");
299     mv.visitInsn(AALOAD);
300     mv.visitVarInsn(ASTORE, 2);
301     mv.visitLabel(l2);
302     ByteCodeUtil.pushThis(mv);
303     Type[] params = Type.getArgumentTypes(description);
304     for (int i = 0; i < params.length; i++) {
305       mv.visitVarInsn(params[i].getOpcode(ILOAD), i + 1);
306     }
307     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, getNewName(), description);
308     Type ret = Type.getReturnType(description);
309     mv.visitVarInsn(ret.getOpcode(ISTORE), 3);
310
311     ByteCodeUtil.pushThis(mv);
312     mv.visitLdcInsn(methodName + description);
313     mv.visitLdcInsn(new Integer JavaDoc(2));
314     mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
315     mv.visitInsn(DUP);
316     int count = 0;
317     mv.visitLdcInsn(new Integer JavaDoc(count++));
318     mv.visitVarInsn(ALOAD, 2);
319     mv.visitInsn(AASTORE);
320
321     mv.visitInsn(DUP);
322     mv.visitLdcInsn(new Integer JavaDoc(count++));
323     mv.visitVarInsn(ALOAD, 1);
324     mv.visitInsn(AASTORE);
325
326     managerHelper.callManagerMethod("logicalInvoke", mv);
327
328     mv.visitVarInsn(ret.getOpcode(ILOAD), 3);
329     mv.visitInsn(ret.getOpcode(IRETURN));
330     mv.visitMaxs(0, 0);
331   }
332
333   private void createTHashSetRemoveMethod(ClassVisitor classVisitor) {
334     MethodVisitor mv = classVisitor.visitMethod(wrapperAccess, "removeAt", "(I)V", null, null);
335     addCheckWriteAccessInstrumentedCode(mv, true);
336     mv.visitInsn(ACONST_NULL);
337     mv.visitVarInsn(ASTORE, 2);
338     ByteCodeUtil.pushThis(mv);
339     mv.visitFieldInsn(GETFIELD, ownerSlashes, "_set", "[Ljava/lang/Object;");
340     mv.visitVarInsn(ILOAD, 1);
341     mv.visitInsn(AALOAD);
342     mv.visitVarInsn(ASTORE, 2);
343     ByteCodeUtil.pushThis(mv);
344     Type[] params = Type.getArgumentTypes("(I)V");
345     for (int i = 0; i < params.length; i++) {
346       mv.visitVarInsn(params[i].getOpcode(ILOAD), i + 1);
347     }
348     mv.visitMethodInsn(INVOKESPECIAL, "gnu/trove/TObjectHash", "removeAt", "(I)V");
349
350     ByteCodeUtil.pushThis(mv);
351
352     mv.visitLdcInsn("removeAt" + "(I)V");
353     mv.visitLdcInsn(new Integer JavaDoc(1));
354     mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
355     mv.visitInsn(DUP);
356     mv.visitLdcInsn(new Integer JavaDoc(0));
357     mv.visitVarInsn(ALOAD, 2);
358     mv.visitInsn(AASTORE);
359     managerHelper.callManagerMethod("logicalInvoke", mv);
360
361     mv.visitInsn(RETURN);
362     mv.visitMaxs(0, 0);
363   }
364
365   private void createTHashMapPutWrapperMethod(ClassVisitor classVisitor) {
366     MethodVisitor mv = classVisitor.visitMethod(wrapperAccess, methodName, description, signature, exceptions);
367     addCheckWriteAccessInstrumentedCode(mv, true);
368     mv.visitInsn(ACONST_NULL);
369     mv.visitVarInsn(ASTORE, 3);
370     ByteCodeUtil.pushThis(mv);
371     mv.visitVarInsn(ALOAD, 1);
372     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, "containsKey", "(Ljava/lang/Object;)Z");
373     Label l2 = new Label();
374     mv.visitJumpInsn(IFEQ, l2);
375     ByteCodeUtil.pushThis(mv);
376     mv.visitFieldInsn(GETFIELD, ownerSlashes, "_set", "[Ljava/lang/Object;");
377     ByteCodeUtil.pushThis(mv);
378     mv.visitVarInsn(ALOAD, 1);
379     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, "index", "(Ljava/lang/Object;)I");
380     mv.visitInsn(AALOAD);
381     mv.visitVarInsn(ASTORE, 3);
382     mv.visitLabel(l2);
383     ByteCodeUtil.pushThis(mv);
384     Type[] params = Type.getArgumentTypes(description);
385     for (int i = 0; i < params.length; i++) {
386       mv.visitVarInsn(params[i].getOpcode(ILOAD), i + 1);
387     }
388     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, getNewName(), description);
389
390     mv.visitVarInsn(ASTORE, 4);
391
392     ByteCodeUtil.pushThis(mv);
393     mv.visitLdcInsn(methodName + description);
394     mv.visitLdcInsn(new Integer JavaDoc(3));
395     mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
396     mv.visitInsn(DUP);
397     int count = 0;
398     mv.visitLdcInsn(new Integer JavaDoc(count++));
399     mv.visitVarInsn(ALOAD, 3);
400     mv.visitInsn(AASTORE);
401
402     mv.visitInsn(DUP);
403     mv.visitLdcInsn(new Integer JavaDoc(count++));
404     mv.visitVarInsn(ALOAD, 1);
405     mv.visitInsn(AASTORE);
406
407     mv.visitInsn(DUP);
408     mv.visitLdcInsn(new Integer JavaDoc(count++));
409     mv.visitVarInsn(ALOAD, 2);
410     mv.visitInsn(AASTORE);
411
412     managerHelper.callManagerMethod("logicalInvoke", mv);
413
414     mv.visitVarInsn(ALOAD, 4);
415     mv.visitInsn(ARETURN);
416     mv.visitMaxs(0, 0);
417   }
418
419   private void createHashPutWrapperMethod(ClassVisitor classVisitor, boolean checkWriteAccessRequired) {
420     MethodVisitor mv = classVisitor.visitMethod(wrapperAccess, methodName, description, signature, exceptions);
421     if (checkWriteAccessRequired) {
422       addCheckWriteAccessInstrumentedCode(mv, true);
423     }
424
425     // run the local put()
426
ByteCodeUtil.pushThis(mv);
427     Type[] params = Type.getArgumentTypes(description);
428     for (int i = 0; i < params.length; i++) {
429       mv.visitVarInsn(params[i].getOpcode(ILOAD), i + 1);
430     }
431     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, getNewName(), description);
432     mv.visitVarInsn(ASTORE, params.length + 1);
433
434     // record the logical action if this map managed
435
Label notManaged = new Label();
436     ByteCodeUtil.pushThis(mv);
437     mv
438         .visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, ClassAdapterBase.MANAGED_METHOD,
439                          "()Lcom/tc/object/TCObject;");
440     mv.visitJumpInsn(IFNULL, notManaged);
441     ByteCodeUtil.pushThis(mv);
442     mv.visitLdcInsn(originalMethodName + description);
443     ByteCodeUtil.pushThis(mv);
444     mv.visitVarInsn(ALOAD, 1);
445     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, "getEntry", "(Ljava/lang/Object;)L" + ownerSlashes + "$Entry;");
446     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes + "$Entry", "getKey", "()Ljava/lang/Object;");
447     mv.visitVarInsn(ASTORE, 1);
448     ByteCodeUtil.createParametersToArrayByteCode(mv, params);
449     managerHelper.callManagerMethod("logicalInvoke", mv);
450
451     mv.visitLabel(notManaged);
452     mv.visitVarInsn(ALOAD, params.length + 1);
453     mv.visitInsn(ARETURN);
454     mv.visitMaxs(0, 0);
455   }
456
457   private void createHashMapRemoveWrapperMethod(ClassVisitor classVisitor, boolean checkWriteAccessRequired) {
458     MethodVisitor mv = classVisitor.visitMethod(wrapperAccess, methodName, description, signature, exceptions);
459     if (checkWriteAccessRequired) {
460       addCheckWriteAccessInstrumentedCode(mv, true);
461     }
462     Type[] params = Type.getArgumentTypes(description);
463     Label l0 = new Label();
464     mv.visitLabel(l0);
465     ByteCodeUtil.pushThis(mv);
466     mv.visitVarInsn(ALOAD, 1);
467     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, "getEntry", "(Ljava/lang/Object;)L" + ownerSlashes + "$Entry;");
468     mv.visitVarInsn(ASTORE, 2);
469     mv.visitVarInsn(ALOAD, 2);
470     Label l2 = new Label();
471     mv.visitJumpInsn(IFNULL, l2);
472     ByteCodeUtil.pushThis(mv);
473     mv.visitLdcInsn(originalMethodName + description);
474     mv.visitVarInsn(ALOAD, 2);
475     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes + "$Entry", "getKey", "()Ljava/lang/Object;");
476     mv.visitVarInsn(ASTORE, 1);
477     ByteCodeUtil.createParametersToArrayByteCode(mv, params);
478     managerHelper.callManagerMethod("logicalInvoke", mv);
479     mv.visitLabel(l2);
480     ByteCodeUtil.pushThis(mv);
481     mv.visitVarInsn(ALOAD, 1);
482     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, getNewName(), description);
483     mv.visitInsn(ARETURN);
484     mv.visitMaxs(0, 0);
485   }
486
487   private void createIfTrueLogWrapperMethod(ClassVisitor classVisitor) {
488     MethodVisitor mv = classVisitor.visitMethod(wrapperAccess, methodName, description, signature, exceptions);
489     addCheckWriteAccessInstrumentedCode(mv, true);
490     Type[] params = Type.getArgumentTypes(description);
491     Type returnType = Type.getReturnType(description);
492     ByteCodeUtil.pushThis(mv);
493     mv.visitVarInsn(ALOAD, 1);
494     mv.visitMethodInsn(INVOKEVIRTUAL, ownerSlashes, getNewName(), description);
495     mv.visitVarInsn(returnType.getOpcode(ISTORE), 2);
496     mv.visitVarInsn(ILOAD, 2);
497     Label l1 = new Label();
498     mv.visitJumpInsn(IFEQ, l1);
499     ByteCodeUtil.pushThis(mv);
500     mv.visitLdcInsn(methodName + description);
501     ByteCodeUtil.createParametersToArrayByteCode(mv, params);
502     managerHelper.callManagerMethod("logicalInvoke", mv);
503     mv.visitLabel(l1);
504     mv.visitVarInsn(returnType.getOpcode(ILOAD), 2);
505     mv.visitInsn(returnType.getOpcode(IRETURN));
506     mv.visitMaxs(0, 0);
507   }
508
509   private void createAlwaysLogWrapperMethod(ClassVisitor classVisitor, boolean checkWriteAccessRequired) {
510     MethodVisitor mv = classVisitor.visitMethod(wrapperAccess, methodName, description, signature, exceptions);
511     if (checkWriteAccessRequired) {
512       addCheckWriteAccessInstrumentedCode(mv, true);
513     }
514     Label l0 = new Label();
515     mv.visitLabel(l0);
516     ByteCodeUtil.pushThis(mv);
517     Type[] params = Type.getArgumentTypes(description);
518     Type returnType = Type.getReturnType(description);
519     for (int i = 0; i < params.length; i++) {
520       mv.visitVarInsn(params[i].getOpcode(ILOAD), i + 1);
521     }
522
523     mv.visitMethodInsn(INVOKESPECIAL, ownerSlashes, getNewName(), description);
524     if (!returnType.equals(Type.VOID_TYPE)) {
525       mv.visitVarInsn(returnType.getOpcode(ISTORE), params.length + 1);
526     }
527     ByteCodeUtil.pushThis(mv);
528     mv.visitLdcInsn(originalMethodName + description);
529
530     ByteCodeUtil.createParametersToArrayByteCode(mv, params);
531     managerHelper.callManagerMethod("logicalInvoke", mv);
532
533     if (!returnType.equals(Type.VOID_TYPE)) {
534       mv.visitVarInsn(returnType.getOpcode(ILOAD), params.length + 1);
535     }
536     mv.visitInsn(returnType.getOpcode(IRETURN));
537     mv.visitMaxs(0, 0);
538   }
539
540   protected void addCheckWriteAccessInstrumentedCode(MethodVisitor mv, boolean checkManaged) {
541     Label notManaged = new Label();
542
543     if (checkManaged) {
544       ByteCodeUtil.pushThis(mv);
545       mv.visitMethodInsn(INVOKEVIRTUAL, getOwnerSlashes(), ClassAdapterBase.MANAGED_METHOD,
546                          "()Lcom/tc/object/TCObject;");
547       mv.visitJumpInsn(IFNULL, notManaged);
548     }
549     ByteCodeUtil.pushThis(mv);
550     managerHelper.callManagerMethod("checkWriteAccess", mv);
551     mv.visitLabel(notManaged);
552   }
553
554   protected int getInstrumentationType() {
555     return instrumentationType;
556   }
557
558   protected int getAccess() {
559     return access;
560   }
561
562   protected String JavaDoc getDescription() {
563     return description;
564   }
565
566   protected String JavaDoc[] getExceptions() {
567     return exceptions;
568   }
569
570   protected ManagerHelper getManagerHelper() {
571     return managerHelper;
572   }
573
574   protected String JavaDoc getMethodName() {
575     return methodName;
576   }
577
578   protected String JavaDoc getOwnerSlashes() {
579     return ownerSlashes;
580   }
581
582   protected String JavaDoc getSignature() {
583     return signature;
584   }
585
586   protected int getWrapperAccess() {
587     return wrapperAccess;
588   }
589   
590   protected String JavaDoc getOriginalMethodName() {
591     return originalMethodName;
592   }
593 }
594
Popular Tags