diff --git a/DiSLProject2022/src-profiler/ex10/CustomMarker.java b/DiSLProject2022/src-profiler/ex10/CustomMarker.java deleted file mode 100644 index be70f6c..0000000 --- a/DiSLProject2022/src-profiler/ex10/CustomMarker.java +++ /dev/null @@ -1,2 +0,0 @@ -package ex10;public class CustomMarker { -} diff --git a/DiSLProject2022/src-profiler/ex10/CustomStaticContext.java b/DiSLProject2022/src-profiler/ex10/CustomStaticContext.java deleted file mode 100644 index ceb41d2..0000000 --- a/DiSLProject2022/src-profiler/ex10/CustomStaticContext.java +++ /dev/null @@ -1,2 +0,0 @@ -package ex10;public class CustomStaticContext { -} diff --git a/DiSLProject2022/src-profiler/ex10/DeclarationGuard.java b/DiSLProject2022/src-profiler/ex10/DeclarationGuard.java deleted file mode 100644 index 73320d7..0000000 --- a/DiSLProject2022/src-profiler/ex10/DeclarationGuard.java +++ /dev/null @@ -1,2 +0,0 @@ -package ex10;public class DeclarationGuard { -} diff --git a/DiSLProject2022/src-profiler/ex10/Instrumentation.java b/DiSLProject2022/src-profiler/ex10/Instrumentation.java index 3925438..f0fee68 100644 --- a/DiSLProject2022/src-profiler/ex10/Instrumentation.java +++ b/DiSLProject2022/src-profiler/ex10/Instrumentation.java @@ -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 classes = List.of("ex10.Player", "ex10.VideoGamePlayer"); + for (final String clazzName : classes) { + try { + final Class clazz = cls.loadClass(clazzName); + final Set 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); + } + } + } } diff --git a/DiSLProject2022/src-profiler/ex10/MethodDecoder.java b/DiSLProject2022/src-profiler/ex10/MethodDecoder.java deleted file mode 100644 index 410753f..0000000 --- a/DiSLProject2022/src-profiler/ex10/MethodDecoder.java +++ /dev/null @@ -1,2 +0,0 @@ -package ex10;public class MethodDecoder { -} diff --git a/DiSLProject2022/src-profiler/ex10/Profiler.java b/DiSLProject2022/src-profiler/ex10/Profiler.java new file mode 100644 index 0000000..3064a96 --- /dev/null +++ b/DiSLProject2022/src-profiler/ex10/Profiler.java @@ -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> methodInvocations = new ConcurrentHashMap<>(); + + private static final ConcurrentMap> methodDeclarations = new ConcurrentHashMap<>(); + + + private static final ConcurrentMap> 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> 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); + } +}