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.object.SerializationUtil; 15 16 public class JavaUtilConcurrentHashMapSegmentAdapter extends ClassAdapter implements Opcodes { 17 private static final String PARENT_CONCURRENT_HASH_MAP_FIELD_TYPE = "Ljava/util/concurrent/ConcurrentHashMap;"; 18 19 private static final String PARENT_CONCURRENT_HASH_MAP_FIELD_NAME = "parentMap"; 20 21 private static final String TC_PUT_METHOD_NAME = ByteCodeUtil.TC_METHOD_PREFIX + "put"; 22 private static final String TC_PUT_METHOD_DESC = "(Ljava/lang/Object;ILjava/lang/Object;Z)Ljava/lang/Object;"; 23 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 27 public static final String INITIAL_TABLE_METHOD_NAME = "initTable"; 28 private static final String INITIAL_TABLE_METHOD_DESC = "(I)V"; 29 30 public final static String CONCURRENT_HASH_MAP_SEGMENT_SLASH = "java/util/concurrent/ConcurrentHashMap$Segment"; 31 public final static String INIT_DESC = "(" + PARENT_CONCURRENT_HASH_MAP_FIELD_TYPE 32 + "IF)V"; 33 34 public JavaUtilConcurrentHashMapSegmentAdapter(ClassVisitor cv) { 35 super(cv); 36 } 37 38 public MethodVisitor visitMethod(int access, String name, String desc, String signature, String [] exceptions) { 39 if (("get".equals(name) && "(Ljava/lang/Object;I)Ljava/lang/Object;".equals(desc)) || 40 ("containsKey".equals(name) && "(Ljava/lang/Object;I)Z".equals(desc))) { 41 return addWrapperMethod(access, name, desc, signature, exceptions); 42 } 43 44 String description = desc; 45 if ("<init>".equals(name) && "(IF)V".equals(desc)) { 46 description = INIT_DESC; 47 } 48 MethodVisitor mv = super.visitMethod(access, name, description, signature, exceptions); 49 50 if ("put".equals(name) && "(Ljava/lang/Object;ILjava/lang/Object;Z)Ljava/lang/Object;".equals(desc)) { 51 return new PutMethodAdapter(mv); 52 } else if ("clear".equals(name) && "()V".equals(desc)) { 53 return new ClearMethodAdapter(mv); 54 } else if ("remove".equals(name) && "(Ljava/lang/Object;ILjava/lang/Object;)Ljava/lang/Object;".equals(desc)) { 55 return new RemoveMethodAdapter(mv); 56 } else if ("replace".equals(name) && "(Ljava/lang/Object;ILjava/lang/Object;)Ljava/lang/Object;".equals(desc)) { 57 return new ReplaceMethodAdapter(mv); 58 } else if ("replace".equals(name) && "(Ljava/lang/Object;ILjava/lang/Object;Ljava/lang/Object;)Z".equals(desc)) { 59 return new ReplaceIfValueEqualMethodAdapter(mv); 60 } else if ("<init>".equals(name) && "(IF)V".equals(desc)) { 61 return new InitMethodAdapter(mv); 62 } else { 63 return mv; 64 } 65 } 66 67 private String getNewName(String methodName) { 68 return ByteCodeUtil.TC_METHOD_PREFIX + methodName; 69 } 70 71 private MethodVisitor addWrapperMethod(int access, String name, String desc, String signature, String [] exceptions) { 72 createWrapperMethod(access, name, desc, signature, exceptions); 73 return cv.visitMethod(ACC_PRIVATE, getNewName(name), desc, signature, exceptions); 74 } 75 76 private void createWrapperMethod(int access, String name, String desc, String signature, String [] exceptions) { 77 Type[] params = Type.getArgumentTypes(desc); 78 Type returnType = Type.getReturnType(desc); 79 80 MethodVisitor mv = cv.visitMethod(access, name, desc, signature, exceptions); 81 mv.visitCode(); 82 Label l0 = new Label(); 83 Label l1 = new Label(); 84 Label l2 = new Label(); 85 mv.visitTryCatchBlock(l0, l1, l2, null); 86 Label l3 = new Label(); 87 mv.visitLabel(l3); 88 mv.visitLineNumber(280, l3); 89 mv.visitVarInsn(ALOAD, 0); 90 mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "isManaged", "(Ljava/lang/Object;)Z"); 91 mv.visitVarInsn(ISTORE, 3); 92 Label l4 = new Label(); 93 mv.visitLabel(l4); 94 mv.visitLineNumber(281, l4); 95 mv.visitVarInsn(ILOAD, 3); 96 mv.visitJumpInsn(IFEQ, l0); 97 mv.visitVarInsn(ALOAD, 0); 98 mv.visitMethodInsn(INVOKEVIRTUAL, CONCURRENT_HASH_MAP_SEGMENT_SLASH, "lock", "()V"); 99 mv.visitLabel(l0); 100 mv.visitLineNumber(283, l0); 101 mv.visitVarInsn(ALOAD, 0); 102 for (int i = 0; i < params.length; i++) { 103 mv.visitVarInsn(params[i].getOpcode(ILOAD), i + 1); 104 } 105 mv.visitMethodInsn(INVOKESPECIAL, CONCURRENT_HASH_MAP_SEGMENT_SLASH, getNewName(name), desc); 106 mv.visitVarInsn(returnType.getOpcode(ISTORE), 5); 107 mv.visitLabel(l1); 108 mv.visitLineNumber(285, l1); 109 mv.visitVarInsn(ILOAD, 3); 110 Label l5 = new Label(); 111 mv.visitJumpInsn(IFEQ, l5); 112 mv.visitVarInsn(ALOAD, 0); 113 mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/concurrent/ConcurrentHashMap$Segment", "unlock", "()V"); 114 mv.visitLabel(l5); 115 mv.visitLineNumber(283, l5); 116 mv.visitVarInsn(returnType.getOpcode(ILOAD), 5); 117 mv.visitInsn(returnType.getOpcode(IRETURN)); 118 mv.visitLabel(l2); 119 mv.visitLineNumber(284, l2); 120 mv.visitVarInsn(ASTORE, 4); 121 Label l6 = new Label(); 122 mv.visitLabel(l6); 123 mv.visitLineNumber(285, l6); 124 mv.visitVarInsn(ILOAD, 3); 125 Label l7 = new Label(); 126 mv.visitJumpInsn(IFEQ, l7); 127 mv.visitVarInsn(ALOAD, 0); 128 mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/concurrent/ConcurrentHashMap$Segment", "unlock", "()V"); 129 mv.visitLabel(l7); 130 mv.visitLineNumber(286, l7); 131 mv.visitVarInsn(ALOAD, 4); 132 mv.visitInsn(ATHROW); 133 Label l8 = new Label(); 134 mv.visitLabel(l8); 135 mv.visitMaxs(0, 0); 136 mv.visitEnd(); 137 } 138 139 public void visitEnd() { 140 createDefaultConstructor(); 141 createInitTableMethod(); 142 createTCPutMethod(); 143 createTCClearMethod(); 144 super.visitField(ACC_FINAL + ACC_SYNTHETIC, PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, 145 "Ljava/util/concurrent/ConcurrentHashMap;", null, null); 146 super.visitEnd(); 147 } 148 149 private void createDefaultConstructor() { 150 MethodVisitor mv = cv.visitMethod(0, "<init>", "()V", null, null); 151 mv.visitCode(); 152 Label l0 = new Label(); 153 mv.visitLabel(l0); 154 mv.visitLineNumber(232, l0); 155 mv.visitVarInsn(ALOAD, 0); 156 mv.visitMethodInsn(INVOKESPECIAL, "java/util/concurrent/locks/ReentrantLock", "<init>", "()V"); 157 Label l1 = new Label(); 158 mv.visitLabel(l1); 159 mv.visitLineNumber(233, l1); 160 mv.visitVarInsn(ALOAD, 0); 161 mv.visitInsn(ICONST_1); 162 mv.visitTypeInsn(ANEWARRAY, "java/util/concurrent/ConcurrentHashMap$HashEntry"); 163 mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/concurrent/ConcurrentHashMap$Segment", "setTable", 164 "([Ljava/util/concurrent/ConcurrentHashMap$HashEntry;)V"); 165 Label l2 = new Label(); 166 mv.visitLabel(l2); 167 mv.visitLineNumber(234, l2); 168 mv.visitVarInsn(ALOAD, 0); 169 mv.visitInsn(FCONST_0); 170 mv.visitFieldInsn(PUTFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "loadFactor", "F"); 171 Label l3 = new Label(); 172 mv.visitLabel(l3); 173 mv.visitLineNumber(235, l3); 174 mv.visitVarInsn(ALOAD, 0); 175 mv.visitInsn(ACONST_NULL); 176 mv.visitFieldInsn(PUTFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "parentMap", 177 "Ljava/util/concurrent/ConcurrentHashMap;"); 178 Label l4 = new Label(); 179 mv.visitLabel(l4); 180 mv.visitLineNumber(236, l4); 181 mv.visitInsn(RETURN); 182 Label l5 = new Label(); 183 mv.visitLabel(l5); 184 mv.visitLocalVariable("this", "Ljava/util/concurrent/ConcurrentHashMap$Segment;", 185 "Ljava/util/concurrent/ConcurrentHashMap<TK;TV;>.Segment<TK;TV;>;", l0, l5, 0); 186 mv.visitMaxs(2, 1); 187 mv.visitEnd(); 188 } 189 190 private void createTCPutMethod() { 195 MethodVisitor mv = super.visitMethod(0 + ACC_SYNTHETIC, TC_PUT_METHOD_NAME, TC_PUT_METHOD_DESC, null, null); 196 mv.visitCode(); 197 Label l0 = new Label(); 198 mv.visitLabel(l0); 199 mv.visitVarInsn(ALOAD, 0); 200 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "count", "I"); 201 mv.visitVarInsn(ISTORE, 5); 202 Label l1 = new Label(); 203 mv.visitLabel(l1); 204 mv.visitVarInsn(ILOAD, 5); 205 mv.visitIincInsn(5, 1); 206 mv.visitVarInsn(ALOAD, 0); 207 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "threshold", "I"); 208 Label l2 = new Label(); 209 mv.visitJumpInsn(IF_ICMPLE, l2); 210 mv.visitVarInsn(ALOAD, 0); 211 mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/concurrent/ConcurrentHashMap$Segment", "rehash", "()V"); 212 mv.visitLabel(l2); 213 mv.visitVarInsn(ALOAD, 0); 214 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "table", 215 "[Ljava/util/concurrent/ConcurrentHashMap$HashEntry;"); 216 mv.visitVarInsn(ASTORE, 6); 217 Label l3 = new Label(); 218 mv.visitLabel(l3); 219 mv.visitVarInsn(ILOAD, 2); 220 mv.visitVarInsn(ALOAD, 6); 221 mv.visitInsn(ARRAYLENGTH); 222 mv.visitInsn(ICONST_1); 223 mv.visitInsn(ISUB); 224 mv.visitInsn(IAND); 225 mv.visitVarInsn(ISTORE, 7); 226 Label l4 = new Label(); 227 mv.visitLabel(l4); 228 mv.visitVarInsn(ALOAD, 6); 229 mv.visitVarInsn(ILOAD, 7); 230 mv.visitInsn(AALOAD); 231 mv.visitVarInsn(ASTORE, 8); 232 Label l5 = new Label(); 233 mv.visitLabel(l5); 234 mv.visitVarInsn(ALOAD, 8); 235 mv.visitVarInsn(ASTORE, 9); 236 Label l6 = new Label(); 237 mv.visitLabel(l6); 238 Label l7 = new Label(); 239 mv.visitJumpInsn(GOTO, l7); 240 Label l8 = new Label(); 241 mv.visitLabel(l8); 242 mv.visitVarInsn(ALOAD, 9); 243 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "next", 244 "Ljava/util/concurrent/ConcurrentHashMap$HashEntry;"); 245 mv.visitVarInsn(ASTORE, 9); 246 mv.visitLabel(l7); 247 mv.visitVarInsn(ALOAD, 9); 248 Label l9 = new Label(); 249 mv.visitJumpInsn(IFNULL, l9); 250 mv.visitVarInsn(ALOAD, 9); 251 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "hash", "I"); 252 mv.visitVarInsn(ILOAD, 2); 253 mv.visitJumpInsn(IF_ICMPNE, l8); 254 mv.visitVarInsn(ALOAD, 1); 255 mv.visitVarInsn(ALOAD, 9); 256 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "key", "Ljava/lang/Object;"); 257 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z"); 258 mv.visitJumpInsn(IFEQ, l8); 259 mv.visitLabel(l9); 260 mv.visitVarInsn(ALOAD, 9); 261 Label l10 = new Label(); 262 mv.visitJumpInsn(IFNULL, l10); 263 Label l11 = new Label(); 264 mv.visitLabel(l11); 265 mv.visitVarInsn(ALOAD, 9); 266 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "value", "Ljava/lang/Object;"); 267 mv.visitVarInsn(ASTORE, 10); 268 Label l12 = new Label(); 269 mv.visitLabel(l12); 270 mv.visitVarInsn(ILOAD, 4); 271 Label l13 = new Label(); 272 mv.visitJumpInsn(IFNE, l13); 273 Label l14 = new Label(); 274 mv.visitLabel(l14); 275 mv.visitVarInsn(ALOAD, 9); 276 mv.visitVarInsn(ALOAD, 3); 277 mv.visitFieldInsn(PUTFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "value", "Ljava/lang/Object;"); 278 mv.visitJumpInsn(GOTO, l13); 279 mv.visitLabel(l10); 280 mv.visitInsn(ACONST_NULL); 281 mv.visitVarInsn(ASTORE, 10); 282 Label l15 = new Label(); 283 mv.visitLabel(l15); 284 mv.visitVarInsn(ALOAD, 0); 285 mv.visitInsn(DUP); 286 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "modCount", "I"); 287 mv.visitInsn(ICONST_1); 288 mv.visitInsn(IADD); 289 mv.visitFieldInsn(PUTFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "modCount", "I"); 290 Label l16 = new Label(); 291 mv.visitLabel(l16); 292 mv.visitVarInsn(ALOAD, 6); 293 mv.visitVarInsn(ILOAD, 7); 294 mv.visitTypeInsn(NEW, "java/util/concurrent/ConcurrentHashMap$HashEntry"); 295 mv.visitInsn(DUP); 296 mv.visitVarInsn(ALOAD, 1); 297 mv.visitVarInsn(ILOAD, 2); 298 mv.visitVarInsn(ALOAD, 8); 299 mv.visitVarInsn(ALOAD, 3); 300 mv.visitMethodInsn(INVOKESPECIAL, "java/util/concurrent/ConcurrentHashMap$HashEntry", "<init>", 301 "(Ljava/lang/Object;ILjava/util/concurrent/ConcurrentHashMap$HashEntry;Ljava/lang/Object;)V"); 302 mv.visitInsn(AASTORE); 303 Label l17 = new Label(); 304 mv.visitLabel(l17); 305 mv.visitVarInsn(ALOAD, 0); 306 mv.visitVarInsn(ILOAD, 5); 307 mv.visitFieldInsn(PUTFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "count", "I"); 308 mv.visitLabel(l13); 309 mv.visitVarInsn(ALOAD, 10); 310 mv.visitInsn(ARETURN); 311 Label l18 = new Label(); 312 mv.visitLabel(l18); 313 mv.visitMaxs(0, 0); 314 mv.visitEnd(); 315 } 316 317 private void createTCClearMethod() { 320 MethodVisitor mv = super.visitMethod(0, TC_CLEAR_METHOD_NAME, TC_CLEAR_METHOD_DESC, null, null); 321 mv.visitCode(); 322 Label l0 = new Label(); 323 mv.visitLabel(l0); 324 mv.visitVarInsn(ALOAD, 0); 325 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "count", "I"); 326 Label l1 = new Label(); 327 mv.visitJumpInsn(IFEQ, l1); 328 Label l2 = new Label(); 329 mv.visitLabel(l2); 330 mv.visitVarInsn(ALOAD, 0); 331 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "table", 332 "[Ljava/util/concurrent/ConcurrentHashMap$HashEntry;"); 333 mv.visitVarInsn(ASTORE, 1); 334 Label l3 = new Label(); 335 mv.visitLabel(l3); 336 mv.visitInsn(ICONST_0); 337 mv.visitVarInsn(ISTORE, 2); 338 Label l4 = new Label(); 339 mv.visitLabel(l4); 340 Label l5 = new Label(); 341 mv.visitJumpInsn(GOTO, l5); 342 Label l6 = new Label(); 343 mv.visitLabel(l6); 344 mv.visitVarInsn(ALOAD, 1); 345 mv.visitVarInsn(ILOAD, 2); 346 mv.visitInsn(ACONST_NULL); 347 mv.visitInsn(AASTORE); 348 Label l7 = new Label(); 349 mv.visitLabel(l7); 350 mv.visitIincInsn(2, 1); 351 mv.visitLabel(l5); 352 mv.visitVarInsn(ILOAD, 2); 353 mv.visitVarInsn(ALOAD, 1); 354 mv.visitInsn(ARRAYLENGTH); 355 mv.visitJumpInsn(IF_ICMPLT, l6); 356 Label l8 = new Label(); 357 mv.visitLabel(l8); 358 mv.visitVarInsn(ALOAD, 0); 359 mv.visitInsn(DUP); 360 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "modCount", "I"); 361 mv.visitInsn(ICONST_1); 362 mv.visitInsn(IADD); 363 mv.visitFieldInsn(PUTFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "modCount", "I"); 364 Label l9 = new Label(); 365 mv.visitLabel(l9); 366 mv.visitVarInsn(ALOAD, 0); 367 mv.visitInsn(ICONST_0); 368 mv.visitFieldInsn(PUTFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", "count", "I"); 369 mv.visitLabel(l1); 370 mv.visitInsn(RETURN); 371 Label l10 = new Label(); 372 mv.visitLabel(l10); 373 mv.visitMaxs(0, 0); 374 mv.visitEnd(); 375 } 376 377 private void createInitTableMethod() { 378 MethodVisitor mv = super.visitMethod(ACC_PRIVATE + ACC_FINAL + ACC_SYNTHETIC, INITIAL_TABLE_METHOD_NAME, 379 INITIAL_TABLE_METHOD_DESC, null, null); 380 mv.visitCode(); 381 ByteCodeUtil.pushThis(mv); 382 mv.visitVarInsn(ILOAD, 1); 383 mv.visitTypeInsn(ANEWARRAY, "java/util/concurrent/ConcurrentHashMap$HashEntry"); 384 mv.visitMethodInsn(INVOKEVIRTUAL, "java/util/concurrent/ConcurrentHashMap$Segment", "setTable", 385 "([Ljava/util/concurrent/ConcurrentHashMap$HashEntry;)V"); 386 mv.visitInsn(RETURN); 387 mv.visitMaxs(0, 0); 388 mv.visitEnd(); 389 } 390 391 private static class InitMethodAdapter extends MethodAdapter implements Opcodes { 392 public InitMethodAdapter(MethodVisitor mv) { 393 super(mv); 394 } 395 396 public void visitInsn(int opcode) { 397 if (RETURN == opcode) { 398 403 ByteCodeUtil.pushThis(mv); 404 mv.visitVarInsn(ALOAD, 1); 405 mv.visitFieldInsn(PUTFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", 406 PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;"); 407 408 } 409 super.visitInsn(opcode); 410 } 411 412 public void visitVarInsn(int opcode, int var) { 413 if (var == 1) { 414 var = 2; 415 } else if (var == 2) { 416 var = 3; 417 } 418 super.visitVarInsn(opcode, var); 419 } 420 } 421 422 private static class PutMethodAdapter extends MethodAdapter implements Opcodes { 423 424 public PutMethodAdapter(MethodVisitor mv) { 425 super(mv); 426 } 427 428 public void visitFieldInsn(int opcode, String owner, String name, String desc) { 429 super.visitFieldInsn(opcode, owner, name, desc); 430 if (PUTFIELD == opcode && "java/util/concurrent/ConcurrentHashMap$HashEntry".equals(owner) 431 && "value".equals(name) && "Ljava/lang/Object;".equals(desc)) { 432 addFoundLogicalInvokePutMethodCall(); 433 } else if (PUTFIELD == opcode && "java/util/concurrent/ConcurrentHashMap$Segment".equals(owner) 434 && "count".equals(name) && "I".equals(desc)) { 435 addNotFoundLogicalInvokePutMethodCall(); 436 } 437 } 438 439 private void addNotFoundLogicalInvokePutMethodCall() { 440 Label endBlock = new Label(); 441 Label logicalInvokeLabel = new Label(); 442 443 mv.visitLabel(logicalInvokeLabel); 444 445 ByteCodeUtil.pushThis(mv); 446 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", 447 PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;"); 448 mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "isManaged", "(Ljava/lang/Object;)Z"); 449 mv.visitJumpInsn(IFEQ, endBlock); 450 mv.visitVarInsn(ILOAD, 4); 451 Label l0 = new Label(); 452 mv.visitJumpInsn(IFEQ, l0); 453 ByteCodeUtil.pushThis(mv); 454 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", 455 PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;"); 456 mv.visitLdcInsn(SerializationUtil.PUT_SIGNATURE); 457 mv.visitInsn(ICONST_2); 458 mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); 459 mv.visitInsn(DUP); 460 mv.visitInsn(ICONST_0); 461 mv.visitVarInsn(ALOAD, 1); 462 mv.visitInsn(AASTORE); 463 mv.visitInsn(DUP); 464 mv.visitInsn(ICONST_1); 465 mv.visitVarInsn(ALOAD, 3); 466 mv.visitInsn(AASTORE); 467 mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "logicalInvoke", 468 "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V"); 469 mv.visitJumpInsn(GOTO, endBlock); 470 mv.visitLabel(l0); 471 ByteCodeUtil.pushThis(mv); 472 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", 473 PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;"); 474 mv.visitLdcInsn(SerializationUtil.PUT_SIGNATURE); 475 mv.visitInsn(ICONST_2); 476 mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); 477 mv.visitInsn(DUP); 478 mv.visitInsn(ICONST_0); 479 mv.visitVarInsn(ALOAD, 1); 480 mv.visitInsn(AASTORE); 481 mv.visitInsn(DUP); 482 mv.visitInsn(ICONST_1); 483 mv.visitVarInsn(ALOAD, 3); 484 mv.visitInsn(AASTORE); 485 mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "logicalInvoke", 486 "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V"); 487 mv.visitLabel(endBlock); 488 } 489 490 private void addFoundLogicalInvokePutMethodCall() { 491 Label notManaged = new Label(); 492 Label logicalInvokeLabel = new Label(); 493 494 mv.visitLabel(logicalInvokeLabel); 495 496 ByteCodeUtil.pushThis(mv); 497 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", 498 PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;"); 499 mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "isManaged", "(Ljava/lang/Object;)Z"); 500 mv.visitJumpInsn(IFEQ, notManaged); 501 ByteCodeUtil.pushThis(mv); 502 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", 503 PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;"); 504 mv.visitLdcInsn(SerializationUtil.PUT_SIGNATURE); 505 mv.visitInsn(ICONST_2); 506 mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); 507 mv.visitInsn(DUP); 508 mv.visitInsn(ICONST_0); 509 mv.visitVarInsn(ALOAD, 9); 510 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "key", "Ljava/lang/Object;"); 511 mv.visitInsn(AASTORE); 512 mv.visitInsn(DUP); 513 mv.visitInsn(ICONST_1); 514 mv.visitVarInsn(ALOAD, 3); 515 mv.visitInsn(AASTORE); 516 mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "logicalInvoke", 517 "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V"); 518 mv.visitLabel(notManaged); 519 } 520 } 521 522 private static class ReplaceMethodAdapter extends MethodAdapter implements Opcodes { 523 524 public ReplaceMethodAdapter(MethodVisitor mv) { 525 super(mv); 526 } 527 528 public void visitFieldInsn(int opcode, String owner, String name, String desc) { 529 super.visitFieldInsn(opcode, owner, name, desc); 530 if (PUTFIELD == opcode && "java/util/concurrent/ConcurrentHashMap$HashEntry".equals(owner) 531 && "value".equals(name) && "Ljava/lang/Object;".equals(desc)) { 532 addLogicalInvokeReplaceMethodCall(); 533 } 534 } 535 536 public void addLogicalInvokeReplaceMethodCall() { 537 Label notManaged = new Label(); 538 ByteCodeUtil.pushThis(this); 539 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", 540 PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;"); 541 mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "isManaged", "(Ljava/lang/Object;)Z"); 542 mv.visitJumpInsn(IFEQ, notManaged); 543 mv.visitVarInsn(ALOAD, 0); 544 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", 545 PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;"); 546 mv.visitLdcInsn(SerializationUtil.PUT_SIGNATURE); 547 mv.visitInsn(ICONST_2); 548 mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); 549 mv.visitInsn(DUP); 550 mv.visitInsn(ICONST_0); 551 mv.visitVarInsn(ALOAD, 4); 552 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "key", "Ljava/lang/Object;"); 553 mv.visitInsn(AASTORE); 554 mv.visitInsn(DUP); 555 mv.visitInsn(ICONST_1); 556 mv.visitVarInsn(ALOAD, 3); 557 mv.visitInsn(AASTORE); 558 mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "logicalInvoke", 559 "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V"); 560 mv.visitLabel(notManaged); 561 } 562 } 563 564 private static class ReplaceIfValueEqualMethodAdapter extends MethodAdapter implements Opcodes { 565 566 public ReplaceIfValueEqualMethodAdapter(MethodVisitor mv) { 567 super(mv); 568 } 569 570 public void visitFieldInsn(int opcode, String owner, String name, String desc) { 571 if (PUTFIELD == opcode && "java/util/concurrent/ConcurrentHashMap$HashEntry".equals(owner) 572 && "value".equals(name) && "Ljava/lang/Object;".equals(desc)) { 573 addLogicalInvokeReplaceMethodCall(); 574 } 575 super.visitFieldInsn(opcode, owner, name, desc); 576 } 577 578 public void addLogicalInvokeReplaceMethodCall() { 579 Label notManaged = new Label(); 580 ByteCodeUtil.pushThis(mv); 581 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", 582 PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;"); 583 mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "isManaged", "(Ljava/lang/Object;)Z"); 584 mv.visitJumpInsn(IFEQ, notManaged); 585 ByteCodeUtil.pushThis(mv); 586 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", 587 PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;"); 588 mv.visitLdcInsn(SerializationUtil.PUT_SIGNATURE); 589 mv.visitInsn(ICONST_2); 590 mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); 591 mv.visitInsn(DUP); 592 mv.visitInsn(ICONST_0); 593 mv.visitVarInsn(ALOAD, 5); 594 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "key", "Ljava/lang/Object;"); 595 mv.visitInsn(AASTORE); 596 mv.visitInsn(DUP); 597 mv.visitInsn(ICONST_1); 598 mv.visitVarInsn(ALOAD, 4); 599 mv.visitInsn(AASTORE); 600 mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "logicalInvoke", 601 "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V"); 602 mv.visitLabel(notManaged); 603 } 604 } 605 606 private static class RemoveMethodAdapter extends MethodAdapter implements Opcodes { 607 608 public RemoveMethodAdapter(MethodVisitor mv) { 609 super(mv); 610 } 611 612 631 public void visitFieldInsn(int opcode, String owner, String name, String desc) { 632 super.visitFieldInsn(opcode, owner, name, desc); 633 if (PUTFIELD == opcode && "java/util/concurrent/ConcurrentHashMap$Segment".equals(owner) && "count".equals(name) 634 && "I".equals(desc)) { 635 addLogicalInvokeRemoveMethodCall(); 636 } 637 } 638 639 public void addLogicalInvokeRemoveMethodCall() { 640 Label notManaged = new Label(); 641 Label logicalInvokeLabel = new Label(); 642 643 mv.visitLabel(logicalInvokeLabel); 644 645 ByteCodeUtil.pushThis(mv); 646 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", 647 PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;"); 648 mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "isManaged", "(Ljava/lang/Object;)Z"); 649 mv.visitJumpInsn(IFEQ, notManaged); 650 mv.visitVarInsn(ALOAD, 0); 651 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", 652 PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;"); 653 mv.visitLdcInsn(SerializationUtil.REMOVE_SIGNATURE); 654 mv.visitInsn(ICONST_1); 655 mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); 656 mv.visitInsn(DUP); 657 mv.visitInsn(ICONST_0); 658 mv.visitVarInsn(ALOAD, 8); 659 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$HashEntry", "key", "Ljava/lang/Object;"); 660 mv.visitInsn(AASTORE); 661 mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "logicalInvoke", 662 "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V"); 663 mv.visitLabel(notManaged); 664 } 665 } 666 667 private static class ClearMethodAdapter extends MethodAdapter implements Opcodes { 668 669 public ClearMethodAdapter(MethodVisitor mv) { 670 super(mv); 671 } 672 673 public void visitMethodInsn(int opcode, String owner, String name, String desc) { 674 super.visitMethodInsn(opcode, owner, name, desc); 675 if ("lock".equals(name) && "()V".equals(desc)) { 676 addLogicalInvokeMethodCall(); 677 } 678 } 679 680 public void addLogicalInvokeMethodCall() { 681 ByteCodeUtil.pushThis(mv); 682 mv.visitFieldInsn(GETFIELD, "java/util/concurrent/ConcurrentHashMap$Segment", 683 PARENT_CONCURRENT_HASH_MAP_FIELD_NAME, "Ljava/util/concurrent/ConcurrentHashMap;"); 684 mv.visitLdcInsn(SerializationUtil.CLEAR_SIGNATURE); 685 686 mv.visitLdcInsn(new Integer (0)); 687 mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); 688 689 mv.visitMethodInsn(INVOKESTATIC, "com/tc/object/bytecode/ManagerUtil", "logicalInvoke", 690 "(Ljava/lang/Object;Ljava/lang/String;[Ljava/lang/Object;)V"); 691 } 692 } 693 } | Popular Tags |