Some bugs fixed
This commit is contained in:
parent
a78c260dbf
commit
32b063052f
15 changed files with 396 additions and 0 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
29
DiSLProject2022/src-profiler/ex4/Profiler.java
Normal file
29
DiSLProject2022/src-profiler/ex4/Profiler.java
Normal 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();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
31
DiSLProject2022/src-profiler/ex5/Profiler.java
Normal file
31
DiSLProject2022/src-profiler/ex5/Profiler.java
Normal 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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
10
DiSLProject2022/src-profiler/ex6/IsLoopInstructionGuard.java
Normal file
10
DiSLProject2022/src-profiler/ex6/IsLoopInstructionGuard.java
Normal 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();
|
||||
}
|
||||
}
|
21
DiSLProject2022/src-profiler/ex6/LoopContext.java
Normal file
21
DiSLProject2022/src-profiler/ex6/LoopContext.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
29
DiSLProject2022/src-profiler/ex6/Profiler.java
Normal file
29
DiSLProject2022/src-profiler/ex6/Profiler.java
Normal 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();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
66
DiSLProject2022/src-profiler/ex7/Profiler.java
Normal file
66
DiSLProject2022/src-profiler/ex7/Profiler.java
Normal 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();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
11
DiSLProject2022/src-profiler/ex8/InvocationContext.java
Normal file
11
DiSLProject2022/src-profiler/ex8/InvocationContext.java
Normal 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();
|
||||
}
|
||||
}
|
33
DiSLProject2022/src-profiler/ex8/InvokeType.java
Normal file
33
DiSLProject2022/src-profiler/ex8/InvokeType.java
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
55
DiSLProject2022/src-profiler/ex8/Profiler.java
Normal file
55
DiSLProject2022/src-profiler/ex8/Profiler.java
Normal 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();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
Reference in a new issue