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