Some bugs fixed

This commit is contained in:
tripparsugo 2023-01-09 08:01:15 +01:00
parent a78c260dbf
commit 32b063052f
15 changed files with 396 additions and 0 deletions

View file

@ -1,4 +1,14 @@
package ex4;
import ch.usi.dag.disl.annotation.Before;
import ch.usi.dag.disl.dynamiccontext.DynamicContext;
import ch.usi.dag.disl.marker.BytecodeMarker;
public class Instrumentation {
@Before(marker = BytecodeMarker.class, args = "athrow", scope = "ex4.MainThread.*")
static void beforeThrowing(final DynamicContext dc) {
final Throwable throwableThrown = dc.getStackValue(0, Throwable.class);
Profiler.countException(throwableThrown);
}
}

View file

@ -0,0 +1,29 @@
package ex4;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.LongAdder;
public final class Profiler {
private static final Map<String, LongAdder> exceptionNameToCount = new ConcurrentHashMap<>();
static {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
for (final var entry : exceptionNameToCount.entrySet()) {
System.out.printf("Exception: %s - occurrences: %d%n", entry.getKey(), entry.getValue().intValue());
}
}));
}
private Profiler() {
}
public static void countException(Throwable e) {
final String exceptionName = e.getClass().getName();
exceptionNameToCount.computeIfAbsent(exceptionName, k -> new LongAdder());
exceptionNameToCount.get(exceptionName).increment();
}
}

View file

@ -1,4 +1,21 @@
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 = "*")
static void handleSafeAllocation() {
Profiler.addSafeAllocation();
}
// TODO why is it always 0
@Before(marker = BodyMarker.class, scope = "jdk.internal.misc.Unsafe.allocateInstance")
static void handleUnsafeAllocation() {
Profiler.addUnsafeAllocation();
}
}

View file

@ -0,0 +1,31 @@
package ex5;
import java.util.concurrent.atomic.LongAdder;
public final class Profiler {
private static final LongAdder safeAllocations = new LongAdder();
private static final LongAdder unsafeAllocation = new LongAdder();
static {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.printf("Safe allocation: %d%n", safeAllocations.intValue());
System.out.printf("Unsafe allocation: %d%n", unsafeAllocation.intValue());
}));
}
private Profiler() {
}
public static void addSafeAllocation(){
safeAllocations.increment();
}
public static void addUnsafeAllocation(){
unsafeAllocation.increment();
}
}

View file

@ -1,4 +1,32 @@
package ex6;
import ch.usi.dag.disl.annotation.Before;
import ch.usi.dag.disl.marker.BytecodeMarker;
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);
}
}

View file

@ -0,0 +1,10 @@
package ex6;
import ch.usi.dag.disl.annotation.GuardMethod;
public class IsLoopInstructionGuard {
@GuardMethod
public static boolean isLoopInstruction(LoopContext lc) {
return lc.isLoopInstruction();
}
}

View file

@ -0,0 +1,21 @@
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

@ -0,0 +1,29 @@
package ex6;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.LongAdder;
public final class Profiler {
private static final Map<String, LongAdder> methodToLoopCount = new ConcurrentHashMap<>();
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());
}
}));
}
private Profiler() {
}
public static void countLoop(String methodName) {
methodToLoopCount.computeIfAbsent(methodName, k -> new LongAdder());
methodToLoopCount.get(methodName).increment();
}
}

View file

@ -1,4 +1,35 @@
package ex7;
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.marker.BytecodeMarker;
import ch.usi.dag.disl.staticcontext.ClassStaticContext;
import ch.usi.dag.disl.staticcontext.MethodStaticContext;
public class Instrumentation {
@Before(marker = BytecodeMarker.class, args = "MONITORENTER", scope = "ex7.MainThread.*")
static void handleMonitorAccess(final DynamicContext dc) {
final Object monitor = dc.getStackValue(0, Object.class);
Profiler.countMonitorAccess(monitor);
}
@After(marker = BodyMarker.class, scope = "ex7.MainThread.*", guard = IsSynchronizedMethodGuard.class)
static void handledSynchronizedAccess(final MethodStaticContext mc, final DynamicContext dc, final ClassStaticContext cc) {
if (mc.isMethodStatic()) {
try {
Class<?> methodClass = Class.forName(cc.getName());
Profiler.countMonitorAccess(methodClass);
} catch (ClassNotFoundException e) {
throw new RuntimeException("Class " + cc.getName() + " not found");
}
} else {
Profiler.countMonitorAccess(dc.getThis());
}
}
}

View file

@ -0,0 +1,11 @@
package ex7;
import ch.usi.dag.disl.annotation.GuardMethod;
import ch.usi.dag.disl.staticcontext.MethodStaticContext;
public class IsSynchronizedMethodGuard {
@GuardMethod
public static boolean isSynchronizedMethod(MethodStaticContext mc) {
return mc.isMethodSynchronized();
}
}

View file

@ -0,0 +1,66 @@
package ex7;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.LongAdder;
public final class Profiler {
private static final class MonitorEntry {
private final int hashCode;
private final String name;
public MonitorEntry(int hashCode, String name) {
this.hashCode = hashCode;
this.name = name;
}
public int getHashCode() {
return hashCode;
}
public String getName() {
return name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MonitorEntry that = (MonitorEntry) o;
return hashCode == that.hashCode && Objects.equals(name, that.name);
}
@Override
public int hashCode() {
return Objects.hash(hashCode, name);
}
}
private static final Map<MonitorEntry, LongAdder> monitorToAccessCount = new ConcurrentHashMap<>();
static {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
for (final var entry : monitorToAccessCount.entrySet()) {
System.out.printf("%d - %s - #Locks: %d%n",
entry.getKey().getHashCode(),
entry.getKey().getName(),
entry.getValue().intValue()
);
}
}));
}
private Profiler() {
}
public static void countMonitorAccess(final Object obj) {
final MonitorEntry monitorEntry = new MonitorEntry(obj.hashCode(), obj.getClass().getName());
monitorToAccessCount.computeIfAbsent(monitorEntry, k -> new LongAdder());
monitorToAccessCount.get(monitorEntry).increment();
}
}

View file

@ -1,4 +1,18 @@
package ex8;
import ch.usi.dag.disl.annotation.Before;
import ch.usi.dag.disl.marker.BytecodeMarker;
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");
}
}
}

View file

@ -0,0 +1,11 @@
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,33 @@
package ex8;
import org.objectweb.asm.Opcodes;
import java.util.HashMap;
public enum InvokeType {
STATIC("static"),
DYNAMIC("dynamic"),
SPECIAL("special"),
VIRTUAL("virtual");
final String name;
final static HashMap<Integer, InvokeType> opcodeToInvokeType = new HashMap<>() {
{
put(Opcodes.INVOKESTATIC, InvokeType.STATIC);
put(Opcodes.INVOKEDYNAMIC, InvokeType.DYNAMIC);
put(Opcodes.INVOKESPECIAL, InvokeType.SPECIAL);
put(Opcodes.INVOKEVIRTUAL, InvokeType.VIRTUAL);
}
};
InvokeType(String name) {
this.name = name;
}
static InvokeType fromOpcode(int opCode) {
return opcodeToInvokeType.get(opCode);
}
}

View file

@ -0,0 +1,55 @@
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();
}
}