package ex11; import ch.usi.dag.disl.annotation.Before; import ch.usi.dag.disl.annotation.ThreadLocal; import ch.usi.dag.disl.marker.BodyMarker; import ch.usi.dag.disl.marker.BytecodeMarker; import ch.usi.dag.disl.staticcontext.InstructionStaticContext; import ch.usi.dag.disl.staticcontext.InvocationStaticContext; import ch.usi.dag.disl.staticcontext.MethodStaticContext; public class Instrumentation { @ThreadLocal private static int opCode; @ThreadLocal private static int index; @ThreadLocal private static String callee; @ThreadLocal private static String caller; @ThreadLocal private static boolean initialized; @Before(marker = BytecodeMarker.class, args = "invokevirtual, invokeinterface") static void atObjectRefCallSite(final InstructionStaticContext isc, final MethodStaticContext msc, final InvocationStaticContext ivc) { opCode = isc.getOpcode(); index = isc.getIndex(); caller = msc.thisMethodFullName().concat(msc.thisMethodDescriptor()); callee = ivc.getInternalName().concat(ivc.getDescriptor()); initialized = true; } @Before(marker = BytecodeMarker.class, args = "invokedynamic") static void atObjectRefCallSiteDynamic(final InstructionStaticContext isc, final MethodStaticContext msc, final InvocationStaticContext ivc) { opCode = isc.getOpcode(); index = isc.getIndex(); caller = msc.thisMethodFullName().concat(msc.thisMethodDescriptor()); callee = "[UNDETERMINED]"; initialized = true; } @Before(marker = BodyMarker.class, guard = IsNotConstructorOrPrivateMethod.class) static void beforeMethod(MethodStaticContext msc) { // we can ignore here constructors and private methods since we know they must be invoked with "invokespecial" // which performs static binding. Instrumenting the constructor of java.lang.Object would actually cause a // segmentation fault of the JVM. if (initialized) { Profiler.registerCall(new CallInfo(opCode, index, caller, callee, msc.getUniqueInternalName())); initialized = false; } } @Before(marker = BytecodeMarker.class, args = "invokestatic, invokespecial") static void atStaticCallSite(final InstructionStaticContext isc, final MethodStaticContext msc, final InvocationStaticContext ivc) { final String v = ivc.getInternalName().concat(ivc.getDescriptor()); Profiler.registerCall(new CallInfo( isc.getOpcode(), isc.getIndex(), msc.thisMethodFullName().concat(msc.thisMethodDescriptor()), v, v )); } }