package ex9; import ch.usi.dag.disl.annotation.Before; import ch.usi.dag.disl.marker.BodyMarker; import ch.usi.dag.disl.marker.BytecodeMarker; import ch.usi.dag.disl.staticcontext.InvocationStaticContext; import ch.usi.dag.disl.staticcontext.MethodStaticContext; public class Instrumentation { @Before(marker = BytecodeMarker.class, args = "invokevirtual, invokespecial, invokeinterface, invokestatic", guard = IsNotConstructorOrStaticGuard.class, scope = "ex9.MainThread.*") static void logCall(final InvocationStaticContext isc) { // this will log calls for all types of methods (including constructors and static initializers). // However, constructors and static initializers will not be instrumented thanks to the included guard. // Should calls to constructors and static methods not be instrumented, add the following line: // // if (isc.isConstructor()) return; // // and remove `invokestatic` from the BytecodeMarker argument list Profiler.logCall(Thread.currentThread(), isc.getInternalName()); } @Before(marker = BodyMarker.class, guard = IsNotConstructorOrStaticGuard.class, scope = "ex9.MainThread.run") static void logThreadStart(final MethodStaticContext msc) { // We separately instrument the Thread.run() method as there is no obvious way to instrument the caller of // Thread.run(). Hence, we log the call at method start. Profiler.logCall(Thread.currentThread(), msc.thisMethodFullName()); } }