ex8 now follows guidelines in project description
This commit is contained in:
parent
cc38d2872b
commit
6a7bf23a9d
10 changed files with 69 additions and 134 deletions
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
11
DiSLProject2022/src-profiler/ex6/IsFirstInLoopGuard.java
Normal file
11
DiSLProject2022/src-profiler/ex6/IsFirstInLoopGuard.java
Normal file
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
12
DiSLProject2022/src-profiler/ex8/IsNonStaticGuard.java
Normal file
12
DiSLProject2022/src-profiler/ex8/IsNonStaticGuard.java
Normal file
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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<Invocation, LongAdder> 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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
Reference in a new issue