ex9 done
This commit is contained in:
parent
a78c260dbf
commit
8bf55cf46a
9 changed files with 84 additions and 5 deletions
2
DiSLProject2022/src-profiler/ex10/CustomMarker.java
Normal file
2
DiSLProject2022/src-profiler/ex10/CustomMarker.java
Normal file
|
@ -0,0 +1,2 @@
|
|||
package ex10;public class CustomMarker {
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
package ex10;public class CustomStaticContext {
|
||||
}
|
2
DiSLProject2022/src-profiler/ex10/DeclarationGuard.java
Normal file
2
DiSLProject2022/src-profiler/ex10/DeclarationGuard.java
Normal file
|
@ -0,0 +1,2 @@
|
|||
package ex10;public class DeclarationGuard {
|
||||
}
|
2
DiSLProject2022/src-profiler/ex10/MethodDecoder.java
Normal file
2
DiSLProject2022/src-profiler/ex10/MethodDecoder.java
Normal file
|
@ -0,0 +1,2 @@
|
|||
package ex10;public class MethodDecoder {
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package ex2;
|
||||
|
||||
import ch.usi.dag.disl.annotation.GuardMethod;
|
||||
import ch.usi.dag.disl.dynamiccontext.DynamicContext;
|
||||
import ch.usi.dag.disl.staticcontext.ClassStaticContext;
|
||||
import ch.usi.dag.disl.staticcontext.MethodStaticContext;
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package ex2;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
|
@ -15,9 +14,9 @@ public final class Profiler {
|
|||
|
||||
static {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
System.out.printf("Instance field read access: %d\nInstance field write access: %d\n",
|
||||
reads.longValue(),
|
||||
writes.longValue());
|
||||
System.out.printf("Instance field read access: %d\nInstance field write access: %d\n",
|
||||
reads.longValue(),
|
||||
writes.longValue());
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,35 @@
|
|||
package ex9;
|
||||
|
||||
import ch.usi.dag.disl.annotation.Before;
|
||||
import ch.usi.dag.disl.marker.BodyMarker;
|
||||
import ch.usi.dag.disl.marker.BytecodeMarker;
|
||||
import ch.usi.dag.disl.staticcontext.InvocationStaticContext;
|
||||
import ch.usi.dag.disl.staticcontext.MethodStaticContext;
|
||||
|
||||
public class Instrumentation {
|
||||
|
||||
@Before(marker = BytecodeMarker.class,
|
||||
args = "invokevirtual, invokespecial, invokeinterface, invokestatic",
|
||||
guard = IsNotConstructorOrStaticGuard.class,
|
||||
scope = "ex9.MainThread.*")
|
||||
static void logCall(final InvocationStaticContext isc) {
|
||||
// this will log calls for all types of methods (including constructors and static initializers).
|
||||
// However, constructors and static initializers will not be instrumented thanks to the included guard.
|
||||
// Should calls to constructors and static methods not be instrumented, add the following line:
|
||||
//
|
||||
// if (isc.isConstructor()) return;
|
||||
//
|
||||
// and remove `invokestatic` from the BytecodeMarker argument list
|
||||
|
||||
Profiler.logCall(Thread.currentThread(), isc.getInternalName());
|
||||
}
|
||||
|
||||
@Before(marker = BodyMarker.class,
|
||||
guard = IsNotConstructorOrStaticGuard.class,
|
||||
scope = "ex9.MainThread.run")
|
||||
static void logThreadStart(final MethodStaticContext msc) {
|
||||
// We separately instrument the Thread.run() method as there is no obvious way to instrument the caller of
|
||||
// Thread.run(). Hence, we log the call at method start.
|
||||
Profiler.logCall(Thread.currentThread(), msc.thisMethodFullName());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package ex9;
|
||||
|
||||
import ch.usi.dag.disl.annotation.GuardMethod;
|
||||
import ch.usi.dag.disl.staticcontext.MethodStaticContext;
|
||||
|
||||
public class IsNotConstructorOrStaticGuard {
|
||||
@GuardMethod
|
||||
public static boolean isNotConstructorOrStatic(final MethodStaticContext msc) {
|
||||
return !msc.isMethodStatic() && !msc.isMethodConstructor();
|
||||
}
|
||||
}
|
31
DiSLProject2022/src-profiler/ex9/Profiler.java
Normal file
31
DiSLProject2022/src-profiler/ex9/Profiler.java
Normal file
|
@ -0,0 +1,31 @@
|
|||
package ex9;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
public final class Profiler {
|
||||
private static final ConcurrentMap<String, List<String>> callLog = new ConcurrentHashMap<>();
|
||||
|
||||
static {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(Profiler::print));
|
||||
}
|
||||
|
||||
private Profiler() {
|
||||
}
|
||||
|
||||
public static void logCall(final Thread thread, final String methodName) {
|
||||
final List<String> list = callLog.computeIfAbsent(thread.getName(), ignored -> new LinkedList<>());
|
||||
|
||||
// thread safe, as once a thread accesses its own list access to said list is non-concurrent
|
||||
list.add(methodName);
|
||||
}
|
||||
|
||||
private static void print() {
|
||||
for (final String threadName : callLog.keySet()) {
|
||||
System.out.printf("=== %s ===\n", threadName);
|
||||
callLog.get(threadName).forEach(System.out::println);
|
||||
}
|
||||
}
|
||||
}
|
Reference in a new issue