summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSiva Velusamy <vsiva@google.com>2013-08-07 13:40:02 -0700
committerAndroid Git Automerger <android-git-automerger@android.com>2013-08-07 13:40:02 -0700
commitaca3dbe3fc617175bfb715bc573048ab2e14c18d (patch)
tree564076e3aa4e023666af0938621938face971282
parent432f4cc35d7941328d43a8e8283e974c593a30c9 (diff)
parent9030e9d402cc8be11665dac22c49dc3f186ecee0 (diff)
downloadbase-kitkat-mr2.1-release.tar.gz
* commit '9030e9d402cc8be11665dac22c49dc3f186ecee0': perflib: Use the builder pattern for the Call structure.
-rw-r--r--perflib/src/main/java/com/android/tools/perflib/vmtrace/Call.java106
-rw-r--r--perflib/src/main/java/com/android/tools/perflib/vmtrace/CallStackReconstructor.java61
-rw-r--r--perflib/src/main/java/com/android/tools/perflib/vmtrace/MethodInfo.java26
-rw-r--r--perflib/src/main/java/com/android/tools/perflib/vmtrace/VmTraceData.java3
-rw-r--r--perflib/src/test/java/com/android/tools/perflib/vmtrace/VmTraceParserTest.java3
5 files changed, 134 insertions, 65 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 e6f0dc7793..9144ea5776 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
@@ -18,42 +18,47 @@ package com.android.tools.perflib.vmtrace;
import com.android.annotations.NonNull;
import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
public class Call {
private final long mMethodId;
- private int mEntryThreadTime;
- private int mEntryGlobalTime;
- private int mExitGlobalTime;
- private int mExitThreadTime;
+ private final int mEntryThreadTime;
+ private final int mEntryGlobalTime;
+ private final int mExitGlobalTime;
+ private final int mExitThreadTime;
- private int mDepth = 0;
+ private final int mDepth;
- private List<Call> mCallees = new ArrayList<Call>();
+ private final List<Call> mCallees;
- public Call(long methodId) {
- mMethodId = methodId;
- }
+ private Call(Builder builder) {
+ mMethodId = builder.mMethodId;
- public long getMethodId() {
- return mMethodId;
- }
+ mEntryThreadTime = builder.mEntryThreadTime;
+ mEntryGlobalTime = builder.mEntryGlobalTime;
+ mExitThreadTime = builder.mExitThreadTime;
+ mExitGlobalTime = builder.mExitGlobalTime;
- public void setMethodEntryTime(int threadTime, int globalTime) {
- mEntryThreadTime = threadTime;
- mEntryGlobalTime = globalTime;
- }
-
- public void setMethodExitTime(int threadTime, int globalTime) {
- mExitThreadTime = threadTime;
- mExitGlobalTime = globalTime;
+ mDepth = builder.mDepth;
+ if (builder.mCallees == null) {
+ mCallees = Collections.emptyList();
+ } else {
+ List<Call> callees = new ArrayList<Call>(builder.mCallees.size());
+ for (Builder b : builder.mCallees) {
+ b.setStackDepth(mDepth + 1);
+ callees.add(b.build());
+ }
+ mCallees = new ImmutableList.Builder<Call>().addAll(callees).build();
+ }
}
- public void addCallee(Call c) {
- mCallees.add(c);
+ public long getMethodId() {
+ return mMethodId;
}
@NonNull
@@ -65,8 +70,58 @@ public class Call {
return mDepth;
}
- public void setDepth(int depth) {
- mDepth = depth;
+ public int getEntryThreadTime() {
+ return mEntryThreadTime;
+ }
+
+ public int getExitThreadTime() {
+ return mExitThreadTime;
+ }
+
+ public static class Builder {
+ private final long mMethodId;
+
+ private int mEntryThreadTime;
+ private int mEntryGlobalTime;
+ private int mExitGlobalTime;
+ private int mExitThreadTime;
+
+ private int mDepth = 0;
+
+ private List<Builder> mCallees = null;
+
+ public Builder(long methodId) {
+ mMethodId = methodId;
+ }
+
+ public long getMethodId() {
+ return mMethodId;
+ }
+
+ public void setMethodEntryTime(int threadTime, int globalTime) {
+ mEntryThreadTime = threadTime;
+ mEntryGlobalTime = globalTime;
+ }
+
+ public void setMethodExitTime(int threadTime, int globalTime) {
+ mExitThreadTime = threadTime;
+ mExitGlobalTime = globalTime;
+ }
+
+ public void addCallee(Builder c) {
+ if (mCallees == null) {
+ mCallees = new ArrayList<Builder>();
+ }
+ mCallees.add(c);
+ }
+
+ public void setStackDepth(int depth) {
+ mDepth = depth;
+ }
+
+ public Call build() {
+ return new Call(this);
+ }
}
/**
@@ -100,9 +155,6 @@ public class Call {
sb.append(formatter.format(this));
List<Call> callees = getCallees();
- if (callees == null) {
- return;
- }
int lineStart = sb.lastIndexOf("\n");
int depth = sb.length() - (lineStart + 1);
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 027d550695..e241db8fba 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
@@ -16,18 +16,24 @@
package com.android.tools.perflib.vmtrace;
-import com.android.annotations.NonNull;
+import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
-/** Reconstructs call stacks from a sequence of trace events (method entry/exit events) */
+/**
+ * {@link CallStackReconstructor} helps in reconstructing per thread call stacks from a sequence of
+ * trace events (method entry/exit events).
+ */
public class CallStackReconstructor {
- private List<Call> mTopLevelCallees = new ArrayList<Call>();
- private Stack<Call> mCallStack = new Stack<Call>();
+ /** 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>();
+
+ /** Current call stack based on the sequence of received trace events. */
+ private Stack<Call.Builder> mCallStack = new Stack<Call.Builder>();
- private boolean mFixupComplete;
+ private List<Call> mTopLevelCallees;
public void addTraceAction(long methodId, TraceAction action, int threadTime, int globalTime) {
if (action == TraceAction.METHOD_ENTER) {
@@ -38,22 +44,22 @@ public class CallStackReconstructor {
}
private void enterMethod(long methodId, int threadTime, int globalTime) {
- Call c = new Call(methodId);
- c.setMethodEntryTime(threadTime, globalTime);
+ Call.Builder cb = new Call.Builder(methodId);
+ cb.setMethodEntryTime(threadTime, globalTime);
if (mCallStack.isEmpty()) {
- mTopLevelCallees.add(c);
+ mTopLevelCalls.add(cb);
} else {
- Call caller = mCallStack.peek();
- caller.addCallee(c);
+ Call.Builder caller = mCallStack.peek();
+ caller.addCallee(cb);
}
- mCallStack.push(c);
+ mCallStack.push(cb);
}
private void exitMethod(long methodId, int threadTime, int globalTime) {
if (!mCallStack.isEmpty()) {
- Call c = mCallStack.pop();
+ Call.Builder c = mCallStack.pop();
if (c.getMethodId() != methodId) {
String msg = String
.format("Error during call stack reconstruction. Attempt to exit from method 0x%1$x while in method 0x%2$x",
@@ -65,42 +71,35 @@ public class CallStackReconstructor {
} else {
// We are exiting out of a method that was entered into before tracing was started.
// In such a case, create this method
- Call c = new Call(methodId);
+ 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
// the top level to only include this method
- for (Call topLevelCallee : mTopLevelCallees) {
- c.addCallee(topLevelCallee);
+ for (Call.Builder cb : mTopLevelCalls) {
+ c.addCallee(cb);
}
- mTopLevelCallees.clear();
- mTopLevelCallees.add(c);
+ mTopLevelCalls.clear();
+ mTopLevelCalls.add(c);
}
}
private void fixupCallStacks() {
- if (mFixupComplete) {
+ if (mTopLevelCallees != null) {
return;
}
- // fixup whatever needs fixing up
// TODO: use global / thread times to infer context switches
- // Fix call stack depths
- for (Call c : mTopLevelCallees) {
- setStackDepthRecursive(c, 0);
+ // 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());
}
- mFixupComplete = true;
- }
-
- private void setStackDepthRecursive(@NonNull Call call, int i) {
- call.setDepth(i);
-
- for (Call c : call.getCallees()) {
- setStackDepthRecursive(c, i+1);
- }
+ mTopLevelCallees = new ImmutableList.Builder<Call>().addAll(topLevelCallees).build();
}
public List<Call> getTopLevelCallees() {
diff --git a/perflib/src/main/java/com/android/tools/perflib/vmtrace/MethodInfo.java b/perflib/src/main/java/com/android/tools/perflib/vmtrace/MethodInfo.java
index 518d5c8362..c2b0edb6e0 100644
--- a/perflib/src/main/java/com/android/tools/perflib/vmtrace/MethodInfo.java
+++ b/perflib/src/main/java/com/android/tools/perflib/vmtrace/MethodInfo.java
@@ -26,6 +26,9 @@ public class MethodInfo {
public final String srcPath;
public final int srcLineNumber;
+ private String mFullName;
+ private String mShortName;
+
public MethodInfo(long id, String className, String methodName, String signature, String srcPath,
int srcLineNumber) {
this.id = id;
@@ -36,7 +39,26 @@ public class MethodInfo {
this.srcLineNumber = srcLineNumber;
}
- public String getName() {
- return String.format(Locale.US, "%s.%s: %s", className, methodName, signature);
+ public String getFullName() {
+ if (mFullName == null) {
+ mFullName = String.format(Locale.US, "%s.%s: %s", className, methodName, signature);
+ }
+ return mFullName;
+ }
+
+ public String getShortName() {
+ if (mShortName == null) {
+ mShortName = String.format(Locale.US, "%s.%s", getUnqualifiedClassName(), methodName);
+ }
+ return mShortName;
+ }
+
+ private String getUnqualifiedClassName() {
+ String cn = className;
+ int i = cn.lastIndexOf('/');
+ if (i > 0) {
+ cn = cn.substring(i + 1);
+ }
+ return cn;
}
}
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 cb5f54e0e7..b6f27c8419 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
@@ -17,10 +17,7 @@
package com.android.tools.perflib.vmtrace;
import com.android.utils.SparseArray;
-import com.google.common.base.Joiner;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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 19fad82565..87b7109069 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
@@ -27,7 +27,6 @@ import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
-import java.util.Locale;
import java.util.Map;
public class VmTraceParserTest extends TestCase {
@@ -73,7 +72,7 @@ public class VmTraceParserTest extends TestCase {
@Override
public String format(Call c) {
MethodInfo info = mMethodInfo.get(c.getMethodId());
- return info == null ? Long.toString(c.getMethodId()) : info.getName();
+ return info == null ? Long.toString(c.getMethodId()) : info.getFullName();
}
}