This commit is contained in:
Claudio Maggioni 2023-01-09 17:39:09 +01:00
parent df3ab8626b
commit 5773ffe1b6
6 changed files with 101 additions and 8 deletions

View File

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

View File

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

View File

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

View File

@ -1,4 +1,51 @@
package ex10;
import ch.usi.dag.disl.annotation.After;
import ch.usi.dag.disl.annotation.Before;
import ch.usi.dag.disl.dynamiccontext.DynamicContext;
import ch.usi.dag.disl.marker.BodyMarker;
import ch.usi.dag.disl.staticcontext.ClassStaticContext;
import ch.usi.dag.disl.staticcontext.MethodStaticContext;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Instrumentation {
@Before(marker = BodyMarker.class,
scope = "ex10.VideoGamePlayer.*")
static void instrumentCall(final ClassStaticContext csc, final MethodStaticContext msc) {
Profiler.registerInvoke(csc.getName(), msc.thisMethodName());
}
@Before(marker = BodyMarker.class,
scope = "ex10.Player.*")
static void instrumentCallPlayer(final ClassStaticContext csc, final MethodStaticContext msc) {
Profiler.registerInvoke(csc.getName(), msc.thisMethodName());
}
@After(marker = BodyMarker.class,
scope = "ex10.Main.main")
static void instrumentMain() {
final ClassLoader cls = ClassLoader.getSystemClassLoader();
final List<String> classes = List.of("ex10.Player", "ex10.VideoGamePlayer");
for (final String clazzName : classes) {
try {
final Class<?> clazz = cls.loadClass(clazzName);
final Set<Method> declaredMethods = Set.of(clazz.getDeclaredMethods());
for (final Method m : declaredMethods) {
Profiler.registerDeclare(clazzName, m.toString());
}
for (final Method m : clazz.getMethods()) {
if (declaredMethods.contains(m)) {
continue;
}
Profiler.registerInherited(clazzName, m.toString());
}
} catch (final ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
}

View File

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

View File

@ -0,0 +1,54 @@
package ex10;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
public class Profiler {
private static final ConcurrentMap<String, Set<String>> methodInvocations = new ConcurrentHashMap<>();
private static final ConcurrentMap<String, Set<String>> methodDeclarations = new ConcurrentHashMap<>();
private static final ConcurrentMap<String, Set<String>> inheritedMethods = new ConcurrentHashMap<>();
static {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
for (final String className : methodInvocations.keySet()) {
System.out.println("=== Class Name: " + className + " ===");
for (final String method : methodDeclarations.get(className)) {
System.out.println("Declared: " + method);
}
for (final String method : inheritedMethods.get(className)) {
System.out.println("Inherited: " + method);
}
for (final String method : methodInvocations.get(className)) {
System.out.println("Executed: " + className.replace('.', '/') + "." + method);
}
}
}));
}
private Profiler() {
}
private static void register(final String className, final String methodName, final ConcurrentMap<String, Set<String>> methods) {
methods.computeIfAbsent(className, ignored -> Collections.synchronizedSet(new HashSet<>()))
.add(methodName);
}
public static void registerInvoke(final String className, final String methodName) {
register(className, methodName, methodInvocations);
}
public static void registerDeclare(final String className, final String methodName) {
register(className, methodName, methodDeclarations);
}
public static void registerInherited(final String className, final String methodName) {
register(className, methodName, inheritedMethods);
}
}