1 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.asm.commons.LocalVariablesSorter; 15 import com.tc.util.runtime.Vm; 16 17 public class JavaUtilConcurrentHashMapAdapter extends ClassAdapter implements Opcodes { 18 private final static String CONCURRENT_HASH_MAP_SLASH = "java/util/concurrent/ConcurrentHashMap"; 19 private final static String TC_HASH_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX + "hash"; 20 private final static String TC_HASH_METHOD_DESC = "(Ljava/lang/Object;)I"; 21 private final static String TC_HASH_METHOD_CHECK_DESC = "(Ljava/lang/Object;Z)I"; 22 private final static String TC_REHASH_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX + "rehash"; 23 private final static String TC_REHASH_METHOD_DESC = "()V"; 24 private final static String TC_CLEAR_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX + "clear"; 25 private final static String TC_CLEAR_METHOD_DESC = "()V"; 26 private final static String TC_PUT_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX + "put"; 27 private final static String TC_PUT_METHOD_DESC = "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; 28 private final static String SEGMENT_TC_PUT_METHOD_DESC = "(Ljava/lang/Object;ILjava/lang/Object;Z)Ljava/lang/Object;"; 29 private final static String TC_IS_DSO_HASH_REQUIRED_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX + "isDsoHashRequired"; 30 private final static String TC_IS_DSO_HASH_REQUIRED_METHOD_DESC = "(Ljava/lang/Object;)Z"; 31 private final static String TC_FULLY_LOCK_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX + "fullyLock"; 32 private final static String TC_FULLY_LOCK_METHOD_DESC = "()V"; 33 private final static String TC_FULLY_UNLOCK_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX + "fullyUnLock"; 34 private final static String TC_FULLY_UNLOCK_METHOD_DESC = "()V"; 35 private final static String HASH_METHOD_NAME = "hash"; 36 37 public JavaUtilConcurrentHashMapAdapter(ClassVisitor cv) { 38 super(cv); 39 } 40 41 52 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String [] exceptions) { 53 if ("size".equals(name) && "()I".equals(desc)) { 54 return addWrapperMethod(access, name, desc, signature, exceptions); 55 } else if ("isEmpty".equals(name) && "()Z".equals(desc)) { 56 return addWrapperMethod(access, name, desc, signature, exceptions); 57 } else if ("containsValue".equals(name) && "(Ljava/lang/Object;)Z".equals(desc)) { return addWrapperMethod( 58 access, 59 name, 60 desc, 61 signature, 62 exceptions); } 63 64 MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); 65 if ("entrySet".equals(name) && "()Ljava/util/Set;".equals(desc)) { 66 return new EntrySetMethodAdapter(mv); 67 } else if ("segmentFor".equals(name) && "(I)Ljava/util/concurrent/ConcurrentHashMap$Segment;".equals(desc)) { 68 rewriteSegmentForMethod(mv); 69 } else if ("containsKey".equals(name) && "(Ljava/lang/Object;)Z".equals(desc)) { 70 mv = new ContainsKeyMethodAdapter(mv); 71 } else if ("get".equals(name) && "(Ljava/lang/Object;)Ljava/lang/Object;".equals(desc)) { 72 mv = new GetMethodAdapter(mv); 73 } else if ("remove".equals(name) && "(Ljava/lang/Object;)Ljava/lang/Object;".equals(desc)) { 74 mv = new SimpleRemoveMethodAdapter(mv); 75 } else if ("remove".equals(name) && "(Ljava/lang/Object;Ljava/lang/Object;)Z".equals(desc)) { 76 mv = new RemoveMethodAdapter(mv); 77 } else if ("replace".equals(name) && "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;".equals(desc)) { 78 mv = new SimpleReplaceMethodAdapter(mv); 79 } else if ("replace".equals(name) && "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Z".equals(desc)) { 80 mv = new ReplaceMethodAdapter(mv); 81 } 82 83 return new ConcurrentHashMapMethodAdapter(access, desc, mv); 84 } 85 86 public void visitEnd() { 87 createTCPutMethod(); 88 createTCSharedHashMethod(); 89 createTCForcedHashMethod(); 90 createTCDsoRequiredMethod(); 91 createTCRehashAndSupportMethods(); 92 createTCFullyLockMethod(); 93 createTCFullyUnLockMethod(); 94 super.visitEnd(); 95 } 96 97 private String getNewName(String methodName) { 98 return ByteCodeUtil.TC_METHOD_PREFIX + methodName; 99 } 100 101 private MethodVisitor addWrapperMethod(int access, String name, String desc, String signature, String [] exceptions) { 102 createWrapperMethod(access, name, desc, signature, exceptions); 103 return cv.visitMethod(ACC_PRIVATE, getNewName(name), desc, signature, exceptions); 104 } 105 106 private void createWrapperMethod(int access, String name, String desc, String signature, String [] exceptions) { 107 Type[] params = Type.getArgumentTypes(desc); 108 Type returnType = Type.getReturnType(desc); 109 110 MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); 111 mv.visitCode(); 112 Label l0 = new Label(); 113 Label l1 = new Label(); 114 Label l2 = new Label(); 115 mv.visitTryCatchBlock(l0, l1, l2, null); 116 Label l3 = new Label(); 117 mv.visitLabel(l3); 118 mv.visitLineNumber(805, l3); 119 mv.visitVarInsn(ALOAD, 0); 120 mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "isManaged", "(Ljava/lang/Object;)Z"); 121 mv.visitVarInsn(ISTORE, 2); 122 Label l4 = new Label(); 123 mv.visitLabel(l4); 124 mv.visitLineNumber(806, l4); 125 mv.visitVarInsn(ILOAD, 2); 126 mv.visitJumpInsn(IFEQ, l0); 127 Label l5 = new Label(); 128 mv.visitLabel(l5); 129 mv.visitLineNumber(807, l5); 130 mv.visitVarInsn(ALOAD, 0); 131 mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH, TC_FULLY_LOCK_METHOD_NAME, TC_FULLY_LOCK_METHOD_DESC); 132 mv.visitLabel(l0); 133 mv.visitLineNumber(810, l0); 134 mv.visitVarInsn(ALOAD, 0); 135 for (int i = 0; i < params.length; i++) { 136 mv.visitVarInsn(params[i].getOpcode(ILOAD), i + 1); 137 } 138 mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH, getNewName(name), desc); 139 mv.visitVarInsn(returnType.getOpcode(ISTORE), 4); 140 mv.visitLabel(l1); 141 mv.visitLineNumber(812, l1); 142 mv.visitVarInsn(ILOAD, 2); 143 Label l6 = new Label(); 144 mv.visitJumpInsn(IFEQ, l6); 145 Label l7 = new Label(); 146 mv.visitLabel(l7); 147 mv.visitLineNumber(813, l7); 148 mv.visitVarInsn(ALOAD, 0); 149 mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH, TC_FULLY_UNLOCK_METHOD_NAME, 150 TC_FULLY_UNLOCK_METHOD_DESC); 151 mv.visitLabel(l6); 152 mv.visitLineNumber(810, l6); 153 mv.visitVarInsn(returnType.getOpcode(ILOAD), 4); 154 mv.visitInsn(returnType.getOpcode(IRETURN)); 155 mv.visitLabel(l2); 156 mv.visitLineNumber(811, l2); 157 mv.visitVarInsn(ASTORE, 3); 158 Label l8 = new Label(); 159 mv.visitLabel(l8); 160 mv.visitLineNumber(812, l8); 161 mv.visitVarInsn(ILOAD, 2); 162 Label l9 = new Label(); 163 mv.visitJumpInsn(IFEQ, l9); 164 Label l10 = new Label(); 165 mv.visitLabel(l10); 166 mv.visitLineNumber(813, l10); 167 mv.visitVarInsn(ALOAD, 0); 168 mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH, TC_FULLY_UNLOCK_METHOD_NAME, 169 TC_FULLY_UNLOCK_METHOD_DESC); 170 mv.visitLabel(l9); 171 mv.visitLineNumber(815, l9); 172 mv.visitVarInsn(ALOAD, 3); 173 mv.visitInsn(ATHROW); 174 Label l11 = new Label(); 175 mv.visitLabel(l11); 176 mv.visitLocalVariable("this", "Ljava/util/concurrent/ConcurrentHashMap;", 177 "Ljava/util/concurrent/ConcurrentHashMap<TK;TV;>;", l3, l11, 0); 178 mv.visitLocalVariable("value", "Ljava/lang/Object;", null, l3, l11, 1); 179 mv.visitLocalVariable("isManaged", "Z", null, l4, l11, 2); 180 mv.visitMaxs(2, 5); 181 mv.visitEnd(); 182 } 183 184 private void rewriteSegmentForMethod(MethodVisitor mv) { 185 mv.visitCode(); 186 Label l0 = new Label(); 187 mv.visitLabel(l0); 188 mv.visitVarInsn(ILOAD, 1); 189 mv.visitMethodInsn(INVOKESTATIC, "java/lang/Math", "abs", "(I)I"); 190 mv.visitVarInsn(ISTORE, 1); 191 Label l1 = new Label(); 192 mv.visitLabel(l1); 193 mv.visitVarInsn(ALOAD, 0); 194 mv.visitFieldInsn(GETFIELD, CONCURRENT_HASH_MAP_SLASH, "segments", 195 "[Ljava/util/concurrent/ConcurrentHashMap$Segment;"); 196 mv.visitVarInsn(ILOAD, 1); 197 mv.visitVarInsn(ALOAD, 0); 198 mv.visitFieldInsn(GETFIELD, CONCURRENT_HASH_MAP_SLASH, "segments", 199 "[Ljava/util/concurrent/ConcurrentHashMap$Segment;"); 200 mv.visitInsn(ARRAYLENGTH); 201 mv.visitInsn(IREM); 202 mv.visitInsn(AALOAD); 203 mv.visitInsn(ARETURN); 204 Label l2 = new Label(); 205 mv.visitLabel(l2); 206 mv.visitMaxs(0, 0); 207 mv.visitEnd(); 208 } 209 210 private void createTCFullyLockMethod() { 211 MethodVisitor mv = cv.visitMethod(ACC_PRIVATE, TC_FULLY_LOCK_METHOD_NAME, TC_FULLY_LOCK_METHOD_DESC, null, null); 212 mv.visitCode(); 213 Label l0 = new Label(); 214 mv.visitLabel(l0); 215 mv.visitLineNumber(789, l0); 216 mv.visitVarInsn(ALOAD, 0); 217 mv.visitFieldInsn(GETFIELD, CONCURRENT_HASH_MAP_SLASH, "segments", 218 "[Ljava/util/concurrent/ConcurrentHashMap$Segment;"); 219 mv.visitVarInsn(ASTORE, 1); 220 Label l1 = new Label(); 221 mv.visitLabel(l1); 222 mv.visitLineNumber(790, l1); 223 mv.visitInsn(ICONST_0); 224 mv.visitVarInsn(ISTORE, 2); 225 Label l2 = new Label(); 226 mv.visitLabel(l2); 227 Label l3 = new Label(); 228 mv.visitJumpInsn(GOTO, l3); 229 Label l4 = new Label(); 230 mv.visitLabel(l4); 231 mv.visitLineNumber(791, l4); 232 mv.visitVarInsn(ALOAD, 1); 233 mv.visitVarInsn(ILOAD, 2); 234 mv.visitInsn(AALOAD); 235 mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/concurrent/ConcurrentHashMap$Segment", "lock", "()V"); 236 Label l5 = new Label(); 237 mv.visitLabel(l5); 238 mv.visitLineNumber(790, l5); 239 mv.visitIincInsn(2, 1); 240 mv.visitLabel(l3); 241 mv.visitVarInsn(ILOAD, 2); 242 mv.visitVarInsn(ALOAD, 1); 243 mv.visitInsn(ARRAYLENGTH); 244 mv.visitJumpInsn(IF_ICMPLT, l4); 245 Label l6 = new Label(); 246 mv.visitLabel(l6); 247 mv.visitLineNumber(792, l6); 248 mv.visitInsn(RETURN); 249 Label l7 = new Label(); 250 mv.visitLabel(l7); 251 mv.visitLocalVariable("this", "Ljava/util/concurrent/ConcurrentHashMap;", 252 "Ljava/util/concurrent/ConcurrentHashMap<TK;TV;>;", l0, l7, 0); 253 mv.visitLocalVariable("segments", "[Ljava/util/concurrent/ConcurrentHashMap$Segment;", null, l1, l7, 1); 254 mv.visitLocalVariable("i", "I", null, l2, l6, 2); 255 mv.visitMaxs(2, 3); 256 mv.visitEnd(); 257 } 258 259 private void createTCFullyUnLockMethod() { 260 MethodVisitor mv = cv 261 .visitMethod(ACC_PRIVATE, TC_FULLY_UNLOCK_METHOD_NAME, TC_FULLY_UNLOCK_METHOD_DESC, null, null); 262 mv.visitCode(); 263 Label l0 = new Label(); 264 mv.visitLabel(l0); 265 mv.visitLineNumber(795, l0); 266 mv.visitVarInsn(ALOAD, 0); 267 mv.visitFieldInsn(GETFIELD, CONCURRENT_HASH_MAP_SLASH, "segments", 268 "[Ljava/util/concurrent/ConcurrentHashMap$Segment;"); 269 mv.visitVarInsn(ASTORE, 1); 270 Label l1 = new Label(); 271 mv.visitLabel(l1); 272 mv.visitLineNumber(796, l1); 273 mv.visitInsn(ICONST_0); 274 mv.visitVarInsn(ISTORE, 2); 275 Label l2 = new Label(); 276 mv.visitLabel(l2); 277 Label l3 = new Label(); 278 mv.visitJumpInsn(GOTO, l3); 279 Label l4 = new Label(); 280 mv.visitLabel(l4); 281 mv.visitLineNumber(797, l4); 282 mv.visitVarInsn(ALOAD, 1); 283 mv.visitVarInsn(ILOAD, 2); 284 mv.visitInsn(AALOAD); 285 mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/concurrent/ConcurrentHashMap$Segment", "unlock", "()V"); 286 Label l5 = new Label(); 287 mv.visitLabel(l5); 288 mv.visitLineNumber(796, l5); 289 mv.visitIincInsn(2, 1); 290 mv.visitLabel(l3); 291 mv.visitVarInsn(ILOAD, 2); 292 mv.visitVarInsn(ALOAD, 1); 293 mv.visitInsn(ARRAYLENGTH); 294 mv.visitJumpInsn(IF_ICMPLT, l4); 295 Label l6 = new Label(); 296 mv.visitLabel(l6); 297 mv.visitLineNumber(798, l6); 298 mv.visitInsn(RETURN); 299 Label l7 = new Label(); 300 mv.visitLabel(l7); 301 mv.visitLocalVariable("this", "Ljava/util/concurrent/ConcurrentHashMap;", 302 "Ljava/util/concurrent/ConcurrentHashMap<TK;TV;>;", l0, l7, 0); 303 mv.visitLocalVariable("segments", "[Ljava/util/concurrent/ConcurrentHashMap$Segment;", null, l1, l7, 1); 304 mv.visitLocalVariable("i", "I", null, l2, l6, 2); 305 mv.visitMaxs(2, 3); 306 mv.visitEnd(); 307 } 308 309 private void createTCDsoRequiredMethod() { 310 MethodVisitor mv = super.visitMethod(ACC_PRIVATE, TC_IS_DSO_HASH_REQUIRED_METHOD_NAME, 311 TC_IS_DSO_HASH_REQUIRED_METHOD_DESC, null, null); 312 mv.visitCode(); 313 Label l0 = new Label(); 314 mv.visitLabel(l0); 315 mv.visitVarInsn(ALOAD, 0); 316 mv.visitMethodInsn(INVOKEVIRTUAL, CONCURRENT_HASH_MAP_SLASH, "__tc_managed", "()Lcom/tc/object/TCObject;"); 317 Label l1 = new Label(); 318 mv.visitJumpInsn(IFNULL, l1); 319 mv.visitVarInsn(ALOAD, 1); 320 mv.visitTypeInsn(INSTANCEOF, "com/tc/object/bytecode/Manageable"); 321 Label l2 = new Label(); 322 mv.visitJumpInsn(IFEQ, l2); 323 mv.visitVarInsn(ALOAD, 1); 324 mv.visitTypeInsn(CHECKCAST, "com/tc/object/bytecode/Manageable"); 325 mv.visitMethodInsn(INVOKEINTERFACE, "com/tc/object/bytecode/Manageable", "__tc_managed", 326 "()Lcom/tc/object/TCObject;"); 327 mv.visitJumpInsn(IFNONNULL, l1); 328 mv.visitLabel(l2); 329 mv.visitVarInsn(ALOAD, 1); 330 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I"); 331 mv.visitVarInsn(ALOAD, 1); 332 mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "identityHashCode", "(Ljava/lang/Object;)I"); 333 mv.visitJumpInsn(IF_ICMPNE, l1); 334 Label l3 = new Label(); 335 mv.visitLabel(l3); 336 mv.visitInsn(ICONST_0); 337 mv.visitInsn(IRETURN); 338 mv.visitLabel(l1); 339 mv.visitInsn(ICONST_1); 340 mv.visitInsn(IRETURN); 341 Label l4 = new Label(); 342 mv.visitLabel(l4); 343 mv.visitMaxs(0, 0); 344 mv.visitEnd(); 345 } 346 347 private void createTCRehashAndSupportMethods() { 348 createTCRehashMethod(); 349 createTCClearMethod(); 350 } 351 352 private void createTCRehashMethod() { 353 MethodVisitor mv = super.visitMethod(ACC_PUBLIC + ACC_SYNTHETIC, TC_REHASH_METHOD_NAME, TC_REHASH_METHOD_DESC, 354 null, null); 355 mv.visitCode(); 356 Label l0 = new Label(); 357 Label l1 = new Label(); 358 mv.visitTryCatchBlock(l0, l1, l1, "java/lang/Throwable"); 359 Label l2 = new Label(); 360 mv.visitTryCatchBlock(l0, l2, l2, null); 361 Label l3 = new Label(); 362 mv.visitLabel(l3); 363 mv.visitLineNumber(670, l3); 364 mv.visitVarInsn(ALOAD, 0); 365 mv.visitMethodInsn(INVOKEVIRTUAL, CONCURRENT_HASH_MAP_SLASH, "size", "()I"); 366 Label l4 = new Label(); 367 mv.visitJumpInsn(IFLE, l4); 368 Label l5 = new Label(); 369 mv.visitLabel(l5); 370 mv.visitLineNumber(671, l5); 371 mv.visitVarInsn(ALOAD, 0); 372 mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH, TC_FULLY_LOCK_METHOD_NAME, TC_FULLY_LOCK_METHOD_DESC); 373 mv.visitLabel(l0); 374 mv.visitLineNumber(673, l0); 375 mv.visitTypeInsn(NEW, "java/util/ArrayList"); 376 mv.visitInsn(DUP); 377 mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V"); 378 mv.visitVarInsn(ASTORE, 1); 379 Label l6 = new Label(); 380 mv.visitLabel(l6); 381 mv.visitLineNumber(674, l6); 382 mv.visitInsn(ICONST_0); 383 mv.visitVarInsn(ISTORE, 2); 384 Label l7 = new Label(); 385 mv.visitLabel(l7); 386 Label l8 = new Label(); 387 mv.visitJumpInsn(GOTO, l8); 388 Label l9 = new Label(); 389 mv.visitLabel(l9); 390 mv.visitLineNumber(675, l9); 391 mv.visitVarInsn(ALOAD, 0); 392 mv.visitFieldInsn(GETFIELD, CONCURRENT_HASH_MAP_SLASH, "segments", 393 "[Ljava/util/concurrent/ConcurrentHashMap$Segment;"); 394 mv.visitVarInsn(ILOAD, 2); 395 mv.visitInsn(AALOAD); 396 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "table", 397 "[Ljava/util/concurrent/ConcurrentHashMap$HashEntry;"); 398 mv.visitVarInsn(ASTORE, 3); 399 Label l10 = new Label(); 400 mv.visitLabel(l10); 401 mv.visitLineNumber(676, l10); 402 mv.visitInsn(ICONST_0); 403 mv.visitVarInsn(ISTORE, 4); 404 Label l11 = new Label(); 405 mv.visitLabel(l11); 406 Label l12 = new Label(); 407 mv.visitJumpInsn(GOTO, l12); 408 Label l13 = new Label(); 409 mv.visitLabel(l13); 410 mv.visitLineNumber(677, l13); 411 mv.visitVarInsn(ALOAD, 3); 412 mv.visitVarInsn(ILOAD, 4); 413 mv.visitInsn(AALOAD); 414 Label l14 = new Label(); 415 mv.visitJumpInsn(IFNULL, l14); 416 Label l15 = new Label(); 417 mv.visitLabel(l15); 418 mv.visitLineNumber(678, l15); 419 mv.visitVarInsn(ALOAD, 3); 420 mv.visitVarInsn(ILOAD, 4); 421 mv.visitInsn(AALOAD); 422 mv.visitVarInsn(ASTORE, 5); 423 Label l16 = new Label(); 424 mv.visitLabel(l16); 425 mv.visitLineNumber(679, l16); 426 Label l17 = new Label(); 427 mv.visitJumpInsn(GOTO, l17); 428 Label l18 = new Label(); 429 mv.visitLabel(l18); 430 mv.visitLineNumber(680, l18); 431 mv.visitVarInsn(ALOAD, 1); 432 mv.visitVarInsn(ALOAD, 5); 433 mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z"); 434 mv.visitInsn(POP); 435 Label l19 = new Label(); 436 mv.visitLabel(l19); 437 mv.visitLineNumber(681, l19); 438 mv.visitVarInsn(ALOAD, 5); 439 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "next", 440 "Ljava/util/concurrent/ConcurrentHashMap$HashEntry;"); 441 mv.visitVarInsn(ASTORE, 5); 442 mv.visitLabel(l17); 443 mv.visitLineNumber(679, l17); 444 mv.visitVarInsn(ALOAD, 5); 445 mv.visitJumpInsn(IFNONNULL, l18); 446 mv.visitLabel(l14); 447 mv.visitLineNumber(676, l14); 448 mv.visitIincInsn(4, 1); 449 mv.visitLabel(l12); 450 mv.visitVarInsn(ILOAD, 4); 451 mv.visitVarInsn(ALOAD, 3); 452 mv.visitInsn(ARRAYLENGTH); 453 mv.visitJumpInsn(IF_ICMPLT, l13); 454 Label l20 = new Label(); 455 mv.visitLabel(l20); 456 mv.visitLineNumber(674, l20); 457 mv.visitIincInsn(2, 1); 458 mv.visitLabel(l8); 459 mv.visitVarInsn(ILOAD, 2); 460 mv.visitVarInsn(ALOAD, 0); 461 mv.visitFieldInsn(GETFIELD, CONCURRENT_HASH_MAP_SLASH, "segments", 462 "[Ljava/util/concurrent/ConcurrentHashMap$Segment;"); 463 mv.visitInsn(ARRAYLENGTH); 464 mv.visitJumpInsn(IF_ICMPLT, l9); 465 Label l21 = new Label(); 466 mv.visitLabel(l21); 467 mv.visitLineNumber(686, l21); 468 mv.visitVarInsn(ALOAD, 0); 469 mv.visitMethodInsn(INVOKEVIRTUAL, CONCURRENT_HASH_MAP_SLASH, "__tc_clear", "()V"); 470 Label l22 = new Label(); 471 mv.visitLabel(l22); 472 mv.visitLineNumber(687, l22); 473 mv.visitVarInsn(ALOAD, 1); 474 mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "iterator", "()Ljava/util/Iterator;"); 475 mv.visitVarInsn(ASTORE, 2); 476 Label l23 = new Label(); 477 mv.visitLabel(l23); 478 Label l24 = new Label(); 479 mv.visitJumpInsn(GOTO, l24); 480 Label l25 = new Label(); 481 mv.visitLabel(l25); 482 mv.visitLineNumber(688, l25); 483 mv.visitVarInsn(ALOAD, 2); 484 mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;"); 485 mv.visitTypeInsn(CHECKCAST, "java/util/concurrent/ConcurrentHashMap$HashEntry"); 486 mv.visitTypeInsn(CHECKCAST, "java/util/concurrent/ConcurrentHashMap$HashEntry"); 487 mv.visitVarInsn(ASTORE, 3); 488 Label l26 = new Label(); 489 mv.visitLabel(l26); 490 mv.visitLineNumber(689, l26); 491 mv.visitVarInsn(ALOAD, 3); 492 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "key", "Ljava/lang/Object;"); 493 mv.visitVarInsn(ASTORE, 4); 494 Label l27 = new Label(); 495 mv.visitLabel(l27); 496 mv.visitLineNumber(690, l27); 497 mv.visitVarInsn(ALOAD, 3); 498 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "value", "Ljava/lang/Object;"); 499 mv.visitVarInsn(ASTORE, 5); 500 Label l28 = new Label(); 501 mv.visitLabel(l28); 502 mv.visitLineNumber(691, l28); 503 invokeJdkHashMethod(mv, 4); 504 mv.visitVarInsn(ISTORE, 6); 505 Label l29 = new Label(); 506 mv.visitLabel(l29); 507 mv.visitLineNumber(692, l29); 508 mv.visitVarInsn(ALOAD, 0); 509 mv.visitVarInsn(ALOAD, 0); 510 mv.visitVarInsn(ALOAD, 4); 511 mv.visitInsn(ICONST_0); 512 mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH, TC_HASH_METHOD_NAME, TC_HASH_METHOD_CHECK_DESC); 513 mv.visitMethodInsn(INVOKEVIRTUAL, CONCURRENT_HASH_MAP_SLASH, "segmentFor", 514 "(I)Ljava/util/concurrent/ConcurrentHashMap$Segment;"); 515 mv.visitVarInsn(ALOAD, 4); 516 mv.visitVarInsn(ILOAD, 6); 517 mv.visitVarInsn(ALOAD, 5); 518 mv.visitInsn(ICONST_0); 519 mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/concurrent/ConcurrentHashMap$Segment", TC_PUT_METHOD_NAME, 520 SEGMENT_TC_PUT_METHOD_DESC); 521 mv.visitInsn(POP); 522 mv.visitLabel(l24); 523 mv.visitLineNumber(687, l24); 524 mv.visitVarInsn(ALOAD, 2); 525 mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z"); 526 mv.visitJumpInsn(IFNE, l25); 527 Label l30 = new Label(); 528 mv.visitLabel(l30); 529 Label l31 = new Label(); 530 mv.visitJumpInsn(GOTO, l31); 531 mv.visitLabel(l1); 532 mv.visitLineNumber(694, l1); 533 mv.visitVarInsn(ASTORE, 1); 534 Label l32 = new Label(); 535 mv.visitLabel(l32); 536 mv.visitLineNumber(695, l32); 537 mv.visitVarInsn(ALOAD, 1); 538 mv.visitFieldInsn(GETSTATIC, "java/lang/System", "err", "Ljava/io/PrintStream;"); 539 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Throwable", "printStackTrace", "(Ljava/io/PrintStream;)V"); 540 Label l33 = new Label(); 541 mv.visitLabel(l33); 542 mv.visitJumpInsn(GOTO, l31); 543 mv.visitLabel(l2); 544 mv.visitLineNumber(696, l2); 545 mv.visitVarInsn(ASTORE, 7); 546 Label l34 = new Label(); 547 mv.visitLabel(l34); 548 mv.visitLineNumber(697, l34); 549 mv.visitVarInsn(ALOAD, 0); 550 mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH, TC_FULLY_UNLOCK_METHOD_NAME, 551 TC_FULLY_UNLOCK_METHOD_DESC); 552 Label l35 = new Label(); 553 mv.visitLabel(l35); 554 mv.visitLineNumber(698, l35); 555 mv.visitVarInsn(ALOAD, 7); 556 mv.visitInsn(ATHROW); 557 mv.visitLabel(l31); 558 mv.visitLineNumber(697, l31); 559 mv.visitVarInsn(ALOAD, 0); 560 mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH, "__tc_fullyUnLock", "()V"); 561 mv.visitLabel(l4); 562 mv.visitLineNumber(700, l4); 563 mv.visitInsn(RETURN); 564 Label l36 = new Label(); 565 mv.visitLabel(l36); 566 mv.visitLocalVariable("this", "Ljava/util/concurrent/ConcurrentHashMap;", 567 "Ljava/util/concurrent/ConcurrentHashMap<TK;TV;>;", l3, l36, 0); 568 mv.visitLocalVariable("entries", "Ljava/util/List;", null, l6, l1, 1); 569 mv.visitLocalVariable("i", "I", null, l7, l21, 2); 570 mv.visitLocalVariable("segmentEntries", "[Ljava/util/concurrent/ConcurrentHashMap$HashEntry;", null, l10, l20, 3); 571 mv.visitLocalVariable("j", "I", null, l11, l20, 4); 572 mv.visitLocalVariable("first", "Ljava/util/concurrent/ConcurrentHashMap$HashEntry;", null, l16, l14, 5); 573 mv.visitLocalVariable("i", "Ljava/util/Iterator;", null, l23, l30, 2); 574 mv.visitLocalVariable("entry", "Ljava/util/concurrent/ConcurrentHashMap$HashEntry;", null, l26, l24, 3); 575 mv.visitLocalVariable("key", "Ljava/lang/Object;", null, l27, l24, 4); 576 mv.visitLocalVariable("value", "Ljava/lang/Object;", null, l28, l24, 5); 577 mv.visitLocalVariable("hash", "I", null, l29, l24, 6); 578 mv.visitLocalVariable("t", "Ljava/lang/Throwable;", null, l32, l33, 1); 579 mv.visitMaxs(5, 8); 580 mv.visitEnd(); 581 } 582 583 private void createTCPutMethod() { 584 MethodVisitor mv = super 585 .visitMethod(ACC_PUBLIC + ACC_SYNTHETIC, TC_PUT_METHOD_NAME, TC_PUT_METHOD_DESC, null, null); 586 mv.visitCode(); 587 Label l0 = new Label(); 588 mv.visitLabel(l0); 589 mv.visitVarInsn(ALOAD, 2); 590 Label l1 = new Label(); 591 mv.visitJumpInsn(IFNONNULL, l1); 592 mv.visitTypeInsn(NEW, "java/lang/NullPointerException"); 593 mv.visitInsn(DUP); 594 mv.visitMethodInsn(INVOKESPECIAL, "java/lang/NullPointerException", "<init>", "()V"); 595 mv.visitInsn(ATHROW); 596 mv.visitLabel(l1); 597 invokeJdkHashMethod(mv, 1); 598 mv.visitVarInsn(ISTORE, 3); 599 Label l2 = new Label(); 600 mv.visitLabel(l2); 601 mv.visitVarInsn(ALOAD, 0); 602 mv.visitVarInsn(ALOAD, 0); 603 mv.visitVarInsn(ALOAD, 1); 604 mv.visitInsn(ICONST_0); 605 mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH, TC_HASH_METHOD_NAME, TC_HASH_METHOD_CHECK_DESC); 606 mv.visitMethodInsn(INVOKEVIRTUAL, CONCURRENT_HASH_MAP_SLASH, "segmentFor", 607 "(I)Ljava/util/concurrent/ConcurrentHashMap$Segment;"); 608 mv.visitVarInsn(ALOAD, 1); 609 mv.visitVarInsn(ILOAD, 3); 610 mv.visitVarInsn(ALOAD, 2); 611 mv.visitInsn(ICONST_0); 612 mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/concurrent/ConcurrentHashMap$Segment", TC_PUT_METHOD_NAME, 613 SEGMENT_TC_PUT_METHOD_DESC); 614 mv.visitInsn(ARETURN); 615 Label l3 = new Label(); 616 mv.visitLabel(l3); 617 mv.visitMaxs(0, 0); 618 mv.visitEnd(); 619 } 620 621 private void createTCClearMethod() { 622 MethodVisitor mv = super.visitMethod(ACC_PRIVATE + ACC_SYNTHETIC, TC_CLEAR_METHOD_NAME, TC_CLEAR_METHOD_DESC, null, 623 null); 624 mv.visitCode(); 625 Label l0 = new Label(); 626 mv.visitLabel(l0); 627 mv.visitInsn(ICONST_0); 628 mv.visitVarInsn(ISTORE, 1); 629 Label l1 = new Label(); 630 mv.visitLabel(l1); 631 Label l2 = new Label(); 632 mv.visitJumpInsn(GOTO, l2); 633 Label l3 = new Label(); 634 mv.visitLabel(l3); 635 mv.visitVarInsn(ALOAD, 0); 636 mv.visitFieldInsn(GETFIELD, CONCURRENT_HASH_MAP_SLASH, "segments", 637 "[Ljava/util/concurrent/ConcurrentHashMap$Segment;"); 638 mv.visitVarInsn(ILOAD, 1); 639 mv.visitInsn(AALOAD); 640 mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/concurrent/ConcurrentHashMap$Segment", TC_CLEAR_METHOD_NAME, 641 TC_CLEAR_METHOD_DESC); 642 Label l4 = new Label(); 643 mv.visitLabel(l4); 644 mv.visitIincInsn(1, 1); 645 mv.visitLabel(l2); 646 mv.visitVarInsn(ILOAD, 1); 647 mv.visitVarInsn(ALOAD, 0); 648 mv.visitFieldInsn(GETFIELD, CONCURRENT_HASH_MAP_SLASH, "segments", 649 "[Ljava/util/concurrent/ConcurrentHashMap$Segment;"); 650 mv.visitInsn(ARRAYLENGTH); 651 mv.visitJumpInsn(IF_ICMPLT, l3); 652 Label l5 = new Label(); 653 mv.visitLabel(l5); 654 mv.visitInsn(RETURN); 655 Label l6 = new Label(); 656 mv.visitLabel(l6); 657 mv.visitMaxs(0, 0); 658 mv.visitEnd(); 659 } 660 661 681 private void createTCSharedHashMethod() { 682 MethodVisitor mv = cv 683 .visitMethod(ACC_PRIVATE + ACC_SYNTHETIC, TC_HASH_METHOD_NAME, TC_HASH_METHOD_DESC, null, null); 684 Label l0 = new Label(); 685 mv.visitLabel(l0); 686 mv.visitVarInsn(ALOAD, 0); 687 mv.visitVarInsn(ALOAD, 1); 688 mv.visitInsn(ICONST_1); 689 mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH, TC_HASH_METHOD_NAME, TC_HASH_METHOD_CHECK_DESC); 690 mv.visitInsn(IRETURN); 691 Label l1 = new Label(); 692 mv.visitLabel(l1); 693 mv.visitMaxs(0, 0); 694 mv.visitEnd(); 695 } 696 697 private void createTCForcedHashMethod() { 698 MethodVisitor mv = super.visitMethod(ACC_PRIVATE + ACC_SYNTHETIC, TC_HASH_METHOD_NAME, TC_HASH_METHOD_CHECK_DESC, 699 null, null); 700 mv.visitCode(); 701 Label l0 = new Label(); 702 mv.visitLabel(l0); 703 mv.visitVarInsn(ALOAD, 1); 704 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I"); 705 mv.visitVarInsn(ISTORE, 3); 706 Label l1 = new Label(); 707 mv.visitLabel(l1); 708 mv.visitInsn(ICONST_0); 709 mv.visitVarInsn(ISTORE, 4); 710 Label l2 = new Label(); 711 mv.visitLabel(l2); 712 mv.visitVarInsn(ALOAD, 1); 713 mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "identityHashCode", "(Ljava/lang/Object;)I"); 714 mv.visitVarInsn(ILOAD, 3); 715 Label l3 = new Label(); 716 mv.visitJumpInsn(IF_ICMPNE, l3); 717 Label l4 = new Label(); 718 mv.visitLabel(l4); 719 mv.visitVarInsn(ILOAD, 2); 720 Label l5 = new Label(); 721 mv.visitJumpInsn(IFEQ, l5); 722 Label l6 = new Label(); 723 mv.visitLabel(l6); 724 mv.visitVarInsn(ALOAD, 0); 725 mv.visitMethodInsn(INVOKEVIRTUAL, CONCURRENT_HASH_MAP_SLASH, "__tc_managed", "()Lcom/tc/object/TCObject;"); 726 Label l7 = new Label(); 727 mv.visitJumpInsn(IFNONNULL, l7); 728 mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "isCreationInProgress", "()Z"); 729 mv.visitJumpInsn(IFEQ, l3); 730 mv.visitLabel(l7); 731 mv.visitInsn(ICONST_1); 732 mv.visitVarInsn(ISTORE, 4); 733 mv.visitJumpInsn(GOTO, l3); 734 mv.visitLabel(l5); 735 mv.visitInsn(ICONST_1); 736 mv.visitVarInsn(ISTORE, 4); 737 mv.visitLabel(l3); 738 mv.visitVarInsn(ILOAD, 4); 739 Label l8 = new Label(); 740 mv.visitJumpInsn(IFEQ, l8); 741 Label l9 = new Label(); 742 mv.visitLabel(l9); 743 mv.visitVarInsn(ALOAD, 1); 744 mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "shareObjectIfNecessary", 745 "(Ljava/lang/Object;)Lcom/tc/object/TCObject;"); 746 mv.visitVarInsn(ASTORE, 5); 747 Label l10 = new Label(); 748 mv.visitLabel(l10); 749 mv.visitVarInsn(ALOAD, 5); 750 mv.visitJumpInsn(IFNULL, l8); 751 mv.visitVarInsn(ALOAD, 5); 752 mv.visitMethodInsn(INVOKEINTERFACE, "com/tc/object/TCObject", "getObjectID", "()Lcom/tc/object/ObjectID;"); 753 mv.visitMethodInsn(INVOKEVIRTUAL, "com/tc/object/ObjectID", "hashCode", "()I"); 754 mv.visitVarInsn(ISTORE, 3); 755 mv.visitLabel(l8); 756 mv.visitVarInsn(ILOAD, 3); 757 mv.visitVarInsn(ILOAD, 3); 758 mv.visitIntInsn(BIPUSH, 9); 759 mv.visitInsn(ISHL); 760 mv.visitInsn(ICONST_M1); 761 mv.visitInsn(IXOR); 762 mv.visitInsn(IADD); 763 mv.visitVarInsn(ISTORE, 3); 764 Label l11 = new Label(); 765 mv.visitLabel(l11); 766 mv.visitVarInsn(ILOAD, 3); 767 mv.visitVarInsn(ILOAD, 3); 768 mv.visitIntInsn(BIPUSH, 14); 769 mv.visitInsn(IUSHR); 770 mv.visitInsn(IXOR); 771 mv.visitVarInsn(ISTORE, 3); 772 Label l12 = new Label(); 773 mv.visitLabel(l12); 774 mv.visitVarInsn(ILOAD, 3); 775 mv.visitVarInsn(ILOAD, 3); 776 mv.visitInsn(ICONST_4); 777 mv.visitInsn(ISHL); 778 mv.visitInsn(IADD); 779 mv.visitVarInsn(ISTORE, 3); 780 Label l13 = new Label(); 781 mv.visitLabel(l13); 782 mv.visitVarInsn(ILOAD, 3); 783 mv.visitVarInsn(ILOAD, 3); 784 mv.visitIntInsn(BIPUSH, 10); 785 mv.visitInsn(IUSHR); 786 mv.visitInsn(IXOR); 787 mv.visitVarInsn(ISTORE, 3); 788 Label l14 = new Label(); 789 mv.visitLabel(l14); 790 mv.visitVarInsn(ILOAD, 3); 791 mv.visitInsn(IRETURN); 792 Label l17 = new Label(); 793 mv.visitLabel(l17); 794 mv.visitMaxs(0, 0); 795 mv.visitEnd(); 796 } 797 798 private static class EntrySetMethodAdapter extends MethodAdapter implements Opcodes { 799 800 public EntrySetMethodAdapter(MethodVisitor mv) { 801 super(mv); 802 } 803 804 public void visitMethodInsn(int opcode, String owner, String name, String desc) { 805 super.visitMethodInsn(opcode, owner, name, desc); 806 807 if ((opcode == INVOKESPECIAL) && "java/util/concurrent/ConcurrentHashMap$EntrySet".equals(owner) 808 && "<init>".equals(name) && "(Ljava/util/concurrent/ConcurrentHashMap;)V".equals(desc)) { 809 mv.visitVarInsn(ASTORE, 1); 810 mv.visitTypeInsn(NEW, "com/tcclient/util/ConcurrentHashMapEntrySetWrapper"); 811 mv.visitInsn(DUP); 812 mv.visitVarInsn(ALOAD, 0); 813 mv.visitVarInsn(ALOAD, 1); 814 mv.visitMethodInsn(INVOKESPECIAL, "com/tcclient/util/ConcurrentHashMapEntrySetWrapper", "<init>", 815 "(Ljava/util/Map;Ljava/util/Set;)V"); 816 } 817 } 818 } 819 820 private abstract static class AddCheckManagedKeyMethodAdapter extends MethodAdapter implements Opcodes { 821 public AddCheckManagedKeyMethodAdapter(MethodVisitor mv) { 822 super(mv); 823 } 824 825 public void visitCode() { 826 super.visitCode(); 827 addCheckManagedKeyCode(); 828 } 829 830 protected abstract void addCheckManagedKeyCode(); 831 } 832 833 private static class ContainsKeyMethodAdapter extends AddCheckManagedKeyMethodAdapter { 834 public ContainsKeyMethodAdapter(MethodVisitor mv) { 835 super(mv); 836 } 837 838 protected void addCheckManagedKeyCode() { 839 mv.visitVarInsn(ALOAD, 0); 840 mv.visitVarInsn(ALOAD, 1); 841 mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH, TC_IS_DSO_HASH_REQUIRED_METHOD_NAME, 842 TC_IS_DSO_HASH_REQUIRED_METHOD_DESC); 843 Label l1 = new Label(); 844 mv.visitJumpInsn(IFNE, l1); 845 Label l2 = new Label(); 846 mv.visitLabel(l2); 847 mv.visitInsn(ICONST_0); 848 mv.visitInsn(IRETURN); 849 mv.visitLabel(l1); 850 } 851 } 852 853 private static class GetMethodAdapter extends AddCheckManagedKeyMethodAdapter { 854 public GetMethodAdapter(MethodVisitor mv) { 855 super(mv); 856 } 857 858 protected void addCheckManagedKeyCode() { 859 mv.visitVarInsn(ALOAD, 0); 860 mv.visitVarInsn(ALOAD, 1); 861 mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH, TC_IS_DSO_HASH_REQUIRED_METHOD_NAME, 862 TC_IS_DSO_HASH_REQUIRED_METHOD_DESC); 863 Label l1 = new Label(); 864 mv.visitJumpInsn(IFNE, l1); 865 Label l2 = new Label(); 866 mv.visitLabel(l2); 867 mv.visitInsn(ACONST_NULL); 868 mv.visitInsn(ARETURN); 869 mv.visitLabel(l1); 870 } 871 } 872 873 private static class SimpleRemoveMethodAdapter extends GetMethodAdapter { 874 public SimpleRemoveMethodAdapter(MethodVisitor mv) { 875 super(mv); 876 } 877 } 878 879 private static class SimpleReplaceMethodAdapter extends SimpleRemoveMethodAdapter { 880 private Label target; 881 882 public SimpleReplaceMethodAdapter(MethodVisitor mv) { 883 super(mv); 884 } 885 886 public void visitCode() { 887 mv.visitCode(); 888 } 889 890 public void visitJumpInsn(int opcode, Label label) { 891 super.visitJumpInsn(opcode, label); 892 if (IFNONNULL == opcode) { 893 target = label; 894 } 895 } 896 897 public void visitLabel(Label label) { 898 super.visitLabel(label); 899 if (label.equals(target)) { 900 addCheckManagedKeyCode(); 901 } 902 } 903 } 904 905 private static class RemoveMethodAdapter extends AddCheckManagedKeyMethodAdapter { 906 public RemoveMethodAdapter(MethodVisitor mv) { 907 super(mv); 908 } 909 910 protected void addCheckManagedKeyCode() { 911 mv.visitVarInsn(ALOAD, 0); 912 mv.visitVarInsn(ALOAD, 1); 913 mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SLASH, TC_IS_DSO_HASH_REQUIRED_METHOD_NAME, 914 TC_IS_DSO_HASH_REQUIRED_METHOD_DESC); 915 Label l1 = new Label(); 916 mv.visitJumpInsn(IFNE, l1); 917 Label l2 = new Label(); 918 mv.visitLabel(l2); 919 mv.visitInsn(ICONST_0); 920 mv.visitInsn(IRETURN); 921 mv.visitLabel(l1); 922 } 923 } 924 925 private static class ReplaceMethodAdapter extends RemoveMethodAdapter { 926 private Label target; 927 928 public ReplaceMethodAdapter(MethodVisitor mv) { 929 super(mv); 930 } 931 932 public void visitCode() { 933 mv.visitCode(); 934 } 935 936 public void visitJumpInsn(int opcode, Label label) { 937 super.visitJumpInsn(opcode, label); 938 if (IFNONNULL == opcode) { 939 target = label; 940 } 941 } 942 943 public void visitLabel(Label label) { 944 super.visitLabel(label); 945 if (label.equals(target)) { 946 addCheckManagedKeyCode(); 947 } 948 } 949 } 950 951 private static class ConcurrentHashMapMethodAdapter extends LocalVariablesSorter implements Opcodes { 952 953 public ConcurrentHashMapMethodAdapter(int access, String desc, MethodVisitor mv) { 954 super(access, desc, mv); 955 } 956 957 public int newLocal(int size) { 958 return super.newLocal(size); 959 } 960 961 public void visitMethodInsn(int opcode, String owner, String name, String desc) { 962 if (INVOKEVIRTUAL == opcode && CONCURRENT_HASH_MAP_SLASH.equals(owner) && "segmentFor".equals(name) 963 && "(I)Ljava/util/concurrent/ConcurrentHashMap$Segment;".equals(desc)) { 964 mv.visitInsn(POP); 965 ByteCodeUtil.pushThis(mv); 966 mv.visitVarInsn(ALOAD, 1); 967 mv.visitMethodInsn(INVOKEVIRTUAL, owner, TC_HASH_METHOD_NAME, TC_HASH_METHOD_DESC); 968 super.visitMethodInsn(opcode, owner, name, desc); 969 } else if (INVOKESPECIAL == opcode 970 && JavaUtilConcurrentHashMapSegmentAdapter.CONCURRENT_HASH_MAP_SEGMENT_SLASH.equals(owner) 971 && "<init>".equals(name) && "(IF)V".equals(desc)) { 972 mv.visitInsn(POP); 973 mv.visitInsn(POP); 974 ByteCodeUtil.pushThis(mv); 975 mv.visitVarInsn(ILOAD, 7); 976 mv.visitVarInsn(FLOAD, 2); 977 mv.visitMethodInsn(opcode, owner, name, JavaUtilConcurrentHashMapSegmentAdapter.INIT_DESC); 978 } else { 979 super.visitMethodInsn(opcode, owner, name, desc); 980 } 981 } 982 } 983 984 private void invokeJdkHashMethod(MethodVisitor mv, int objectVarNumber) { 985 mv.visitVarInsn(ALOAD, objectVarNumber); 986 if (Vm.isJDK16()) { 987 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I"); 988 mv.visitMethodInsn(INVOKESTATIC, CONCURRENT_HASH_MAP_SLASH, HASH_METHOD_NAME, "(I)I"); 989 } else { 990 mv.visitMethodInsn(INVOKESTATIC, CONCURRENT_HASH_MAP_SLASH, HASH_METHOD_NAME, "(Ljava/lang/Object;)I"); 991 } 992 } 993 } | Popular Tags |