use of com.android.tools.adtui.chart.hchart.Method in project android by JetBrains.
the class TraceSimplePerf method addRecordToModel.
private void addRecordToModel(SimpleperfReport.Record record, SparseArray<Long> maxSampleTime) {
SimpleperfReport.Sample sample = record.getSample();
if (sample == null) {
return;
}
if (sample.getCallchainCount() == 0) {
return;
}
int threadId = sample.getThreadId();
long sampleTime = sample.getTime();
maxSampleTime.put(threadId, sampleTime);
// Retrieve the ongoing tree associate with this thread.
HNode<Method> tree = forest.get(sample.getThreadId());
if (tree == null) {
tree = new HNode();
tree.setStart(sampleTime);
Method rootMethod = new Method();
rootMethod.setName("root()");
rootMethod.setNamespace("root.package.foo.bar");
tree.setData(rootMethod);
forest.put(sample.getThreadId(), tree);
}
// Compare last captured stack with current stack. Stop as soon as they diverge.
int depth = sample.getCallchainCount() - 1;
HNode<Method> previousNode = tree;
HNode<Method> currentNode = previousNode.getLastChild();
while (currentNode != null && depth >= 0 && isSameMethod(currentNode.getData(), sample.getCallchain(depth))) {
depth--;
previousNode = currentNode;
currentNode = currentNode.getLastChild();
}
// We found the point where the stacks diverge. We need to:
// 1. Mark previous calls are ended via timestamps.
// 2. Insert all new calls which are currently ongoing.
//1. Mark all previous calls as ended.
markCallEnds(currentNode, sampleTime);
//2. Those are new calls on the stack: Add them to the tree.
while (depth >= 0) {
SimpleperfReport.Sample.CallChainEntry invocation = sample.getCallchain(depth);
// Discard all kernel stack frames
if (KERNEL_SYMBOL.equals(invocation.getFile())) {
break;
}
// New node data is a Method.
Method m = new Method();
parseInvocation(invocation, m);
m.setFilename(invocation.getFile());
HNode<Method> newNode = new HNode<>();
newNode.setStart(sampleTime);
newNode.setData(m);
newNode.setDepth(sample.getCallchainCount() - depth - 1);
previousNode.addHNode(newNode);
previousNode = newNode;
depth--;
}
}
use of com.android.tools.adtui.chart.hchart.Method in project android by JetBrains.
the class TraceArt method convertCallsToNode.
// Convert perflib |calls| to HNodes and add them to |root|.
private void convertCallsToNode(List<Call> calls, HNode root, int depth) {
for (Call c : calls) {
HNode<Method> node = new HNode();
node.setStart((c.getEntryTime(ClockType.GLOBAL, TimeUnit.MICROSECONDS) + myData.getStartTimeUs()));
node.setEnd((c.getExitTime(ClockType.GLOBAL, TimeUnit.MICROSECONDS) + myData.getStartTimeUs()));
node.setDepth(depth);
Method method = new Method();
method.setName(myData.getMethod(c.getMethodId()).methodName);
method.setNamespace(myData.getMethod(c.getMethodId()).className);
node.setData(method);
root.addHNode(node);
// Recursion
convertCallsToNode(c.getCallees(), node, depth + 1);
}
}
use of com.android.tools.adtui.chart.hchart.Method in project android by JetBrains.
the class TraceSimplePerf method isSameMethod.
private boolean isSameMethod(Method method, SimpleperfReport.Sample.CallChainEntry invocation) {
Method parseInvocation = new Method();
parseInvocation(invocation, parseInvocation);
return method.getName().equals(parseInvocation.getName()) && method.getNameSpace().equals(parseInvocation.getNameSpace());
}
use of com.android.tools.adtui.chart.hchart.Method in project android by JetBrains.
the class AppTrace method generateTopDownGraphs.
// TopDown graph are flamegraphs: The execution stacks merged together (on a per-thread basis).
// TopDown graphs are used in flamegraphs but also in top-down and bottom-up statistics display.
private void generateTopDownGraphs() {
myTopDownStats = new SparseArray<>();
SparseArray<HNode<Method>> threadGraphs = getThreadsGraph();
for (int i = 0; i < threadGraphs.size(); i++) {
int threadPid = threadGraphs.keyAt(i);
HNode<Method> execGraph = threadGraphs.get(threadPid);
HNode<MethodUsage> usageGraphRoot = new HNode<>();
usageGraphRoot.setStart(0);
usageGraphRoot.setEnd(execGraph.duration());
usageGraphRoot.setData(new MethodUsage());
long totalDuration = usageGraphRoot.duration();
// Graph generation is a two passes algorithm:
// 1/ Merge all the stackframes.
// 2/ Generate all the node data and layout (start,end)
mergeStackTraces(execGraph, usageGraphRoot);
generateStats(usageGraphRoot, totalDuration);
myTopDownStats.put(threadPid, usageGraphRoot);
}
}
use of com.android.tools.adtui.chart.hchart.Method in project android by JetBrains.
the class Sampler method sample.
private void sample() {
lastSampleTime = currSampleTime;
currSampleTime = currentTimeMicroSec();
Set<java.lang.Thread> threadSet = java.lang.Thread.getAllStackTraces().keySet();
for (java.lang.Thread sampledThread : threadSet) {
StackTraceElement[] elements = sampledThread.getStackTrace();
// Some threads (e.g: SignalDispatcher) have no elements.
if (elements.length == 0) {
continue;
}
// Retrieve the ongoing tree associate with this thread.
HNode<Method> tree = forest.get(sampledThread.getName());
if (tree == null) {
tree = new HNode();
tree.setStart(getLastMidTime());
Method rootMethod = new Method();
rootMethod.setName("rootMethod");
rootMethod.setNamespace("root.package.foo.bar");
tree.setData(rootMethod);
forest.put(sampledThread.getName(), tree);
}
// Compare last captured stack with current stack. Stop as soon as they diverge.
int depth = elements.length - 1;
HNode<Method> previousNode = tree;
HNode<Method> currentNode = previousNode.getLastChild();
while (currentNode != null && depth >= 0 && isSameMethod(currentNode, elements[depth])) {
depth--;
previousNode = currentNode;
currentNode = currentNode.getLastChild();
}
// We found the point where the stacks diverge. We need to:
// 1. Mark previous calls are ended via timestamps.
// 2. Insert all new calls which are currently ongoing.
//1. Mark all previous calls as ended.
HNode endedCall = currentNode;
while (endedCall != null) {
endedCall.setEnd(getLastMidTime());
endedCall = endedCall.getLastChild();
}
//2. Those are new calls on the stack: Add them to the tree.
while (depth != -1) {
StackTraceElement trace = elements[depth];
// New node data is a Method.
Method m = new Method();
m.setNamespace(trace.getClassName());
m.setName(trace.getMethodName());
HNode<Method> newNode = new HNode<>();
newNode.setStart(getLastMidTime());
newNode.setData(m);
newNode.setDepth(elements.length - depth - 1);
previousNode.addHNode(newNode);
previousNode = newNode;
depth--;
}
}
}
Aggregations