This commit is contained in:
Claudio Maggioni 2023-01-07 17:48:53 +01:00
parent a78c260dbf
commit 8bf55cf46a
9 changed files with 84 additions and 5 deletions

View File

@ -0,0 +1,2 @@
package ex10;public class CustomMarker {
}

View File

@ -0,0 +1,2 @@
package ex10;public class CustomStaticContext {
}

View File

@ -0,0 +1,2 @@
package ex10;public class DeclarationGuard {
}

View File

@ -0,0 +1,2 @@
package ex10;public class MethodDecoder {
}

View File

@ -1,7 +1,6 @@
package ex2;
import ch.usi.dag.disl.annotation.GuardMethod;
import ch.usi.dag.disl.dynamiccontext.DynamicContext;
import ch.usi.dag.disl.staticcontext.ClassStaticContext;
import ch.usi.dag.disl.staticcontext.MethodStaticContext;

View File

@ -1,6 +1,5 @@
package ex2;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.LongAdder;
@ -15,9 +14,9 @@ public final class Profiler {
static {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.printf("Instance field read access: %d\nInstance field write access: %d\n",
reads.longValue(),
writes.longValue());
System.out.printf("Instance field read access: %d\nInstance field write access: %d\n",
reads.longValue(),
writes.longValue());
}));
}

View File

@ -1,4 +1,35 @@
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());
}
}

View File

@ -0,0 +1,11 @@
package ex9;
import ch.usi.dag.disl.annotation.GuardMethod;
import ch.usi.dag.disl.staticcontext.MethodStaticContext;
public class IsNotConstructorOrStaticGuard {
@GuardMethod
public static boolean isNotConstructorOrStatic(final MethodStaticContext msc) {
return !msc.isMethodStatic() && !msc.isMethodConstructor();
}
}

View File

@ -0,0 +1,31 @@
package ex9;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public final class Profiler {
private static final ConcurrentMap<String, List<String>> callLog = new ConcurrentHashMap<>();
static {
Runtime.getRuntime().addShutdownHook(new Thread(Profiler::print));
}
private Profiler() {
}
public static void logCall(final Thread thread, final String methodName) {
final List<String> list = callLog.computeIfAbsent(thread.getName(), ignored -> new LinkedList<>());
// thread safe, as once a thread accesses its own list access to said list is non-concurrent
list.add(methodName);
}
private static void print() {
for (final String threadName : callLog.keySet()) {
System.out.printf("=== %s ===\n", threadName);
callLog.get(threadName).forEach(System.out::println);
}
}
}