1 package ch.ethz.prose.jvmai.jikesrvm.advice_weaver; 2 3 import java.lang.reflect.*; 4 import java.util.*; 5 6 import ch.ethz.jvmai.*; 7 8 import com.ibm.JikesRVM.VM_Callbacks; 9 import com.ibm.JikesRVM.VM_Thread; 10 import com.ibm.JikesRVM.classloader.*; 11 12 18 public class AdviceJVMAI 19 implements VM_Callbacks.ClassLoadedMonitor, VM_Callbacks.ExceptionThrownMonitor, VM_Callbacks.ExceptionCaughtMonitor, JVMAspectInterface { 20 21 24 protected static AdviceJVMAI instance; 25 26 29 protected static BitSet suspendedThreads; 30 31 34 protected static boolean initialized; 35 36 39 protected static JoinPointHook hook; 40 41 45 protected static Object [] fieldAccessTags; 46 protected static Object [] fieldModificationTags; 47 protected static Object [] methodEntryTags; 48 protected static Object [] methodExitTags; 49 protected static Object [] exceptionThrowTags; 50 protected static Object [] exceptionCatchTags; 51 52 56 protected static Object aopNullTag = new Object (); 57 58 protected static MethodEntryJoinPointImpl methodEntryJoinPoint = new MethodEntryJoinPointImpl(); 59 protected static MethodExitJoinPointImpl methodExitJoinPoint = new MethodExitJoinPointImpl(); 60 protected static FieldAccessJoinPointImpl fieldAccessJoinPoint = new FieldAccessJoinPointImpl(); 61 protected static FieldModificationJoinPointImpl fieldModificationJoinPoint = new FieldModificationJoinPointImpl(); 62 protected static ExceptionThrowJoinPointImpl exceptionThrowJoinPoint = new ExceptionThrowJoinPointImpl(); 63 protected static ExceptionCatchJoinPointImpl exceptionCatchJoinPoint = new ExceptionCatchJoinPointImpl(); 64 65 70 public static AdviceJVMAI getInstance() { 71 if (instance == null) { 72 instance = new AdviceJVMAI(); 73 VM_Callbacks.addClassLoadedMonitor(instance); 74 VM_Callbacks.addExceptionThrownMonitor(instance); 75 VM_Callbacks.addExceptionCaughtMonitor(instance); 76 } 77 return instance; 78 } 79 80 88 public static final void onMethodEntry(int methodId, Object this0, Object [] args) { 89 if (hook == null || suspendedThreads.get(VM_Thread.getCurrentThread().getIndex())) 90 return; 91 92 methodEntryJoinPoint.init(methodId, methodEntryTags[methodId], this0, args); 94 hook.onMethodEntry(methodEntryJoinPoint); 95 } 96 97 105 public static final void onMethodExit(int methodId, Object this0, Object [] args) { 106 if (hook == null || suspendedThreads.get(VM_Thread.getCurrentThread().getIndex())) 107 return; 108 109 methodExitJoinPoint.init(methodId, methodExitTags[methodId], this0, args); 111 hook.onMethodExit(methodExitJoinPoint); 112 } 113 114 125 public static final void onFieldAccess(Object owner, int fieldId, int methodId, Object this0, Object [] args) { 126 if (hook == null || suspendedThreads.get(VM_Thread.getCurrentThread().getIndex())) 127 return; 128 129 fieldAccessJoinPoint.init(methodId, fieldAccessTags[fieldId], this0, args, fieldId, owner); 130 hook.onFieldAccess(fieldAccessJoinPoint); 133 } 134 135 147 public static final void onFieldModification(Object owner, int fieldId, int methodId, Object this0, Object [] args) { 148 if (hook == null || suspendedThreads.get(VM_Thread.getCurrentThread().getIndex())) 149 return; 150 151 fieldModificationJoinPoint.init(methodId, fieldModificationTags[fieldId], this0, args, fieldId, owner); 153 hook.onFieldModification(fieldModificationJoinPoint); 155 } 156 157 160 protected AdviceJVMAI() {} 161 162 public void notifyClassLoaded(VM_Class klass) { 163 if (!initialized || hook == null || suspendedThreads.get(VM_Thread.getCurrentThread().getIndex())) 164 return; 165 166 hook.onClassLoad(klass.getClassForType()); 168 } 169 170 public final void notifyExceptionThrown(Throwable exception, VM_Method thrower) { 171 if (hook == null) 172 return; 173 174 int id = java.lang.JikesRVMSupport.getTypeForClass(exception.getClass()).getId(); 175 if (id >= exceptionThrowTags.length) 176 return; 177 178 Object tag = exceptionThrowTags[id]; 179 if (tag == null) 180 return; 181 182 if (suspendedThreads.get(VM_Thread.getCurrentThread().getIndex())) 183 return; 184 185 if (thrower.getDeclaringClass().toString().startsWith("com.ibm.JikesRVM.")) 187 return; 188 189 exceptionThrowJoinPoint.init(thrower.getId(), tag, null, null, exception); 190 hook.onExceptionThrow(exceptionThrowJoinPoint); 192 } 193 194 public final void notifyExceptionCaught(Throwable exception, VM_Method catcher) { 195 if (hook == null) 196 return; 197 198 int id = java.lang.JikesRVMSupport.getTypeForClass(exception.getClass()).getId(); 199 if (id >= exceptionCatchTags.length) 200 return; 201 202 Object tag = exceptionCatchTags[id]; 203 if (tag == null) 204 return; 205 206 if (suspendedThreads.get(VM_Thread.getCurrentThread().getIndex())) 207 return; 208 209 if (catcher.getDeclaringClass().toString().startsWith("com.ibm.JikesRVM.")) 211 return; 212 213 exceptionCatchJoinPoint.init(catcher.getId(), tag, null, null, exception); 214 hook.onExceptionCatch(exceptionCatchJoinPoint); 216 } 217 218 public void startup(String [] packagePrefixes, boolean openWorldAssumption) { 219 fieldAccessTags = new Object [1024]; 220 fieldModificationTags = new Object [1024]; 221 methodEntryTags = new Object [1024]; 222 methodExitTags = new Object [1024]; 223 exceptionThrowTags = new Object [1024]; 224 exceptionCatchTags = new Object [1024]; 225 suspendedThreads = new BitSet(1024); 226 227 initialized = true; 228 } 229 230 public void teardown() { 231 hook = null; 233 initialized = false; 234 235 fieldAccessTags = null; 236 fieldModificationTags = null; 237 methodEntryTags = null; 238 methodExitTags = null; 239 exceptionThrowTags = null; 240 exceptionCatchTags = null; 241 suspendedThreads.clear(); 242 243 FieldWeaver.resetAll(); 244 MethodWeaver.resetAll(); 245 } 246 247 public void setJoinPointHook(JoinPointHook h) { 248 if (!initialized) 249 throw new NotInitializedException(); 250 251 hook = h; 252 } 253 254 public void setFieldAccessWatch(Field f, Object aopTag) { 255 if (!initialized) 256 throw new NotInitializedException(); 257 if (f == null) 258 throw new NullPointerException ("Parameter `f' must not be null."); 259 if (aopTag == null) 260 throw new NullPointerException ("Parameter `aopTag' must not be null."); 261 262 int id = java.lang.reflect.JikesRVMSupport.getFieldOf(f).getId(); 264 fieldAccessTags = setWatch(fieldAccessTags, aopTag, id); 265 FieldWeaver.getWeaver(f).setFieldAccessEnabled(true); 266 } 267 268 public void clearFieldAccessWatch(Field f) { 269 if (!initialized) 270 throw new NotInitializedException(); 271 if (f == null) 272 throw new NullPointerException ("Parameter `f' must not be null."); 273 274 int id = java.lang.reflect.JikesRVMSupport.getFieldOf(f).getId(); 275 clearWatch(fieldAccessTags, id); 276 FieldWeaver.getWeaver(f).setFieldAccessEnabled(false); 277 } 278 279 public void setFieldModificationWatch(Field f, Object aopTag) { 280 if (!initialized) 281 throw new NotInitializedException(); 282 if (f == null) 283 throw new NullPointerException ("Parameter `f' must not be null."); 284 if (aopTag == null) 285 throw new NullPointerException ("Parameter `aopTag' must not be null."); 286 287 int id = java.lang.reflect.JikesRVMSupport.getFieldOf(f).getId(); 289 fieldModificationTags = setWatch(fieldModificationTags, aopTag, id); 290 FieldWeaver.getWeaver(f).setFieldModificationEnabled(true); 291 } 292 293 public void clearFieldModificationWatch(Field f) { 294 if (!initialized) 295 throw new NotInitializedException(); 296 if (f == null) 297 throw new NullPointerException ("Parameter `f' must not be null."); 298 299 int id = java.lang.reflect.JikesRVMSupport.getFieldOf(f).getId(); 300 clearWatch(fieldModificationTags, id); 301 FieldWeaver.getWeaver(f).setFieldModificationEnabled(false); 302 } 303 304 public void setMethodEntryWatch(Method m, Object aopTag) { 305 if (!initialized) 306 throw new NotInitializedException(); 307 if (m == null) 308 throw new NullPointerException ("Parameter `m' must not be null."); 309 if (aopTag == null) 310 throw new NullPointerException ("Parameter `aopTag' must not be null."); 311 if (Modifier.isAbstract(m.getModifiers())) 312 throw new CannotSetWatchException("Method is abstract: " + m); 313 314 int id = java.lang.reflect.JikesRVMSupport.getMethodOf(m).getId(); 316 methodEntryTags = setWatch(methodEntryTags, aopTag, id); 317 MethodWeaver.getWeaver(m).setMethodEntryEnabled(true); 318 } 319 320 public void clearMethodEntryWatch(Method m) { 321 if (!initialized) 322 throw new NotInitializedException(); 323 if (m == null) 324 throw new NullPointerException ("Parameter `m' must not be null."); 325 326 int id = java.lang.reflect.JikesRVMSupport.getMethodOf(m).getId(); 328 clearWatch(methodEntryTags, id); 329 MethodWeaver.getWeaver(m).setMethodEntryEnabled(false); 330 } 331 332 public void setMethodExitWatch(Method m, Object aopTag) { 333 if (!initialized) 334 throw new NotInitializedException(); 335 if (m == null) 336 throw new NullPointerException ("Parameter `m' must not be null."); 337 if (aopTag == null) 338 throw new NullPointerException ("Parameter `aopTag' must not be null."); 339 if (Modifier.isAbstract(m.getModifiers())) 340 throw new CannotSetWatchException("Method is abstract: " + m); 341 342 int id = java.lang.reflect.JikesRVMSupport.getMethodOf(m).getId(); 344 methodExitTags = setWatch(methodExitTags, aopTag, id); 345 MethodWeaver.getWeaver(m).setMethodExitEnabled(true); 346 } 347 348 public void clearMethodExitWatch(Method m) { 349 if (!initialized) 350 throw new NotInitializedException(); 351 if (m == null) 352 throw new NullPointerException ("Parameter `m' must not be null."); 353 354 int id = java.lang.reflect.JikesRVMSupport.getMethodOf(m).getId(); 356 clearWatch(methodExitTags, id); 357 MethodWeaver.getWeaver(m).setMethodExitEnabled(false); 358 } 359 360 public void setExceptionThrowWatch(Class c, Object aopTag) { 361 if (!initialized) 362 throw new NotInitializedException(); 363 if (c == null) 364 throw new NullPointerException ("Parameter `c' must not be null."); 365 if (aopTag == null) 366 throw new NullPointerException ("Parameter `aopTag' must not be null."); 367 368 int id = java.lang.JikesRVMSupport.getTypeForClass(c).getId(); 370 exceptionThrowTags = setWatch(exceptionThrowTags, aopTag, id); 371 } 372 373 public void clearExceptionThrowWatch(Class c) { 374 if (!initialized) 375 throw new NotInitializedException(); 376 if (c == null) 377 throw new NullPointerException ("Parameter `c' must not be null."); 378 379 int id = java.lang.JikesRVMSupport.getTypeForClass(c).getId(); 380 clearWatch(exceptionThrowTags, id); 381 } 382 383 public void setExceptionCatchWatch(Class c, Object aopTag) { 384 if (!initialized) 385 throw new NotInitializedException(); 386 if (c == null) 387 throw new NullPointerException ("Parameter `c' must not be null."); 388 if (aopTag == null) 389 throw new NullPointerException ("Parameter `aopTag' must not be null."); 390 391 int id = java.lang.JikesRVMSupport.getTypeForClass(c).getId(); 393 exceptionCatchTags = setWatch(exceptionCatchTags, aopTag, id); 394 } 395 396 public void clearExceptionCatchWatch(Class c) { 397 if (!initialized) 398 throw new NotInitializedException(); 399 if (c == null) 400 throw new NullPointerException ("Parameter `c' must not be null."); 401 402 int id = java.lang.JikesRVMSupport.getTypeForClass(c).getId(); 403 clearWatch(exceptionCatchTags, id); 404 } 405 406 public void suspendNotification(Thread thread) { 407 if (!initialized) 408 throw new NotInitializedException(); 409 if (thread == null) 410 throw new NullPointerException ("Parameter `thread' must not be null"); 411 412 suspendedThreads.set(thread.getIndex()); 413 } 414 415 public void resumeNotification(Thread thread) { 416 if (!initialized) 417 throw new NotInitializedException(); 418 if (thread == null) 419 throw new NullPointerException ("Parameter `thread' must not be null"); 420 421 FieldWeaver.commit(); 422 MethodWeaver.commit(); 423 suspendedThreads.set(thread.getIndex(), false); 424 } 425 426 public List getLoadedClasses() { 427 if (!initialized) 428 throw new NotInitializedException(); 429 430 VM_Type[] types = VM_Type.getTypes(); 431 Vector classes = new Vector(); 432 433 for (int t = 0; t < types.length; t++) { 434 if ((types[t] == null) || !types[t].isClassType()) 435 continue; 436 437 VM_Class klass = types[t].asClass(); 438 if (!klass.isResolved() || klass.toString().startsWith("com.ibm.JikesRVM.")) 439 continue; 440 441 classes.add(klass.getClassForType()); 442 } 443 444 return classes; 445 } 446 447 451 protected Object [] setWatch(Object [] tags, Object tag, int id) { 452 synchronized (tags) { 453 try { 454 if (tags[id] != null) 455 throw new WatchAlreadySetException("<" + id + ">"); 456 } catch (ArrayIndexOutOfBoundsException e) { 457 Object tmp[] = new Object [2 * id]; 458 System.arraycopy(tags, 0, tmp, 0, tags.length); 459 tags = tmp; 460 } 461 tags[id] = (tag == null) ? aopNullTag : tag; 462 } 463 return tags; 464 } 465 466 473 protected void clearWatch(Object [] tags, int id) { 474 synchronized (tags) { 475 try { 476 if (tags[id] == null) 477 throw new WatchNotSetException("<" + id + ">"); 478 tags[id] = null; 479 } catch (ArrayIndexOutOfBoundsException e) { 480 throw new WatchNotSetException("<" + id + ">"); 481 } 482 } 483 } 484 485 } 486 | Popular Tags |