package org.ntlab.debuggingControl; import com.sun.jdi.ClassNotLoadedException; import com.sun.jdi.IncompatibleThreadStateException; import com.sun.jdi.IntegerValue; import com.sun.jdi.InvalidTypeException; import com.sun.jdi.InvocationException; import com.sun.jdi.LongValue; import com.sun.jdi.ObjectReference; import com.sun.jdi.StringReference; import com.sun.jdi.ThreadReference; import com.sun.jdi.Value; import com.sun.jdi.VirtualMachine; public class SpeedTester { private static final String TRACE = "org.ntlab.traceCollector.tracer.trace"; private static final String ANALYZER = "org.ntlab.reverseDebugger"; public void countMethodExecutionTest(VirtualMachine vm, ThreadReference thread) { MethodCaller mc = new MethodCaller(vm, thread); try { StringReference threadId = mc.getVm().mirrorOf(String.valueOf(mc.getThreadId())); ObjectReference threadInstance = (ObjectReference)mc.callStaticMethod(TRACE, "TraceJSON", "getThreadInstance", threadId); ObjectReference roots = (ObjectReference)mc.setObj(threadInstance).callInstanceMethod("getRoot"); ObjectReference currentMe = (ObjectReference)mc.callInstanceMethod("getCurrentMethodExecution"); String targetSignature = ((StringReference)mc.setObj(currentMe).callInstanceMethod("getSignature")).value(); System.out.println("targetSignature: " + targetSignature); final int LOOP = 10; // 一次解析の探索処理を, ReverseDebugger側に作成した場合での処理時間計測 System.out.println(); System.out.println("ReverseDebugger:"); test(mc, roots, targetSignature, SpeedTestType.REVERSE_DEBUGGER, LOOP); // 一次解析の探索処理を, ターゲットプログラムに埋め込んだTraceCollector側に作成した場合での処理時間計測 System.out.println(); System.out.println("TraceCollector:"); test(mc, roots, targetSignature, SpeedTestType.TRACE_COLLECTOR, LOOP); } catch (InvalidTypeException | ClassNotLoadedException | InvocationException | IncompatibleThreadStateException e) { e.printStackTrace(); } } private void test(MethodCaller mc, ObjectReference roots, String targetSignature, SpeedTestType type, final int LOOP) throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { int count = 0; long beforeTime = 0, afterTime = 0; for (int i = 0; i < LOOP; i++) { mc.setObj(roots); switch (type) { case REVERSE_DEBUGGER: beforeTime = System.nanoTime(); count = countMethodExecutionInReverseDebugger(mc, targetSignature, 0, "--------"); afterTime = System.nanoTime(); break; case TRACE_COLLECTOR: beforeTime = System.nanoTime(); count = countMethodExecutionInTraceCollector(mc, targetSignature, 0, "--------"); afterTime = System.nanoTime(); break; } System.out.println("Exp " + "(" + type.getTypeName() + ")," + (afterTime - beforeTime)); } } private int countMethodExecutionInTraceCollector(MethodCaller mc, String targetSignture, int count, String indent) throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { VirtualMachine vm = mc.getVm(); String methodName = "countMethodExecutionInTraceCollector"; // return ((IntegerValue)mc.callStaticMethod(TRACE, "TraceJSON", methodName, mc.getObj(), // vm.mirrorOf(targetSignture), vm.mirrorOf(count), vm.mirrorOf(indent))).value(); return ((IntegerValue)mc.callStaticMethod(ANALYZER, "OnlineTraceAnalyzer", methodName, mc.getObj(), vm.mirrorOf(targetSignture), vm.mirrorOf(count), vm.mirrorOf(indent))).value(); } private int countMethodExecutionInReverseDebugger(MethodCaller mc, String targetSignature, int count, String indent) throws InvalidTypeException, ClassNotLoadedException, InvocationException, IncompatibleThreadStateException { VirtualMachine vm = mc.getVm(); ObjectReference methodExecutions = mc.getObj(); if (methodExecutions == null) { return count; } int methodExecutionsSize = ((IntegerValue)mc.callInstanceMethod("size")).value(); if (methodExecutionsSize == 0) { return count; } for (int i = 0; i < methodExecutionsSize; i++) { IntegerValue index = vm.mirrorOf(i); ObjectReference methodExecution = (ObjectReference)mc.setObj(methodExecutions).callInstanceMethod("get", index); String signature = ((StringReference)mc.setObj(methodExecution).callInstanceMethod("getSignature")).value(); // System.out.println(indent + signature); if (targetSignature.equals(signature)) { count++; } ObjectReference children = (ObjectReference)mc.callInstanceMethod("getChildren"); count = countMethodExecutionInReverseDebugger(mc.setObj(children), targetSignature, count, indent + "--------"); } return count; } private enum SpeedTestType { REVERSE_DEBUGGER, TRACE_COLLECTOR; public String getTypeName() { switch (this) { case REVERSE_DEBUGGER: return "RD"; case TRACE_COLLECTOR: return "TC"; default: return ""; } } } }