Source Code Cross Referenced for JavaUtilConcurrentHashMapAdapter.java in  » Net » Terracotta » com » tc » object » bytecode » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Net » Terracotta » com.tc.object.bytecode 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright
0003:         * notice. All rights reserved.
0004:         */
0005:        package com.tc.object.bytecode;
0006:
0007:        import com.tc.asm.ClassAdapter;
0008:        import com.tc.asm.ClassVisitor;
0009:        import com.tc.asm.Label;
0010:        import com.tc.asm.MethodAdapter;
0011:        import com.tc.asm.MethodVisitor;
0012:        import com.tc.asm.Opcodes;
0013:        import com.tc.asm.Type;
0014:        import com.tc.asm.commons.LocalVariablesSorter;
0015:        import com.tc.util.runtime.Vm;
0016:
0017:        public class JavaUtilConcurrentHashMapAdapter extends ClassAdapter
0018:                implements  Opcodes {
0019:            private final static String CONCURRENT_HASH_MAP_SLASH = "java/util/concurrent/ConcurrentHashMap";
0020:            private final static String TC_REHASH_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX
0021:                    + "rehash";
0022:            private final static String TC_REHASH_METHOD_DESC = "()V";
0023:            private final static String TC_CLEAR_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX
0024:                    + "clear";
0025:            private final static String TC_CLEAR_METHOD_DESC = "()V";
0026:            private final static String TC_ORIG_GET_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX
0027:                    + "origGet";
0028:            private final static String TC_ORIG_GET_METHOD_DESC = "(Ljava/lang/Object;)Ljava/lang/Object;";
0029:            private final static String TC_PUT_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX
0030:                    + "put";
0031:            private final static String TC_PUT_METHOD_DESC = "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;";
0032:            private final static String TC_HASH_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX
0033:                    + "hash";
0034:            private final static String TC_HASH_METHOD_DESC = "(Ljava/lang/Object;)I";
0035:            private final static String TC_HASH_METHOD_CHECK_DESC = "(Ljava/lang/Object;Z)I";
0036:            private final static String TC_IS_DSO_HASH_REQUIRED_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX
0037:                    + "isDsoHashRequired";
0038:            private final static String TC_IS_DSO_HASH_REQUIRED_METHOD_DESC = "(Ljava/lang/Object;)Z";
0039:            private final static String TC_FULLY_READLOCK_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX
0040:                    + "fullyReadLock";
0041:            private final static String TC_FULLY_READLOCK_METHOD_DESC = "()V";
0042:            private final static String TC_FULLY_READUNLOCK_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX
0043:                    + "fullyReadUnlock";
0044:            private final static String TC_FULLY_READUNLOCK_METHOD_DESC = "()V";
0045:            private final static String TC_APPLICATOR_PUT_METHOD_NAME = "__tc_applicator_put";
0046:            private final static String TC_APPLICATOR_PUT_METHOD_DESC = "(Ljava/lang/Object;Ljava/lang/Object;)V";
0047:            private final static String TC_APPLICATOR_REMOVE_METHOD_NAME = "__tc_applicator_remove";
0048:            private final static String TC_APPLICATOR_REMOVE_METHOD_DESC = "(Ljava/lang/Object;)V";
0049:            private final static String TC_REMOVE_LOGICAL_METHOD_NAME = "__tc_remove_logical";
0050:            private final static String TC_REMOVE_LOGICAL_METHOD_DESC = "(Ljava/lang/Object;)V";
0051:            private final static String HASH_METHOD_NAME = "hash";
0052:
0053:            public JavaUtilConcurrentHashMapAdapter(ClassVisitor cv) {
0054:                super (cv);
0055:            }
0056:
0057:            /**
0058:             * We need to instrument the size(), isEmpty(), and containsValue() methods because the original implementation in JDK
0059:             * 1.5 has an optimization which uses a volatile variable and does not require locking of the segments. It resorts to
0060:             * locking only after several unsuccessful attempts. For instance, the original implementation of the size() method
0061:             * looks at the count and mod_count volatile variables of each segment and makes sure that there is no update during
0062:             * executing the size() method. If it detects any update while the size() method is being executed, it will resort to
0063:             * locking. Since ConcurrentHashMap is supported logically, it is possible that while the application is obtaining the
0064:             * size of the map while there are still pending updates. Therefore, when ConcurrentHashMap is shared, the
0065:             * instrumented code will always use an locking scheme to make sure all updates are applied before returning the size.
0066:             * The same is true for isEmpty() and containsValue methods().
0067:             */
0068:            public MethodVisitor visitMethod(int access, String name,
0069:                    String desc, String signature, String[] exceptions) {
0070:                if ("size".equals(name) && "()I".equals(desc)) {
0071:                    return addWrapperMethod(access, name, desc, signature,
0072:                            exceptions);
0073:                } else if ("isEmpty".equals(name) && "()Z".equals(desc)) {
0074:                    return addWrapperMethod(access, name, desc, signature,
0075:                            exceptions);
0076:                } else if ("containsValue".equals(name)
0077:                        && "(Ljava/lang/Object;)Z".equals(desc)) {
0078:                    return addWrapperMethod(access, name, desc, signature,
0079:                            exceptions);
0080:                }
0081:
0082:                MethodVisitor mv = super .visitMethod(access, name, desc,
0083:                        signature, exceptions);
0084:                if ("entrySet".equals(name) && "()Ljava/util/Set;".equals(desc)) {
0085:                    return new EntrySetMethodAdapter(mv);
0086:                } else if ("segmentFor".equals(name)
0087:                        && "(I)Ljava/util/concurrent/ConcurrentHashMap$Segment;"
0088:                                .equals(desc)) {
0089:                    return rewriteSegmentForMethod(mv);
0090:                } else if ("get".equals(name)
0091:                        && "(Ljava/lang/Object;)Ljava/lang/Object;"
0092:                                .equals(desc)) {
0093:                    return new MulticastMethodVisitor(new MethodVisitor[] {
0094:                            new OriginalGetMethodAdapter(super .visitMethod(
0095:                                    ACC_SYNTHETIC | ACC_PUBLIC,
0096:                                    TC_ORIG_GET_METHOD_NAME,
0097:                                    TC_ORIG_GET_METHOD_DESC, null, null)),
0098:                            new ConcurrentHashMapMethodAdapter(
0099:                                    new GetMethodAdapter(mv)) });
0100:                }
0101:
0102:                if ("put".equals(name)
0103:                        && "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"
0104:                                .equals(desc)) {
0105:                    mv = new MulticastMethodVisitor(
0106:                            new MethodVisitor[] {
0107:                                    mv,
0108:                                    new ApplicatorPutMethodAdapter(
0109:                                            super 
0110:                                                    .visitMethod(
0111:                                                            ACC_SYNTHETIC
0112:                                                                    | ACC_PUBLIC,
0113:                                                            TC_APPLICATOR_PUT_METHOD_NAME,
0114:                                                            TC_APPLICATOR_PUT_METHOD_DESC,
0115:                                                            null, null)) });
0116:                } else if ("containsKey".equals(name)
0117:                        && "(Ljava/lang/Object;)Z".equals(desc)) {
0118:                    mv = new ContainsKeyMethodAdapter(mv);
0119:                } else if ("remove".equals(name)
0120:                        && "(Ljava/lang/Object;)Ljava/lang/Object;"
0121:                                .equals(desc)) {
0122:                    mv = new MulticastMethodVisitor(
0123:                            new MethodVisitor[] {
0124:                                    new SimpleRemoveMethodAdapter(mv),
0125:                                    new ApplicatorRemoveMethodAdapter(
0126:                                            super 
0127:                                                    .visitMethod(
0128:                                                            ACC_SYNTHETIC
0129:                                                                    | ACC_PUBLIC,
0130:                                                            TC_APPLICATOR_REMOVE_METHOD_NAME,
0131:                                                            TC_APPLICATOR_REMOVE_METHOD_DESC,
0132:                                                            null, null)),
0133:                                    new RemoveLogicalMethodAdapter(
0134:                                            super 
0135:                                                    .visitMethod(
0136:                                                            ACC_SYNTHETIC
0137:                                                                    | ACC_PUBLIC,
0138:                                                            TC_REMOVE_LOGICAL_METHOD_NAME,
0139:                                                            TC_REMOVE_LOGICAL_METHOD_DESC,
0140:                                                            null, null)) });
0141:                } else if ("remove".equals(name)
0142:                        && "(Ljava/lang/Object;Ljava/lang/Object;)Z"
0143:                                .equals(desc)) {
0144:                    mv = new RemoveMethodAdapter(mv);
0145:                } else if ("replace".equals(name)
0146:                        && "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"
0147:                                .equals(desc)) {
0148:                    mv = new SimpleReplaceMethodAdapter(mv);
0149:                } else if ("replace".equals(name)
0150:                        && "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Z"
0151:                                .equals(desc)) {
0152:                    mv = new ReplaceMethodAdapter(mv);
0153:                } else if ("writeObject".equals(name)
0154:                        && "(Ljava/io/ObjectOutputStream;)V".equals(desc)) {
0155:                    mv = new JavaUtilConcurrentHashMapLazyValuesMethodAdapter(
0156:                            access, desc, mv, false);
0157:                }
0158:
0159:                return new ConcurrentHashMapMethodAdapter(mv);
0160:            }
0161:
0162:            public void visitEnd() {
0163:                createTCPutMethod();
0164:                createTCRehashAndSupportMethods();
0165:                createTCFullyReadLockMethod();
0166:                createTCFullyReadUnlockMethod();
0167:
0168:                super .visitEnd();
0169:            }
0170:
0171:            private String getNewName(String methodName) {
0172:                return ByteCodeUtil.TC_METHOD_PREFIX + methodName;
0173:            }
0174:
0175:            private MethodVisitor addWrapperMethod(int access, String name,
0176:                    String desc, String signature, String[] exceptions) {
0177:                createWrapperMethod(access, name, desc, signature, exceptions);
0178:                return new TurnIntoReadLocksMethodAdapter(cv.visitMethod(
0179:                        ACC_PRIVATE, getNewName(name), desc, signature,
0180:                        exceptions));
0181:            }
0182:
0183:            private void createWrapperMethod(int access, String name,
0184:                    String desc, String signature, String[] exceptions) {
0185:                Type[] params = Type.getArgumentTypes(desc);
0186:                Type returnType = Type.getReturnType(desc);
0187:
0188:                LocalVariablesSorter mv = new LocalVariablesSorter(access,
0189:                        desc, cv.visitMethod(access, name, desc, signature,
0190:                                exceptions));
0191:
0192:                mv.visitCode();
0193:                Label l0 = new Label();
0194:                Label l1 = new Label();
0195:                Label l2 = new Label();
0196:                mv.visitTryCatchBlock(l0, l1, l2, null);
0197:
0198:                Label l3 = new Label();
0199:                mv.visitLabel(l3);
0200:                mv.visitVarInsn(ALOAD, 0);
0201:                mv.visitMethodInsn(INVOKESTATIC,
0202:                        "com/tc/object/bytecode/ManagerUtil", "isManaged",
0203:                        "(Ljava/lang/Object;)Z");
0204:                int isManagedVar = mv.newLocal(Type.BOOLEAN_TYPE);
0205:                mv.visitVarInsn(ISTORE, isManagedVar);
0206:                Label l4 = new Label();
0207:                mv.visitLabel(l4);
0208:                mv.visitVarInsn(ILOAD, isManagedVar);
0209:                mv.visitJumpInsn(IFEQ, l0);
0210:                mv.visitVarInsn(ALOAD, 0);
0211:                mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH,
0212:                        TC_FULLY_READLOCK_METHOD_NAME,
0213:                        TC_FULLY_READLOCK_METHOD_DESC);
0214:                mv.visitLabel(l0);
0215:
0216:                mv.visitVarInsn(ALOAD, 0);
0217:                for (int i = 0; i < params.length; i++) {
0218:                    mv.visitVarInsn(params[i].getOpcode(ILOAD), i + 1);
0219:                }
0220:                mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH,
0221:                        getNewName(name), desc);
0222:                int valueVar = mv.newLocal(returnType);
0223:                mv.visitVarInsn(returnType.getOpcode(ISTORE), valueVar);
0224:
0225:                mv.visitLabel(l1);
0226:                mv.visitVarInsn(ILOAD, isManagedVar);
0227:                Label l6 = new Label();
0228:                mv.visitJumpInsn(IFEQ, l6);
0229:                Label l7 = new Label();
0230:                mv.visitLabel(l7);
0231:                mv.visitVarInsn(ALOAD, 0);
0232:                mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH,
0233:                        TC_FULLY_READUNLOCK_METHOD_NAME,
0234:                        TC_FULLY_READUNLOCK_METHOD_DESC);
0235:                mv.visitLabel(l6);
0236:                mv.visitVarInsn(returnType.getOpcode(ILOAD), valueVar);
0237:                mv.visitInsn(returnType.getOpcode(IRETURN));
0238:
0239:                mv.visitLabel(l2);
0240:                int exceptionVar = mv.newLocal(Type
0241:                        .getObjectType("java/lang/Exception"));
0242:                mv.visitVarInsn(ASTORE, exceptionVar);
0243:                mv.visitVarInsn(ILOAD, isManagedVar);
0244:                Label l9 = new Label();
0245:                mv.visitJumpInsn(IFEQ, l9);
0246:                mv.visitVarInsn(ALOAD, 0);
0247:                mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH,
0248:                        TC_FULLY_READUNLOCK_METHOD_NAME,
0249:                        TC_FULLY_READUNLOCK_METHOD_DESC);
0250:                mv.visitLabel(l9);
0251:                mv.visitVarInsn(ALOAD, exceptionVar);
0252:                mv.visitInsn(ATHROW);
0253:                Label l11 = new Label();
0254:                mv.visitLabel(l11);
0255:                mv.visitLocalVariable("this",
0256:                        "Ljava/util/concurrent/ConcurrentHashMap;",
0257:                        "Ljava/util/concurrent/ConcurrentHashMap<TK;TV;>;", l3,
0258:                        l11, 0);
0259:                mv.visitLocalVariable("value", "Ljava/lang/Object;", null, l3,
0260:                        l11, valueVar);
0261:                mv.visitLocalVariable("isManaged", "Z", null, l4, l11,
0262:                        isManagedVar);
0263:                mv.visitMaxs(2, 5);
0264:                mv.visitEnd();
0265:            }
0266:
0267:            private MethodVisitor rewriteSegmentForMethod(MethodVisitor mv) {
0268:                mv.visitCode();
0269:                Label l0 = new Label();
0270:                mv.visitLabel(l0);
0271:                mv.visitVarInsn(ILOAD, 1);
0272:                mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "abs",
0273:                        "(I)I");
0274:                mv.visitVarInsn(ISTORE, 1);
0275:                Label l1 = new Label();
0276:                mv.visitLabel(l1);
0277:                mv.visitVarInsn(ALOAD, 0);
0278:                mv.visitFieldInsn(GETFIELD, CONCURRENT_HASH_MAP_SLASH,
0279:                        "segments",
0280:                        "[Ljava/util/concurrent/ConcurrentHashMap$Segment;");
0281:                mv.visitVarInsn(ILOAD, 1);
0282:                mv.visitVarInsn(ALOAD, 0);
0283:                mv.visitFieldInsn(GETFIELD, CONCURRENT_HASH_MAP_SLASH,
0284:                        "segments",
0285:                        "[Ljava/util/concurrent/ConcurrentHashMap$Segment;");
0286:                mv.visitInsn(ARRAYLENGTH);
0287:                mv.visitInsn(IREM);
0288:                mv.visitInsn(AALOAD);
0289:                mv.visitInsn(ARETURN);
0290:                Label l2 = new Label();
0291:                mv.visitLabel(l2);
0292:                mv.visitMaxs(0, 0);
0293:                mv.visitEnd();
0294:                return null;
0295:            }
0296:
0297:            private void createTCFullyReadLockMethod() {
0298:                MethodVisitor mv = cv.visitMethod(ACC_PRIVATE,
0299:                        TC_FULLY_READLOCK_METHOD_NAME,
0300:                        TC_FULLY_READLOCK_METHOD_DESC, null, null);
0301:                mv.visitCode();
0302:                Label l0 = new Label();
0303:                mv.visitLabel(l0);
0304:                mv.visitVarInsn(ALOAD, 0);
0305:                mv.visitFieldInsn(GETFIELD, CONCURRENT_HASH_MAP_SLASH,
0306:                        "segments",
0307:                        "[Ljava/util/concurrent/ConcurrentHashMap$Segment;");
0308:                mv.visitVarInsn(ASTORE, 1);
0309:                Label l1 = new Label();
0310:                mv.visitLabel(l1);
0311:                mv.visitInsn(ICONST_0);
0312:                mv.visitVarInsn(ISTORE, 2);
0313:                Label l2 = new Label();
0314:                mv.visitLabel(l2);
0315:                Label l3 = new Label();
0316:                mv.visitJumpInsn(GOTO, l3);
0317:                Label l4 = new Label();
0318:                mv.visitLabel(l4);
0319:                mv.visitVarInsn(ALOAD, 1);
0320:                mv.visitVarInsn(ILOAD, 2);
0321:                mv.visitInsn(AALOAD);
0322:                mv
0323:                        .visitMethodInsn(
0324:                                INVOKEVIRTUAL,
0325:                                JavaUtilConcurrentHashMapSegmentAdapter.CONCURRENT_HASH_MAP_SEGMENT_SLASH,
0326:                                JavaUtilConcurrentHashMapSegmentAdapter.TC_READLOCK_METHOD_NAME,
0327:                                JavaUtilConcurrentHashMapSegmentAdapter.TC_READLOCK_METHOD_DESC);
0328:                mv.visitIincInsn(2, 1);
0329:                mv.visitLabel(l3);
0330:                mv.visitVarInsn(ILOAD, 2);
0331:                mv.visitVarInsn(ALOAD, 1);
0332:                mv.visitInsn(ARRAYLENGTH);
0333:                mv.visitJumpInsn(IF_ICMPLT, l4);
0334:                Label l6 = new Label();
0335:                mv.visitLabel(l6);
0336:                mv.visitInsn(RETURN);
0337:                Label l7 = new Label();
0338:                mv.visitLabel(l7);
0339:                mv.visitLocalVariable("this",
0340:                        "Ljava/util/concurrent/ConcurrentHashMap;",
0341:                        "Ljava/util/concurrent/ConcurrentHashMap<TK;TV;>;", l0,
0342:                        l7, 0);
0343:                mv.visitLocalVariable("segments",
0344:                        "[Ljava/util/concurrent/ConcurrentHashMap$Segment;",
0345:                        null, l1, l7, 1);
0346:                mv.visitLocalVariable("i", "I", null, l2, l6, 2);
0347:                mv.visitMaxs(2, 3);
0348:                mv.visitEnd();
0349:            }
0350:
0351:            private void createTCFullyReadUnlockMethod() {
0352:                MethodVisitor mv = cv.visitMethod(ACC_PRIVATE,
0353:                        TC_FULLY_READUNLOCK_METHOD_NAME,
0354:                        TC_FULLY_READUNLOCK_METHOD_DESC, null, null);
0355:                mv.visitCode();
0356:                Label l0 = new Label();
0357:                mv.visitLabel(l0);
0358:                mv.visitVarInsn(ALOAD, 0);
0359:                mv.visitFieldInsn(GETFIELD, CONCURRENT_HASH_MAP_SLASH,
0360:                        "segments",
0361:                        "[Ljava/util/concurrent/ConcurrentHashMap$Segment;");
0362:                mv.visitVarInsn(ASTORE, 1);
0363:                Label l1 = new Label();
0364:                mv.visitLabel(l1);
0365:                mv.visitInsn(ICONST_0);
0366:                mv.visitVarInsn(ISTORE, 2);
0367:                Label l2 = new Label();
0368:                mv.visitLabel(l2);
0369:                Label l3 = new Label();
0370:                mv.visitJumpInsn(GOTO, l3);
0371:                Label l4 = new Label();
0372:                mv.visitLabel(l4);
0373:                mv.visitVarInsn(ALOAD, 1);
0374:                mv.visitVarInsn(ILOAD, 2);
0375:                mv.visitInsn(AALOAD);
0376:                mv
0377:                        .visitMethodInsn(
0378:                                INVOKEVIRTUAL,
0379:                                JavaUtilConcurrentHashMapSegmentAdapter.CONCURRENT_HASH_MAP_SEGMENT_SLASH,
0380:                                JavaUtilConcurrentHashMapSegmentAdapter.TC_READUNLOCK_METHOD_NAME,
0381:                                JavaUtilConcurrentHashMapSegmentAdapter.TC_READUNLOCK_METHOD_DESC);
0382:                mv.visitIincInsn(2, 1);
0383:                mv.visitLabel(l3);
0384:                mv.visitVarInsn(ILOAD, 2);
0385:                mv.visitVarInsn(ALOAD, 1);
0386:                mv.visitInsn(ARRAYLENGTH);
0387:                mv.visitJumpInsn(IF_ICMPLT, l4);
0388:                Label l6 = new Label();
0389:                mv.visitLabel(l6);
0390:                mv.visitInsn(RETURN);
0391:                Label l7 = new Label();
0392:                mv.visitLabel(l7);
0393:                mv.visitLocalVariable("this",
0394:                        "Ljava/util/concurrent/ConcurrentHashMap;",
0395:                        "Ljava/util/concurrent/ConcurrentHashMap<TK;TV;>;", l0,
0396:                        l7, 0);
0397:                mv.visitLocalVariable("segments",
0398:                        "[Ljava/util/concurrent/ConcurrentHashMap$Segment;",
0399:                        null, l1, l7, 1);
0400:                mv.visitLocalVariable("i", "I", null, l2, l6, 2);
0401:                mv.visitMaxs(2, 3);
0402:                mv.visitEnd();
0403:            }
0404:
0405:            private void createTCRehashAndSupportMethods() {
0406:                createTCRehashMethod();
0407:                createTCClearMethod();
0408:            }
0409:
0410:            private void createTCRehashMethod() {
0411:                int access = ACC_PUBLIC + ACC_SYNTHETIC;
0412:                String name = TC_REHASH_METHOD_NAME;
0413:                String desc = TC_REHASH_METHOD_DESC;
0414:                MethodVisitor mv = super .visitMethod(access, name, desc, null,
0415:                        null);
0416:                mv = new JavaUtilConcurrentHashMapLazyValuesMethodAdapter(
0417:                        access, desc, mv, false);
0418:
0419:                mv.visitCode();
0420:                Label l0 = new Label();
0421:                Label l1 = new Label();
0422:                mv.visitTryCatchBlock(l0, l1, l1, "java/lang/Throwable");
0423:                Label l2 = new Label();
0424:                mv.visitTryCatchBlock(l0, l2, l2, null);
0425:                Label l3 = new Label();
0426:                mv.visitLabel(l3);
0427:                mv.visitVarInsn(ALOAD, 0);
0428:                mv.visitMethodInsn(INVOKEVIRTUAL, CONCURRENT_HASH_MAP_SLASH,
0429:                        "size", "()I");
0430:                Label l4 = new Label();
0431:                mv.visitJumpInsn(IFLE, l4);
0432:                mv.visitVarInsn(ALOAD, 0);
0433:                mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH,
0434:                        TC_FULLY_READLOCK_METHOD_NAME,
0435:                        TC_FULLY_READLOCK_METHOD_DESC);
0436:                mv.visitLabel(l0);
0437:                mv.visitTypeInsn(NEW, "java/util/ArrayList");
0438:                mv.visitInsn(DUP);
0439:                mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList",
0440:                        "<init>", "()V");
0441:                mv.visitVarInsn(ASTORE, 1);
0442:                Label l6 = new Label();
0443:                mv.visitLabel(l6);
0444:                mv.visitInsn(ICONST_0);
0445:                mv.visitVarInsn(ISTORE, 2);
0446:                Label l7 = new Label();
0447:                mv.visitLabel(l7);
0448:                Label l8 = new Label();
0449:                mv.visitJumpInsn(GOTO, l8);
0450:                Label l9 = new Label();
0451:                mv.visitLabel(l9);
0452:                mv.visitVarInsn(ALOAD, 0);
0453:                mv.visitFieldInsn(GETFIELD, CONCURRENT_HASH_MAP_SLASH,
0454:                        "segments",
0455:                        "[Ljava/util/concurrent/ConcurrentHashMap$Segment;");
0456:                mv.visitVarInsn(ILOAD, 2);
0457:                mv.visitInsn(AALOAD);
0458:                mv.visitFieldInsn(GETFIELD,
0459:                        "java/util/concurrent/ConcurrentHashMap$Segment",
0460:                        "table",
0461:                        "[Ljava/util/concurrent/ConcurrentHashMap$HashEntry;");
0462:                mv.visitVarInsn(ASTORE, 3);
0463:                Label l10 = new Label();
0464:                mv.visitLabel(l10);
0465:                mv.visitInsn(ICONST_0);
0466:                mv.visitVarInsn(ISTORE, 4);
0467:                Label l11 = new Label();
0468:                mv.visitLabel(l11);
0469:                Label l12 = new Label();
0470:                mv.visitJumpInsn(GOTO, l12);
0471:                Label l13 = new Label();
0472:                mv.visitLabel(l13);
0473:                mv.visitVarInsn(ALOAD, 3);
0474:                mv.visitVarInsn(ILOAD, 4);
0475:                mv.visitInsn(AALOAD);
0476:                Label l14 = new Label();
0477:                mv.visitJumpInsn(IFNULL, l14);
0478:                mv.visitVarInsn(ALOAD, 3);
0479:                mv.visitVarInsn(ILOAD, 4);
0480:                mv.visitInsn(AALOAD);
0481:                mv.visitVarInsn(ASTORE, 5);
0482:                Label l16 = new Label();
0483:                mv.visitLabel(l16);
0484:                Label l17 = new Label();
0485:                mv.visitJumpInsn(GOTO, l17);
0486:                Label l18 = new Label();
0487:                mv.visitLabel(l18);
0488:                mv.visitVarInsn(ALOAD, 1);
0489:                mv.visitVarInsn(ALOAD, 5);
0490:                mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "add",
0491:                        "(Ljava/lang/Object;)Z");
0492:                mv.visitInsn(POP);
0493:                mv.visitVarInsn(ALOAD, 5);
0494:                mv.visitFieldInsn(GETFIELD,
0495:                        "java/util/concurrent/ConcurrentHashMap$HashEntry",
0496:                        "next",
0497:                        "Ljava/util/concurrent/ConcurrentHashMap$HashEntry;");
0498:                mv.visitVarInsn(ASTORE, 5);
0499:                mv.visitLabel(l17);
0500:                mv.visitVarInsn(ALOAD, 5);
0501:                mv.visitJumpInsn(IFNONNULL, l18);
0502:                mv.visitLabel(l14);
0503:                mv.visitIincInsn(4, 1);
0504:                mv.visitLabel(l12);
0505:                mv.visitVarInsn(ILOAD, 4);
0506:                mv.visitVarInsn(ALOAD, 3);
0507:                mv.visitInsn(ARRAYLENGTH);
0508:                mv.visitJumpInsn(IF_ICMPLT, l13);
0509:                Label l20 = new Label();
0510:                mv.visitLabel(l20);
0511:                mv.visitIincInsn(2, 1);
0512:                mv.visitLabel(l8);
0513:                mv.visitVarInsn(ILOAD, 2);
0514:                mv.visitVarInsn(ALOAD, 0);
0515:                mv.visitFieldInsn(GETFIELD, CONCURRENT_HASH_MAP_SLASH,
0516:                        "segments",
0517:                        "[Ljava/util/concurrent/ConcurrentHashMap$Segment;");
0518:                mv.visitInsn(ARRAYLENGTH);
0519:                mv.visitJumpInsn(IF_ICMPLT, l9);
0520:                Label l21 = new Label();
0521:                mv.visitLabel(l21);
0522:                mv.visitVarInsn(ALOAD, 0);
0523:                mv.visitMethodInsn(INVOKEVIRTUAL, CONCURRENT_HASH_MAP_SLASH,
0524:                        "__tc_clear", "()V");
0525:                mv.visitVarInsn(ALOAD, 1);
0526:                mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List",
0527:                        "iterator", "()Ljava/util/Iterator;");
0528:                mv.visitVarInsn(ASTORE, 2);
0529:                Label l23 = new Label();
0530:                mv.visitLabel(l23);
0531:                Label l24 = new Label();
0532:                mv.visitJumpInsn(GOTO, l24);
0533:                Label l25 = new Label();
0534:                mv.visitLabel(l25);
0535:                mv.visitVarInsn(ALOAD, 2);
0536:                mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator",
0537:                        "next", "()Ljava/lang/Object;");
0538:                mv.visitTypeInsn(CHECKCAST,
0539:                        "java/util/concurrent/ConcurrentHashMap$HashEntry");
0540:                mv.visitTypeInsn(CHECKCAST,
0541:                        "java/util/concurrent/ConcurrentHashMap$HashEntry");
0542:                mv.visitVarInsn(ASTORE, 3);
0543:                Label l26 = new Label();
0544:                mv.visitLabel(l26);
0545:                mv.visitVarInsn(ALOAD, 3);
0546:                mv.visitFieldInsn(GETFIELD,
0547:                        "java/util/concurrent/ConcurrentHashMap$HashEntry",
0548:                        "key", "Ljava/lang/Object;");
0549:                mv.visitVarInsn(ASTORE, 4);
0550:                Label l27 = new Label();
0551:                mv.visitLabel(l27);
0552:                mv.visitVarInsn(ALOAD, 3);
0553:                mv.visitFieldInsn(GETFIELD,
0554:                        "java/util/concurrent/ConcurrentHashMap$HashEntry",
0555:                        "value", "Ljava/lang/Object;");
0556:                mv.visitVarInsn(ASTORE, 5);
0557:                Label l28 = new Label();
0558:                mv.visitLabel(l28);
0559:                invokeJdkHashMethod(mv, 4);
0560:                mv.visitVarInsn(ISTORE, 6);
0561:                Label l29 = new Label();
0562:                mv.visitLabel(l29);
0563:                mv.visitVarInsn(ALOAD, 0);
0564:                mv.visitVarInsn(ALOAD, 0);
0565:                mv.visitVarInsn(ALOAD, 4);
0566:                mv.visitInsn(ICONST_0);
0567:                mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH,
0568:                        TC_HASH_METHOD_NAME, TC_HASH_METHOD_CHECK_DESC);
0569:                mv.visitMethodInsn(INVOKEVIRTUAL, CONCURRENT_HASH_MAP_SLASH,
0570:                        "segmentFor",
0571:                        "(I)Ljava/util/concurrent/ConcurrentHashMap$Segment;");
0572:                mv.visitVarInsn(ALOAD, 4);
0573:                mv.visitVarInsn(ILOAD, 6);
0574:                mv.visitVarInsn(ALOAD, 5);
0575:                mv.visitInsn(ICONST_0);
0576:                mv
0577:                        .visitMethodInsn(
0578:                                INVOKEVIRTUAL,
0579:                                "java/util/concurrent/ConcurrentHashMap$Segment",
0580:                                JavaUtilConcurrentHashMapSegmentAdapter.TC_PUT_METHOD_NAME,
0581:                                JavaUtilConcurrentHashMapSegmentAdapter.TC_PUT_METHOD_DESC);
0582:                mv.visitInsn(POP);
0583:                mv.visitLabel(l24);
0584:                mv.visitVarInsn(ALOAD, 2);
0585:                mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator",
0586:                        "hasNext", "()Z");
0587:                mv.visitJumpInsn(IFNE, l25);
0588:                Label l30 = new Label();
0589:                mv.visitLabel(l30);
0590:                Label l31 = new Label();
0591:                mv.visitJumpInsn(GOTO, l31);
0592:                mv.visitLabel(l1);
0593:                mv.visitVarInsn(ASTORE, 1);
0594:                Label l32 = new Label();
0595:                mv.visitLabel(l32);
0596:                mv.visitVarInsn(ALOAD, 1);
0597:                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "err",
0598:                        "Ljava/io/PrintStream;");
0599:                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Throwable",
0600:                        "printStackTrace", "(Ljava/io/PrintStream;)V");
0601:                Label l33 = new Label();
0602:                mv.visitLabel(l33);
0603:                mv.visitJumpInsn(GOTO, l31);
0604:                mv.visitLabel(l2);
0605:                mv.visitVarInsn(ASTORE, 7);
0606:                Label l34 = new Label();
0607:                mv.visitLabel(l34);
0608:                mv.visitVarInsn(ALOAD, 0);
0609:                mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH,
0610:                        TC_FULLY_READUNLOCK_METHOD_NAME,
0611:                        TC_FULLY_READUNLOCK_METHOD_DESC);
0612:                mv.visitVarInsn(ALOAD, 7);
0613:                mv.visitInsn(ATHROW);
0614:                mv.visitLabel(l31);
0615:                mv.visitVarInsn(ALOAD, 0);
0616:                mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH,
0617:                        TC_FULLY_READUNLOCK_METHOD_NAME,
0618:                        TC_FULLY_READUNLOCK_METHOD_DESC);
0619:                mv.visitLabel(l4);
0620:                mv.visitInsn(RETURN);
0621:                Label l36 = new Label();
0622:                mv.visitLabel(l36);
0623:                mv.visitLocalVariable("this",
0624:                        "Ljava/util/concurrent/ConcurrentHashMap;",
0625:                        "Ljava/util/concurrent/ConcurrentHashMap<TK;TV;>;", l3,
0626:                        l36, 0);
0627:                mv.visitLocalVariable("entries", "Ljava/util/List;", null, l6,
0628:                        l1, 1);
0629:                mv.visitLocalVariable("i", "I", null, l7, l21, 2);
0630:                mv.visitLocalVariable("segmentEntries",
0631:                        "[Ljava/util/concurrent/ConcurrentHashMap$HashEntry;",
0632:                        null, l10, l20, 3);
0633:                mv.visitLocalVariable("j", "I", null, l11, l20, 4);
0634:                mv.visitLocalVariable("first",
0635:                        "Ljava/util/concurrent/ConcurrentHashMap$HashEntry;",
0636:                        null, l16, l14, 5);
0637:                mv.visitLocalVariable("i", "Ljava/util/Iterator;", null, l23,
0638:                        l30, 2);
0639:                mv.visitLocalVariable("entry",
0640:                        "Ljava/util/concurrent/ConcurrentHashMap$HashEntry;",
0641:                        null, l26, l24, 3);
0642:                mv.visitLocalVariable("key", "Ljava/lang/Object;", null, l27,
0643:                        l24, 4);
0644:                mv.visitLocalVariable("value", "Ljava/lang/Object;", null, l28,
0645:                        l24, 5);
0646:                mv.visitLocalVariable("hash", "I", null, l29, l24, 6);
0647:                mv.visitLocalVariable("t", "Ljava/lang/Throwable;", null, l32,
0648:                        l33, 1);
0649:                mv.visitMaxs(5, 8);
0650:                mv.visitEnd();
0651:            }
0652:
0653:            private void createTCPutMethod() {
0654:                MethodVisitor mv = super .visitMethod(
0655:                        ACC_PUBLIC + ACC_SYNTHETIC, TC_PUT_METHOD_NAME,
0656:                        TC_PUT_METHOD_DESC, null, null);
0657:                mv.visitCode();
0658:                Label l0 = new Label();
0659:                mv.visitLabel(l0);
0660:                mv.visitVarInsn(ALOAD, 2);
0661:                Label l1 = new Label();
0662:                mv.visitJumpInsn(IFNONNULL, l1);
0663:                mv.visitTypeInsn(NEW, "java/lang/NullPointerException");
0664:                mv.visitInsn(DUP);
0665:                mv.visitMethodInsn(INVOKESPECIAL,
0666:                        "java/lang/NullPointerException", "<init>", "()V");
0667:                mv.visitInsn(ATHROW);
0668:                mv.visitLabel(l1);
0669:                invokeJdkHashMethod(mv, 1);
0670:                mv.visitVarInsn(ISTORE, 3);
0671:                Label l2 = new Label();
0672:                mv.visitLabel(l2);
0673:                mv.visitVarInsn(ALOAD, 0);
0674:                mv.visitVarInsn(ALOAD, 0);
0675:                mv.visitVarInsn(ALOAD, 1);
0676:                mv.visitInsn(ICONST_0);
0677:                mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH,
0678:                        TC_HASH_METHOD_NAME, TC_HASH_METHOD_CHECK_DESC);
0679:                mv.visitMethodInsn(INVOKEVIRTUAL, CONCURRENT_HASH_MAP_SLASH,
0680:                        "segmentFor",
0681:                        "(I)Ljava/util/concurrent/ConcurrentHashMap$Segment;");
0682:                mv.visitVarInsn(ALOAD, 1);
0683:                mv.visitVarInsn(ILOAD, 3);
0684:                mv.visitVarInsn(ALOAD, 2);
0685:                mv.visitInsn(ICONST_0);
0686:                mv
0687:                        .visitMethodInsn(
0688:                                INVOKEVIRTUAL,
0689:                                "java/util/concurrent/ConcurrentHashMap$Segment",
0690:                                JavaUtilConcurrentHashMapSegmentAdapter.TC_PUT_METHOD_NAME,
0691:                                JavaUtilConcurrentHashMapSegmentAdapter.TC_PUT_METHOD_DESC);
0692:                mv.visitInsn(ARETURN);
0693:                Label l3 = new Label();
0694:                mv.visitLabel(l3);
0695:                mv.visitMaxs(0, 0);
0696:                mv.visitEnd();
0697:            }
0698:
0699:            private void createTCClearMethod() {
0700:                MethodVisitor mv = super .visitMethod(ACC_PRIVATE
0701:                        + ACC_SYNTHETIC, TC_CLEAR_METHOD_NAME,
0702:                        TC_CLEAR_METHOD_DESC, null, null);
0703:                mv.visitCode();
0704:                Label l0 = new Label();
0705:                mv.visitLabel(l0);
0706:                mv.visitInsn(ICONST_0);
0707:                mv.visitVarInsn(ISTORE, 1);
0708:                Label l1 = new Label();
0709:                mv.visitLabel(l1);
0710:                Label l2 = new Label();
0711:                mv.visitJumpInsn(GOTO, l2);
0712:                Label l3 = new Label();
0713:                mv.visitLabel(l3);
0714:                mv.visitVarInsn(ALOAD, 0);
0715:                mv.visitFieldInsn(GETFIELD, CONCURRENT_HASH_MAP_SLASH,
0716:                        "segments",
0717:                        "[Ljava/util/concurrent/ConcurrentHashMap$Segment;");
0718:                mv.visitVarInsn(ILOAD, 1);
0719:                mv.visitInsn(AALOAD);
0720:                mv.visitMethodInsn(INVOKEVIRTUAL,
0721:                        "java/util/concurrent/ConcurrentHashMap$Segment",
0722:                        TC_CLEAR_METHOD_NAME, TC_CLEAR_METHOD_DESC);
0723:                Label l4 = new Label();
0724:                mv.visitLabel(l4);
0725:                mv.visitIincInsn(1, 1);
0726:                mv.visitLabel(l2);
0727:                mv.visitVarInsn(ILOAD, 1);
0728:                mv.visitVarInsn(ALOAD, 0);
0729:                mv.visitFieldInsn(GETFIELD, CONCURRENT_HASH_MAP_SLASH,
0730:                        "segments",
0731:                        "[Ljava/util/concurrent/ConcurrentHashMap$Segment;");
0732:                mv.visitInsn(ARRAYLENGTH);
0733:                mv.visitJumpInsn(IF_ICMPLT, l3);
0734:                Label l5 = new Label();
0735:                mv.visitLabel(l5);
0736:                mv.visitInsn(RETURN);
0737:                Label l6 = new Label();
0738:                mv.visitLabel(l6);
0739:                mv.visitMaxs(0, 0);
0740:                mv.visitEnd();
0741:            }
0742:
0743:            private static class EntrySetMethodAdapter extends MethodAdapter
0744:                    implements  Opcodes {
0745:                public EntrySetMethodAdapter(MethodVisitor mv) {
0746:                    super (mv);
0747:                }
0748:
0749:                public void visitMethodInsn(int opcode, String owner,
0750:                        String name, String desc) {
0751:                    super .visitMethodInsn(opcode, owner, name, desc);
0752:
0753:                    if (INVOKESPECIAL == opcode
0754:                            && "java/util/concurrent/ConcurrentHashMap$EntrySet"
0755:                                    .equals(owner)
0756:                            && "<init>".equals(name)
0757:                            && "(Ljava/util/concurrent/ConcurrentHashMap;)V"
0758:                                    .equals(desc)) {
0759:                        mv.visitVarInsn(ASTORE, 1);
0760:                        mv
0761:                                .visitTypeInsn(NEW,
0762:                                        "com/tcclient/util/ConcurrentHashMapEntrySetWrapper");
0763:                        mv.visitInsn(DUP);
0764:                        mv.visitVarInsn(ALOAD, 0);
0765:                        mv.visitVarInsn(ALOAD, 1);
0766:                        mv
0767:                                .visitMethodInsn(
0768:                                        INVOKESPECIAL,
0769:                                        "com/tcclient/util/ConcurrentHashMapEntrySetWrapper",
0770:                                        "<init>",
0771:                                        "(Ljava/util/Map;Ljava/util/Set;)V");
0772:                    }
0773:                }
0774:            }
0775:
0776:            private static class ApplicatorPutMethodAdapter extends
0777:                    MethodAdapter implements  Opcodes {
0778:                public ApplicatorPutMethodAdapter(MethodVisitor mv) {
0779:                    super (mv);
0780:                }
0781:
0782:                public void visitMethodInsn(int opcode, String owner,
0783:                        String name, String desc) {
0784:                    if (INVOKEVIRTUAL == opcode
0785:                            && "java/util/concurrent/ConcurrentHashMap$Segment"
0786:                                    .equals(owner)
0787:                            && "put".equals(name)
0788:                            && JavaUtilConcurrentHashMapSegmentAdapter.TC_ORIG_PUT_METHOD_DESC
0789:                                    .equals(desc)) {
0790:                        // use the un-instrumented version of the segment put method
0791:                        super 
0792:                                .visitMethodInsn(
0793:                                        opcode,
0794:                                        owner,
0795:                                        JavaUtilConcurrentHashMapSegmentAdapter.TC_ORIG_PUT_METHOD_NAME,
0796:                                        desc);
0797:                    } else {
0798:                        super .visitMethodInsn(opcode, owner, name, desc);
0799:                    }
0800:                }
0801:
0802:                public void visitInsn(int opcode) {
0803:                    if (ARETURN == opcode) {
0804:                        // change the old value return to a void return and swallow the normally returned value
0805:                        super .visitInsn(POP);
0806:                        super .visitInsn(RETURN);
0807:                    } else {
0808:                        super .visitInsn(opcode);
0809:                    }
0810:                }
0811:            }
0812:
0813:            private static class OriginalGetMethodAdapter extends MethodAdapter
0814:                    implements  Opcodes {
0815:                public OriginalGetMethodAdapter(MethodVisitor mv) {
0816:                    super (mv);
0817:                }
0818:
0819:                public void visitMethodInsn(int opcode, String owner,
0820:                        String name, String desc) {
0821:                    if (INVOKEVIRTUAL == opcode
0822:                            && "java/util/concurrent/ConcurrentHashMap$Segment"
0823:                                    .equals(owner)
0824:                            && "get".equals(name)
0825:                            && JavaUtilConcurrentHashMapSegmentAdapter.TC_ORIG_GET_METHOD_DESC
0826:                                    .equals(desc)) {
0827:                        // use the un-instrumented version of the segment 'get' method
0828:                        super 
0829:                                .visitMethodInsn(
0830:                                        opcode,
0831:                                        owner,
0832:                                        JavaUtilConcurrentHashMapSegmentAdapter.TC_ORIG_GET_METHOD_NAME,
0833:                                        desc);
0834:                    } else {
0835:                        super .visitMethodInsn(opcode, owner, name, desc);
0836:                    }
0837:                }
0838:            }
0839:
0840:            private static class ApplicatorRemoveMethodAdapter extends
0841:                    MethodAdapter implements  Opcodes {
0842:                public ApplicatorRemoveMethodAdapter(MethodVisitor mv) {
0843:                    super (mv);
0844:                }
0845:
0846:                public void visitMethodInsn(int opcode, String owner,
0847:                        String name, String desc) {
0848:                    if (INVOKEVIRTUAL == opcode
0849:                            && "java/util/concurrent/ConcurrentHashMap$Segment"
0850:                                    .equals(owner)
0851:                            && "remove".equals(name)
0852:                            && JavaUtilConcurrentHashMapSegmentAdapter.TC_ORIG_REMOVE_METHOD_DESC
0853:                                    .equals(desc)) {
0854:                        // use the un-instrumented version of the segment 'remove' method
0855:                        super 
0856:                                .visitMethodInsn(
0857:                                        opcode,
0858:                                        owner,
0859:                                        JavaUtilConcurrentHashMapSegmentAdapter.TC_ORIG_REMOVE_METHOD_NAME,
0860:                                        desc);
0861:                    } else {
0862:                        super .visitMethodInsn(opcode, owner, name, desc);
0863:                    }
0864:                }
0865:
0866:                public void visitInsn(int opcode) {
0867:                    if (ARETURN == opcode) {
0868:                        // change the old value return to a void return and swallow the normally returned value
0869:                        super .visitInsn(POP);
0870:                        super .visitInsn(RETURN);
0871:                    } else {
0872:                        super .visitInsn(opcode);
0873:                    }
0874:                }
0875:            }
0876:
0877:            private static class RemoveLogicalMethodAdapter extends
0878:                    MethodAdapter implements  Opcodes {
0879:                public RemoveLogicalMethodAdapter(MethodVisitor mv) {
0880:                    super (mv);
0881:                }
0882:
0883:                public void visitMethodInsn(int opcode, String owner,
0884:                        String name, String desc) {
0885:                    if (INVOKEVIRTUAL == opcode
0886:                            && "java/util/concurrent/ConcurrentHashMap$Segment"
0887:                                    .equals(owner)
0888:                            && "remove".equals(name)
0889:                            && JavaUtilConcurrentHashMapSegmentAdapter.TC_NULLOLDVALUE_REMOVE_METHOD_DESC
0890:                                    .equals(desc)) {
0891:                        // use the segment remove method that doesn't fault in the old values
0892:                        super 
0893:                                .visitMethodInsn(
0894:                                        opcode,
0895:                                        owner,
0896:                                        JavaUtilConcurrentHashMapSegmentAdapter.TC_NULLOLDVALUE_REMOVE_METHOD_NAME,
0897:                                        desc);
0898:                    } else {
0899:                        super .visitMethodInsn(opcode, owner, name, desc);
0900:                    }
0901:                }
0902:
0903:                public void visitInsn(int opcode) {
0904:                    if (ARETURN == opcode) {
0905:                        // change the old value return to a void return and swallow the normally returned value
0906:                        super .visitInsn(POP);
0907:                        super .visitInsn(RETURN);
0908:                    } else {
0909:                        super .visitInsn(opcode);
0910:                    }
0911:                }
0912:            }
0913:
0914:            private abstract static class AddCheckManagedKeyMethodAdapter
0915:                    extends MethodAdapter implements  Opcodes {
0916:                public AddCheckManagedKeyMethodAdapter(MethodVisitor mv) {
0917:                    super (mv);
0918:                }
0919:
0920:                public void visitCode() {
0921:                    super .visitCode();
0922:                    addCheckManagedKeyCode();
0923:                }
0924:
0925:                protected abstract void addCheckManagedKeyCode();
0926:            }
0927:
0928:            private static class ContainsKeyMethodAdapter extends
0929:                    AddCheckManagedKeyMethodAdapter {
0930:                public ContainsKeyMethodAdapter(MethodVisitor mv) {
0931:                    super (mv);
0932:                }
0933:
0934:                protected void addCheckManagedKeyCode() {
0935:                    mv.visitVarInsn(ALOAD, 0);
0936:                    mv.visitVarInsn(ALOAD, 1);
0937:                    mv.visitMethodInsn(INVOKESPECIAL,
0938:                            CONCURRENT_HASH_MAP_SLASH,
0939:                            TC_IS_DSO_HASH_REQUIRED_METHOD_NAME,
0940:                            TC_IS_DSO_HASH_REQUIRED_METHOD_DESC);
0941:                    Label l1 = new Label();
0942:                    mv.visitJumpInsn(IFNE, l1);
0943:                    Label l2 = new Label();
0944:                    mv.visitLabel(l2);
0945:                    mv.visitInsn(ICONST_0);
0946:                    mv.visitInsn(IRETURN);
0947:                    mv.visitLabel(l1);
0948:                }
0949:            }
0950:
0951:            private static class GetMethodAdapter extends
0952:                    AddCheckManagedKeyMethodAdapter {
0953:                public GetMethodAdapter(MethodVisitor mv) {
0954:                    super (mv);
0955:                }
0956:
0957:                protected void addCheckManagedKeyCode() {
0958:                    mv.visitVarInsn(ALOAD, 0);
0959:                    mv.visitVarInsn(ALOAD, 1);
0960:                    mv.visitMethodInsn(INVOKESPECIAL,
0961:                            CONCURRENT_HASH_MAP_SLASH,
0962:                            TC_IS_DSO_HASH_REQUIRED_METHOD_NAME,
0963:                            TC_IS_DSO_HASH_REQUIRED_METHOD_DESC);
0964:                    Label l1 = new Label();
0965:                    mv.visitJumpInsn(IFNE, l1);
0966:                    Label l2 = new Label();
0967:                    mv.visitLabel(l2);
0968:                    mv.visitInsn(ACONST_NULL);
0969:                    mv.visitInsn(ARETURN);
0970:                    mv.visitLabel(l1);
0971:                }
0972:            }
0973:
0974:            private static class SimpleRemoveMethodAdapter extends
0975:                    GetMethodAdapter {
0976:                public SimpleRemoveMethodAdapter(MethodVisitor mv) {
0977:                    super (mv);
0978:                }
0979:            }
0980:
0981:            private static class SimpleReplaceMethodAdapter extends
0982:                    SimpleRemoveMethodAdapter {
0983:                private Label target;
0984:
0985:                public SimpleReplaceMethodAdapter(MethodVisitor mv) {
0986:                    super (mv);
0987:                }
0988:
0989:                public void visitCode() {
0990:                    mv.visitCode();
0991:                }
0992:
0993:                public void visitJumpInsn(int opcode, Label label) {
0994:                    super .visitJumpInsn(opcode, label);
0995:                    if (IFNONNULL == opcode) {
0996:                        target = label;
0997:                    }
0998:                }
0999:
1000:                public void visitLabel(Label label) {
1001:                    super .visitLabel(label);
1002:                    if (label.equals(target)) {
1003:                        addCheckManagedKeyCode();
1004:                    }
1005:                }
1006:            }
1007:
1008:            private static class RemoveMethodAdapter extends
1009:                    AddCheckManagedKeyMethodAdapter {
1010:                public RemoveMethodAdapter(MethodVisitor mv) {
1011:                    super (mv);
1012:                }
1013:
1014:                protected void addCheckManagedKeyCode() {
1015:                    mv.visitVarInsn(ALOAD, 0);
1016:                    mv.visitVarInsn(ALOAD, 1);
1017:                    mv.visitMethodInsn(INVOKESPECIAL,
1018:                            CONCURRENT_HASH_MAP_SLASH,
1019:                            TC_IS_DSO_HASH_REQUIRED_METHOD_NAME,
1020:                            TC_IS_DSO_HASH_REQUIRED_METHOD_DESC);
1021:                    Label l1 = new Label();
1022:                    mv.visitJumpInsn(IFNE, l1);
1023:                    Label l2 = new Label();
1024:                    mv.visitLabel(l2);
1025:                    mv.visitInsn(ICONST_0);
1026:                    mv.visitInsn(IRETURN);
1027:                    mv.visitLabel(l1);
1028:                }
1029:            }
1030:
1031:            private static class ReplaceMethodAdapter extends
1032:                    RemoveMethodAdapter {
1033:                private Label target;
1034:
1035:                public ReplaceMethodAdapter(MethodVisitor mv) {
1036:                    super (mv);
1037:                }
1038:
1039:                public void visitCode() {
1040:                    mv.visitCode();
1041:                }
1042:
1043:                public void visitJumpInsn(int opcode, Label label) {
1044:                    super .visitJumpInsn(opcode, label);
1045:                    if (IFNONNULL == opcode) {
1046:                        target = label;
1047:                    }
1048:                }
1049:
1050:                public void visitLabel(Label label) {
1051:                    super .visitLabel(label);
1052:                    if (label.equals(target)) {
1053:                        addCheckManagedKeyCode();
1054:                    }
1055:                }
1056:            }
1057:
1058:            private static class ConcurrentHashMapMethodAdapter extends
1059:                    MethodAdapter implements  Opcodes {
1060:
1061:                public ConcurrentHashMapMethodAdapter(MethodVisitor mv) {
1062:                    super (mv);
1063:                }
1064:
1065:                public void visitMethodInsn(int opcode, String owner,
1066:                        String name, String desc) {
1067:                    if (INVOKEVIRTUAL == opcode
1068:                            && CONCURRENT_HASH_MAP_SLASH.equals(owner)
1069:                            && "segmentFor".equals(name)
1070:                            && "(I)Ljava/util/concurrent/ConcurrentHashMap$Segment;"
1071:                                    .equals(desc)) {
1072:                        super .visitInsn(POP);
1073:                        super .visitVarInsn(ALOAD, 0);
1074:                        super .visitVarInsn(ALOAD, 1);
1075:                        super .visitMethodInsn(INVOKEVIRTUAL, owner,
1076:                                TC_HASH_METHOD_NAME, TC_HASH_METHOD_DESC);
1077:                        super .visitMethodInsn(opcode, owner, name, desc);
1078:                    } else if (INVOKESPECIAL == opcode
1079:                            && JavaUtilConcurrentHashMapSegmentAdapter.CONCURRENT_HASH_MAP_SEGMENT_SLASH
1080:                                    .equals(owner) && "<init>".equals(name)
1081:                            && "(IF)V".equals(desc)) {
1082:                        super .visitInsn(POP);
1083:                        super .visitInsn(POP);
1084:                        super .visitVarInsn(ALOAD, 0);
1085:                        super .visitVarInsn(ILOAD, 7);
1086:                        super .visitVarInsn(FLOAD, 2);
1087:                        super 
1088:                                .visitMethodInsn(
1089:                                        opcode,
1090:                                        owner,
1091:                                        name,
1092:                                        JavaUtilConcurrentHashMapSegmentAdapter.INIT_DESC);
1093:                    } else {
1094:                        super .visitMethodInsn(opcode, owner, name, desc);
1095:                    }
1096:                }
1097:            }
1098:
1099:            private static class TurnIntoReadLocksMethodAdapter extends
1100:                    MethodAdapter implements  Opcodes {
1101:
1102:                public TurnIntoReadLocksMethodAdapter(MethodVisitor mv) {
1103:                    super (mv);
1104:                }
1105:
1106:                public void visitMethodInsn(int opcode, String owner,
1107:                        String name, String desc) {
1108:                    if (INVOKEVIRTUAL == opcode
1109:                            && JavaUtilConcurrentHashMapSegmentAdapter.CONCURRENT_HASH_MAP_SEGMENT_SLASH
1110:                                    .equals(owner) && "()V".equals(desc)) {
1111:                        if ("lock".equals(name)) {
1112:                            name = JavaUtilConcurrentHashMapSegmentAdapter.TC_READLOCK_METHOD_NAME;
1113:                        } else if ("unlock".equals(name)) {
1114:                            name = JavaUtilConcurrentHashMapSegmentAdapter.TC_READUNLOCK_METHOD_NAME;
1115:                        }
1116:                    }
1117:
1118:                    super .visitMethodInsn(opcode, owner, name, desc);
1119:                }
1120:            }
1121:
1122:            private void invokeJdkHashMethod(MethodVisitor mv,
1123:                    int objectVarNumber) {
1124:                mv.visitVarInsn(ALOAD, objectVarNumber);
1125:                if (Vm.isJDK16()) {
1126:                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object",
1127:                            "hashCode", "()I");
1128:                    mv.visitMethodInsn(INVOKESTATIC, CONCURRENT_HASH_MAP_SLASH,
1129:                            HASH_METHOD_NAME, "(I)I");
1130:                } else {
1131:                    mv.visitMethodInsn(INVOKESTATIC, CONCURRENT_HASH_MAP_SLASH,
1132:                            HASH_METHOD_NAME, "(Ljava/lang/Object;)I");
1133:                }
1134:            }
1135:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.