diff --git a/DiSLProject2022/src-profiler/ex5/Instrumentation.java b/DiSLProject2022/src-profiler/ex5/Instrumentation.java index 3c44945..af00773 100644 --- a/DiSLProject2022/src-profiler/ex5/Instrumentation.java +++ b/DiSLProject2022/src-profiler/ex5/Instrumentation.java @@ -1,14 +1,11 @@ package ex5; 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.marker.BytecodeMarker; -import ch.usi.dag.disl.staticcontext.MethodStaticContext; -//import jdk.internal.misc.Unsafe; public class Instrumentation { - @Before(marker = BytecodeMarker.class, args = "new,newarray,anewarray,multianewarray", scope = "*") + @Before(marker = BytecodeMarker.class, args = "new,newarray,anewarray,multianewarray") static void handleSafeAllocation() { Profiler.addSafeAllocation(); } diff --git a/DiSLProject2022/src-profiler/ex6/Instrumentation.java b/DiSLProject2022/src-profiler/ex6/Instrumentation.java index e9e90da..e86003d 100644 --- a/DiSLProject2022/src-profiler/ex6/Instrumentation.java +++ b/DiSLProject2022/src-profiler/ex6/Instrumentation.java @@ -1,32 +1,17 @@ package ex6; import ch.usi.dag.disl.annotation.Before; +import ch.usi.dag.disl.marker.BasicBlockMarker; import ch.usi.dag.disl.marker.BytecodeMarker; +import ch.usi.dag.disl.staticcontext.LoopStaticContext; import ch.usi.dag.disl.staticcontext.MethodStaticContext; -import org.objectweb.asm.Opcodes; -import org.objectweb.asm.util.Printer; public class Instrumentation { - final static String[] BRANCH_OP_NAMES = new String[]{ - Printer.OPCODES[Opcodes.GOTO], - Printer.OPCODES[Opcodes.IF_ACMPEQ], - Printer.OPCODES[Opcodes.IF_ACMPNE], - Printer.OPCODES[Opcodes.IF_ICMPEQ], - Printer.OPCODES[Opcodes.IF_ICMPGE], - Printer.OPCODES[Opcodes.IF_ICMPLE], - Printer.OPCODES[Opcodes.IF_ICMPGT], - Printer.OPCODES[Opcodes.IF_ICMPLT], - Printer.OPCODES[Opcodes.IF_ICMPNE] - }; -// static final String BRANCH_OP_NAMES_STRING = String.join(",", BRANCH_OP_NAMES); - static final String BRANCH_OP_NAMES_STRING = "GOTO,IF_ACMPEQ,IF_ACMPNE,IF_ICMPEQ,IF_ICMPGE,IF_ICMPLE,IF_ICMPGT,IF_ICMPLT,IF_ICMPNE"; - - - @Before(marker = BytecodeMarker.class, args = BRANCH_OP_NAMES_STRING, scope = "ex6.MainThread.*", guard = IsLoopInstructionGuard.class) - static void handleLoopInstruction(MethodStaticContext mc) { - final String methodName = mc.thisMethodFullName(); - Profiler.countLoop(methodName); - + @Before(marker = BasicBlockMarker.class, + scope = "ex6.MainThread.*", + guard = IsFirstInLoopGuard.class) + static void handleLoopInstruction(final LoopStaticContext lsc, final MethodStaticContext msc) { + Profiler.countLoop(msc.thisMethodFullName()); } } diff --git a/DiSLProject2022/src-profiler/ex6/IsFirstInLoopGuard.java b/DiSLProject2022/src-profiler/ex6/IsFirstInLoopGuard.java new file mode 100644 index 0000000..be22baa --- /dev/null +++ b/DiSLProject2022/src-profiler/ex6/IsFirstInLoopGuard.java @@ -0,0 +1,11 @@ +package ex6; + +import ch.usi.dag.disl.annotation.GuardMethod; +import ch.usi.dag.disl.staticcontext.LoopStaticContext; + +public class IsFirstInLoopGuard { + @GuardMethod + public static boolean isLoopInstruction(final LoopStaticContext lsc) { + return lsc.isFirstOfLoop(); + } +} diff --git a/DiSLProject2022/src-profiler/ex6/IsLoopInstructionGuard.java b/DiSLProject2022/src-profiler/ex6/IsLoopInstructionGuard.java deleted file mode 100644 index d2aecf2..0000000 --- a/DiSLProject2022/src-profiler/ex6/IsLoopInstructionGuard.java +++ /dev/null @@ -1,10 +0,0 @@ -package ex6; - -import ch.usi.dag.disl.annotation.GuardMethod; - -public class IsLoopInstructionGuard { - @GuardMethod - public static boolean isLoopInstruction(LoopContext lc) { - return lc.isLoopInstruction(); - } -} diff --git a/DiSLProject2022/src-profiler/ex6/LoopContext.java b/DiSLProject2022/src-profiler/ex6/LoopContext.java deleted file mode 100644 index 9ab64ac..0000000 --- a/DiSLProject2022/src-profiler/ex6/LoopContext.java +++ /dev/null @@ -1,21 +0,0 @@ -package ex6; - -import ch.usi.dag.disl.staticcontext.AbstractStaticContext; -import org.objectweb.asm.tree.AbstractInsnNode; -import org.objectweb.asm.tree.InsnList; -import org.objectweb.asm.tree.JumpInsnNode; - -public class LoopContext extends AbstractStaticContext { -// considered loop instruction if loop footer. - public boolean isLoopInstruction() { - final InsnList insList = staticContextData.getMethodNode().instructions; - final AbstractInsnNode ins = staticContextData.getRegionStart(); - if (ins instanceof final JumpInsnNode jIns) { - final int nextInsOffset = insList.indexOf(jIns.label); - final int insOffset = insList.indexOf(jIns); - return nextInsOffset < insOffset; - } - return false; - } -} - diff --git a/DiSLProject2022/src-profiler/ex6/Profiler.java b/DiSLProject2022/src-profiler/ex6/Profiler.java index 54f8a5c..e77a768 100644 --- a/DiSLProject2022/src-profiler/ex6/Profiler.java +++ b/DiSLProject2022/src-profiler/ex6/Profiler.java @@ -11,7 +11,7 @@ public final class Profiler { static { Runtime.getRuntime().addShutdownHook(new Thread(() -> { for (final var entry : methodToLoopCount.entrySet()) { - System.out.printf("Method name: %s - # executed loops: %d%n", entry.getKey(), entry.getValue().intValue()); + System.out.printf("Method name: %s - # executed loops: %d%n", entry.getKey(), entry.getValue().longValue()); } })); } @@ -19,11 +19,8 @@ public final class Profiler { private Profiler() { } - public static void countLoop(String methodName) { methodToLoopCount.computeIfAbsent(methodName, k -> new LongAdder()); methodToLoopCount.get(methodName).increment(); } - - } diff --git a/DiSLProject2022/src-profiler/ex8/Instrumentation.java b/DiSLProject2022/src-profiler/ex8/Instrumentation.java index ad94de9..4ead815 100644 --- a/DiSLProject2022/src-profiler/ex8/Instrumentation.java +++ b/DiSLProject2022/src-profiler/ex8/Instrumentation.java @@ -1,18 +1,48 @@ package ex8; +import ch.usi.dag.disl.annotation.After; import ch.usi.dag.disl.annotation.Before; +import ch.usi.dag.disl.annotation.ThreadLocal; +import ch.usi.dag.disl.dynamiccontext.DynamicContext; +import ch.usi.dag.disl.marker.BodyMarker; import ch.usi.dag.disl.marker.BytecodeMarker; +import ch.usi.dag.disl.staticcontext.InstructionStaticContext; import org.objectweb.asm.Opcodes; public class Instrumentation { - @Before(marker = BytecodeMarker.class, args = "invokestatic,invokespecial,invokevirtual,invokedynamic", scope = "*") - static void handleInvoke(InvocationContext ic) { - switch (ic.getInvocationOp()){ - case Opcodes.INVOKEDYNAMIC -> Profiler.countInvoke(Thread.currentThread().getName(), "dynamic"); - case Opcodes.INVOKEVIRTUAL -> Profiler.countInvoke(Thread.currentThread().getName(), "virtual"); - case Opcodes.INVOKESTATIC -> Profiler.countInvoke(Thread.currentThread().getName(), "static"); - case Opcodes.INVOKESPECIAL -> Profiler.countInvoke(Thread.currentThread().getName(), "special"); + @ThreadLocal + private static long staticCount; + + @ThreadLocal + private static long dynamicCount; + + @ThreadLocal + private static long specialCount; + + @ThreadLocal + private static long virtualCount; + + @Before(marker = BytecodeMarker.class, + args = "invokestatic, invokespecial, invokevirtual, invokedynamic") + static void handleInvoke(final InstructionStaticContext isc) { + switch (isc.getOpcode()) { + case Opcodes.INVOKESTATIC -> staticCount++; + case Opcodes.INVOKEDYNAMIC -> dynamicCount++; + case Opcodes.INVOKESPECIAL -> specialCount++; + case Opcodes.INVOKEVIRTUAL -> virtualCount++; + } + } + + @After(marker = BodyMarker.class, scope = "void run()", guard = IsNonStaticGuard.class) + static void endThread(final DynamicContext dc) { + if (dc.getThis() instanceof Thread) { + System.out.printf("Thread: %20s - static: %6d - special: %6d - virtual: %6d - dynamic: %6d\n", + ((Thread) dc.getThis()).getName(), + staticCount, + specialCount, + virtualCount, + dynamicCount); } } } diff --git a/DiSLProject2022/src-profiler/ex8/InvocationContext.java b/DiSLProject2022/src-profiler/ex8/InvocationContext.java deleted file mode 100644 index de705e8..0000000 --- a/DiSLProject2022/src-profiler/ex8/InvocationContext.java +++ /dev/null @@ -1,11 +0,0 @@ -package ex8; - -import ch.usi.dag.disl.staticcontext.AbstractStaticContext; -import org.objectweb.asm.tree.AbstractInsnNode; - -public class InvocationContext extends AbstractStaticContext { - public int getInvocationOp() { - final AbstractInsnNode ins = staticContextData.getRegionStart(); - return ins.getOpcode(); - } -} diff --git a/DiSLProject2022/src-profiler/ex8/IsNonStaticGuard.java b/DiSLProject2022/src-profiler/ex8/IsNonStaticGuard.java new file mode 100644 index 0000000..bc2c65e --- /dev/null +++ b/DiSLProject2022/src-profiler/ex8/IsNonStaticGuard.java @@ -0,0 +1,12 @@ +package ex8; + +import ch.usi.dag.disl.annotation.GuardMethod; +import ch.usi.dag.disl.staticcontext.MethodStaticContext; + +public class IsNonStaticGuard { + + @GuardMethod + public static boolean isNonStatic(final MethodStaticContext msc) { + return !msc.isMethodStatic(); + } +} diff --git a/DiSLProject2022/src-profiler/ex8/Profiler.java b/DiSLProject2022/src-profiler/ex8/Profiler.java deleted file mode 100644 index c66b15c..0000000 --- a/DiSLProject2022/src-profiler/ex8/Profiler.java +++ /dev/null @@ -1,55 +0,0 @@ -package ex8; - -import java.util.Map; -import java.util.Objects; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.LongAdder; - -public final class Profiler { - - - private record Invocation(String threadName, String invokeType) { - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Invocation that = (Invocation) o; - return Objects.equals(threadName, that.threadName) && Objects.equals(invokeType, that.invokeType); - } - - @Override - public int hashCode() { - return Objects.hash(threadName, invokeType); - } - - } - - - private Profiler() { - } - - private static final Map invocationToCount = new ConcurrentHashMap<>(); - - // TODO change format to match assignment - static { - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - for (final var entry : invocationToCount.entrySet()) { - System.out.printf("Thread: %s Type: %s Count: %d%n", - entry.getKey().threadName, - entry.getKey().invokeType, - entry.getValue().intValue() - ); - } - })); - } - - public static void countInvoke(final String threadName, final String invokeType) { - final Invocation invocation = new Invocation(threadName, invokeType); - invocationToCount.computeIfAbsent(invocation, k -> new LongAdder()); - invocationToCount.get(invocation).increment(); - - } - - -}