ex8 now follows guidelines in project description

This commit is contained in:
Claudio Maggioni 2023-01-11 12:02:10 +01:00
parent cc38d2872b
commit 6a7bf23a9d
10 changed files with 69 additions and 134 deletions

View file

@ -1,14 +1,11 @@
package ex5; package ex5;
import ch.usi.dag.disl.annotation.Before; 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.BodyMarker;
import ch.usi.dag.disl.marker.BytecodeMarker; import ch.usi.dag.disl.marker.BytecodeMarker;
import ch.usi.dag.disl.staticcontext.MethodStaticContext;
//import jdk.internal.misc.Unsafe;
public class Instrumentation { 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() { static void handleSafeAllocation() {
Profiler.addSafeAllocation(); Profiler.addSafeAllocation();
} }

View file

@ -1,32 +1,17 @@
package ex6; package ex6;
import ch.usi.dag.disl.annotation.Before; 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.marker.BytecodeMarker;
import ch.usi.dag.disl.staticcontext.LoopStaticContext;
import ch.usi.dag.disl.staticcontext.MethodStaticContext; import ch.usi.dag.disl.staticcontext.MethodStaticContext;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.util.Printer;
public class Instrumentation { public class Instrumentation {
final static String[] BRANCH_OP_NAMES = new String[]{ @Before(marker = BasicBlockMarker.class,
Printer.OPCODES[Opcodes.GOTO], scope = "ex6.MainThread.*",
Printer.OPCODES[Opcodes.IF_ACMPEQ], guard = IsFirstInLoopGuard.class)
Printer.OPCODES[Opcodes.IF_ACMPNE], static void handleLoopInstruction(final LoopStaticContext lsc, final MethodStaticContext msc) {
Printer.OPCODES[Opcodes.IF_ICMPEQ], Profiler.countLoop(msc.thisMethodFullName());
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);
} }
} }

View 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();
}
}

View file

@ -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();
}
}

View file

@ -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;
}
}

View file

@ -11,7 +11,7 @@ public final class Profiler {
static { static {
Runtime.getRuntime().addShutdownHook(new Thread(() -> { Runtime.getRuntime().addShutdownHook(new Thread(() -> {
for (final var entry : methodToLoopCount.entrySet()) { 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() { private Profiler() {
} }
public static void countLoop(String methodName) { public static void countLoop(String methodName) {
methodToLoopCount.computeIfAbsent(methodName, k -> new LongAdder()); methodToLoopCount.computeIfAbsent(methodName, k -> new LongAdder());
methodToLoopCount.get(methodName).increment(); methodToLoopCount.get(methodName).increment();
} }
} }

View file

@ -1,18 +1,48 @@
package ex8; package ex8;
import ch.usi.dag.disl.annotation.After;
import ch.usi.dag.disl.annotation.Before; 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.marker.BytecodeMarker;
import ch.usi.dag.disl.staticcontext.InstructionStaticContext;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
public class Instrumentation { public class Instrumentation {
@Before(marker = BytecodeMarker.class, args = "invokestatic,invokespecial,invokevirtual,invokedynamic", scope = "*") @ThreadLocal
static void handleInvoke(InvocationContext ic) { private static long staticCount;
switch (ic.getInvocationOp()){
case Opcodes.INVOKEDYNAMIC -> Profiler.countInvoke(Thread.currentThread().getName(), "dynamic"); @ThreadLocal
case Opcodes.INVOKEVIRTUAL -> Profiler.countInvoke(Thread.currentThread().getName(), "virtual"); private static long dynamicCount;
case Opcodes.INVOKESTATIC -> Profiler.countInvoke(Thread.currentThread().getName(), "static");
case Opcodes.INVOKESPECIAL -> Profiler.countInvoke(Thread.currentThread().getName(), "special"); @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);
} }
} }
} }

View file

@ -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();
}
}

View 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();
}
}

View file

@ -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();
}
}