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;
|
package ex2;
|
||||||
|
|
||||||
import ch.usi.dag.disl.annotation.GuardMethod;
|
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.ClassStaticContext;
|
||||||
import ch.usi.dag.disl.staticcontext.MethodStaticContext;
|
import ch.usi.dag.disl.staticcontext.MethodStaticContext;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package ex2;
|
package ex2;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.atomic.LongAdder;
|
import java.util.concurrent.atomic.LongAdder;
|
||||||
|
@ -15,9 +14,9 @@ public final class Profiler {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||||
System.out.printf("Instance field read access: %d\nInstance field write access: %d\n",
|
System.out.printf("Instance field read access: %d\nInstance field write access: %d\n",
|
||||||
reads.longValue(),
|
reads.longValue(),
|
||||||
writes.longValue());
|
writes.longValue());
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,35 @@
|
||||||
package ex9;
|
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 {
|
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