diff options
author | Siva Velusamy <vsiva@google.com> | 2015-10-19 23:14:03 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2015-10-19 23:14:03 +0000 |
commit | 3c865681765e9e8ec498ed249d0fb7600a67dea4 (patch) | |
tree | 107eb18ad5a8bb278eff528623d019bfe7c63c1b | |
parent | 607b50bd4954dc1cb216364592e8de5f069590f5 (diff) | |
parent | 0817cbeaf7fed0bd420e8289ebc260cf54f41ace (diff) | |
download | base-3c865681765e9e8ec498ed249d0fb7600a67dea4.tar.gz |
Merge "Generate inclusive and exclusive times for all calls."
am: 0817cbeaf7
* commit '0817cbeaf7fed0bd420e8289ebc260cf54f41ace':
Generate inclusive and exclusive times for all calls.
6 files changed, 221 insertions, 87 deletions
diff --git a/perflib/src/main/java/com/android/tools/perflib/vmtrace/Call.java b/perflib/src/main/java/com/android/tools/perflib/vmtrace/Call.java index 9144ea5776..2b62626d8f 100644 --- a/perflib/src/main/java/com/android/tools/perflib/vmtrace/Call.java +++ b/perflib/src/main/java/com/android/tools/perflib/vmtrace/Call.java @@ -17,8 +17,10 @@ package com.android.tools.perflib.vmtrace; import com.android.annotations.NonNull; +import com.android.annotations.Nullable; import com.google.common.base.Strings; import com.google.common.collect.ImmutableList; +import com.google.common.primitives.UnsignedInts; import java.util.ArrayList; import java.util.Collections; @@ -27,11 +29,18 @@ import java.util.List; public class Call { private final long mMethodId; + /** + * Note: The thread entry and exit times are stored as unsigned integers in the trace data. + * In this model, they are stored as integers, but the getters for all of these time values + * convert them into longs. + */ private final int mEntryThreadTime; private final int mEntryGlobalTime; private final int mExitGlobalTime; private final int mExitThreadTime; + private final long mInclusiveThreadTimeInCallees; + private final int mDepth; private final List<Call> mCallees; @@ -55,6 +64,16 @@ public class Call { } mCallees = new ImmutableList.Builder<Call>().addAll(callees).build(); } + + mInclusiveThreadTimeInCallees = sumThreadTimes(mCallees); + } + + private long sumThreadTimes(@NonNull List<Call> callees) { + long sum = 0; + for (Call c : callees) { + sum += c.getInclusiveThreadTime(); + } + return sum; } public long getMethodId() { @@ -70,12 +89,28 @@ public class Call { return mDepth; } - public int getEntryThreadTime() { - return mEntryThreadTime; + public long getEntryThreadTime() { + return UnsignedInts.toLong(mEntryThreadTime); + } + + public long getExitThreadTime() { + return UnsignedInts.toLong(mExitThreadTime); + } + + public long getEntryGlobalTime() { + return UnsignedInts.toLong(mEntryGlobalTime); + } + + public long getExitGlobalTime() { + return UnsignedInts.toLong(mExitGlobalTime); } - public int getExitThreadTime() { - return mExitThreadTime; + public long getInclusiveThreadTime() { + return UnsignedInts.toLong(mExitThreadTime - mEntryThreadTime); + } + + public long getExclusiveThreadTime() { + return getInclusiveThreadTime() - mInclusiveThreadTimeInCallees; } public static class Builder { @@ -115,13 +150,35 @@ public class Call { mCallees.add(c); } + public void setStackDepth(int depth) { mDepth = depth; } + @Nullable + public List<Builder> getCallees() { + return mCallees; + } + public Call build() { return new Call(this); } + + public int getMethodEntryThreadTime() { + return mEntryThreadTime; + } + + public int getMethodEntryGlobalTime() { + return mEntryGlobalTime; + } + + public int getMethodExitThreadTime() { + return mExitThreadTime; + } + + public int getMethodExitGlobalTime() { + return mExitGlobalTime; + } } /** diff --git a/perflib/src/main/java/com/android/tools/perflib/vmtrace/CallStackReconstructor.java b/perflib/src/main/java/com/android/tools/perflib/vmtrace/CallStackReconstructor.java index e241db8fba..d1574752bb 100644 --- a/perflib/src/main/java/com/android/tools/perflib/vmtrace/CallStackReconstructor.java +++ b/perflib/src/main/java/com/android/tools/perflib/vmtrace/CallStackReconstructor.java @@ -27,13 +27,25 @@ import java.util.Stack; * trace events (method entry/exit events). */ public class CallStackReconstructor { + /** Method id corresponding to the top level call under which all calls are nested. */ + private final long mTopLevelCallId; + /** List of calls currently assumed to be at stack depth 0 (called from the top level) */ - private List<Call.Builder> mTopLevelCalls = new ArrayList<Call.Builder>(); + private final List<Call.Builder> mTopLevelCalls = new ArrayList<Call.Builder>(); /** Current call stack based on the sequence of received trace events. */ - private Stack<Call.Builder> mCallStack = new Stack<Call.Builder>(); + private final Stack<Call.Builder> mCallStack = new Stack<Call.Builder>(); + + /** The single top level call under which the entire reconstructed call stack nests. */ + private Call mTopLevelCall; - private List<Call> mTopLevelCallees; + /** + * Constructs a call stack reconstructor with the method id under which + * the entire call stack should nest. + * */ + public CallStackReconstructor(long topLevelCallId) { + mTopLevelCallId = topLevelCallId; + } public void addTraceAction(long methodId, TraceAction action, int threadTime, int globalTime) { if (action == TraceAction.METHOD_ENTER) { @@ -72,7 +84,6 @@ public class CallStackReconstructor { // We are exiting out of a method that was entered into before tracing was started. // In such a case, create this method Call.Builder c = new Call.Builder(methodId); - c.setMethodExitTime(threadTime, globalTime); // All the previous calls at the top level are now assumed to have been called from // this method. So mark this method as having called all of those methods, and reset @@ -82,28 +93,59 @@ public class CallStackReconstructor { } mTopLevelCalls.clear(); mTopLevelCalls.add(c); + + c.setMethodExitTime(threadTime, globalTime); + + // We don't know this method's entry times, so we try to guess: + // If it has atleast 1 callee, then we know it must've been atleast before that callee's + // start time. If there are no callees, then we just assume that it was just before its + // exit times. + int entryThreadTime = threadTime - 1; + int entryGlobalTime = globalTime - 1; + + if (c.getCallees() != null && !c.getCallees().isEmpty()) { + Call.Builder callee = c.getCallees().get(0); + entryThreadTime = callee.getMethodEntryThreadTime() - 1; + entryGlobalTime = callee.getMethodEntryGlobalTime() - 1; + } + c.setMethodEntryTime(entryThreadTime, entryGlobalTime); } } private void fixupCallStacks() { - if (mTopLevelCallees != null) { + if (mTopLevelCall != null) { return; } - // TODO: use global / thread times to infer context switches + int lastExitThreadTime = 0; + int lastExitGlobalTime = 0; + if (!mTopLevelCalls.isEmpty()) { + Call.Builder last = mTopLevelCalls.get(mTopLevelCalls.size() - 1); + lastExitThreadTime = last.getMethodExitThreadTime() + 1; + lastExitGlobalTime = last.getMethodExitGlobalTime() + 1; + } - // Build calls from their respective builders - List<Call> topLevelCallees = new ArrayList<Call>(mTopLevelCalls.size()); - for (Call.Builder b : mTopLevelCalls) { - b.setStackDepth(0); - topLevelCallees.add(b.build()); + // If there are any methods still on the call stack, then the trace doesn't have + // exit trace action for them, so clean those up + while (!mCallStack.isEmpty()) { + Call.Builder builder = mCallStack.peek(); + exitMethod(builder.getMethodId(), lastExitThreadTime, lastExitGlobalTime); } - mTopLevelCallees = new ImmutableList.Builder<Call>().addAll(topLevelCallees).build(); + // Now that we have parsed the entire call stack, let us move all of it under a single + // top level call. + exitMethod(mTopLevelCallId, lastExitThreadTime, lastExitGlobalTime); + + // TODO: use global / thread times to infer context switches + + // Build calls from their respective builders + // Now that we've added the top level call, there should be only 1 top level call + assert mTopLevelCalls.size() == 1; + mTopLevelCall = mTopLevelCalls.get(0).build(); } - public List<Call> getTopLevelCallees() { + public Call getTopLevel() { fixupCallStacks(); - return mTopLevelCallees; + return mTopLevelCall; } } diff --git a/perflib/src/main/java/com/android/tools/perflib/vmtrace/VmTraceData.java b/perflib/src/main/java/com/android/tools/perflib/vmtrace/VmTraceData.java index b6f27c8419..d9ec9ba730 100644 --- a/perflib/src/main/java/com/android/tools/perflib/vmtrace/VmTraceData.java +++ b/perflib/src/main/java/com/android/tools/perflib/vmtrace/VmTraceData.java @@ -28,7 +28,7 @@ import java.util.Map; * <ul> * <li>A mapping from thread ids to thread names.</li> * <li>A mapping from method ids to {@link MethodInfo}</li> - * <li>A mapping from each thread to the list of call stacks ({@link Call}) on that thread.</li> + * <li>A mapping from each thread to the top level call on that thread.</li> * </ul> */ public class VmTraceData { @@ -46,8 +46,8 @@ public class VmTraceData { /** Map from method id to method info. */ private final Map<Long,MethodInfo> mMethods; - /** Map from thread id to list of call stacks invoked in that thread */ - private final SparseArray<List<Call>> mCalls; + /** Map from thread id to the top level call in that thread */ + private final SparseArray<Call> mCalls; private VmTraceData(Builder b) { mVersion = b.mVersion; @@ -57,7 +57,7 @@ public class VmTraceData { mTraceProperties = b.mProperties; mThreads = b.mThreads; mMethods = b.mMethods; - mCalls = b.mCalls; + mCalls = b.mTopLevelCalls; } public int getVersion() { @@ -92,7 +92,7 @@ public class VmTraceData { return mMethods.get(methodId); } - public List<Call> getCalls(int threadId) { + public Call getTopLevelCall(int threadId) { return mCalls.get(threadId); } @@ -115,8 +115,8 @@ public class VmTraceData { private final SparseArray<CallStackReconstructor> mStackReconstructors = new SparseArray<CallStackReconstructor>(10); - /** Map from thread id to list of call stacks invoked in that thread */ - private final SparseArray<List<Call>> mCalls = new SparseArray<List<Call>>(10); + /** Map from thread id to the top level call for that thread. */ + private final SparseArray<Call> mTopLevelCalls = new SparseArray<Call>(10); public void setVersion(int version) { mVersion = version; @@ -180,18 +180,28 @@ public class VmTraceData { CallStackReconstructor reconstructor = mStackReconstructors.get(threadId); if (reconstructor == null) { - reconstructor = new CallStackReconstructor(); + long topLevelCallId = createUniqueMethodIdForThread(threadId); + reconstructor = new CallStackReconstructor(topLevelCallId); mStackReconstructors.put(threadId, reconstructor); } reconstructor.addTraceAction(methodId, methodAction, threadTime, globalTime); } + private long createUniqueMethodIdForThread(int threadId) { + long id = Long.MAX_VALUE - mThreads.indexOfKey(threadId); + assert mMethods.get(id) == null : + "Unexpected error while attempting to create a unique key - key already exists"; + MethodInfo info = new MethodInfo(id, mThreads.get(threadId), "", "", "", 0); + mMethods.put(id, info); + return id; + } + public VmTraceData build() { for (int i = 0; i < mStackReconstructors.size(); i++) { int threadId = mStackReconstructors.keyAt(i); CallStackReconstructor reconstructor = mStackReconstructors.valueAt(i); - mCalls.put(threadId, reconstructor.getTopLevelCallees()); + mTopLevelCalls.put(threadId, reconstructor.getTopLevel()); } return new VmTraceData(this); diff --git a/perflib/src/main/java/com/android/tools/perflib/vmtrace/VmTraceParser.java b/perflib/src/main/java/com/android/tools/perflib/vmtrace/VmTraceParser.java index 41a9087891..e3e1b0cdd0 100644 --- a/perflib/src/main/java/com/android/tools/perflib/vmtrace/VmTraceParser.java +++ b/perflib/src/main/java/com/android/tools/perflib/vmtrace/VmTraceParser.java @@ -252,8 +252,8 @@ public class VmTraceParser { switch (clockType) { case WALL: - threadTime = 0; globalTime = buffer.getInt(); + threadTime = globalTime; break; case DUAL: threadTime = buffer.getInt(); @@ -262,7 +262,7 @@ public class VmTraceParser { case THREAD_CPU: default: threadTime = buffer.getInt(); - globalTime = 0; + globalTime = threadTime; break; } diff --git a/perflib/src/test/java/com/android/tools/perflib/vmtrace/CallStackReconstructorTest.java b/perflib/src/test/java/com/android/tools/perflib/vmtrace/CallStackReconstructorTest.java index f24b4c10f2..c3adb06145 100644 --- a/perflib/src/test/java/com/android/tools/perflib/vmtrace/CallStackReconstructorTest.java +++ b/perflib/src/test/java/com/android/tools/perflib/vmtrace/CallStackReconstructorTest.java @@ -16,26 +16,23 @@ package com.android.tools.perflib.vmtrace; -import com.google.common.base.Joiner; - import junit.framework.TestCase; -import java.util.ArrayList; import java.util.List; public class CallStackReconstructorTest extends TestCase { public void testBasicCallStack() { - CallStackReconstructor reconstructor = new CallStackReconstructor(); + CallStackReconstructor reconstructor = new CallStackReconstructor(0xff); reconstructor.addTraceAction(0x1, TraceAction.METHOD_ENTER, 10, 10); reconstructor.addTraceAction(0x1, TraceAction.METHOD_EXIT, 15, 15); - List<Call> callees = reconstructor.getTopLevelCallees(); - assertEquals(1, callees.size()); - assertEquals(0x1, callees.get(0).getMethodId()); + Call topLevel = reconstructor.getTopLevel(); + assertEquals(1, topLevel.getCallees().size()); + assertEquals(0x1, topLevel.getCallees().get(0).getMethodId()); } public void testCallStack1() { - CallStackReconstructor reconstructor = new CallStackReconstructor(); + CallStackReconstructor reconstructor = new CallStackReconstructor(0xff); reconstructor.addTraceAction(0x1, TraceAction.METHOD_ENTER, 10, 10); reconstructor.addTraceAction(0x2, TraceAction.METHOD_ENTER, 11, 11); @@ -50,17 +47,17 @@ public class CallStackReconstructorTest extends TestCase { reconstructor.addTraceAction(0x6, TraceAction.METHOD_ENTER, 21, 21); reconstructor.addTraceAction(0x6, TraceAction.METHOD_EXIT, 22, 22); - String callStack = getCallStackInfo(reconstructor.getTopLevelCallees()); + String callStack = reconstructor.getTopLevel().toString(); String expectedCallStack = - " -> 1 -> 2 -> 3\n" - + " -> 3\n" - + " -> 5\n" - + " -> 6"; + " -> 255 -> 1 -> 2 -> 3\n" + + " -> 3\n" + + " -> 5\n" + + " -> 6"; assertEquals(expectedCallStack, callStack); } public void testInvalidTrace() { - CallStackReconstructor reconstructor = new CallStackReconstructor(); + CallStackReconstructor reconstructor = new CallStackReconstructor(0xff); try { reconstructor.addTraceAction(0x1, TraceAction.METHOD_ENTER, 1, 1); @@ -72,29 +69,18 @@ public class CallStackReconstructorTest extends TestCase { } public void testMisMatchedCallStack() { - CallStackReconstructor reconstructor = new CallStackReconstructor(); + CallStackReconstructor reconstructor = new CallStackReconstructor(0xff); reconstructor.addTraceAction(0x3, TraceAction.METHOD_EXIT, 1, 1); reconstructor.addTraceAction(0x2, TraceAction.METHOD_EXIT, 2, 2); reconstructor.addTraceAction(0x1, TraceAction.METHOD_EXIT, 3, 3); - String callStack = getCallStackInfo(reconstructor.getTopLevelCallees()); - assertEquals(" -> 1 -> 2 -> 3", callStack); + String callStack = reconstructor.getTopLevel().toString(); + assertEquals(" -> 255 -> 1 -> 2 -> 3", callStack); } - private String getCallStackInfo(List<Call> calls) { - List<String> callStacks = new ArrayList<String>(calls.size()); - - for (Call c : calls) { - callStacks.add(c.toString()); - } - - return Joiner.on('\n').join(callStacks); - } - - public void testCallStackDepths() { - CallStackReconstructor reconstructor = new CallStackReconstructor(); + CallStackReconstructor reconstructor = new CallStackReconstructor(0xff); reconstructor.addTraceAction(0x1, TraceAction.METHOD_ENTER, 10, 10); reconstructor.addTraceAction(0x2, TraceAction.METHOD_ENTER, 11, 11); @@ -107,10 +93,10 @@ public class CallStackReconstructorTest extends TestCase { reconstructor.addTraceAction(0x5, TraceAction.METHOD_EXIT, 18, 18); reconstructor.addTraceAction(0x1, TraceAction.METHOD_EXIT, 20, 20); - List<Call> calls = reconstructor.getTopLevelCallees(); - assertEquals(1, calls.size()); + Call topLevel = reconstructor.getTopLevel(); + assertEquals(1, topLevel.getCallees().size()); - Call c = calls.get(0); + Call c = topLevel.getCallees().get(0); String actualDepths = c.format(new Call.Formatter() { @Override public String format(Call c) { @@ -119,9 +105,59 @@ public class CallStackReconstructorTest extends TestCase { }); String expected = - " -> 0 -> 1 -> 2\n" - + " -> 2\n" - + " -> 1"; + " -> 1 -> 2 -> 3\n" + + " -> 3\n" + + " -> 2"; assertEquals(expected, actualDepths); } + + public void testCallDurations() { + CallStackReconstructor reconstructor = new CallStackReconstructor(0xff); + + reconstructor.addTraceAction(0x1, TraceAction.METHOD_ENTER, 10, 10); + reconstructor.addTraceAction(0x2, TraceAction.METHOD_ENTER, 11, 11); + reconstructor.addTraceAction(0x2, TraceAction.METHOD_EXIT, 14, 14); + reconstructor.addTraceAction(0x1, TraceAction.METHOD_EXIT, 15, 15); + + List<Call> callees = reconstructor.getTopLevel().getCallees(); + assertFalse(callees.isEmpty()); + Call call = callees.get(0); + assertEquals(15 - 10, call.getInclusiveThreadTime()); + assertEquals(15 - 10 - (14 - 11), call.getExclusiveThreadTime()); + } + + public void testMissingCallDurations() { + CallStackReconstructor reconstructor = new CallStackReconstructor(0xff); + + // missing entry time for method 0x1, verify that it is computed as 1 less than + // the entry time for its callee (method 0x2) + reconstructor.addTraceAction(0x2, TraceAction.METHOD_ENTER, 11, 11); + reconstructor.addTraceAction(0x2, TraceAction.METHOD_EXIT, 14, 14); + reconstructor.addTraceAction(0x1, TraceAction.METHOD_EXIT, 15, 15); + + List<Call> callees = reconstructor.getTopLevel().getCallees(); + assertFalse(callees.isEmpty()); + Call call = callees.get(0); + assertEquals(15 - (11 - 1), call.getInclusiveThreadTime()); + assertEquals(15 - (11 - 1) - (14 - 11), call.getExclusiveThreadTime()); + } + + /** + * Verify that the model handles cases where the timings exceed {@link Integer#MAX_VALUE}, + * but are still within the scope of an unsigned integer. + */ + public void testCallDurationOverflow() { + CallStackReconstructor reconstructor = new CallStackReconstructor(0xff); + + reconstructor.addTraceAction(0x1, TraceAction.METHOD_ENTER, 0xfffffff0, 0xfffffff0); + reconstructor.addTraceAction(0x2, TraceAction.METHOD_ENTER, 0xfffffff2, 0xfffffff2); + reconstructor.addTraceAction(0x2, TraceAction.METHOD_EXIT, 0xfffffff4, 0xfffffff4); + reconstructor.addTraceAction(0x1, TraceAction.METHOD_EXIT, 0xfffffff8, 0xfffffff8); + + List<Call> callees = reconstructor.getTopLevel().getCallees(); + assertFalse(callees.isEmpty()); + Call call = callees.get(0); + assertEquals(8, call.getInclusiveThreadTime()); + assertEquals(6, call.getExclusiveThreadTime()); + } } diff --git a/perflib/src/test/java/com/android/tools/perflib/vmtrace/VmTraceParserTest.java b/perflib/src/test/java/com/android/tools/perflib/vmtrace/VmTraceParserTest.java index 87b7109069..ea7e0e6f17 100644 --- a/perflib/src/test/java/com/android/tools/perflib/vmtrace/VmTraceParserTest.java +++ b/perflib/src/test/java/com/android/tools/perflib/vmtrace/VmTraceParserTest.java @@ -82,33 +82,33 @@ public class VmTraceParserTest extends TestCase { int threadId = findThreadIdFromName(threadName, traceData.getThreads()); assertTrue(String.format("Thread %s was not found in the trace", threadName), threadId > 0); - List<Call> calls = traceData.getCalls(threadId); - String actual = formatCallStacks(calls, new CallFormatter(traceData.getMethods())); + Call call = traceData.getTopLevelCall(threadId); + String actual = call.format(new CallFormatter(traceData.getMethods())); assertEquals(expectedCallSequence, actual); } public void testBasicTrace() throws IOException { String expected = - " -> android/os/Debug.startMethodTracing: (Ljava/lang/String;)V -> android/os/Debug.startMethodTracing: (Ljava/lang/String;II)V -> dalvik/system/VMDebug.startMethodTracing: (Ljava/lang/String;II)V\n" - + " -> com/test/android/traceview/Basic.foo: ()V -> com/test/android/traceview/Basic.bar: ()I\n" - + " -> android/os/Debug.stopMethodTracing: ()V -> dalvik/system/VMDebug.stopMethodTracing: ()V"; + " -> AsyncTask #1.: -> android/os/Debug.startMethodTracing: (Ljava/lang/String;)V -> android/os/Debug.startMethodTracing: (Ljava/lang/String;II)V -> dalvik/system/VMDebug.startMethodTracing: (Ljava/lang/String;II)V\n" + + " -> com/test/android/traceview/Basic.foo: ()V -> com/test/android/traceview/Basic.bar: ()I\n" + + " -> android/os/Debug.stopMethodTracing: ()V -> dalvik/system/VMDebug.stopMethodTracing: ()V"; testTrace("/basic.trace", "AsyncTask #1", expected); } public void testMisMatchedTrace() throws IOException { String expected = - " -> com/test/android/traceview/MisMatched.foo: ()V -> com/test/android/traceview/MisMatched.bar: ()V -> android/os/Debug.startMethodTracing: (Ljava/lang/String;)V -> android/os/Debug.startMethodTracing: (Ljava/lang/String;II)V -> dalvik/system/VMDebug.startMethodTracing: (Ljava/lang/String;II)V\n" - + " -> com/test/android/traceview/MisMatched.baz: ()I\n" - + " -> android/os/Debug.stopMethodTracing: ()V -> dalvik/system/VMDebug.stopMethodTracing: ()V"; + " -> AsyncTask #1.: -> com/test/android/traceview/MisMatched.foo: ()V -> com/test/android/traceview/MisMatched.bar: ()V -> android/os/Debug.startMethodTracing: (Ljava/lang/String;)V -> android/os/Debug.startMethodTracing: (Ljava/lang/String;II)V -> dalvik/system/VMDebug.startMethodTracing: (Ljava/lang/String;II)V\n" + + " -> com/test/android/traceview/MisMatched.baz: ()I\n" + + " -> android/os/Debug.stopMethodTracing: ()V -> dalvik/system/VMDebug.stopMethodTracing: ()V"; testTrace("/mismatched.trace", "AsyncTask #1", expected); } public void testExceptionTrace() throws IOException { String expected = - " -> android/os/Debug.startMethodTracing: (Ljava/lang/String;)V -> android/os/Debug.startMethodTracing: (Ljava/lang/String;II)V -> dalvik/system/VMDebug.startMethodTracing: (Ljava/lang/String;II)V\n" - + " -> com/test/android/traceview/Exceptions.foo: ()V -> com/test/android/traceview/Exceptions.bar: ()V -> com/test/android/traceview/Exceptions.baz: ()V -> java/lang/RuntimeException.<init>: ()V -> java/lang/Exception.<init>: ()V -> java/lang/Throwable.<init>: ()V -> java/util/Collections.emptyList: ()Ljava/util/List;\n" - + " -> java/lang/Throwable.fillInStackTrace: ()Ljava/lang/Throwable; -> java/lang/Throwable.nativeFillInStackTrace: ()Ljava/lang/Object;\n" - + " -> android/os/Debug.stopMethodTracing: ()V -> dalvik/system/VMDebug.stopMethodTracing: ()V"; + " -> AsyncTask #1.: -> android/os/Debug.startMethodTracing: (Ljava/lang/String;)V -> android/os/Debug.startMethodTracing: (Ljava/lang/String;II)V -> dalvik/system/VMDebug.startMethodTracing: (Ljava/lang/String;II)V\n" + + " -> com/test/android/traceview/Exceptions.foo: ()V -> com/test/android/traceview/Exceptions.bar: ()V -> com/test/android/traceview/Exceptions.baz: ()V -> java/lang/RuntimeException.<init>: ()V -> java/lang/Exception.<init>: ()V -> java/lang/Throwable.<init>: ()V -> java/util/Collections.emptyList: ()Ljava/util/List;\n" + + " -> java/lang/Throwable.fillInStackTrace: ()Ljava/lang/Throwable; -> java/lang/Throwable.nativeFillInStackTrace: ()Ljava/lang/Object;\n" + + " -> android/os/Debug.stopMethodTracing: ()V -> dalvik/system/VMDebug.stopMethodTracing: ()V"; testTrace("/exception.trace", "AsyncTask #1", expected); } @@ -125,17 +125,6 @@ public class VmTraceParserTest extends TestCase { return -1; } - private String formatCallStacks(List<Call> calls, Call.Formatter formatter) { - if (calls == null) return "<none>"; - List<String> callStacks = new ArrayList<String>(calls.size()); - - for (Call c : calls) { - callStacks.add(c.format(formatter)); - } - - return Joiner.on('\n').join(callStacks); - } - private VmTraceData getVmTraceData(String traceFilePath) throws IOException { VmTraceParser parser = new VmTraceParser(getFile(traceFilePath)); parser.parse(); |