KickJava   Java API By Example, From Geeks To Geeks.

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


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.ClassAdapter;
8 import com.tc.asm.ClassVisitor;
9 import com.tc.asm.Label;
10 import com.tc.asm.MethodAdapter;
11 import com.tc.asm.MethodVisitor;
12 import com.tc.asm.Opcodes;
13 import com.tc.asm.Type;
14 import com.tc.object.SerializationUtil;
15
16 public class JavaUtilConcurrentHashMapSegmentAdapter extends ClassAdapter implements Opcodes {
17   private static final String JavaDoc PARENT_CONCURRENT_HASH_MAP_FIELD_TYPE = "Ljava/util/concurrent/ConcurrentHashMap;";
18
19   private static final String JavaDoc PARENT_CONCURRENT_HASH_MAP_FIELD_NAME = "parentMap";
20
21   private static final String JavaDoc TC_PUT_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX + "put";
22   private static final String JavaDoc TC_PUT_METHOD_DESC = "(Ljava/lang/Object;ILjava/lang/Object;Z)Ljava/lang/Object;";
23
24   private final static String JavaDoc TC_CLEAR_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX + "clear";
25   private final static String JavaDoc TC_CLEAR_METHOD_DESC = "()V";
26
27   public static final String JavaDoc INITIAL_TABLE_METHOD_NAME = "initTable";
28   private static final String JavaDoc INITIAL_TABLE_METHOD_DESC = "(I)V";
29
30   public final static String JavaDoc CONCURRENT_HASH_MAP_SEGMENT_SLASH = "java/util/concurrent/ConcurrentHashMap$Segment";
31   public final static String JavaDoc INIT_DESC = "(" + PARENT_CONCURRENT_HASH_MAP_FIELD_TYPE
32                                                                       + "IF)V";
33
34   public JavaUtilConcurrentHashMapSegmentAdapter(ClassVisitor cv) {
35     super(cv);
36   }
37
38   public MethodVisitor visitMethod(int access, String JavaDoc name, String JavaDoc desc, String JavaDoc signature, String JavaDoc[] exceptions) {
39     if (("get".equals(name) && "(Ljava/lang/Object;I)Ljava/lang/Object;".equals(desc)) ||
40         ("containsKey".equals(name) && "(Ljava/lang/Object;I)Z".equals(desc))) {
41       return addWrapperMethod(access, name, desc, signature, exceptions);
42     }
43     
44     String JavaDoc description = desc;
45     if ("<init>".equals(name) && "(IF)V".equals(desc)) {
46       description = INIT_DESC;
47     }
48     MethodVisitor mv = super.visitMethod(access, name, description, signature, exceptions);
49
50     if ("put".equals(name) && "(Ljava/lang/Object;ILjava/lang/Object;Z)Ljava/lang/Object;".equals(desc)) {
51       return new PutMethodAdapter(mv);
52     } else if ("clear".equals(name) && "()V".equals(desc)) {
53       return new ClearMethodAdapter(mv);
54     } else if ("remove".equals(name) && "(Ljava/lang/Object;ILjava/lang/Object;)Ljava/lang/Object;".equals(desc)) {
55       return new RemoveMethodAdapter(mv);
56     } else if ("replace".equals(name) && "(Ljava/lang/Object;ILjava/lang/Object;)Ljava/lang/Object;".equals(desc)) {
57       return new ReplaceMethodAdapter(mv);
58     } else if ("replace".equals(name) && "(Ljava/lang/Object;ILjava/lang/Object;Ljava/lang/Object;)Z".equals(desc)) {
59       return new ReplaceIfValueEqualMethodAdapter(mv);
60     } else if ("<init>".equals(name) && "(IF)V".equals(desc)) {
61       return new InitMethodAdapter(mv);
62     } else {
63       return mv;
64     }
65   }
66   
67   private String JavaDoc getNewName(String JavaDoc methodName) {
68     return ByteCodeUtil.TC_METHOD_PREFIX + methodName;
69   }
70   
71   private MethodVisitor addWrapperMethod(int access, String JavaDoc name, String JavaDoc desc, String JavaDoc signature, String JavaDoc[] exceptions) {
72     createWrapperMethod(access, name, desc, signature, exceptions);
73     return cv.visitMethod(ACC_PRIVATE, getNewName(name), desc, signature, exceptions);
74   }
75   
76   private void createWrapperMethod(int access, String JavaDoc name, String JavaDoc desc, String JavaDoc signature, String JavaDoc[] exceptions) {
77     Type[] params = Type.getArgumentTypes(desc);
78     Type returnType = Type.getReturnType(desc);
79
80     MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions);
81     mv.visitCode();
82     Label l0 = new Label();
83     Label l1 = new Label();
84     Label l2 = new Label();
85     mv.visitTryCatchBlock(l0, l1, l2, null);
86     Label l3 = new Label();
87     mv.visitLabel(l3);
88     mv.visitLineNumber(280, l3);
89     mv.visitVarInsn(ALOAD, 0);
90     mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "isManaged", "(Ljava/lang/Object;)Z");
91     mv.visitVarInsn(ISTORE, 3);
92     Label l4 = new Label();
93     mv.visitLabel(l4);
94     mv.visitLineNumber(281, l4);
95     mv.visitVarInsn(ILOAD, 3);
96     mv.visitJumpInsn(IFEQ, l0);
97     mv.visitVarInsn(ALOAD, 0);
98     mv.visitMethodInsn(INVOKEVIRTUAL, CONCURRENT_HASH_MAP_SEGMENT_SLASH, "lock", "()V");
99     mv.visitLabel(l0);
100     mv.visitLineNumber(283, l0);
101     mv.visitVarInsn(ALOAD, 0);
102     for (int i = 0; i < params.length; i++) {
103       mv.visitVarInsn(params[i].getOpcode(ILOAD), i + 1);
104     }
105     mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SEGMENT_SLASH, getNewName(name), desc);
106     mv.visitVarInsn(returnType.getOpcode(ISTORE), 5);
107     mv.visitLabel(l1);
108     mv.visitLineNumber(285, l1);
109     mv.visitVarInsn(ILOAD, 3);
110     Label l5 = new Label();
111     mv.visitJumpInsn(IFEQ, l5);
112     mv.visitVarInsn(ALOAD, 0);
113     mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/concurrent/ConcurrentHashMap$Segment", "unlock", "()V");
114     mv.visitLabel(l5);
115     mv.visitLineNumber(283, l5);
116     mv.visitVarInsn(returnType.getOpcode(ILOAD), 5);
117     mv.visitInsn(returnType.getOpcode(IRETURN));
118     mv.visitLabel(l2);
119     mv.visitLineNumber(284, l2);
120     mv.visitVarInsn(ASTORE, 4);
121     Label l6 = new Label();
122     mv.visitLabel(l6);
123     mv.visitLineNumber(285, l6);
124     mv.visitVarInsn(ILOAD, 3);
125     Label l7 = new Label();
126     mv.visitJumpInsn(IFEQ, l7);
127     mv.visitVarInsn(ALOAD, 0);
128     mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/concurrent/ConcurrentHashMap$Segment", "unlock", "()V");
129     mv.visitLabel(l7);
130     mv.visitLineNumber(286, l7);
131     mv.visitVarInsn(ALOAD, 4);
132     mv.visitInsn(ATHROW);
133     Label l8 = new Label();
134     mv.visitLabel(l8);
135     mv.visitMaxs(0, 0);
136     mv.visitEnd();
137   }
138
139   public void visitEnd() {
140     createDefaultConstructor();
141     createInitTableMethod();
142     createTCPutMethod();
143     createTCClearMethod();
144     super.visitField(ACC_FINAL + ACC_SYNTHETIC, PARENT_CONCURRENT_HASH_MAP_FIELD_NAME,
145                      "Ljava/util/concurrent/ConcurrentHashMap;", null, null);
146     super.visitEnd();
147   }
148
149   private void createDefaultConstructor() {
150     MethodVisitor mv = cv.visitMethod(0, "<init>", "()V", null, null);
151     mv.visitCode();
152     Label l0 = new Label();
153     mv.visitLabel(l0);
154     mv.visitLineNumber(232, l0);
155     mv.visitVarInsn(ALOAD, 0);
156     mv.visitMethodInsn(INVOKESPECIAL, "java/util/concurrent/locks/ReentrantLock", "<init>", "()V");
157     Label l1 = new Label();
158     mv.visitLabel(l1);
159     mv.visitLineNumber(233, l1);
160     mv.visitVarInsn(ALOAD, 0);
161     mv.visitInsn(ICONST_1);
162     mv.visitTypeInsn(ANEWARRAY, "java/util/concurrent/ConcurrentHashMap$HashEntry");
163     mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/concurrent/ConcurrentHashMap$Segment", "setTable",
164                        "([Ljava/util/concurrent/ConcurrentHashMap$HashEntry;)V");
165     Label l2 = new Label();
166     mv.visitLabel(l2);
167     mv.visitLineNumber(234, l2);
168     mv.visitVarInsn(ALOAD, 0);
169     mv.visitInsn(FCONST_0);
170     mv.visitFieldInsn(PUTFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "loadFactor", "F");
171     Label l3 = new Label();
172     mv.visitLabel(l3);
173     mv.visitLineNumber(235, l3);
174     mv.visitVarInsn(ALOAD, 0);
175     mv.visitInsn(ACONST_NULL);
176     mv.visitFieldInsn(PUTFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "parentMap",
177                       "Ljava/util/concurrent/ConcurrentHashMap;");
178     Label l4 = new Label();
179     mv.visitLabel(l4);
180     mv.visitLineNumber(236, l4);
181     mv.visitInsn(RETURN);
182     Label l5 = new Label();
183     mv.visitLabel(l5);
184     mv.visitLocalVariable("this", "Ljava/util/concurrent/ConcurrentHashMap$Segment;",
185                           "Ljava/util/concurrent/ConcurrentHashMap<TK;TV;>.Segment<TK;TV;>;", l0, l5, 0);
186     mv.visitMaxs(2, 1);
187     mv.visitEnd();
188   }
189
190   // This is the identical copy of the put() method of Segments except that it does not lock and does
191
// not invoke the instrumented version of the logicalInvoke(). The reason that it does not require
192
// locking is because it is called from the __tc_rehash() instrumented method and the lock is grabed
193
// at the __tc_rehash() method already.
194
private void createTCPutMethod() {
195     MethodVisitor mv = super.visitMethod(0 + ACC_SYNTHETIC, TC_PUT_METHOD_NAME, TC_PUT_METHOD_DESC, null, null);
196     mv.visitCode();
197     Label l0 = new Label();
198     mv.visitLabel(l0);
199     mv.visitVarInsn(ALOAD, 0);
200     mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "count", "I");
201     mv.visitVarInsn(ISTORE, 5);
202     Label l1 = new Label();
203     mv.visitLabel(l1);
204     mv.visitVarInsn(ILOAD, 5);
205     mv.visitIincInsn(5, 1);
206     mv.visitVarInsn(ALOAD, 0);
207     mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "threshold", "I");
208     Label l2 = new Label();
209     mv.visitJumpInsn(IF_ICMPLE, l2);
210     mv.visitVarInsn(ALOAD, 0);
211     mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/concurrent/ConcurrentHashMap$Segment", "rehash", "()V");
212     mv.visitLabel(l2);
213     mv.visitVarInsn(ALOAD, 0);
214     mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "table",
215                       "[Ljava/util/concurrent/ConcurrentHashMap$HashEntry;");
216     mv.visitVarInsn(ASTORE, 6);
217     Label l3 = new Label();
218     mv.visitLabel(l3);
219     mv.visitVarInsn(ILOAD, 2);
220     mv.visitVarInsn(ALOAD, 6);
221     mv.visitInsn(ARRAYLENGTH);
222     mv.visitInsn(ICONST_1);
223     mv.visitInsn(ISUB);
224     mv.visitInsn(IAND);
225     mv.visitVarInsn(ISTORE, 7);
226     Label l4 = new Label();
227     mv.visitLabel(l4);
228     mv.visitVarInsn(ALOAD, 6);
229     mv.visitVarInsn(ILOAD, 7);
230     mv.visitInsn(AALOAD);
231     mv.visitVarInsn(ASTORE, 8);
232     Label l5 = new Label();
233     mv.visitLabel(l5);
234     mv.visitVarInsn(ALOAD, 8);
235     mv.visitVarInsn(ASTORE, 9);
236     Label l6 = new Label();
237     mv.visitLabel(l6);
238     Label l7 = new Label();
239     mv.visitJumpInsn(GOTO, l7);
240     Label l8 = new Label();
241     mv.visitLabel(l8);
242     mv.visitVarInsn(ALOAD, 9);
243     mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "next",
244                       "Ljava/util/concurrent/ConcurrentHashMap$HashEntry;");
245     mv.visitVarInsn(ASTORE, 9);
246     mv.visitLabel(l7);
247     mv.visitVarInsn(ALOAD, 9);
248     Label l9 = new Label();
249     mv.visitJumpInsn(IFNULL, l9);
250     mv.visitVarInsn(ALOAD, 9);
251     mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "hash", "I");
252     mv.visitVarInsn(ILOAD, 2);
253     mv.visitJumpInsn(IF_ICMPNE, l8);
254     mv.visitVarInsn(ALOAD, 1);
255     mv.visitVarInsn(ALOAD, 9);
256     mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "key", "Ljava/lang/Object;");
257     mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z");
258     mv.visitJumpInsn(IFEQ, l8);
259     mv.visitLabel(l9);
260     mv.visitVarInsn(ALOAD, 9);
261     Label l10 = new Label();
262     mv.visitJumpInsn(IFNULL, l10);
263     Label l11 = new Label();
264     mv.visitLabel(l11);
265     mv.visitVarInsn(ALOAD, 9);
266     mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "value", "Ljava/lang/Object;");
267     mv.visitVarInsn(ASTORE, 10);
268     Label l12 = new Label();
269     mv.visitLabel(l12);
270     mv.visitVarInsn(ILOAD, 4);
271     Label l13 = new Label();
272     mv.visitJumpInsn(IFNE, l13);
273     Label l14 = new Label();
274     mv.visitLabel(l14);
275     mv.visitVarInsn(ALOAD, 9);
276     mv.visitVarInsn(ALOAD, 3);
277     mv.visitFieldInsn(PUTFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "value", "Ljava/lang/Object;");
278     mv.visitJumpInsn(GOTO, l13);
279     mv.visitLabel(l10);
280     mv.visitInsn(ACONST_NULL);
281     mv.visitVarInsn(ASTORE, 10);
282     Label l15 = new Label();
283     mv.visitLabel(l15);
284     mv.visitVarInsn(ALOAD, 0);
285     mv.visitInsn(DUP);
286     mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "modCount", "I");
287     mv.visitInsn(ICONST_1);
288     mv.visitInsn(IADD);
289     mv.visitFieldInsn(PUTFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "modCount", "I");
290     Label l16 = new Label();
291     mv.visitLabel(l16);
292     mv.visitVarInsn(ALOAD, 6);
293     mv.visitVarInsn(ILOAD, 7);
294     mv.visitTypeInsn(NEW, "java/util/concurrent/ConcurrentHashMap$HashEntry");
295     mv.visitInsn(DUP);
296     mv.visitVarInsn(ALOAD, 1);
297     mv.visitVarInsn(ILOAD, 2);
298     mv.visitVarInsn(ALOAD, 8);
299     mv.visitVarInsn(ALOAD, 3);
300     mv.visitMethodInsn(INVOKESPECIAL, "java/util/concurrent/ConcurrentHashMap$HashEntry", "<init>",
301                        "(Ljava/lang/Object;ILjava/util/concurrent/ConcurrentHashMap$HashEntry;Ljava/lang/Object;)V");
302     mv.visitInsn(AASTORE);
303     Label l17 = new Label();
304     mv.visitLabel(l17);
305     mv.visitVarInsn(ALOAD, 0);
306     mv.visitVarInsn(ILOAD, 5);
307     mv.visitFieldInsn(PUTFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "count", "I");
308     mv.visitLabel(l13);
309     mv.visitVarInsn(ALOAD, 10);
310     mv.visitInsn(ARETURN);
311     Label l18 = new Label();
312     mv.visitLabel(l18);
313     mv.visitMaxs(0, 0);
314     mv.visitEnd();
315   }
316
317   // Again, this method does not require lock as it is called by __tc_rehash() which grabs the
318
// lock already.
319
private void createTCClearMethod() {
320     MethodVisitor mv = super.visitMethod(0, TC_CLEAR_METHOD_NAME, TC_CLEAR_METHOD_DESC, null, null);
321     mv.visitCode();
322     Label l0 = new Label();
323     mv.visitLabel(l0);
324     mv.visitVarInsn(ALOAD, 0);
325     mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "count", "I");
326     Label l1 = new Label();
327     mv.visitJumpInsn(IFEQ, l1);
328     Label l2 = new Label();
329     mv.visitLabel(l2);
330     mv.visitVarInsn(ALOAD, 0);
331     mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "table",
332                       "[Ljava/util/concurrent/ConcurrentHashMap$HashEntry;");
333     mv.visitVarInsn(ASTORE, 1);
334     Label l3 = new Label();
335     mv.visitLabel(l3);
336     mv.visitInsn(ICONST_0);
337     mv.visitVarInsn(ISTORE, 2);
338     Label l4 = new Label();
339     mv.visitLabel(l4);
340     Label l5 = new Label();
341     mv.visitJumpInsn(GOTO, l5);
342     Label l6 = new Label();
343     mv.visitLabel(l6);
344     mv.visitVarInsn(ALOAD, 1);
345     mv.visitVarInsn(ILOAD, 2);
346     mv.visitInsn(ACONST_NULL);
347     mv.visitInsn(AASTORE);
348     Label l7 = new Label();
349     mv.visitLabel(l7);
350     mv.visitIincInsn(2, 1);
351     mv.visitLabel(l5);
352     mv.visitVarInsn(ILOAD, 2);
353     mv.visitVarInsn(ALOAD, 1);
354     mv.visitInsn(ARRAYLENGTH);
355     mv.visitJumpInsn(IF_ICMPLT, l6);
356     Label l8 = new Label();
357     mv.visitLabel(l8);
358     mv.visitVarInsn(ALOAD, 0);
359     mv.visitInsn(DUP);
360     mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "modCount", "I");
361     mv.visitInsn(ICONST_1);
362     mv.visitInsn(IADD);
363     mv.visitFieldInsn(PUTFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "modCount", "I");
364     Label l9 = new Label();
365     mv.visitLabel(l9);
366     mv.visitVarInsn(ALOAD, 0);
367     mv.visitInsn(ICONST_0);
368     mv.visitFieldInsn(PUTFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "count", "I");
369     mv.visitLabel(l1);
370     mv.visitInsn(RETURN);
371     Label l10 = new Label();
372     mv.visitLabel(l10);
373     mv.visitMaxs(0, 0);
374     mv.visitEnd();
375   }
376
377   private void createInitTableMethod() {
378     MethodVisitor mv = super.visitMethod(ACC_PRIVATE + ACC_FINAL + ACC_SYNTHETIC, INITIAL_TABLE_METHOD_NAME,
379                                          INITIAL_TABLE_METHOD_DESC, null, null);
380     mv.visitCode();
381     ByteCodeUtil.pushThis(mv);
382     mv.visitVarInsn(ILOAD, 1);
383     mv.visitTypeInsn(ANEWARRAY, "java/util/concurrent/ConcurrentHashMap$HashEntry");
384     mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/concurrent/ConcurrentHashMap$Segment", "setTable",
385                        "([Ljava/util/concurrent/ConcurrentHashMap$HashEntry;)V");
386     mv.visitInsn(RETURN);
387     mv.visitMaxs(0, 0);
388     mv.visitEnd();
389   }
390
391   private static class InitMethodAdapter extends MethodAdapter implements Opcodes {
392     public InitMethodAdapter(MethodVisitor mv) {
393       super(mv);
394     }
395
396     public void visitInsn(int opcode) {
397       if (RETURN == opcode) {
398         // ByteCodeUtil.pushThis(mv);
399
// mv.visitVarInsn(ALOAD, 1);
400
// mv.visitFieldInsn(PUTFIELD, CONCURRENT_HASH_MAP_SEGMENT_SLASH, INITIAL_CAPACITY_FIELD_NAME,
401
// INITIAL_CAPACITY_FIELD_TYPE);
402

403         ByteCodeUtil.pushThis(mv);
404         mv.visitVarInsn(ALOAD, 1);
405         mv.visitFieldInsn(PUTFIELD, "java/util/concurrent/ConcurrentHashMap$Segment",
406                           PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;");
407
408       }
409       super.visitInsn(opcode);
410     }
411
412     public void visitVarInsn(int opcode, int var) {
413       if (var == 1) {
414         var = 2;
415       } else if (var == 2) {
416         var = 3;
417       }
418       super.visitVarInsn(opcode, var);
419     }
420   }
421
422   private static class PutMethodAdapter extends MethodAdapter implements Opcodes {
423
424     public PutMethodAdapter(MethodVisitor mv) {
425       super(mv);
426     }
427
428     public void visitFieldInsn(int opcode, String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
429       super.visitFieldInsn(opcode, owner, name, desc);
430       if (PUTFIELD == opcode && "java/util/concurrent/ConcurrentHashMap$HashEntry".equals(owner)
431           && "value".equals(name) && "Ljava/lang/Object;".equals(desc)) {
432         addFoundLogicalInvokePutMethodCall();
433       } else if (PUTFIELD == opcode && "java/util/concurrent/ConcurrentHashMap$Segment".equals(owner)
434                  && "count".equals(name) && "I".equals(desc)) {
435         addNotFoundLogicalInvokePutMethodCall();
436       }
437     }
438
439     private void addNotFoundLogicalInvokePutMethodCall() {
440       Label endBlock = new Label();
441       Label logicalInvokeLabel = new Label();
442
443       mv.visitLabel(logicalInvokeLabel);
444
445       ByteCodeUtil.pushThis(mv);
446       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment",
447                         PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;");
448       mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "isManaged", "(Ljava/lang/Object;)Z");
449       mv.visitJumpInsn(IFEQ, endBlock);
450       mv.visitVarInsn(ILOAD, 4);
451       Label l0 = new Label();
452       mv.visitJumpInsn(IFEQ, l0);
453       ByteCodeUtil.pushThis(mv);
454       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment",
455                         PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;");
456       mv.visitLdcInsn(SerializationUtil.PUT_SIGNATURE);
457       mv.visitInsn(ICONST_2);
458       mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
459       mv.visitInsn(DUP);
460       mv.visitInsn(ICONST_0);
461       mv.visitVarInsn(ALOAD, 1);
462       mv.visitInsn(AASTORE);
463       mv.visitInsn(DUP);
464       mv.visitInsn(ICONST_1);
465       mv.visitVarInsn(ALOAD, 3);
466       mv.visitInsn(AASTORE);
467       mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "logicalInvoke",
468                          "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V");
469       mv.visitJumpInsn(GOTO, endBlock);
470       mv.visitLabel(l0);
471       ByteCodeUtil.pushThis(mv);
472       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment",
473                         PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;");
474       mv.visitLdcInsn(SerializationUtil.PUT_SIGNATURE);
475       mv.visitInsn(ICONST_2);
476       mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
477       mv.visitInsn(DUP);
478       mv.visitInsn(ICONST_0);
479       mv.visitVarInsn(ALOAD, 1);
480       mv.visitInsn(AASTORE);
481       mv.visitInsn(DUP);
482       mv.visitInsn(ICONST_1);
483       mv.visitVarInsn(ALOAD, 3);
484       mv.visitInsn(AASTORE);
485       mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "logicalInvoke",
486                          "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V");
487       mv.visitLabel(endBlock);
488     }
489
490     private void addFoundLogicalInvokePutMethodCall() {
491       Label notManaged = new Label();
492       Label logicalInvokeLabel = new Label();
493
494       mv.visitLabel(logicalInvokeLabel);
495
496       ByteCodeUtil.pushThis(mv);
497       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment",
498                         PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;");
499       mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "isManaged", "(Ljava/lang/Object;)Z");
500       mv.visitJumpInsn(IFEQ, notManaged);
501       ByteCodeUtil.pushThis(mv);
502       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment",
503                         PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;");
504       mv.visitLdcInsn(SerializationUtil.PUT_SIGNATURE);
505       mv.visitInsn(ICONST_2);
506       mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
507       mv.visitInsn(DUP);
508       mv.visitInsn(ICONST_0);
509       mv.visitVarInsn(ALOAD, 9);
510       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "key", "Ljava/lang/Object;");
511       mv.visitInsn(AASTORE);
512       mv.visitInsn(DUP);
513       mv.visitInsn(ICONST_1);
514       mv.visitVarInsn(ALOAD, 3);
515       mv.visitInsn(AASTORE);
516       mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "logicalInvoke",
517                          "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V");
518       mv.visitLabel(notManaged);
519     }
520   }
521
522   private static class ReplaceMethodAdapter extends MethodAdapter implements Opcodes {
523
524     public ReplaceMethodAdapter(MethodVisitor mv) {
525       super(mv);
526     }
527
528     public void visitFieldInsn(int opcode, String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
529       super.visitFieldInsn(opcode, owner, name, desc);
530       if (PUTFIELD == opcode && "java/util/concurrent/ConcurrentHashMap$HashEntry".equals(owner)
531           && "value".equals(name) && "Ljava/lang/Object;".equals(desc)) {
532         addLogicalInvokeReplaceMethodCall();
533       }
534     }
535
536     public void addLogicalInvokeReplaceMethodCall() {
537       Label notManaged = new Label();
538       ByteCodeUtil.pushThis(this);
539       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment",
540                         PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;");
541       mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "isManaged", "(Ljava/lang/Object;)Z");
542       mv.visitJumpInsn(IFEQ, notManaged);
543       mv.visitVarInsn(ALOAD, 0);
544       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment",
545                         PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;");
546       mv.visitLdcInsn(SerializationUtil.PUT_SIGNATURE);
547       mv.visitInsn(ICONST_2);
548       mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
549       mv.visitInsn(DUP);
550       mv.visitInsn(ICONST_0);
551       mv.visitVarInsn(ALOAD, 4);
552       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "key", "Ljava/lang/Object;");
553       mv.visitInsn(AASTORE);
554       mv.visitInsn(DUP);
555       mv.visitInsn(ICONST_1);
556       mv.visitVarInsn(ALOAD, 3);
557       mv.visitInsn(AASTORE);
558       mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "logicalInvoke",
559                          "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V");
560       mv.visitLabel(notManaged);
561     }
562   }
563
564   private static class ReplaceIfValueEqualMethodAdapter extends MethodAdapter implements Opcodes {
565
566     public ReplaceIfValueEqualMethodAdapter(MethodVisitor mv) {
567       super(mv);
568     }
569
570     public void visitFieldInsn(int opcode, String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
571       if (PUTFIELD == opcode && "java/util/concurrent/ConcurrentHashMap$HashEntry".equals(owner)
572           && "value".equals(name) && "Ljava/lang/Object;".equals(desc)) {
573         addLogicalInvokeReplaceMethodCall();
574       }
575       super.visitFieldInsn(opcode, owner, name, desc);
576     }
577
578     public void addLogicalInvokeReplaceMethodCall() {
579       Label notManaged = new Label();
580       ByteCodeUtil.pushThis(mv);
581       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment",
582                         PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;");
583       mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "isManaged", "(Ljava/lang/Object;)Z");
584       mv.visitJumpInsn(IFEQ, notManaged);
585       ByteCodeUtil.pushThis(mv);
586       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment",
587                         PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;");
588       mv.visitLdcInsn(SerializationUtil.PUT_SIGNATURE);
589       mv.visitInsn(ICONST_2);
590       mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
591       mv.visitInsn(DUP);
592       mv.visitInsn(ICONST_0);
593       mv.visitVarInsn(ALOAD, 5);
594       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "key", "Ljava/lang/Object;");
595       mv.visitInsn(AASTORE);
596       mv.visitInsn(DUP);
597       mv.visitInsn(ICONST_1);
598       mv.visitVarInsn(ALOAD, 4);
599       mv.visitInsn(AASTORE);
600       mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "logicalInvoke",
601                          "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V");
602       mv.visitLabel(notManaged);
603     }
604   }
605
606   private static class RemoveMethodAdapter extends MethodAdapter implements Opcodes {
607
608     public RemoveMethodAdapter(MethodVisitor mv) {
609       super(mv);
610     }
611
612     /*
613      * public void visitCode() { super.visitCode(); Label l0 = new Label(); mv.visitFieldInsn(GETSTATIC,
614      * "com/tc/util/DebugUtil", "DEBUG", "Z"); mv.visitJumpInsn(IFEQ, l0); Label l5 = new Label(); mv.visitLabel(l5);
615      * mv.visitLineNumber(479, l5); mv.visitFieldInsn(GETSTATIC, "java/lang/System", "err", "Ljava/io/PrintStream;");
616      * mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); mv.visitInsn(DUP); mv.visitLdcInsn("Segment.remove: client id:
617      * "); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V");
618      * mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "getClientID", "()Ljava/lang/String;");
619      * mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
620      * "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); mv.visitLdcInsn(", key: "); mv.visitMethodInsn(INVOKEVIRTUAL,
621      * "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); mv.visitVarInsn(ALOAD, 1);
622      * mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
623      * "(Ljava/lang/Object;)Ljava/lang/StringBuilder;"); mv.visitLdcInsn(", hash: "); mv.visitMethodInsn(INVOKEVIRTUAL,
624      * "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); Label l6 = new Label();
625      * mv.visitLabel(l6); mv.visitLineNumber(480, l6); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn(INVOKEVIRTUAL,
626      * "java/lang/StringBuilder", "append", "(I)Ljava/lang/StringBuilder;"); mv.visitMethodInsn(INVOKEVIRTUAL,
627      * "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); Label l7 = new Label(); mv.visitLabel(l7);
628      * mv.visitLineNumber(479, l7); mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println",
629      * "(Ljava/lang/String;)V"); mv.visitLabel(l0); }
630      */

631     public void visitFieldInsn(int opcode, String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
632       super.visitFieldInsn(opcode, owner, name, desc);
633       if (PUTFIELD == opcode && "java/util/concurrent/ConcurrentHashMap$Segment".equals(owner) && "count".equals(name)
634           && "I".equals(desc)) {
635         addLogicalInvokeRemoveMethodCall();
636       }
637     }
638
639     public void addLogicalInvokeRemoveMethodCall() {
640       Label notManaged = new Label();
641       Label logicalInvokeLabel = new Label();
642
643       mv.visitLabel(logicalInvokeLabel);
644
645       ByteCodeUtil.pushThis(mv);
646       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment",
647                         PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;");
648       mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "isManaged", "(Ljava/lang/Object;)Z");
649       mv.visitJumpInsn(IFEQ, notManaged);
650       mv.visitVarInsn(ALOAD, 0);
651       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment",
652                         PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;");
653       mv.visitLdcInsn(SerializationUtil.REMOVE_SIGNATURE);
654       mv.visitInsn(ICONST_1);
655       mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
656       mv.visitInsn(DUP);
657       mv.visitInsn(ICONST_0);
658       mv.visitVarInsn(ALOAD, 8);
659       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "key", "Ljava/lang/Object;");
660       mv.visitInsn(AASTORE);
661       mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "logicalInvoke",
662                          "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V");
663       mv.visitLabel(notManaged);
664     }
665   }
666
667   private static class ClearMethodAdapter extends MethodAdapter implements Opcodes {
668
669     public ClearMethodAdapter(MethodVisitor mv) {
670       super(mv);
671     }
672
673     public void visitMethodInsn(int opcode, String JavaDoc owner, String JavaDoc name, String JavaDoc desc) {
674       super.visitMethodInsn(opcode, owner, name, desc);
675       if ("lock".equals(name) && "()V".equals(desc)) {
676         addLogicalInvokeMethodCall();
677       }
678     }
679
680     public void addLogicalInvokeMethodCall() {
681       ByteCodeUtil.pushThis(mv);
682       mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment",
683                         PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;");
684       mv.visitLdcInsn(SerializationUtil.CLEAR_SIGNATURE);
685
686       mv.visitLdcInsn(new Integer JavaDoc(0));
687       mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
688
689       mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "logicalInvoke",
690                          "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V");
691     }
692   }
693 }
Popular Tags