1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* //device/tools/dmtracedump/TraceDump.c 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project** 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project** Copyright 2006, The Android Open Source Project 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project** 5de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro** Licensed under the Apache License, Version 2.0 (the "License"); 6de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro** you may not use this file except in compliance with the License. 7de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro** You may obtain a copy of the License at 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project** 9de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro** http://www.apache.org/licenses/LICENSE-2.0 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project** 11de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro** Unless required by applicable law or agreed to in writing, software 12de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro** distributed under the License is distributed on an "AS IS" BASIS, 13de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro** See the License for the specific language governing permissions and 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project** limitations under the License. 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/ 175b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Process dmtrace output. 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is the wrong way to go about it -- C is a clumsy language for 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * shuffling data around. It'll do for a first pass. 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define NOT_VM 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Profile.h" // from VM header 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdio.h> 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdlib.h> 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <string.h> 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <unistd.h> 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <inttypes.h> 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <time.h> 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <errno.h> 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <assert.h> 35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Version number in the key file. Version 1 uses one byte for the thread id. 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Version 2 uses two bytes for the thread ids. 38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint versionNumber; 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* arbitrarily limit indentation */ 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define MAX_STACK_DEPTH 10000 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* thread list in key file is not reliable, so just max out */ 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define MAX_THREADS 32768 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Size of temporary buffers for escaping html strings */ 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HTML_BUFSIZE 10240 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 506978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince/* Size of methodId->method cache */ 516978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince#define METHOD_CACHE_SIZE 2048 5244828ed25841ea5180346695dfc07ef33b2b7e73Jack Veenstra#define METHOD_CACHE_SIZE_MASK (METHOD_CACHE_SIZE - 1) 536978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 546978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince/* Some filter constants */ 556978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince#define FILTER_TAG '*' 566978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince#define FILTER_FLAG_THREAD '+' 576978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince#define FILTER_TYPE_CLASS 0 586978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince#define FILTER_TYPE_METHOD 1 596978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 606978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince#define DEFAULT_ACTIVE_THREADS 8 616978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 62de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapirochar *htmlHeader = 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"<html>\n<head>\n<script type=\"text/javascript\" src=\"%ssortable.js\"></script>\n" 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"<script langugage=\"javascript\">\n" 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"function toggle(item) {\n" 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" obj=document.getElementById(item);\n" 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" visible=(obj.style.display!=\"none\" && obj.style.display!=\"\");\n" 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" key=document.getElementById(\"x\" + item);\n" 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" if (visible) {\n" 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" obj.style.display=\"none\";\n" 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" key.innerHTML=\"+\";\n" 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" } else {\n" 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" obj.style.display=\"block\";\n" 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" key.innerHTML=\"-\";\n" 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" }\n" 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"}\n" 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"function onMouseOver(obj) {\n" 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" obj.style.background=\"lightblue\";\n" 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"}\n" 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"function onMouseOut(obj) {\n" 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" obj.style.background=\"white\";\n" 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"}\n" 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"</script>\n" 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"<style type=\"text/css\">\n" 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"div { font-family: courier; font-size: 13 }\n" 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"div.parent { margin-left: 15; display: none }\n" 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"div.leaf { margin-left: 10 }\n" 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"div.header { margin-left: 10 }\n" 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"div.link { margin-left: 10; cursor: move }\n" 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"span.parent { padding-right: 10; }\n" 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"span.leaf { padding-right: 10; }\n" 92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"a img { border: 0;}\n" 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"table.sortable th { border-width: 0px 1px 1px 1px; background-color: #ccc;}\n" 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"a { text-decoration: none; }\n" 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"a:hover { text-decoration: underline; }\n" 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"table.sortable th, table.sortable td { text-align: left;}" 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"table.sortable tr.odd td { background-color: #ddd; }\n" 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"table.sortable tr.even td { background-color: #fff; }\n" 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"</style>\n" 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"</head><body>\n\n"; 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar *htmlFooter = "\n</body>\n</html>\n"; 103de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapirochar *profileSeparator = 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "======================================================================"; 105de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 106de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiroconst char* tableHeader = 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<table class='sortable' id='%s'><tr>\n" 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>Method</th>\n" 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>Run 1 (us)</th>\n" 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>Run 2 (us)</th>\n" 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>Diff (us)</th>\n" 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>Diff (%%)</th>\n" 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>1: # calls</th>\n" 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>2: # calls</th>\n" 115de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro "</tr>\n"; 116de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 117de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiroconst char* tableHeaderMissing = 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<table class='sortable' id='%s'>\n" 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>Method</th>\n" 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>Exclusive</th>\n" 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>Inclusive</th>\n" 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th># calls</th>\n"; 123de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 124de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro#define GRAPH_LABEL_VISITED 0x0001 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GRAPH_NODE_VISITED 0x0002 126de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Values from the header of the data file. 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct DataHeader { 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int magic; 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project short version; 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project short offsetToData; 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long long startWhen; 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} DataHeader; 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Entry from the thread list. 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct ThreadEntry { 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int threadId; 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* threadName; 1435b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince uint64_t elapsedTime; 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} ThreadEntry; 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstruct MethodEntry; 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct TimedMethod { 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct TimedMethod *next; 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsedInclusive; 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numCalls; 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct MethodEntry *method; 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} TimedMethod; 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct ClassEntry { 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char *className; 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsedExclusive; 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numMethods; 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct MethodEntry **methods; /* list of methods in this class */ 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numCalls[2]; /* 0=normal, 1=recursive */ 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} ClassEntry; 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct UniqueMethodEntry { 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsedExclusive; 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numMethods; 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct MethodEntry **methods; /* list of methods with same name */ 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numCalls[2]; /* 0=normal, 1=recursive */ 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} UniqueMethodEntry; 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Entry from the method list. 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct MethodEntry { 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int methodId; 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* className; 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* methodName; 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* signature; 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* fileName; 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int lineNum; 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsedExclusive; 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsedInclusive; 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t topExclusive; /* non-recursive exclusive time */ 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t recursiveInclusive; 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct TimedMethod *parents[2]; /* 0=normal, 1=recursive */ 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct TimedMethod *children[2]; /* 0=normal, 1=recursive */ 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numCalls[2]; /* 0=normal, 1=recursive */ 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int index; /* used after sorting to number methods */ 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int recursiveEntries; /* number of entries on the stack */ 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int graphState; /* used when graphing to see if this method has been visited before */ 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} MethodEntry; 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The parsed contents of the key file. 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct DataKeys { 1955b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince char* fileData; /* contents of the entire file */ 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long fileLen; 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numThreads; 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ThreadEntry* threads; 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numMethods; 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* methods; /* 2 extra methods: "toplevel" and "unknown" */ 2016978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int* methodCache; /* methodId->methodIndex mapping */ 2026978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // TODO change to map methodId->method itself 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} DataKeys; 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define TOPLEVEL_INDEX 0 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define UNKNOWN_INDEX 1 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct StackEntry { 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry *method; 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t entryTime; 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} StackEntry; 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct CallStack { 2146978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int top; 2156978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince StackEntry calls[MAX_STACK_DEPTH]; 2166978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince uint64_t lastEventTime; 2176978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince uint64_t threadStartTime; 2186978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince uint64_t* remTimes; 2196978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Note: remTimes keeps a sum of 'un-allocated' time for each thread, in case 2206978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // we need to allocate it to one (or many) filter later. This would happen when 2216978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // we see a method exit that maches a filter, but whose entry we hadn't seen. 2226978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // TODO: consider moving remTimes into FilterTimes and change logic appropriately 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} CallStack; 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct DiffEntry { 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method1; 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method2; 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int64_t differenceExclusive; 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int64_t differenceInclusive; 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double differenceExclusivePercentage; 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double differenceInclusivePercentage; 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} DiffEntry; 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// Global options 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct Options { 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* traceFileName; 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* diffFileName; 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* graphFileName; 2396978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince const char* filterFileName; 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int keepDotFile; 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int dump; 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int outputHtml; 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* sortableUrl; 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int threshold; 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} Options; 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct TraceData { 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numClasses; 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassEntry *classes; 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CallStack *stacks[MAX_THREADS]; 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int depth[MAX_THREADS]; 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numUniqueMethods; 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UniqueMethodEntry *uniqueMethods; 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} TraceData; 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2566978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipincetypedef struct FilterKey { 2576978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int type[2]; /* 0=class, 1=method; 2 needed for start and end keys */ 2586978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince uint32_t flags; /* 1st bit = include cross-thread time */ 2596978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince char* keys[2]; /* 2 needed for start and end keys */ 2606978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince} FilterKey; 2616978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 2626978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipincetypedef struct FilterTimes { 2636978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince uint64_t totalWaitTime; 2646978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince uint64_t* threadWaitTimes; 2656978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince uint64_t* threadExecutionTimesWhileWaiting; 2666978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince uint64_t* threadExecutionTimes; 2676978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince} FilterTimes; 2686978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 2696978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipincetypedef struct Filter { 2706978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince char* filterName; 2716978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince FilterKey* filterKeys; 2726978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int numKeys; 2736978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int activeCount; 2746978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int* activeThreads; 2756978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int* activationKeys; 2766978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince FilterTimes times; 2776978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince} Filter; 2786978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 2796978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipinceint numFilters = 0; // global 2806978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Options gOptions; 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Escapes characters in the source string that are html special entities. 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The escaped string is written to "dest" which must be large enough to 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * hold the result. A pointer to "dest" is returned. The characters and 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * their corresponding escape sequences are: 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * '<' < 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * '>' > 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * '&' & 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar *htmlEscape(const char *src, char *dest, int len) 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *destStart = dest; 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (src == NULL) 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nbytes = 0; 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*src) { 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*src == '<') { 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nbytes += 4; 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nbytes >= len) 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = '&'; 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = 'l'; 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = 't'; 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = ';'; 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (*src == '>') { 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nbytes += 4; 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nbytes >= len) 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = '&'; 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = 'g'; 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = 't'; 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = ';'; 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (*src == '&') { 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nbytes += 5; 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nbytes >= len) 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = '&'; 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = 'a'; 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = 'm'; 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = 'p'; 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = ';'; 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nbytes += 1; 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nbytes >= len) 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = *src; 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project src += 1; 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nbytes >= len) { 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "htmlEscape(): buffer overflow\n"); 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exit(1); 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest = 0; 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return destStart; 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Initializes a MethodEntry 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid initMethodEntry(MethodEntry *method, unsigned int methodId, 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char *className, const char *methodName, 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char *signature, const char* fileName, 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* lineNumStr) 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->methodId = methodId; 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->className = className; 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->methodName = methodName; 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->signature = signature; 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->fileName = fileName; 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->lineNum = (lineNumStr != NULL) ? atoi(lineNumStr) : -1; 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedExclusive = 0; 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedInclusive = 0; 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->topExclusive = 0; 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->recursiveInclusive = 0; 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->parents[0] = NULL; 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->parents[1] = NULL; 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->children[0] = NULL; 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->children[1] = NULL; 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->numCalls[0] = 0; 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->numCalls[1] = 0; 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->index = 0; 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->recursiveEntries = 0; 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This comparison function is called from qsort() to sort 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * methods into decreasing order of exclusive elapsed time. 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareElapsedExclusive(const void *a, const void *b) { 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsed1, elapsed2; 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodA = *(const MethodEntry**)a; 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodB = *(const MethodEntry**)b; 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed1 = methodA->elapsedExclusive; 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed2 = methodB->elapsedExclusive; 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 < elapsed2) 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 > elapsed2) 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If the elapsed times of two methods are equal, then sort them 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * into alphabetical order. 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->className, methodB->className); 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodA->methodName == NULL || methodB->methodName == NULL) { 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idA = methodA->methodId; 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idB = methodB->methodId; 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA < idB) 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA > idB) 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->methodName, methodB->methodName); 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->signature, methodB->signature); 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This comparison function is called from qsort() to sort 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * methods into decreasing order of inclusive elapsed time. 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareElapsedInclusive(const void *a, const void *b) { 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodA, *methodB; 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsed1, elapsed2; 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodA = *(MethodEntry const **)a; 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodB = *(MethodEntry const **)b; 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed1 = methodA->elapsedInclusive; 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed2 = methodB->elapsedInclusive; 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 < elapsed2) 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 > elapsed2) 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If the elapsed times of two methods are equal, then sort them 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * into alphabetical order. 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->className, methodB->className); 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodA->methodName == NULL || methodB->methodName == NULL) { 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idA = methodA->methodId; 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idB = methodB->methodId; 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA < idB) 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA > idB) 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->methodName, methodB->methodName); 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->signature, methodB->signature); 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This comparison function is called from qsort() to sort 4485b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince * threads into decreasing order of elapsed time. 4495b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince */ 4505b55af706cf3823494123da092a0a0319297a93eRodrigo Ipinceint compareElapsed(const void *a, const void *b) { 4515b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince const ThreadEntry *threadA, *threadB; 4525b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince uint64_t elapsed1, elapsed2; 4535b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince int result = 0; 4545b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 4555b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince threadA = (ThreadEntry const *)a; 4565b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince threadB = (ThreadEntry const *)b; 4575b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince elapsed1 = threadA->elapsedTime; 4585b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince elapsed2 = threadB->elapsedTime; 4595b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince if (elapsed1 < elapsed2) 4605b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince return 1; 4615b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince if (elapsed1 > elapsed2) 4625b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince return -1; 4635b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 4645b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince /* If the elapsed times of two threads are equal, then sort them 4655b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince * by thread id. 4665b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince */ 4675b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince int idA = threadA->threadId; 4685b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince int idB = threadB->threadId; 4695b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince if (idA < idB) 4705b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince result = -1; 4715b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince if (idA > idB) 4725b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince result = 1; 4735b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 4745b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince return result; 4755b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince} 4765b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 4775b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince/* 4785b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince * This comparison function is called from qsort() to sort 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TimedMethods into decreasing order of inclusive elapsed time. 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareTimedMethod(const void *a, const void *b) { 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const TimedMethod *timedA, *timedB; 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsed1, elapsed2; 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project timedA = (TimedMethod const *)a; 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project timedB = (TimedMethod const *)b; 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed1 = timedA->elapsedInclusive; 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed2 = timedB->elapsedInclusive; 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 < elapsed2) 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 > elapsed2) 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If the elapsed times of two methods are equal, then sort them 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * into alphabetical order. 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry *methodA = timedA->method; 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry *methodB = timedB->method; 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->className, methodB->className); 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodA->methodName == NULL || methodB->methodName == NULL) { 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idA = methodA->methodId; 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idB = methodB->methodId; 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA < idB) 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA > idB) 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->methodName, methodB->methodName); 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->signature, methodB->signature); 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This comparison function is called from qsort() to sort 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * MethodEntry pointers into alphabetical order of class names. 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareClassNames(const void *a, const void *b) { 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodA = *(const MethodEntry**)a; 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodB = *(const MethodEntry**)b; 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->className, methodB->className); 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idA = methodA->methodId; 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idB = methodB->methodId; 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA < idB) 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA > idB) 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This comparison function is called from qsort() to sort 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * classes into decreasing order of exclusive elapsed time. 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareClassExclusive(const void *a, const void *b) { 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsed1, elapsed2; 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const ClassEntry *classA = *(const ClassEntry**)a; 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const ClassEntry *classB = *(const ClassEntry**)b; 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed1 = classA->elapsedExclusive; 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed2 = classB->elapsedExclusive; 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 < elapsed2) 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 > elapsed2) 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If the elapsed times of two classs are equal, then sort them 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * into alphabetical order. 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(classA->className, classB->className); 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Break ties with the first method id. This is probably not 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * needed. 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idA = classA->methods[0]->methodId; 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idB = classB->methods[0]->methodId; 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA < idB) 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA > idB) 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This comparison function is called from qsort() to sort 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * MethodEntry pointers into alphabetical order by method name, 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * then by class name. 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareMethodNames(const void *a, const void *b) { 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodA = *(const MethodEntry**)a; 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodB = *(const MethodEntry**)b; 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodA->methodName == NULL || methodB->methodName == NULL) { 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return compareClassNames(a, b); 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->methodName, methodB->methodName); 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->className, methodB->className); 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idA = methodA->methodId; 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idB = methodB->methodId; 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA < idB) 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA > idB) 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This comparison function is called from qsort() to sort 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * unique methods into decreasing order of exclusive elapsed time. 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareUniqueExclusive(const void *a, const void *b) { 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsed1, elapsed2; 611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const UniqueMethodEntry *uniqueA = *(const UniqueMethodEntry**)a; 614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const UniqueMethodEntry *uniqueB = *(const UniqueMethodEntry**)b; 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed1 = uniqueA->elapsedExclusive; 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed2 = uniqueB->elapsedExclusive; 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 < elapsed2) 618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 > elapsed2) 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If the elapsed times of two methods are equal, then sort them 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * into alphabetical order. 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(uniqueA->methods[0]->className, 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uniqueB->methods[0]->className); 627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idA = uniqueA->methods[0]->methodId; 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idB = uniqueB->methods[0]->methodId; 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA < idB) 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA > idB) 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free a DataKeys struct. 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid freeDataKeys(DataKeys* pKeys) 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pKeys == NULL) 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pKeys->fileData); 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pKeys->threads); 649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pKeys->methods); 6506978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince free(pKeys->methodCache); 651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pKeys); 652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the offset to the next occurrence of the specified character. 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "data" should point somewhere within the current line. "len" is the 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * number of bytes left in the buffer. 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns -1 if we hit the end of the buffer. 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint findNextChar(const char* data, int len, char lookFor) 663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* start = data; 665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (len > 0) { 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*data == lookFor) 668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return data - start; 669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data++; 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len--; 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6776978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipinceint countLinesToChar(const char* data, int len, const char toFind) 678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int count = 0; 680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int next; 681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6826978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince while (*data != toFind) { 683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = findNextChar(data, len, '\n'); 684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (next < 0) 6856978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince return count; 686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count++; 687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next+1; 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len -= next+1; 689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return count; 692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 6956978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * Count the number of lines until the next token. 6966978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * 6976978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * Returns 0 if none found before EOF. 6986978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince */ 6996978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipinceint countLinesToToken(const char* data, int len) 7006978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince{ 7016978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince return countLinesToChar(data, len, TOKEN_CHAR); 7026978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince} 7036978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 7046978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince/* 705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Make sure we're at the start of the right section. 706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the length of the token line, or -1 if something is wrong. 708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint checkToken(const char* data, int len, const char* cmpStr) 710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cmpLen = strlen(cmpStr); 712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int next; 713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*data != TOKEN_CHAR) { 715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, 716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "ERROR: not at start of %s (found '%.10s')\n", cmpStr, data); 717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = findNextChar(data, len, '\n'); 721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (next < cmpLen+1) 722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strncmp(data+1, cmpStr, cmpLen) != 0) { 725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "ERROR: '%s' not found (got '%.7s')\n", cmpStr, data+1); 726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return next+1; 730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse the "*version" section. 734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectlong parseVersion(DataKeys* pKeys, long offset, int verbose) 736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* data; 738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* dataEnd; 739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, count, next; 740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (offset < 0) 742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data = pKeys->fileData + offset; 745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataEnd = pKeys->fileData + pKeys->fileLen; 746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = checkToken(data, dataEnd - data, "version"); 747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (next <= 0) 748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next; 751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Count the number of items in the "version" section. 754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count = countLinesToToken(data, dataEnd - data); 756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count <= 0) { 757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, 758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "ERROR: failed while reading version (found %d)\n", count); 759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* find the end of the line */ 763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = findNextChar(data, dataEnd - data, '\n'); 764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (next < 0) 765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data[next] = '\0'; 768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project versionNumber = strtoul(data, NULL, 0); 769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (verbose) 770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("VERSION: %d\n", versionNumber); 771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next+1; 773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* skip over the rest of the stuff, which is "name=value" lines */ 775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 1; i < count; i++) { 776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = findNextChar(data, dataEnd - data, '\n'); 777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (next < 0) 778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //data[next] = '\0'; 780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf("IGNORING: '%s'\n", data); 781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next+1; 782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return data - pKeys->fileData; 785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse the "*threads" section. 789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectlong parseThreads(DataKeys* pKeys, long offset) 791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* data; 793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* dataEnd; 794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, next, tab, count; 795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (offset < 0) 797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data = pKeys->fileData + offset; 800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataEnd = pKeys->fileData + pKeys->fileLen; 801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = checkToken(data, dataEnd - data, "threads"); 802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next; 804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Count the number of thread entries (one per line). 807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count = countLinesToToken(data, dataEnd - data); 809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count <= 0) { 810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, 811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "ERROR: failed while reading threads (found %d)\n", count); 812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf("+++ found %d threads\n", count); 816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->threads = (ThreadEntry*) malloc(sizeof(ThreadEntry) * count); 817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pKeys->threads == NULL) 818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract all entries. 822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < count; i++) { 824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = findNextChar(data, dataEnd - data, '\n'); 825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(next > 0); 826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data[next] = '\0'; 827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab = findNextChar(data, next, '\t'); 829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data[tab] = '\0'; 830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->threads[i].threadId = atoi(data); 832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->threads[i].threadName = data + tab +1; 833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next+1; 835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->numThreads = count; 838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return data - pKeys->fileData; 839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse the "*methods" section. 843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectlong parseMethods(DataKeys* pKeys, long offset) 845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* data; 847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* dataEnd; 848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, next, count; 849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (offset < 0) 851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data = pKeys->fileData + offset; 854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataEnd = pKeys->fileData + pKeys->fileLen; 855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = checkToken(data, dataEnd - data, "methods"); 856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (next < 0) 857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next; 860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Count the number of method entries (one per line). 863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count = countLinesToToken(data, dataEnd - data); 865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count <= 0) { 866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, 867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "ERROR: failed while reading methods (found %d)\n", count); 868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Reserve an extra method at location 0 for the "toplevel" method, 872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and another extra method for all other "unknown" methods. 873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count += 2; 875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->methods = (MethodEntry*) malloc(sizeof(MethodEntry) * count); 876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pKeys->methods == NULL) 877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project initMethodEntry(&pKeys->methods[TOPLEVEL_INDEX], 0, "(toplevel)", 879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project NULL, NULL, NULL, NULL); 880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project initMethodEntry(&pKeys->methods[UNKNOWN_INDEX], 0, "(unknown)", 881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project NULL, NULL, NULL, NULL); 882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract all entries, starting with index 2. 885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = UNKNOWN_INDEX + 1; i < count; i++) { 887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int tab1, tab2, tab3, tab4, tab5; 888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int id; 889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* endptr; 890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = findNextChar(data, dataEnd - data, '\n'); 892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(next > 0); 893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data[next] = '\0'; 894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab1 = findNextChar(data, next, '\t'); 896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab2 = findNextChar(data+(tab1+1), next-(tab1+1), '\t'); 897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab3 = findNextChar(data+(tab1+tab2+2), next-(tab1+tab2+2), '\t'); 898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab4 = findNextChar(data+(tab1+tab2+tab3+3), 899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next-(tab1+tab2+tab3+3), '\t'); 900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab5 = findNextChar(data+(tab1+tab2+tab3+tab4+4), 901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next-(tab1+tab2+tab3+tab4+4), '\t'); 902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (tab1 < 0) { 903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "ERROR: missing field on method line: '%s'\n", 904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data); 905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(data[tab1] == '\t'); 908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data[tab1] = '\0'; 909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id = strtoul(data, &endptr, 0); 911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*endptr != '\0') { 912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "ERROR: bad method ID '%s'\n", data); 913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Allow files that specify just a function name, instead of requiring 917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // "class \t method \t signature" 918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (tab2 > 0 && tab3 > 0) { 919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab2 += tab1+1; 920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab3 += tab2+1; 921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(data[tab2] == '\t'); 922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(data[tab3] == '\t'); 923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data[tab2] = data[tab3] = '\0'; 924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // This is starting to get awkward. Allow filename and line #. 926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (tab4 > 0 && tab5 > 0) { 927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab4 += tab3+1; 928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab5 += tab4+1; 929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(data[tab4] == '\t'); 931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(data[tab5] == '\t'); 932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data[tab4] = data[tab5] = '\0'; 933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project initMethodEntry(&pKeys->methods[i], id, data + tab1 +1, 935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data + tab2 +1, data + tab3 +1, data + tab4 +1, 936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data + tab5 +1); 937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project initMethodEntry(&pKeys->methods[i], id, data + tab1 +1, 939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data + tab2 +1, data + tab3 +1, NULL, NULL); 940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project initMethodEntry(&pKeys->methods[i], id, data + tab1 +1, 943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project NULL, NULL, NULL, NULL); 944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next+1; 947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->numMethods = count; 950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return data - pKeys->fileData; 951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse the "*end" section. 955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectlong parseEnd(DataKeys* pKeys, long offset) 957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* data; 959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* dataEnd; 960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int next; 961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (offset < 0) 963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data = pKeys->fileData + offset; 966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataEnd = pKeys->fileData + pKeys->fileLen; 967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = checkToken(data, dataEnd - data, "end"); 968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (next < 0) 969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next; 972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return data - pKeys->fileData; 974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sort the thread list entries. 978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int compareThreads(const void* thread1, const void* thread2) 980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ((const ThreadEntry*) thread1)->threadId - 982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ((const ThreadEntry*) thread2)->threadId; 983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid sortThreadList(DataKeys* pKeys) 986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pKeys->threads, pKeys->numThreads, sizeof(pKeys->threads[0]), 988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project compareThreads); 989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sort the method list entries. 993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int compareMethods(const void* meth1, const void* meth2) 995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int id1, id2; 997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id1 = ((const MethodEntry*) meth1)->methodId; 999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id2 = ((const MethodEntry*) meth2)->methodId; 1000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (id1 < id2) 1001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 1002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (id1 > id2) 1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 1005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid sortMethodList(DataKeys* pKeys) 1008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pKeys->methods, pKeys->numMethods, sizeof(MethodEntry), 1010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project compareMethods); 1011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse the key section, and return a copy of the parsed contents. 1015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectDataKeys* parseKeys(FILE *fp, int verbose) 1017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DataKeys* pKeys = NULL; 1019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long offset; 1020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 1021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys = (DataKeys*) calloc(1, sizeof(DataKeys)); 1023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pKeys == NULL) 1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We load the entire file into memory. We do this, rather than memory- 1028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * mapping it, because we want to change some whitespace to NULs. 1029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fseek(fp, 0L, SEEK_END) != 0) { 1031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project perror("fseek"); 1032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->fileLen = ftell(fp); 1035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pKeys->fileLen == 0) { 1036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "Key file is empty.\n"); 1037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rewind(fp); 1040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->fileData = (char*) malloc(pKeys->fileLen); 1042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pKeys->fileData == NULL) { 1043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "ERROR: unable to alloc %ld bytes\n", pKeys->fileLen); 1044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fread(pKeys->fileData, 1, pKeys->fileLen, fp) != (size_t) pKeys->fileLen) 1048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 1049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "ERROR: unable to read %ld bytes from trace file\n", 1050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->fileLen); 1051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = 0; 1055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = parseVersion(pKeys, offset, verbose); 1057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = parseThreads(pKeys, offset); 1058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = parseMethods(pKeys, offset); 1059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = parseEnd(pKeys, offset); 1060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (offset < 0) 1061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 1062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Leave fp pointing to the beginning of the data section. */ 1064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fseek(fp, offset, SEEK_SET); 1065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sortThreadList(pKeys); 1067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sortMethodList(pKeys); 1068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Dump list of threads. 1071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (verbose) { 1073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Threads (%d):\n", pKeys->numThreads); 1074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < pKeys->numThreads; i++) { 1075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%2d %s\n", 1076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->threads[i].threadId, pKeys->threads[i].threadName); 1077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 1081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Dump list of methods. 1083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (verbose) { 1085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Methods (%d):\n", pKeys->numMethods); 1086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < pKeys->numMethods; i++) { 1087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("0x%08x %s : %s : %s\n", 10886978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince pKeys->methods[i].methodId >> 2, pKeys->methods[i].className, 1089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->methods[i].methodName, pKeys->methods[i].signature); 1090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 1093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return pKeys; 1095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfail: 1097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project freeDataKeys(pKeys); 1098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Read values from the binary data file. 1104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Make the return value "unsigned int" instead of "unsigned short" so that 1107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we can detect EOF. 1108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectunsigned int read2LE(FILE* fp) 1110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int val; 1112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val = getc(fp); 1114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= getc(fp) << 8; 1115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return val; 1116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectunsigned int read4LE(FILE* fp) 1118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int val; 1120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val = getc(fp); 1122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= getc(fp) << 8; 1123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= getc(fp) << 16; 1124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= getc(fp) << 24; 1125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return val; 1126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectunsigned long long read8LE(FILE* fp) 1128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned long long val; 1130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val = getc(fp); 1132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= (unsigned long long) getc(fp) << 8; 1133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= (unsigned long long) getc(fp) << 16; 1134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= (unsigned long long) getc(fp) << 24; 1135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= (unsigned long long) getc(fp) << 32; 1136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= (unsigned long long) getc(fp) << 40; 1137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= (unsigned long long) getc(fp) << 48; 1138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= (unsigned long long) getc(fp) << 56; 1139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return val; 1140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse the header of the data section. 1144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns with the file positioned at the start of the record data. 1146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint parseDataHeader(FILE *fp, DataHeader* pHeader) 1148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pHeader->magic = read4LE(fp); 1150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pHeader->version = read2LE(fp); 1151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pHeader->offsetToData = read2LE(fp); 1152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pHeader->startWhen = read8LE(fp); 1153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fseek(fp, pHeader->offsetToData - 16, SEEK_CUR) != 0) { 1155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 1156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 1159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 11625b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince * Look up a method by its method ID (using binary search). 1163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns NULL if no matching method was found. 1165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectMethodEntry* lookupMethod(DataKeys* pKeys, unsigned int methodId) 1167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int hi, lo, mid; 1169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int id; 11706978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int hashedId; 11716978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 11726978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince /* Create cache if it doesn't already exist */ 11736978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (pKeys->methodCache == NULL) { 1174fe1d6d586614fa51d82857e09128d6671be21d56Andy McFadden pKeys->methodCache = (int*) calloc(METHOD_CACHE_SIZE, sizeof(int)); 11756978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 11766978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 117744828ed25841ea5180346695dfc07ef33b2b7e73Jack Veenstra // ids are multiples of 4, so shift 117844828ed25841ea5180346695dfc07ef33b2b7e73Jack Veenstra hashedId = (methodId >> 2) & METHOD_CACHE_SIZE_MASK; 11796978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (pKeys->methodCache[hashedId]) /* cache hit */ 11806978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (pKeys->methods[pKeys->methodCache[hashedId]].methodId == methodId) 11816978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince return &pKeys->methods[pKeys->methodCache[hashedId]]; 1182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lo = 0; 1184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hi = pKeys->numMethods - 1; 1185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (hi >= lo) { 1187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mid = (hi + lo) / 2; 1188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id = pKeys->methods[mid].methodId; 11906978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (id == methodId) { /* match, put in cache */ 119144828ed25841ea5180346695dfc07ef33b2b7e73Jack Veenstra hashedId = (methodId >> 2) & METHOD_CACHE_SIZE_MASK; 11926978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince pKeys->methodCache[hashedId] = mid; 11936978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince return &pKeys->methods[mid]; 11946978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } else if (id < methodId) /* too low */ 1195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lo = mid + 1; 1196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else /* too high */ 1197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hi = mid - 1; 1198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Reads the next data record, and assigns the data values to threadId, 1205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * methodVal and elapsedTime. On end-of-file, the threadId, methodVal, 1206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and elapsedTime are unchanged. Returns 1 on end-of-file, otherwise 1207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * returns 0. 1208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint readDataRecord(FILE *dataFp, int *threadId, unsigned int *methodVal, 1210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t *elapsedTime) 1211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int id; 1213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: 1216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This SHOULD NOT be keyed off of the global version number! Use 1217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a name=value setting in the version area instead! 1218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (versionNumber == 1) { 1220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id = getc(dataFp); 1221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id = read2LE(dataFp); 1223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (id == EOF) 1225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 1226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *threadId = id; 1227de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *methodVal = read4LE(dataFp); 1229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *elapsedTime = read4LE(dataFp); 1230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (feof(dataFp)) { 1231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "WARNING: hit EOF mid-record\n"); 1232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 1233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 1235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Read the key file and use it to produce formatted output from the 1239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * data file. 1240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dumpTrace() 1242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static const char* actionStr[] = { "ent", "xit", "unr", "???" }; 1244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry bogusMethod = { 0, "???", "???", "???", "???", -1, 0, 0, 0, 0, 1245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project {NULL, NULL}, {NULL, NULL}, {0, 0}, 0, 0, -1 }; 1246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char bogusBuf[80]; 1247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char spaces[MAX_STACK_DEPTH+1]; 1248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FILE* dataFp = NULL; 1249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DataHeader dataHeader; 1250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DataKeys* pKeys = NULL; 1251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 1252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TraceData traceData; 1253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf("Dumping '%s' '%s'\n", dataFileName, keyFileName); 1255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(spaces, '.', MAX_STACK_DEPTH); 1257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project spaces[MAX_STACK_DEPTH] = '\0'; 1258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < MAX_THREADS; i++) 1260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData.depth[i] = 2; // adjust for return from start function 1261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataFp = fopen(gOptions.traceFileName, "r"); 1263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dataFp == NULL) 1264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((pKeys = parseKeys(dataFp, 1)) == NULL) 1267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (parseDataHeader(dataFp, &dataHeader) < 0) 1270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Trace (threadID action usecs class.method signature):\n"); 1273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (1) { 1275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method; 1276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int threadId; 1277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int methodVal; 1278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsedTime; 1279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int action, printDepth; 1280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int methodId, lastEnter = 0; 1281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int mismatch = 0; 1282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char depthNote; 1283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract values from file. 1286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (readDataRecord(dataFp, &threadId, &methodVal, &elapsedTime)) 1288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project action = METHOD_ACTION(methodVal); 1291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodId = METHOD_ID(methodVal); 1292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Generate a line of output. 1295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (action == METHOD_TRACE_ENTER) { 1297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData.depth[threadId]++; 1298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lastEnter = methodId; 1299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* quick test for mismatched adjacent enter/exit */ 1301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (lastEnter != 0 && lastEnter != methodId) 1302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mismatch = 1; 1303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printDepth = traceData.depth[threadId]; 1306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project depthNote = ' '; 1307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (printDepth < 0) { 1308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printDepth = 0; 1309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project depthNote = '-'; 1310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (printDepth > MAX_STACK_DEPTH) { 1311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printDepth = MAX_STACK_DEPTH; 1312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project depthNote = '+'; 1313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = lookupMethod(pKeys, methodId); 1316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method == NULL) { 1317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = &bogusMethod; 1318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(bogusBuf, "methodId: 0x%x", methodId); 1319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->signature = bogusBuf; 1320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->methodName) { 1323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%2d %s%c %8lld%c%s%s.%s %s\n", threadId, 1324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actionStr[action], mismatch ? '!' : ' ', 1325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsedTime, depthNote, 1326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project spaces + (MAX_STACK_DEPTH - printDepth), 1327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->className, method->methodName, method->signature); 1328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%2d %s%c %8lld%c%s%s\n", threadId, 1330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actionStr[action], mismatch ? '!' : ' ', 1331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsedTime, depthNote, 1332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project spaces + (MAX_STACK_DEPTH - printDepth), 1333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->className); 1334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (action != METHOD_TRACE_ENTER) { 1337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData.depth[threadId]--; /* METHOD_TRACE_EXIT or METHOD_TRACE_UNROLL */ 1338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lastEnter = 0; 1339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mismatch = 0; 1342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 1345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dataFp != NULL) 1346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fclose(dataFp); 1347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pKeys != NULL) 1348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project freeDataKeys(pKeys); 1349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* This routine adds the given time to the parent and child methods. 1352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is called when the child routine exits, after the child has 1353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * been popped from the stack. The elapsedTime parameter is the 1354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * duration of the child routine, including time spent in called routines. 1355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid addInclusiveTime(MethodEntry *parent, MethodEntry *child, 1357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsedTime) 1358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod *pTimed; 1360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 1362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool verbose = false; 1363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(child->className, debugClassName) == 0) 1364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verbose = true; 1365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 1366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int childIsRecursive = (child->recursiveEntries > 0); 1368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int parentIsRecursive = (parent->recursiveEntries > 1); 1369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (child->recursiveEntries == 0) { 1371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project child->elapsedInclusive += elapsedTime; 1372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (child->recursiveEntries == 1) { 1373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project child->recursiveInclusive += elapsedTime; 1374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project child->numCalls[childIsRecursive] += 1; 1376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 1378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (verbose) { 1379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, 1380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "%s %d elapsedTime: %lld eI: %lld, rI: %lld\n", 1381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project child->className, child->recursiveEntries, 1382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsedTime, child->elapsedInclusive, 1383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project child->recursiveInclusive); 1384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 1386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Find the child method in the parent */ 1388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod *children = parent->children[parentIsRecursive]; 1389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (pTimed = children; pTimed; pTimed = pTimed->next) { 1390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pTimed->method == child) { 1391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive += elapsedTime; 1392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->numCalls += 1; 1393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pTimed == NULL) { 1397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Allocate a new TimedMethod */ 1398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed = (TimedMethod *) malloc(sizeof(TimedMethod)); 1399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive = elapsedTime; 1400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->numCalls = 1; 1401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->method = child; 1402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Add it to the front of the list */ 1404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->next = children; 1405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parent->children[parentIsRecursive] = pTimed; 1406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Find the parent method in the child */ 1409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod *parents = child->parents[childIsRecursive]; 1410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (pTimed = parents; pTimed; pTimed = pTimed->next) { 1411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pTimed->method == parent) { 1412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive += elapsedTime; 1413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->numCalls += 1; 1414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pTimed == NULL) { 1418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Allocate a new TimedMethod */ 1419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed = (TimedMethod *) malloc(sizeof(TimedMethod)); 1420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive = elapsedTime; 1421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->numCalls = 1; 1422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->method = parent; 1423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Add it to the front of the list */ 1425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->next = parents; 1426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project child->parents[childIsRecursive] = pTimed; 1427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 1430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (verbose) { 1431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, 1432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project " %s %d eI: %lld\n", 1433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parent->className, parent->recursiveEntries, 1434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive); 1435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 1437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Sorts a linked list and returns a newly allocated array containing 1440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the sorted entries. 1441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectTimedMethod *sortTimedMethodList(TimedMethod *list, int *num) 1443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 1445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod *pTimed, *sorted; 1446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Count the elements */ 1448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int num_entries = 0; 1449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (pTimed = list; pTimed; pTimed = pTimed->next) 1450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project num_entries += 1; 1451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *num = num_entries; 1452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (num_entries == 0) 1453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Copy all the list elements to a new array and sort them */ 1456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sorted = (TimedMethod *) malloc(sizeof(TimedMethod) * num_entries); 1457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0, pTimed = list; pTimed; pTimed = pTimed->next, ++ii) 1458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(&sorted[ii], pTimed, sizeof(TimedMethod)); 1459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(sorted, num_entries, sizeof(TimedMethod), compareTimedMethod); 1460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Fix up the "next" pointers so that they work. */ 1462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < num_entries - 1; ++ii) 1463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sorted[ii].next = &sorted[ii + 1]; 1464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sorted[num_entries - 1].next = NULL; 1465de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sorted; 1467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Define flag values for printInclusiveMethod() */ 1470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const int kIsRecursive = 1; 1471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* This prints the inclusive stats for all the parents or children of a 1473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method, depending on the list that is passed in. 1474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid printInclusiveMethod(MethodEntry *method, TimedMethod *list, int numCalls, 1476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int flags) 1477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int num; 1479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod *pTimed; 1480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buf[80]; 1481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *anchor_close; 1482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *spaces = " "; /* 6 spaces */ 1483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int num_spaces = strlen(spaces); 1484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *space_ptr = &spaces[num_spaces]; 1485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *className, *methodName, *signature; 1486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char classBuf[HTML_BUFSIZE], methodBuf[HTML_BUFSIZE]; 1487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char signatureBuf[HTML_BUFSIZE]; 1488de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project anchor_close = ""; 1490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) 1491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project anchor_close = "</a>"; 1492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod *sorted = sortTimedMethodList(list, &num); 1494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double methodTotal = method->elapsedInclusive; 1495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (pTimed = sorted; pTimed; pTimed = pTimed->next) { 1496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry *relative = pTimed->method; 1497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = (char*)(relative->className); 1498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = (char*)(relative->methodName); 1499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = (char*)(relative->signature); 1500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double per = 100.0 * pTimed->elapsedInclusive / methodTotal; 1501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "[%d]", relative->index); 1502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len = strlen(buf); 1504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (len > num_spaces) 1505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len = num_spaces; 1506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "<a href=\"#m%d\">[%d]", 1507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project relative->index, relative->index); 1508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project space_ptr = &spaces[len]; 1509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = htmlEscape(className, classBuf, HTML_BUFSIZE); 1510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = htmlEscape(methodName, methodBuf, HTML_BUFSIZE); 1511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = htmlEscape(signature, signatureBuf, HTML_BUFSIZE); 1512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nCalls = numCalls; 1514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nCalls == 0) 1515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nCalls = relative->numCalls[0] + relative->numCalls[1]; 1516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (relative->methodName) { 1517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (flags & kIsRecursive) { 1518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Don't display percentages for recursive functions 1519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%6s %5s %6s %s%6s%s %6d/%-6d %9llu %s.%s %s\n", 1520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "", "", "", 1521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project space_ptr, buf, anchor_close, 1522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->numCalls, nCalls, 1523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive, 1524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className, methodName, signature); 1525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%6s %5s %5.1f%% %s%6s%s %6d/%-6d %9llu %s.%s %s\n", 1527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "", "", per, 1528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project space_ptr, buf, anchor_close, 1529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->numCalls, nCalls, 1530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive, 1531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className, methodName, signature); 1532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (flags & kIsRecursive) { 1535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Don't display percentages for recursive functions 1536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%6s %5s %6s %s%6s%s %6d/%-6d %9llu %s\n", 1537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "", "", "", 1538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project space_ptr, buf, anchor_close, 1539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->numCalls, nCalls, 1540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive, 1541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className); 1542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%6s %5s %5.1f%% %s%6s%s %6d/%-6d %9llu %s\n", 1544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "", "", per, 1545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project space_ptr, buf, anchor_close, 1546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->numCalls, nCalls, 1547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive, 1548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className); 1549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid countRecursiveEntries(CallStack *pStack, int top, MethodEntry *method) 1555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 1557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->recursiveEntries = 0; 1559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < top; ++ii) { 1560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pStack->calls[ii].method == method) 1561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->recursiveEntries += 1; 1562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid stackDump(CallStack *pStack, int top) 1566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 1568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < top; ++ii) { 1570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry *method = pStack->calls[ii].method; 1571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t entryTime = pStack->calls[ii].entryTime; 1572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->methodName) { 1573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " %2d: %8llu %s.%s %s\n", ii, entryTime, 1574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->className, method->methodName, method->signature); 1575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " %2d: %8llu %s\n", ii, entryTime, method->className); 1577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid outputTableOfContents() 1582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a name=\"contents\"></a>\n"); 1584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<h2>Table of Contents</h2>\n"); 1585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<ul>\n"); 1586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" <li><a href=\"#exclusive\">Exclusive profile</a></li>\n"); 1587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" <li><a href=\"#inclusive\">Inclusive profile</a></li>\n"); 15885b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince printf(" <li><a href=\"#thread\">Thread profile</a></li>\n"); 1589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" <li><a href=\"#class\">Class/method profile</a></li>\n"); 1590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" <li><a href=\"#method\">Method/class profile</a></li>\n"); 1591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</ul>\n\n"); 1592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid outputNavigationBar() 1595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a href=\"#contents\">[Top]</a>\n"); 1597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a href=\"#exclusive\">[Exclusive]</a>\n"); 1598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a href=\"#inclusive\">[Inclusive]</a>\n"); 15995b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince printf("<a href=\"#thread\">[Thread]</a>\n"); 1600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a href=\"#class\">[Class]</a>\n"); 1601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a href=\"#method\">[Method]</a>\n"); 1602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<br><br>\n"); 1603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid printExclusiveProfile(MethodEntry **pMethods, int numMethods, 1606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t sumThreadTime) 1607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 1609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method; 1610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double total, sum, per, sum_per; 1611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char classBuf[HTML_BUFSIZE], methodBuf[HTML_BUFSIZE]; 1612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char signatureBuf[HTML_BUFSIZE]; 1613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char anchor_buf[80]; 1614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *anchor_close = ""; 1615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project total = sumThreadTime; 1617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project anchor_buf[0] = 0; 1618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project anchor_close = "</a>"; 1620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a name=\"exclusive\"></a>\n"); 1621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<hr>\n"); 1622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outputNavigationBar(); 1623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("\n%s\n", profileSeparator); 1625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* First, sort the methods into decreasing order of inclusive 1628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * elapsed time so that we can assign the method indices. 1629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pMethods, numMethods, sizeof(MethodEntry*), compareElapsedInclusive); 1631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) 1633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMethods[ii]->index = ii; 1634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort the methods into decreasing order of exclusive elapsed time. 1636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pMethods, numMethods, sizeof(MethodEntry*), 1638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project compareElapsedExclusive); 1639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Total cycles: %llu\n\n", sumThreadTime); 1641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<br><br>\n"); 1643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Exclusive elapsed times for each method, not including time spent in\n"); 1645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("children, sorted by exclusive time.\n\n"); 1646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<br><br>\n<pre>\n"); 1648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" Usecs self %% sum %% Method\n"); 1651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum = 0; 1652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) { 1654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *className, *methodName, *signature; 1655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = pMethods[ii]; 1657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Don't show methods with zero cycles */ 1658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->elapsedExclusive == 0) 1659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = (char*)(method->className); 1661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = (char*)(method->methodName); 1662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = (char*)(method->signature); 1663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum += method->elapsedExclusive; 1664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per = 100.0 * method->elapsedExclusive / total; 1665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum_per = 100.0 * sum / total; 1666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(anchor_buf, "<a href=\"#m%d\">", method->index); 1668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = htmlEscape(className, classBuf, HTML_BUFSIZE); 1669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = htmlEscape(methodName, methodBuf, HTML_BUFSIZE); 1670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = htmlEscape(signature, signatureBuf, HTML_BUFSIZE); 1671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->methodName) { 1673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%9llu %6.2f %6.2f %s[%d]%s %s.%s %s\n", 1674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedExclusive, per, sum_per, 1675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project anchor_buf, method->index, anchor_close, 1676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className, methodName, signature); 1677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%9llu %6.2f %6.2f %s[%d]%s %s\n", 1679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedExclusive, per, sum_per, 1680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project anchor_buf, method->index, anchor_close, 1681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className); 1682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</pre>\n"); 1686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* check to make sure that the child method meets the threshold of the parent */ 1690de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiroint checkThreshold(MethodEntry* parent, MethodEntry* child) 1691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double parentTime = parent->elapsedInclusive; 1693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double childTime = child->elapsedInclusive; 1694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int64_t percentage = (childTime / parentTime) * 100.0; 1695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (percentage < gOptions.threshold) ? 0 : 1; 1696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid createLabels(FILE* file, MethodEntry* method) 1699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1700de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro fprintf(file, "node%d[label = \"[%d] %s.%s (%llu, %llu, %d)\"]\n", 1701de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro method->index, method->index, method->className, method->methodName, 1702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedInclusive / 1000, 1703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedExclusive / 1000, 1704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->numCalls[0]); 1705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1706de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro method->graphState = GRAPH_LABEL_VISITED; 1707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod* child; 1709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (child = method->children[0] ; child ; child = child->next) { 1710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* childMethod = child->method; 1711de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((childMethod->graphState & GRAPH_LABEL_VISITED) == 0 && checkThreshold(method, childMethod)) { 1713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createLabels(file, child->method); 1714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid createLinks(FILE* file, MethodEntry* method) 1719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->graphState |= GRAPH_NODE_VISITED; 1721de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod* child; 1723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (child = method->children[0] ; child ; child = child->next) { 1724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* childMethod = child->method; 1725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (checkThreshold(method, child->method)) { 1726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(file, "node%d -> node%d\n", method->index, child->method->index); 1727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // only visit children that haven't been visited before 1728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((childMethod->graphState & GRAPH_NODE_VISITED) == 0) { 1729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createLinks(file, child->method); 1730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid createInclusiveProfileGraphNew(DataKeys* dataKeys) 1736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // create a temporary file in /tmp 1738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char path[FILENAME_MAX]; 1739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.keepDotFile) { 1740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project snprintf(path, FILENAME_MAX, "%s.dot", gOptions.graphFileName); 1741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project snprintf(path, FILENAME_MAX, "/tmp/dot-%d-%d.dot", (int)time(NULL), rand()); 1743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FILE* file = fopen(path, "w+"); 1746de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(file, "digraph g {\nnode [shape = record,height=.1];\n"); 1748de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createLabels(file, dataKeys->methods); 1750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createLinks(file, dataKeys->methods); 1751de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(file, "}"); 1753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fclose(file); 1754de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // now that we have the dot file generate the image 1756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char command[1024]; 1757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project snprintf(command, 1024, "dot -Tpng -o '%s' '%s'", gOptions.graphFileName, path); 1758de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project system(command); 1760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! gOptions.keepDotFile) { 1762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project remove(path); 1763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid printInclusiveProfile(MethodEntry **pMethods, int numMethods, 1767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t sumThreadTime) 1768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 1770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method; 1771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double total, sum, per, sum_per; 1772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char classBuf[HTML_BUFSIZE], methodBuf[HTML_BUFSIZE]; 1773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char signatureBuf[HTML_BUFSIZE]; 1774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char anchor_buf[80]; 1775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project total = sumThreadTime; 1777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project anchor_buf[0] = 0; 1778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a name=\"inclusive\"></a>\n"); 1780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<hr>\n"); 1781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outputNavigationBar(); 1782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("\n%s\n", profileSeparator); 1784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort the methods into decreasing order of inclusive elapsed time. */ 1787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pMethods, numMethods, sizeof(MethodEntry*), 1788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project compareElapsedInclusive); 1789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("\nInclusive elapsed times for each method and its parents and children,\n"); 1791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("sorted by inclusive time.\n\n"); 1792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<br><br>\n<pre>\n"); 1795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("index %%/total %%/self index calls usecs name\n"); 1798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) { 1799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int num; 1800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod *pTimed; 1801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double excl_per; 1802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buf[40]; 1803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *className, *methodName, *signature; 1804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = pMethods[ii]; 1806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Don't show methods with zero cycles */ 1807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->elapsedInclusive == 0) 1808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = (char*)(method->className); 1811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = (char*)(method->methodName); 1812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = (char*)(method->signature); 1813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a name=\"m%d\"></a>", method->index); 1816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = htmlEscape(className, classBuf, HTML_BUFSIZE); 1817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = htmlEscape(methodName, methodBuf, HTML_BUFSIZE); 1818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = htmlEscape(signature, signatureBuf, HTML_BUFSIZE); 1819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("----------------------------------------------------\n"); 1821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort and print the parents */ 1823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numCalls = method->numCalls[0] + method->numCalls[1]; 1824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printInclusiveMethod(method, method->parents[0], numCalls, 0); 1825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->parents[1]) { 1826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" +++++++++++++++++++++++++\n"); 1827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printInclusiveMethod(method, method->parents[1], numCalls, 1828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kIsRecursive); 1829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per = 100.0 * method->elapsedInclusive / total; 1832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "[%d]", ii); 1833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->methodName) { 1834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%-6s %5.1f%% %5s %6s %6d+%-6d %9llu %s.%s %s\n", 1835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf, 1836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per, "", "", method->numCalls[0], method->numCalls[1], 1837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedInclusive, 1838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className, methodName, signature); 1839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%-6s %5.1f%% %5s %6s %6d+%-6d %9llu %s\n", 1841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf, 1842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per, "", "", method->numCalls[0], method->numCalls[1], 1843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedInclusive, 1844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className); 1845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project excl_per = 100.0 * method->topExclusive / method->elapsedInclusive; 1847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%6s %5s %5.1f%% %6s %6s %6s %9llu\n", 1848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "", "", excl_per, "excl", "", "", method->topExclusive); 1849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort and print the children */ 1851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printInclusiveMethod(method, method->children[0], 0, 0); 1852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->children[1]) { 1853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" +++++++++++++++++++++++++\n"); 1854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printInclusiveMethod(method, method->children[1], 0, 1855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kIsRecursive); 1856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</pre>\n"); 1860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 18636978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipincevoid printThreadProfile(ThreadEntry *pThreads, int numThreads, uint64_t sumThreadTime, Filter** filters) 18645b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince{ 18656978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int ii, jj; 18665b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince ThreadEntry thread; 18675b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince double total, per, sum_per; 18685b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince uint64_t sum; 18695b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince char threadBuf[HTML_BUFSIZE]; 18705b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince char anchor_buf[80]; 18716978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int drawTable; 18725b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 18735b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince total = sumThreadTime; 18745b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince anchor_buf[0] = 0; 18755b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince if (gOptions.outputHtml) { 18765b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince printf("<a name=\"thread\"></a>\n"); 18775b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince printf("<hr>\n"); 18785b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince outputNavigationBar(); 18795b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince } else { 18805b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince printf("\n%s\n", profileSeparator); 18815b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince } 18825b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 18835b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince /* Sort the threads into decreasing order of elapsed time. */ 18845b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince qsort(pThreads, numThreads, sizeof(ThreadEntry), compareElapsed); 18855b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 18866978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf("\nElapsed times for each thread, sorted by elapsed time.\n"); 18876978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf("Also includes percentage of time spent during the <i>execution</i> of any filters.\n\n"); 18885b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 18895b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince if (gOptions.outputHtml) { 18905b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince printf("<br><br>\n<pre>\n"); 18915b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince } 18925b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 18936978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf(" Usecs self %% sum %%"); 18946978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (ii = 0; ii < numFilters; ++ii) { 18956978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf(" %s %%", filters[ii]->filterName); 18966978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 18976978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf(" tid ThreadName\n"); 18985b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince sum = 0; 18995b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 19005b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince for (ii = 0; ii < numThreads; ++ii) { 19015b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince int threadId; 19025b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince char *threadName; 19035b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince uint64_t time; 19045b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 19055b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince thread = pThreads[ii]; 19065b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 19075b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince threadId = thread.threadId; 19085b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince threadName = (char*)(thread.threadName); 19095b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince time = thread.elapsedTime; 19105b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 19115b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince sum += time; 19125b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince per = 100.0 * time / total; 19135b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince sum_per = 100.0 * sum / total; 19145b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 19155b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince if (gOptions.outputHtml) { 19165b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince threadName = htmlEscape(threadName, threadBuf, HTML_BUFSIZE); 19175b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince } 19186978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 19196978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf("%9llu %6.2f %6.2f", time, per, sum_per); 19206978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (jj = 0; jj < numFilters; jj++) { 19216978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf(" %6.2f", 100.0 * filters[jj]->times.threadExecutionTimes[threadId] / time); 19226978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 19236978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf(" %3d %s\n", threadId, threadName); 19245b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince } 19255b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 19265b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince if (gOptions.outputHtml) 19276978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf("</pre><br />"); 19286978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 19296978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf("\n\nBreak-down of portion of time spent by each thread while waiting on a filter method.\n"); 19306978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 19316978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (ii = 0; ii < numFilters; ++ii) { 19326978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Draw a table for each filter that measures wait time 19336978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince drawTable = 0; 19346978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (jj = 0; jj < filters[ii]->numKeys; jj++) 19356978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (filters[ii]->filterKeys[jj].flags == 1) 19366978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince drawTable = 1; 19376978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 19386978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (drawTable) { 19396978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 19406978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (gOptions.outputHtml) 19416978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf("<br/><br/>\n<pre>\n"); 19426978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf("Filter: %s\n", filters[ii]->filterName); 19436978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf("Total waiting cycles: %llu (%6.2f%% of total)\n", 19446978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filters[ii]->times.totalWaitTime, 19456978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 100.0 * filters[ii]->times.totalWaitTime / sum); 19466978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 19476978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (filters[ii]->times.totalWaitTime > 0) { 19486978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 19496978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf("Details: \n\n"); 19506978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 19516978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf(" Waiting cycles %% of total waiting time execution time while waiting thread name\n"); 19526978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 19536978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (jj = 0; jj < numThreads; jj++) { 19546978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 19556978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince thread = pThreads[jj]; 19566978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 19576978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince char *threadName; 19586978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince threadName = (char*) thread.threadName; 19596978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (gOptions.outputHtml) { 19606978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince threadName = htmlEscape(threadName, threadBuf, HTML_BUFSIZE); 19616978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 19626978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 19636978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf(" %9llu %6.2f %6.2f %s\n", 19646978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filters[ii]->times.threadWaitTimes[thread.threadId], 19656978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 100.0 * filters[ii]->times.threadWaitTimes[thread.threadId] / filters[ii]->times.totalWaitTime, 19666978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 100.0 * filters[ii]->times.threadExecutionTimesWhileWaiting[thread.threadId] / filters[ii]->times.totalWaitTime, 19676978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince threadName); 19686978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 19696978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 19706978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 19716978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (gOptions.outputHtml) 19726978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf("</pre>\n"); 19736978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 19746978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 19756978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 19765b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 19775b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince} 19785b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 1979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid createClassList(TraceData* traceData, MethodEntry **pMethods, int numMethods) 1980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 1982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort the methods into alphabetical order to find the unique class 1984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * names. 1985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pMethods, numMethods, sizeof(MethodEntry*), compareClassNames); 1987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Count the number of unique class names. */ 1989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char *currentClassName = ""; 1990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char *firstClassName = NULL; 1991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData->numClasses = 0; 1992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) { 1993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMethods[ii]->methodName == NULL) { 1994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 1995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(pMethods[ii]->className, currentClassName) != 0) { 1997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Remember the first one 1998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (firstClassName == NULL) { 1999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project firstClassName = pMethods[ii]->className; 2000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData->numClasses += 1; 2002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentClassName = pMethods[ii]->className; 2003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (traceData->numClasses == 0) { 2007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData->classes = NULL; 2008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Allocate space for all of the unique class names */ 2012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData->classes = (ClassEntry *) malloc(sizeof(ClassEntry) * traceData->numClasses); 2013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Initialize the classes array */ 2015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(traceData->classes, 0, sizeof(ClassEntry) * traceData->numClasses); 2016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassEntry *pClass = traceData->classes; 2017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->className = currentClassName = firstClassName; 2018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int prevNumMethods = 0; 2019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) { 2020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMethods[ii]->methodName == NULL) { 2021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 2022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(pMethods[ii]->className, currentClassName) != 0) { 2024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->numMethods = prevNumMethods; 2025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (++pClass)->className = currentClassName = pMethods[ii]->className; 2026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project prevNumMethods = 0; 2027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project prevNumMethods += 1; 2029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->numMethods = prevNumMethods; 2031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Create the array of MethodEntry pointers for each class */ 2033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass = NULL; 2034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentClassName = ""; 2035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nextMethod = 0; 2036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) { 2037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMethods[ii]->methodName == NULL) { 2038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 2039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(pMethods[ii]->className, currentClassName) != 0) { 2041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentClassName = pMethods[ii]->className; 2042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pClass == NULL) 2043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass = traceData->classes; 2044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass++; 2046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Allocate space for the methods array */ 2047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nbytes = sizeof(MethodEntry*) * pClass->numMethods; 2048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->methods = (MethodEntry**) malloc(nbytes); 2049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextMethod = 0; 2050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->methods[nextMethod++] = pMethods[ii]; 2052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Prints a number of html non-breaking spaces according so that the length 2056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of the string "buf" is at least "width" characters wide. If width is 2057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * negative, then trailing spaces are added instead of leading spaces. 2058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid printHtmlField(char *buf, int width) 2060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 2062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int leadingSpaces = 1; 2064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (width < 0) { 2065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project width = -width; 2066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project leadingSpaces = 0; 2067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len = strlen(buf); 2069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numSpaces = width - len; 2070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (numSpaces <= 0) { 2071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s", buf); 2072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (leadingSpaces == 0) 2075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s", buf); 2076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numSpaces; ++ii) 2077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (leadingSpaces == 1) 2079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s", buf); 2080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid printClassProfiles(TraceData* traceData, uint64_t sumThreadTime) 2083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii, jj; 2085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method; 2086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double total, sum, per, sum_per; 2087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char classBuf[HTML_BUFSIZE], methodBuf[HTML_BUFSIZE]; 2088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char signatureBuf[HTML_BUFSIZE]; 2089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project total = sumThreadTime; 2091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a name=\"class\"></a>\n"); 2093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<hr>\n"); 2094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outputNavigationBar(); 2095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("\n%s\n", profileSeparator); 2097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (traceData->numClasses == 0) { 2100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("\nNo classes.\n"); 2101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<br><br>\n"); 2103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("\nExclusive elapsed time for each class, summed over all the methods\n"); 2108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("in the class.\n\n"); 2109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<br><br>\n"); 2111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* For each class, sum the exclusive times in all of the methods 2114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in that class. Also sum the number of method calls. Also 2115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sort the methods so the most expensive appear at the top. 2116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassEntry *pClass = traceData->classes; 2118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < traceData->numClasses; ++ii, ++pClass) { 2119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf("%s %d methods\n", pClass->className, pClass->numMethods); 2120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numMethods = pClass->numMethods; 2121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (jj = 0; jj < numMethods; ++jj) { 2122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = pClass->methods[jj]; 2123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->elapsedExclusive += method->elapsedExclusive; 2124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->numCalls[0] += method->numCalls[0]; 2125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->numCalls[1] += method->numCalls[1]; 2126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort the methods into decreasing order of exclusive time */ 2129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pClass->methods, numMethods, sizeof(MethodEntry*), 2130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project compareElapsedExclusive); 2131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Allocate an array of pointers to the classes for more efficient 2134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sorting. 2135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassEntry **pClasses; 2137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClasses = (ClassEntry**) malloc(sizeof(ClassEntry*) * traceData->numClasses); 2138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < traceData->numClasses; ++ii) 2139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClasses[ii] = &traceData->classes[ii]; 2140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort the classes into decreasing order of exclusive time */ 2142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pClasses, traceData->numClasses, sizeof(ClassEntry*), compareClassExclusive); 2143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<div class=\"header\"><span class=\"parent\"> </span> "); 2146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Cycles %%/total Cumul.%% Calls+Recur Class</div>\n"); 2147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" Cycles %%/total Cumul.%% Calls+Recur Class\n"); 2149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum = 0; 2152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < traceData->numClasses; ++ii) { 2153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *className, *methodName, *signature; 2154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Skip classes with zero cycles */ 2156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass = pClasses[ii]; 2157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pClass->elapsedExclusive == 0) 2158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per = 100.0 * pClass->elapsedExclusive / total; 2161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum += pClass->elapsedExclusive; 2162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum_per = 100.0 * sum / total; 2163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = (char*)(pClass->className); 2164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buf[80]; 2166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = htmlEscape(className, classBuf, HTML_BUFSIZE); 2168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<div class=\"link\" onClick=\"javascript:toggle('d%d')\" onMouseOver=\"javascript:onMouseOver(this)\" onMouseOut=\"javascript:onMouseOut(this)\"><span class=\"parent\" id=\"xd%d\">+</span>", ii, ii); 2169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%llu", pClass->elapsedExclusive); 2170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 9); 2171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%.1f", per); 2173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 7); 2174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%.1f", sum_per); 2176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 7); 2177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%d", pClass->numCalls[0]); 2179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 6); 2180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("+"); 2181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%d", pClass->numCalls[1]); 2182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, -6); 2183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s", className); 2185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</div>\n"); 2186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<div class=\"parent\" id=\"d%d\">\n", ii); 2187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("---------------------------------------------\n"); 2189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%9llu %7.1f %7.1f %6d+%-6d %s\n", 2190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->elapsedExclusive, per, sum_per, 2191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->numCalls[0], pClass->numCalls[1], 2192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className); 2193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numMethods = pClass->numMethods; 2196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double classExclusive = pClass->elapsedExclusive; 2197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double sumMethods = 0; 2198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (jj = 0; jj < numMethods; ++jj) { 2199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = pClass->methods[jj]; 2200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = (char*)(method->methodName); 2201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = (char*)(method->signature); 2202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per = 100.0 * method->elapsedExclusive / classExclusive; 2203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sumMethods += method->elapsedExclusive; 2204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum_per = 100.0 * sumMethods / classExclusive; 2205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buf[80]; 2207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = htmlEscape(methodName, methodBuf, HTML_BUFSIZE); 2209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = htmlEscape(signature, signatureBuf, HTML_BUFSIZE); 2210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<div class=\"leaf\"><span class=\"leaf\"> </span>"); 2211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%llu", method->elapsedExclusive); 2212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 9); 2213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%llu", method->elapsedInclusive); 2215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 9); 2216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%.1f", per); 2218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 7); 2219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%.1f", sum_per); 2221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 7); 2222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%d", method->numCalls[0]); 2224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 6); 2225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("+"); 2226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%d", method->numCalls[1]); 2227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, -6); 2228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a href=\"#m%d\">[%d]</a> %s %s", 2230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->index, method->index, methodName, signature); 2231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</div>\n"); 2232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%9llu %9llu %7.1f %7.1f %6d+%-6d [%d] %s %s\n", 2234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedExclusive, 2235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedInclusive, 2236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per, sum_per, 2237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->numCalls[0], method->numCalls[1], 2238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->index, methodName, signature); 2239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</div>\n"); 2243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid createUniqueMethodList(TraceData* traceData, MethodEntry **pMethods, int numMethods) 2248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 2250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort the methods into alphabetical order of method names 2252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to find the unique method names. 2253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pMethods, numMethods, sizeof(MethodEntry*), compareMethodNames); 2255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Count the number of unique method names, ignoring class and 2257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * signature. 2258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char *currentMethodName = ""; 2260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData->numUniqueMethods = 0; 2261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) { 2262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMethods[ii]->methodName == NULL) 2263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 2264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(pMethods[ii]->methodName, currentMethodName) != 0) { 2265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData->numUniqueMethods += 1; 2266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentMethodName = pMethods[ii]->methodName; 2267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (traceData->numUniqueMethods == 0) 2270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Allocate space for pointers to all of the unique methods */ 2273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nbytes = sizeof(UniqueMethodEntry) * traceData->numUniqueMethods; 2274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData->uniqueMethods = (UniqueMethodEntry *) malloc(nbytes); 2275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Initialize the uniqueMethods array */ 2277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(traceData->uniqueMethods, 0, nbytes); 2278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UniqueMethodEntry *pUnique = traceData->uniqueMethods; 2279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentMethodName = NULL; 2280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int prevNumMethods = 0; 2281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) { 2282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMethods[ii]->methodName == NULL) 2283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 2284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (currentMethodName == NULL) 2285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentMethodName = pMethods[ii]->methodName; 2286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(pMethods[ii]->methodName, currentMethodName) != 0) { 2287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentMethodName = pMethods[ii]->methodName; 2288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->numMethods = prevNumMethods; 2289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique++; 2290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project prevNumMethods = 0; 2291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project prevNumMethods += 1; 2293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->numMethods = prevNumMethods; 2295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Create the array of MethodEntry pointers for each unique method */ 2297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique = NULL; 2298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentMethodName = ""; 2299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nextMethod = 0; 2300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) { 2301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMethods[ii]->methodName == NULL) 2302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 2303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(pMethods[ii]->methodName, currentMethodName) != 0) { 2304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentMethodName = pMethods[ii]->methodName; 2305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pUnique == NULL) 2306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique = traceData->uniqueMethods; 2307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique++; 2309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Allocate space for the methods array */ 2310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nbytes = sizeof(MethodEntry*) * pUnique->numMethods; 2311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->methods = (MethodEntry**) malloc(nbytes); 2312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextMethod = 0; 2313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->methods[nextMethod++] = pMethods[ii]; 2315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid printMethodProfiles(TraceData* traceData, uint64_t sumThreadTime) 2319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii, jj; 2321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method; 2322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double total, sum, per, sum_per; 2323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char classBuf[HTML_BUFSIZE], methodBuf[HTML_BUFSIZE]; 2324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char signatureBuf[HTML_BUFSIZE]; 2325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (traceData->numUniqueMethods == 0) 2327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project total = sumThreadTime; 2330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a name=\"method\"></a>\n"); 2332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<hr>\n"); 2333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outputNavigationBar(); 2334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("\n%s\n", profileSeparator); 2336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("\nExclusive elapsed time for each method, summed over all the classes\n"); 2339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("that contain a method with the same name.\n\n"); 2340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<br><br>\n"); 2342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* For each unique method, sum the exclusive times in all of the methods 2345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * with the same name. Also sum the number of method calls. Also 2346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sort the methods so the most expensive appear at the top. 2347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UniqueMethodEntry *pUnique = traceData->uniqueMethods; 2349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < traceData->numUniqueMethods; ++ii, ++pUnique) { 2350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numMethods = pUnique->numMethods; 2351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (jj = 0; jj < numMethods; ++jj) { 2352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = pUnique->methods[jj]; 2353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->elapsedExclusive += method->elapsedExclusive; 2354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->numCalls[0] += method->numCalls[0]; 2355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->numCalls[1] += method->numCalls[1]; 2356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort the methods into decreasing order of exclusive time */ 2359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pUnique->methods, numMethods, sizeof(MethodEntry*), 2360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project compareElapsedExclusive); 2361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Allocate an array of pointers to the methods for more efficient 2364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sorting. 2365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UniqueMethodEntry **pUniqueMethods; 2367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nbytes = sizeof(UniqueMethodEntry*) * traceData->numUniqueMethods; 2368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUniqueMethods = (UniqueMethodEntry**) malloc(nbytes); 2369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < traceData->numUniqueMethods; ++ii) 2370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUniqueMethods[ii] = &traceData->uniqueMethods[ii]; 2371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort the methods into decreasing order of exclusive time */ 2373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pUniqueMethods, traceData->numUniqueMethods, sizeof(UniqueMethodEntry*), 2374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project compareUniqueExclusive); 2375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<div class=\"header\"><span class=\"parent\"> </span> "); 2378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Cycles %%/total Cumul.%% Calls+Recur Method</div>\n"); 2379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" Cycles %%/total Cumul.%% Calls+Recur Method\n"); 2381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum = 0; 2384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < traceData->numUniqueMethods; ++ii) { 2385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *className, *methodName, *signature; 2386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Skip methods with zero cycles */ 2388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique = pUniqueMethods[ii]; 2389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pUnique->elapsedExclusive == 0) 2390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per = 100.0 * pUnique->elapsedExclusive / total; 2393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum += pUnique->elapsedExclusive; 2394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum_per = 100.0 * sum / total; 2395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = (char*)(pUnique->methods[0]->methodName); 2396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buf[80]; 2398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = htmlEscape(methodName, methodBuf, HTML_BUFSIZE); 2400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<div class=\"link\" onClick=\"javascript:toggle('e%d')\" onMouseOver=\"javascript:onMouseOver(this)\" onMouseOut=\"javascript:onMouseOut(this)\"><span class=\"parent\" id=\"xe%d\">+</span>", ii, ii); 2401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%llu", pUnique->elapsedExclusive); 2402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 9); 2403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%.1f", per); 2405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 7); 2406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%.1f", sum_per); 2408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 7); 2409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%d", pUnique->numCalls[0]); 2411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 6); 2412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("+"); 2413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%d", pUnique->numCalls[1]); 2414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, -6); 2415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s", methodName); 2417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</div>\n"); 2418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<div class=\"parent\" id=\"e%d\">\n", ii); 2419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("---------------------------------------------\n"); 2421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%9llu %7.1f %7.1f %6d+%-6d %s\n", 2422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->elapsedExclusive, per, sum_per, 2423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->numCalls[0], pUnique->numCalls[1], 2424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName); 2425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numMethods = pUnique->numMethods; 2427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double methodExclusive = pUnique->elapsedExclusive; 2428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double sumMethods = 0; 2429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (jj = 0; jj < numMethods; ++jj) { 2430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = pUnique->methods[jj]; 2431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = (char*)(method->className); 2432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = (char*)(method->signature); 2433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per = 100.0 * method->elapsedExclusive / methodExclusive; 2434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sumMethods += method->elapsedExclusive; 2435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum_per = 100.0 * sumMethods / methodExclusive; 2436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buf[80]; 2438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = htmlEscape(className, classBuf, HTML_BUFSIZE); 2440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = htmlEscape(signature, signatureBuf, HTML_BUFSIZE); 2441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<div class=\"leaf\"><span class=\"leaf\"> </span>"); 2442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%llu", method->elapsedExclusive); 2443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 9); 2444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%llu", method->elapsedInclusive); 2446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 9); 2447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%.1f", per); 2449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 7); 2450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%.1f", sum_per); 2452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 7); 2453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%d", method->numCalls[0]); 2455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 6); 2456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("+"); 2457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%d", method->numCalls[1]); 2458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, -6); 2459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a href=\"#m%d\">[%d]</a> %s.%s %s", 2461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->index, method->index, 2462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className, methodName, signature); 2463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</div>\n"); 2464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%9llu %9llu %7.1f %7.1f %6d+%-6d [%d] %s.%s %s\n", 2466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedExclusive, 2467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedInclusive, 2468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per, sum_per, 2469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->numCalls[0], method->numCalls[1], 2470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->index, className, methodName, signature); 2471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</div>\n"); 2475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 24806978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * Determines whether the given FilterKey matches the method. The FilterKey's 24816978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * key that is used to match against the method is determined by index. 24826978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince */ 24836978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipinceint keyMatchesMethod(FilterKey filterKey, MethodEntry* method, int index) 24846978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince{ 24856978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (filterKey.type[index] == 0) { // Class 24866978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince#if 0 24876978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, " class is %s; filter key is %s\n", method->className, filterKey.keys[index]); 24886978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince#endif 24896978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (strcmp(method->className, filterKey.keys[index]) == 0) { 24906978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince return 1; 24916978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 24926978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } else { // Method 24936978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (method->methodName != NULL) { 24946978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Get fully-qualified name 24956978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // TODO: parse class name and method name an put them in structure to avoid 24966978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // allocating memory here 24976978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince char* str = malloc ((strlen(method->className) + strlen(method->methodName) + 2) * sizeof(char)); 24986978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince strcpy(str, method->className); 24996978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince strcat(str, "."); 25006978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince strcat(str, method->methodName); 25016978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince#if 0 25026978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, " method is %s; filter key is %s\n", str, filterKey.keys[index]); 25036978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince#endif 25046978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (strcmp(str, filterKey.keys[index]) == 0) { 25056978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince free(str); 25066978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince return 1; 25076978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 25086978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince free(str); 25096978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 25106978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 25116978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince return 0; 25126978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince} 25136978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 25146978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince/* 25156978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * Adds the appropriate times to the given filter based on the given method. Activates and 25166978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * de-activates filters as necessary. 25176978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * 25186978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * A filter is activated when the given method matches the 'entry' key of one of its FilterKeys. 25196978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * It is de-activated when the method matches the 'exit' key of the same FilterKey that activated it 25206978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * in the first place. Thus, a filter may be active more than once on the same thread (activated by 25216978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * different FilterKeys). A filter may also be active on different threads at the same time. 25226978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * 25236978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * While the filter is active on thread 1, elapsed time is allocated to different buckets which 25246978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * include: thread execution time (i.e., time thread 1 spent executing while filter was active), 25256978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * thread waiting time (i.e., time thread 1 waited while other threads executed), and execution 25266978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * time while waiting (i.e., time thread x spent executing while thread 1 was waiting). We also 25276978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * keep track of the total waiting time for a given filter. 25286978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * 25296978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * Lastly, we keep track of remaining (un-allocated) time for cases in which we exit a method we 25306978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * had not entered before, and that method happens to match the 'exit' key of a FilterKey. 25316978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince */ 25326978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipinceint filterMethod(MethodEntry* method, Filter* filter, int entry, int threadId, int numThreads, 25336978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince uint64_t elapsed, uint64_t remTime) 25346978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince{ 25356978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int ii, jj; 25366978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int activeCount, addedWaitTimeThreadsCount; 25376978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int* activeThreads; 25386978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int* activationKeys; 25396978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int* addedWaitTimeThreads; 25406978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 25416978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // flags 25426978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int addWaitTime = 0; 25436978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int deactivation = 0; 25446978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int addedExecutionTime = 0; 25456978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int addedExecutionTimeWhileWaiting = 0; 25466978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int addedWaitTime; 25476978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int addedRemTime = 0; 25486978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int threadKeyPairActive = 0; 25496978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 25506978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (filter->times.threadWaitTimes == NULL && filter->times.threadExecutionTimes == NULL && 25516978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->times.threadExecutionTimesWhileWaiting == NULL) { 25526978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->times.threadWaitTimes = (uint64_t*) calloc(MAX_THREADS, sizeof(uint64_t)); 25536978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->times.threadExecutionTimesWhileWaiting = 25546978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince (uint64_t*) calloc(MAX_THREADS, sizeof(uint64_t)); 25556978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->times.threadExecutionTimes = (uint64_t*) calloc(MAX_THREADS, sizeof(uint64_t)); 25566978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 25576978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 25586978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int verbose = 0; 25596978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 25606978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (verbose) 25616978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, 25626978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince "Running %s filter for class %s method %s, thread %d; activeCount: %d time: %llu\n", 25636978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->filterName, method->className, method->methodName, threadId, 25646978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->activeCount, elapsed); 25656978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 25666978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // If active on some thread 25676978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (filter->activeCount > 0) { 25686978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 25696978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Initialize active structures in case there are any de-activations 25706978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince activeThreads = (int*) calloc(filter->activeCount, sizeof(int)); 25716978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince activationKeys = (int*) calloc(filter->activeCount, sizeof(int)); 25726978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince activeCount = 0; 25736978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 25746978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Initialize structure to help us determine which threads we've already added wait time to 25756978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince addedWaitTimeThreads = (int*) calloc(filter->activeCount, sizeof(int)); 25766978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince addedWaitTimeThreadsCount = 0; 25776978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 25786978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Add times to appropriate sums and de-activate (if necessary) 25796978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (ii = 0; ii < filter->activeCount; ii++) { 25806978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 25816978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (verbose) { 25826978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, " Analyzing active thread with id %d, activated by key [%s, %s]\n", 25836978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->activeThreads[ii], 25846978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->filterKeys[filter->activationKeys[ii]].keys[0], 25856978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->filterKeys[filter->activationKeys[ii]].keys[1]); 25866978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 25876978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 25886978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // If active on THIS thread -> add to execution time (only add once!) 25896978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (filter->activeThreads[ii] == threadId && !addedExecutionTime) { 25906978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (verbose) 25916978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, " Adding execution time to this thead\n"); 25926978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->times.threadExecutionTimes[threadId] += elapsed; 25936978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince addedExecutionTime = 1; 25946978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 25956978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 25966978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // If active on ANOTHER thread (or this one too) with CROSS_THREAD_FLAG -> add to 25976978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // both thread's waiting time + total 25986978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (filter->filterKeys[filter->activationKeys[ii]].flags == 1) { 25996978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 26006978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Add time to thread that is waiting (add to each waiting thread at most once!) 26016978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince addedWaitTime = 0; 26026978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (jj = 0; jj < addedWaitTimeThreadsCount; jj++) { 26036978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (addedWaitTimeThreads[jj] == filter->activeThreads[ii]) 26046978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince addedWaitTime = 1; 26056978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 26066978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (!addedWaitTime) { 26076978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (verbose) 26086978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, " Adding wait time to waiting thread\n"); 26096978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->times.threadWaitTimes[filter->activeThreads[ii]] += elapsed; 26106978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince addedWaitTimeThreads[addedWaitTimeThreadsCount++] = filter->activeThreads[ii]; 26116978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 26126978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 26136978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Add execution time to this thread while the other is waiting (only add once!) 26146978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // [Flag is needed only because outside for loop might iterate through same 26156978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // thread twice?] TODO: verify 26166978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (!addedExecutionTimeWhileWaiting) { 26176978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (verbose) 26186978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, " Adding exec time to this thread while thread waits\n"); 26196978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->times.threadExecutionTimesWhileWaiting[threadId] += elapsed; 26206978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince addedExecutionTimeWhileWaiting = 1; 26216978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 26226978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 26236978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince addWaitTime = 1; 26246978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 26256978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 26266978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // If a method exit matches the EXIT method of an ACTIVE key -> de-activate 26276978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // the KEY (not the entire filter!!) 26286978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (!entry && keyMatchesMethod(filter->filterKeys[filter->activationKeys[ii]], 26296978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince method, 1)) { 26306978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (verbose) 26316978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, " Exit key matched!\n"); 26326978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 26336978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Deactivate by removing (NOT adding) entries from activeThreads and activationKeys 26346978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince deactivation = 1; // singal that lists should be replaced 26356978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } else { 26366978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // No de-activation -> copy old entries into new lists 26376978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince activeThreads[activeCount] = filter->activeThreads[ii]; 26386978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince activationKeys[activeCount++] = filter->activationKeys[ii]; 26396978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 26406978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 26416978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 26426978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // If waiting on ANY thread, add wait time to total (but only ONCE!) 26436978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (addWaitTime) { 26446978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->times.totalWaitTime += elapsed; 26456978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 26466978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 26476978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // If de-activation occurred, replace lists 26486978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (deactivation) { 26496978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // TODO: Free memory from old lists 26506978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 26516978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Set new lists 26526978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->activeThreads = activeThreads; 26536978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->activationKeys = activationKeys; 26546978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->activeCount = activeCount; 26556978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } else { 26566978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // TODO: Free memory from new lists 26576978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 26586978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 26596978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } // Else, continue (we might be activating the filter on a different thread) 26606978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 26616978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 26626978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (entry) { // ENTRY 26636978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (verbose) 26646978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, " Here at the entry\n"); 26656978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // If method matches entry key -> activate thread (do not add time since it's a new entry!) 26666978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (ii = 0; ii < filter->numKeys; ii++) { 26676978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (keyMatchesMethod(filter->filterKeys[ii], method, 0)) { 26686978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (verbose) 26696978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, " Entry key matched!\n"); 26706978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Activate thread only if thread/key pair is not already active 26716978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (jj = 0; jj < filter->activeCount; jj++) { 26726978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (filter->activeThreads[jj] == threadId && filter->activationKeys[jj] == ii) 26736978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince threadKeyPairActive = 1; 26746978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 26756978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // TODO: WORRY ABOUT MEMORY WHEN ACTIVE_COUNT > DEFAULT_ACTIVE_THREAD (unlikely) 26766978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // TODO: what if the same thread is active multiple times by different keys? 26776978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // nothing, we just have to make sure we dont double-add, and we dont.. 26786978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (!threadKeyPairActive) { 26796978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->activeThreads[filter->activeCount] = threadId; 26806978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->activationKeys[filter->activeCount++] = ii; 26816978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 26826978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 26836978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 26846978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } else { // EXIT 26856978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // If method matches a terminal key -> add remTime to total (no need to active/de-activate) 26866978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (ii = 0; ii < filter->numKeys; ii++) { 26876978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (!deactivation && keyMatchesMethod(filter->filterKeys[ii], method, 1) && 26886978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince keyMatchesMethod(filter->filterKeys[ii], method, 0)) { 26896978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Add remTime(s) 26906978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // TODO: think about how we should add remTimes.. should we add remTime to threads 26916978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // that were waiting or being waited on? for now, keep it simple and just add the 26926978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // execution time to the current thread. 26936978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->times.threadExecutionTimes[threadId] += remTime; 26946978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince addedRemTime = 1; 26956978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 26966978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 26976978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 26986978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 26996978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince return addedExecutionTime | (addedRemTime << 1); 27006978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince} 27016978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 27026978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipincevoid dumpFilters(Filter** filters) { 27036978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int i; 27046978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (i = 0; i < numFilters; i++) { 27056978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int j; 27066978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, "FILTER %s\n", filters[i]->filterName); 27076978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (j = 0; j < filters[i]->numKeys; j++) { 27086978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, "Keys: %s, type %d", filters[i]->filterKeys[j].keys[0], 27096978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filters[i]->filterKeys[j].type[0]); 27106978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (filters[i]->filterKeys[j].keys[1] != NULL) { 27116978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, " AND %s, type %d", filters[i]->filterKeys[j].keys[1], 27126978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filters[i]->filterKeys[j].type[1]); 27136978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 27146978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, "; flags: %d\n", filters[i]->filterKeys[j].flags); 27156978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 27166978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 27176978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince} 27186978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 27196978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince/* 27206978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * See parseFilters for required data format. 27216978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * 'data' must point to the beginning of a filter definition. 27226978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince */ 27236978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipincechar* parseFilter(char* data, char* dataEnd, Filter** filters, int num) { 27246978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 27256978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince Filter* filter; 27266978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int next, count, i; 27276978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int tmpOffset, tmpKeyLen; 27286978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince char* tmpKey; 27296978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince char* key1; 27306978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince char* key2; 27316978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 27326978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter = (Filter*) malloc(sizeof(Filter)); 27336978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->activeCount = 0; 27346978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->activeThreads = (int*) calloc(DEFAULT_ACTIVE_THREADS, sizeof(int)); 27356978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->activationKeys = (int*) calloc(DEFAULT_ACTIVE_THREADS, sizeof(int)); 27366978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 27376978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince next = findNextChar(data + 1, dataEnd - data - 1, '\n'); 27386978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (next < 0) { 27396978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // TODO: what should we do here? 27406978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // End of file reached... 27416978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 27426978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince data[next+1] = '\0'; 27436978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->filterName = data + 1; 27446978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince data += next + 2; // Careful 27456978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 27466978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince /* 27476978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * Count the number of keys (one per line). 27486978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince */ 27496978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince count = countLinesToChar(data, dataEnd - data, FILTER_TAG); 27506978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (count <= 0) { 27516978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, 27526978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince "ERROR: failed while parsing filter %s (found %d keys)\n", 27536978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->filterName, count); 27546978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince return NULL; // TODO: Should do something else 27556978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Could return filter with 0 keys instead (probably better to avoid random segfaults) 27566978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 27576978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 27586978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->filterKeys = (FilterKey*) malloc(sizeof(FilterKey) * count); 27596978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 27606978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince /* 27616978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * Extract all entries. 27626978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince */ 27636978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince tmpOffset = 0; 27646978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (i = 0; i < count; i++) { 27656978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince next = findNextChar(data, dataEnd - data, '\n'); 27666978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // assert(next > 0); // TODO: revise... (skip if next == 0 ?) 27676978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince data[next] = '\0'; 27686978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince tmpKey = data; 27696978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 27706978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (*data == FILTER_FLAG_THREAD) { 27716978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->filterKeys[i].flags = 1; 27726978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince tmpKey++; 27736978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } else { 27746978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->filterKeys[i].flags = 0; 27756978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 27766978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 27776978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince tmpOffset = findNextChar(tmpKey, next, ','); 27786978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 27796978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (tmpOffset < 0) { 27806978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // No comma, so only 1 key 27816978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince key1 = tmpKey; 27826978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince key2 = tmpKey; 27836978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 27846978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Get type for key1 27856978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->filterKeys[i].type[0] = FILTER_TYPE_CLASS; // default 27866978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince tmpOffset = findNextChar(key1, next, '('); 27876978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (tmpOffset > 0) { 27886978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (findNextChar(key1, next, ')') == tmpOffset + 1) { 27896978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->filterKeys[i].type[0] = FILTER_TYPE_METHOD; 27906978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->filterKeys[i].type[1] = FILTER_TYPE_METHOD; 27916978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 27926978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince key1[tmpOffset] = '\0'; 27936978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 27946978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } else { 27956978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Pair of keys 27966978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince tmpKey[tmpOffset] = '\0'; 27976978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince key1 = tmpKey; 27986978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince key2 = tmpKey + tmpOffset + 1; 27996978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 28006978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Get type for key1 28016978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->filterKeys[i].type[0] = FILTER_TYPE_CLASS; 28026978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince tmpKeyLen = tmpOffset; 28036978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince tmpOffset = findNextChar(key1, tmpKeyLen, '('); 28046978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (tmpOffset > 0) { 28056978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (findNextChar(key1, tmpKeyLen, ')') == tmpOffset + 1) { 28066978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->filterKeys[i].type[0] = FILTER_TYPE_METHOD; 28076978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 28086978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince key1[tmpOffset] = '\0'; 28096978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 28106978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 28116978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Get type for key2 28126978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->filterKeys[i].type[1] = FILTER_TYPE_CLASS; 28136978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince tmpOffset = findNextChar(key2, next - tmpKeyLen, '('); 28146978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (tmpOffset > 0) { 28156978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (findNextChar(key2, next - tmpKeyLen, ')') == tmpOffset + 1) { 28166978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->filterKeys[i].type[1] = FILTER_TYPE_METHOD; 28176978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 28186978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince key2[tmpOffset] = '\0'; 28196978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 28206978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 28216978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 28226978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->filterKeys[i].keys[0] = key1; 28236978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->filterKeys[i].keys[1] = key2; 28246978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince data += next+1; 28256978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 28266978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 28276978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filter->numKeys = count; 28286978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filters[num] = filter; 28296978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 28306978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince return data; 28316978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince} 28326978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 28336978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince/* 28346978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * Parses filters from given file. The file must follow the following format: 28356978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * 28366978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * *FilterName <- creates a new filter with keys to follow 28376978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * A.method() <- key that triggers whenever A.method() enters/exit 28386978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * Class <- key that triggers whenever any method from Class enters/exits 28396978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * +CrossThread <- same as above, but keeps track of execution times accross threads 28406978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * B.m(),C.m() <- key that triggers filter on when B.m() enters and off when C.m() exits 28416978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * 28426978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince * TODO: add concrete example to make things clear 28436978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince */ 28446978d9dd28968b3817533d036ae7b53309053faaRodrigo IpinceFilter** parseFilters(const char* filterFileName) { 28456978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 28466978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince Filter** filters = NULL; 28476978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince FILE* fp = NULL; 28486978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince long len; 28496978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince char* data; 28506978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince char* dataEnd; 28516978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince char* dataStart; 28526978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int i, next, count; 28536978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 28546978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fp = fopen(filterFileName, "r"); 28556978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (fp == NULL) 28566978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince goto bail; 28576978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 28586978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (fseek(fp, 0L, SEEK_END) != 0) { 28596978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince perror("fseek"); 28606978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince goto bail; 28616978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 28626978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 28636978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince len = ftell(fp); 28646978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (len == 0) { 28656978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, "WARNING: Filter file is empty.\n"); 28666978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince goto bail; 28676978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 28686978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince rewind(fp); 28696978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 28706978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince data = (char*) malloc(len); 28716978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (data == NULL) { 28726978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, "ERROR: unable to alloc %ld bytes for filter file\n", len); 28736978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince goto bail; 28746978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 28756978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 28766978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Read file into memory 28776978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (fread(data, 1, len, fp) != (size_t) len) { 28786978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, "ERROR: unable to read %ld bytes from filter file\n", len); 28796978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince goto bail; 28806978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 28816978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 28826978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince dataStart = data; 28836978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince dataEnd = data + len; 28846978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 28856978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Figure out how many filters there are 28866978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince numFilters = 0; 28876978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince next = -1; 28886978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 28896978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince while (1) { 28906978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (*data == FILTER_TAG) 28916978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince numFilters++; 28926978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince next = findNextChar(data, len, '\n'); 28936978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (next < 0) 28946978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince break; 28956978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince data += next+1; 28966978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince len -= next+1; 28976978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 28986978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 28996978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (numFilters == 0) { 29006978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, "WARNING: no filters found. Continuing without filters\n"); 29016978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince goto bail; 29026978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 29036978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 29046978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filters = (Filter**) calloc(numFilters, sizeof(Filter *)); 29056978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (filters == NULL) { 29066978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, "ERROR: unable to alloc memory for filters"); 29076978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince goto bail; 29086978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 29096978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 29106978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince data = dataStart; 29116978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (i = 0; i < numFilters; i++) { 29126978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince data = parseFilter(data, dataEnd, filters, i); 29136978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 29146978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 29156978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince return filters; 29166978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 29176978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipincebail: 29186978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (fp != NULL) 29196978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fclose(fp); 29206978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 29216978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince return NULL; 29226978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 29236978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince} 29246978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 29256978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 29266978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince/* 2927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Read the key and data files and return the MethodEntries for those files 2928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 29296978d9dd28968b3817533d036ae7b53309053faaRodrigo IpinceDataKeys* parseDataKeys(TraceData* traceData, const char* traceFileName, 29306978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince uint64_t* threadTime, Filter** filters) 2931de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro{ 2932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DataKeys* dataKeys = NULL; 2933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry **pMethods = NULL; 2934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method; 2935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FILE* dataFp = NULL; 2936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DataHeader dataHeader; 29376978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int ii, jj, numThreads; 2938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t currentTime; 2939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* caller; 2940de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataFp = fopen(traceFileName, "r"); 2942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dataFp == NULL) 2943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((dataKeys = parseKeys(dataFp, 0)) == NULL) 29466978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince goto bail; 2947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (parseDataHeader(dataFp, &dataHeader) < 0) 2949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 29516978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince numThreads = dataKeys->numThreads; 29526978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 2953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 2954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FILE *dumpStream = fopen("debug", "w"); 2955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 2956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (1) { 2957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int threadId; 2958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int methodVal; 2959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int action; 2960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int methodId; 2961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CallStack *pStack; 29626978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 2963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract values from file. 2965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (readDataRecord(dataFp, &threadId, &methodVal, ¤tTime)) 2967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 29686978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 2969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project action = METHOD_ACTION(methodVal); 2970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodId = METHOD_ID(methodVal); 2971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Get the call stack for this thread */ 2973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack = traceData->stacks[threadId]; 2974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If there is no call stack yet for this thread, then allocate one */ 2976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pStack == NULL) { 2977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack = malloc(sizeof(CallStack)); 2978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack->top = 0; 2979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack->lastEventTime = currentTime; 2980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack->threadStartTime = currentTime; 29816978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince pStack->remTimes = (uint64_t*) calloc(numFilters, sizeof(uint64_t)); 2982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData->stacks[threadId] = pStack; 2983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Lookup the current method */ 2986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = lookupMethod(dataKeys, methodId); 2987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method == NULL) 2988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = &dataKeys->methods[UNKNOWN_INDEX]; 2989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 2991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->methodName) { 29926978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(dumpStream, "%2d %-8llu %d %8llu r %d c %d %s.%s %s\n", 29936978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince threadId, currentTime, action, pStack->threadStartTime, 29946978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince method->recursiveEntries, 29956978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince pStack->top, method->className, method->methodName, 29966978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince method->signature); 2997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 29986978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printf(dumpStream, "%2d %-8llu %d %8llu r %d c %d %s\n", 29996978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince threadId, currentTime, action, pStack->threadStartTime, 30006978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince method->recursiveEntries, 30016978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince pStack->top, method->className); 3002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 3004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (action == METHOD_TRACE_ENTER) { 3006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* This is a method entry */ 3007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pStack->top >= MAX_STACK_DEPTH) { 3008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "Stack overflow (exceeded %d frames)\n", 3009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MAX_STACK_DEPTH); 3010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exit(1); 3011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Get the caller method */ 3014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pStack->top >= 1) 3015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller = pStack->calls[pStack->top - 1].method; 3016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 3017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller = &dataKeys->methods[TOPLEVEL_INDEX]; 3018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project countRecursiveEntries(pStack, pStack->top, caller); 3019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller->elapsedExclusive += currentTime - pStack->lastEventTime; 3020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 3021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (caller->elapsedExclusive > 10000000) 3022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(dumpStream, "%llu current %llu last %llu diff %llu\n", 3023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller->elapsedExclusive, currentTime, 3024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack->lastEventTime, 3025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentTime - pStack->lastEventTime); 3026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 3027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (caller->recursiveEntries <= 1) { 3028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller->topExclusive += currentTime - pStack->lastEventTime; 3029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Push the method on the stack for this thread */ 3032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack->calls[pStack->top].method = method; 3033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack->calls[pStack->top++].entryTime = currentTime; 30346978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 30356978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // For each filter 30366978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int result = 0; 30376978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (ii = 0; ii < numFilters; ii++) { 30386978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince result = filterMethod(method, filters[ii], 1, threadId, numThreads, 30396978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince currentTime - pStack->lastEventTime, pStack->remTimes[ii]); 30406978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 30416978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // TODO: make remTimes work properly 30426978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Consider moving remTimes handling together with the rest 30436978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // of time handling and clean up the return codes 30446978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince /* 30456978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (result == 0) { // no time added, no remTime added 30466978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince pStack->remTimes[ii] += currentTime - pStack->lastEventTime; 30476978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } else if (result == 3 || result == 4) { // remTime added 30486978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Reset remTime, since it's been added 30496978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince pStack->remTimes[ii] = 0; 30506978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 30516978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince */ 30526978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 30536978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 3054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* This is a method exit */ 3056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t entryTime = 0; 3057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Pop the method off the stack for this thread */ 3059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pStack->top > 0) { 3060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack->top -= 1; 3061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project entryTime = pStack->calls[pStack->top].entryTime; 3062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method != pStack->calls[pStack->top].method) { 3063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->methodName) { 3064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, 3065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Exit from method %s.%s %s does not match stack:\n", 3066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->className, method->methodName, 3067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->signature); 3068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, 3070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Exit from method %s does not match stack:\n", 3071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->className); 3072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stackDump(pStack, pStack->top + 1); 3074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exit(1); 3075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Get the caller method */ 3079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pStack->top >= 1) 3080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller = pStack->calls[pStack->top - 1].method; 3081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 3082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller = &dataKeys->methods[TOPLEVEL_INDEX]; 3083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project countRecursiveEntries(pStack, pStack->top, caller); 3084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project countRecursiveEntries(pStack, pStack->top, method); 3085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsed = currentTime - entryTime; 3086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project addInclusiveTime(caller, method, elapsed); 3087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedExclusive += currentTime - pStack->lastEventTime; 3088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->recursiveEntries == 0) { 3089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->topExclusive += currentTime - pStack->lastEventTime; 3090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 30916978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 30926978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // For each filter 30936978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int result = 0; 30946978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (ii = 0; ii < numFilters; ii++) { 30956978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince result = filterMethod(method, filters[ii], 0, threadId, numThreads, 30966978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince currentTime - pStack->lastEventTime, pStack->remTimes[ii]); 30976978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 30986978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // TODO: make remTimes work properly 30996978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince /* 31006978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (result == 0) { // no time added, no remTime added 31016978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince pStack->remTimes[ii] += currentTime - pStack->lastEventTime; 31026978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } else if (result == 3 || result == 4) { // remTime added 31036978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Reset remTime, since it's been added 31046978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince pStack->remTimes[ii] = 0; 31056978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 31066978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince */ 31076978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 31086978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 3109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Remember the time of the last entry or exit event */ 3111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack->lastEventTime = currentTime; 3112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If we have calls on the stack when the trace ends, then clean 3115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * up the stack and add time to the callers by pretending that we 3116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * are exiting from their methods now. 3117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CallStack *pStack; 3119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int threadId; 31205b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince uint64_t elapsedTime = 0; 3121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t sumThreadTime = 0; 3122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (threadId = 0; threadId < MAX_THREADS; ++threadId) { 31235b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 3124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack = traceData->stacks[threadId]; 3125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If this thread never existed, then continue with next thread */ 3127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pStack == NULL) 3128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 3129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 31306978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince /* Calculate times spent in thread, and add it to total time */ 31315b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince elapsedTime = pStack->lastEventTime - pStack->threadStartTime; 31325b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince sumThreadTime += elapsedTime; 31335b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 3134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < pStack->top; ++ii) { 31356978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince //printf("in loop\n"); 31366978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 3137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ii == 0) 3138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller = &dataKeys->methods[TOPLEVEL_INDEX]; 3139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 3140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller = pStack->calls[ii - 1].method; 3141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = pStack->calls[ii].method; 3142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project countRecursiveEntries(pStack, ii, caller); 3143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project countRecursiveEntries(pStack, ii, method); 3144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t entryTime = pStack->calls[ii].entryTime; 3146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsed = pStack->lastEventTime - entryTime; 3147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project addInclusiveTime(caller, method, elapsed); 31486978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 31496978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // For each filter 31506978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int result = 0; 31516978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (ii = 0; ii < numFilters; ii++) { 31526978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince result = filterMethod(method, filters[ii], 0, threadId, numThreads, 31536978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince currentTime - pStack->lastEventTime, pStack->remTimes[ii]); 31546978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 31556978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // TODO: make remTimes work properly 31566978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince /* 31576978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (result == 0) { // no time added, no remTime added 31586978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince pStack->remTimes[ii] += currentTime - pStack->lastEventTime; 31596978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } else if (result == 3 || result == 4) { // remTime added 31606978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince // Reset remTime, since it's been added 31616978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince pStack->remTimes[ii] = 0; 31626978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 31636978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince */ 31646978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 3165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 31666978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 31676978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince /* Save the per-thread elapsed time in the DataKeys struct */ 31686978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince for (ii = 0; ii < dataKeys->numThreads; ++ii) { 31696978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (dataKeys->threads[ii].threadId == threadId) { 31706978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince dataKeys->threads[ii].elapsedTime = elapsedTime; 31716978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 31726978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 31736978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 31746978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 3175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller = &dataKeys->methods[TOPLEVEL_INDEX]; 3177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller->elapsedInclusive = sumThreadTime; 3178de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 3180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fclose(dumpStream); 3181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 3182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (threadTime != NULL) { 3184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *threadTime = sumThreadTime; 3185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 3188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dataFp != NULL) 3189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fclose(dataFp); 3190de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dataKeys; 3192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 3193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectMethodEntry** parseMethodEntries(DataKeys* dataKeys) 3195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 3196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 3197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Create a new array of pointers to the methods and sort the pointers 3198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instead of the actual MethodEntry structs. We need to do this 3199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because there are other lists that contain pointers to the 3200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * MethodEntry structs. 3201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry** pMethods = (MethodEntry**) malloc(sizeof(MethodEntry*) * dataKeys->numMethods); 3203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < dataKeys->numMethods; ++ii) { 3204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* entry = &dataKeys->methods[ii]; 3205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMethods[ii] = entry; 3206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3207de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return pMethods; 3209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 3210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32116978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 3212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 3213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Produce a function profile from the following methods 3214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 32155b55af706cf3823494123da092a0a0319297a93eRodrigo Ipincevoid profileTrace(TraceData* traceData, MethodEntry **pMethods, int numMethods, uint64_t sumThreadTime, 32166978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince ThreadEntry *pThreads, int numThreads, Filter** filters) 3217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 32186978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince /* Print the html header, if necessary */ 3219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 3220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(htmlHeader, gOptions.sortableUrl); 3221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outputTableOfContents(); 3222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printExclusiveProfile(pMethods, numMethods, sumThreadTime); 3225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printInclusiveProfile(pMethods, numMethods, sumThreadTime); 3226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32276978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince printThreadProfile(pThreads, numThreads, sumThreadTime, filters); 32285b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 3229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createClassList(traceData, pMethods, numMethods); 3230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printClassProfiles(traceData, sumThreadTime); 3231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createUniqueMethodList(traceData, pMethods, numMethods); 3233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printMethodProfiles(traceData, sumThreadTime); 3234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 3236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s", htmlFooter); 3237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 3239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareMethodNamesForDiff(const void *a, const void *b) 3241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 3242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 3243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodA = *(const MethodEntry**)a; 3245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodB = *(const MethodEntry**)b; 3246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodA->methodName == NULL || methodB->methodName == NULL) { 3247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return compareClassNames(a, b); 3248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->methodName, methodB->methodName); 3250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 3251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->signature, methodB->signature); 3252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 3253de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro return strcmp(methodA->className, methodB->className); 3254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 3257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 3258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint findMatch(MethodEntry** methods, int size, MethodEntry* matchThis) 3260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 3261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 3262de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0 ; i < size ; i++) { 3264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method = methods[i]; 3265de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method != NULL && !compareMethodNamesForDiff(&method, &matchThis)) { 3267de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro// printf("%s.%s == %s.%s<br>\n", matchThis->className, matchThis->methodName, 3268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // method->className, method->methodName); 3269de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return i; 3271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* if (!compareMethodNames(&method, &matchThis)) { 3272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return i; 3273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/ } 3275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3276de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 3278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 3279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareDiffEntriesExculsive(const void *a, const void *b) 3281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 3282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 3283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DiffEntry* entryA = (const DiffEntry*)a; 3285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DiffEntry* entryB = (const DiffEntry*)b; 3286de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (entryA->differenceExclusive < entryB->differenceExclusive) { 3288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 3289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (entryA->differenceExclusive > entryB->differenceExclusive) { 3290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 3291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3292de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 3294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 3295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareDiffEntriesInculsive(const void *a, const void *b) 3297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 3298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 3299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DiffEntry* entryA = (const DiffEntry*)a; 3301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DiffEntry* entryB = (const DiffEntry*)b; 3302de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (entryA->differenceInclusive < entryB->differenceInclusive) { 3304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 3305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (entryA->differenceInclusive > entryB->differenceInclusive) { 3306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 3307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3308de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 3310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 3311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3312de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapirovoid printMissingMethod(MethodEntry* method) 3313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 3314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char classBuf[HTML_BUFSIZE]; 3315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char methodBuf[HTML_BUFSIZE]; 3316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* className; 3317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* methodName; 3318de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = htmlEscape(method->className, classBuf, HTML_BUFSIZE); 3320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = htmlEscape(method->methodName, methodBuf, HTML_BUFSIZE); 3321de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3322de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro if (gOptions.outputHtml) printf("<tr><td>\n"); 3323de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s.%s ", className, methodName); 3325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 3326de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%lld ", method->elapsedExclusive); 3328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 3329de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%lld ", method->elapsedInclusive); 3331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 3332de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%d\n", method->numCalls[0]); 3334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>\n"); 3335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 3336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid createDiff(DataKeys* d1, uint64_t sum1, DataKeys* d2, uint64_t sum2) 3339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 3340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry** methods1 = parseMethodEntries(d1); 3341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry** methods2 = parseMethodEntries(d2); 3342de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3343de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro // sort and assign the indicies 3344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 3345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(methods1, d1->numMethods, sizeof(MethodEntry*), compareElapsedInclusive); 3346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < d1->numMethods; ++i) { 3347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methods1[i]->index = i; 3348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(methods2, d2->numMethods, sizeof(MethodEntry*), compareElapsedInclusive); 3351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < d2->numMethods; ++i) { 3352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methods2[i]->index = i; 3353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3354de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int max = (d1->numMethods < d2->numMethods) ? d2->numMethods : d1->numMethods; 3356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project max++; 3357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DiffEntry* diffs = (DiffEntry*)malloc(max * sizeof(DiffEntry)); 3358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(diffs, 0, max * sizeof(DiffEntry)); 3359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DiffEntry* ptr = diffs; 3360de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// printf("<br>d1->numMethods: %d d1->numMethods: %d<br>\n", d1->numMethods, d2->numMethods); 3362de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int matches = 0; 3364de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0 ; i < d1->numMethods ; i++) { 3366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int match = findMatch(methods2, d2->numMethods, methods1[i]); 3367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (match >= 0) { 3368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr->method1 = methods1[i]; 3369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr->method2 = methods2[match]; 3370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t e1 = ptr->method1->elapsedExclusive; 3372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t e2 = ptr->method2->elapsedExclusive; 3373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (e1 > 0) { 3374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr->differenceExclusive = e2 - e1; 3375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr->differenceExclusivePercentage = ((double)e2 / (double)e1) * 100.0; 3376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t i1 = ptr->method1->elapsedInclusive; 3379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t i2 = ptr->method2->elapsedInclusive; 3380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (i1 > 0) { 3381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr->differenceInclusive = i2 - i1; 3382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr->differenceInclusivePercentage = ((double)i2 / (double)i1) * 100.0; 3383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3384de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // clear these out so we don't find them again and we know which ones 3386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // we have left over 3387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methods1[i] = NULL; 3388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methods2[match] = NULL; 3389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr++; 3390de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project matches++; 3392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr->method1 = NULL; 3395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr->method2 = NULL; 3396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(diffs, matches, sizeof(DiffEntry), compareDiffEntriesExculsive); 3398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr = diffs; 3399de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 3401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(htmlHeader, gOptions.sortableUrl); 3402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<h3>Table of Contents</h3>\n"); 3403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<ul>\n"); 3404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<li><a href='#exclusive'>Exclusive</a>\n"); 3405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<li><a href='#inclusive'>Inclusive</a>\n"); 3406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</ul>\n"); 3407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Run 1: %s<br>\n", gOptions.diffFileName); 3408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Run 2: %s<br>\n", gOptions.traceFileName); 3409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a name=\"exclusive\"></a><h3 id=\"exclusive\">Exclusive</h3>\n"); 3410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(tableHeader, "exclusive_table"); 3411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3412de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char classBuf[HTML_BUFSIZE]; 3414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char methodBuf[HTML_BUFSIZE]; 3415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* className; 3416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* methodName; 3417de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (ptr->method1 != NULL && ptr->method2 != NULL) { 3419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("<tr><td>\n"); 3420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = htmlEscape(ptr->method1->className, classBuf, HTML_BUFSIZE); 3422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = htmlEscape(ptr->method1->methodName, methodBuf, HTML_BUFSIZE); 3423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s.%s ", className, methodName); 3425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 3426de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%lld ", ptr->method1->elapsedExclusive); 3428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 3429de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%llu ", ptr->method2->elapsedExclusive); 3431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 3432de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%lld ", ptr->differenceExclusive); 3434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 3435de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%.2f\n", ptr->differenceExclusivePercentage); 3437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>\n"); 3438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%d\n", ptr->method1->numCalls[0]); 3440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>\n"); 3441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%d\n", ptr->method2->numCalls[0]); 3443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td></tr>\n"); 3444de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr++; 3446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3447de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</table>\n"); 3449de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 3451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(htmlHeader, gOptions.sortableUrl); 3452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Run 1: %s<br>\n", gOptions.diffFileName); 3453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Run 2: %s<br>\n", gOptions.traceFileName); 3454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a name=\"inclusive\"></a><h3 id=\"inculisve\">Inclusive</h3>\n"); 3455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(tableHeader, "inclusive_table"); 3456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3457de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(diffs, matches, sizeof(DiffEntry), compareDiffEntriesInculsive); 3459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr = diffs; 3460de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (ptr->method1 != NULL && ptr->method2 != NULL) { 3462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("<tr><td>\n"); 3463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = htmlEscape(ptr->method1->className, classBuf, HTML_BUFSIZE); 3465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = htmlEscape(ptr->method1->methodName, methodBuf, HTML_BUFSIZE); 3466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s.%s ", className, methodName); 3468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 3469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%lld ", ptr->method1->elapsedInclusive); 3471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 3472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%llu ", ptr->method2->elapsedInclusive); 3474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 3475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%lld ", ptr->differenceInclusive); 3477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 3478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%.2f\n", ptr->differenceInclusivePercentage); 3480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>\n"); 3481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%d\n", ptr->method1->numCalls[0]); 3483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>\n"); 3484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%d\n", ptr->method2->numCalls[0]); 3486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td></tr>\n"); 3487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr++; 3489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 3492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</table>\n"); 3493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<h3>Run 1 methods not found in Run 2</h3>"); 3494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(tableHeaderMissing); 3495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3496de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < d1->numMethods; ++i) { 3498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methods1[i] != NULL) { 3499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printMissingMethod(methods1[i]); 3500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3502de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 3504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</table>\n"); 3505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<h3>Run 2 methods not found in Run 1</h3>"); 3506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(tableHeaderMissing); 3507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3508de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < d2->numMethods; ++i) { 3510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methods2[i] != NULL) { 3511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printMissingMethod(methods2[i]); 3512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3514de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</body></html\n"); 3516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 3517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint usage(const char *program) 3519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 35206978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, "usage: %s [-ho] [-s sortable] [-d trace-file-name] [-g outfile] [-f filter-file] trace-file-name\n", program); 3521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " -d trace-file-name - Diff with this trace\n"); 3522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " -g outfile - Write graph to 'outfile'\n"); 35236978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince fprintf(stderr, " -f filter-file - Filter functions as specified in file\n"); 3524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " -k - When writing a graph, keep the intermediate DOT file\n"); 3525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " -h - Turn on HTML output\n"); 3526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " -o - Dump the dmtrace file instead of profiling\n"); 3527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " -s - URL base to where the sortable javascript file\n"); 3528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " -t threshold - Threshold percentage for including nodes in the graph\n"); 3529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 2; 3530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 3531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// Returns true if there was an error 3533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint parseOptions(int argc, char **argv) 3534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 3535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (1) { 35366978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince int opt = getopt(argc, argv, "d:hg:kos:t:f:"); 3537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (opt == -1) 3538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (opt) { 3540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'd': 3541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.diffFileName = optarg; 3542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'g': 3544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.graphFileName = optarg; 3545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 35466978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince case 'f': 35476978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince gOptions.filterFileName = optarg; 354844828ed25841ea5180346695dfc07ef33b2b7e73Jack Veenstra break; 3549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'k': 3550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.keepDotFile = 1; 3551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'h': 3553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.outputHtml = 1; 3554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'o': 3556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.dump = 1; 3557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 's': 3559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.sortableUrl = optarg; 3560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 't': 3562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.threshold = atoi(optarg); 3563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 3564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 3565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 3566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 3569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 3570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 3572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse args. 3573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 3574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint main(int argc, char** argv) 3575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 35766978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 3577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.threshold = -1; 35786978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 3579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Parse the options 3580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (parseOptions(argc, argv) || argc - optind != 1) 3581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return usage(argv[0]); 3582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.traceFileName = argv[optind]; 3584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.threshold < 0 || 100 <= gOptions.threshold) { 3586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.threshold = 20; 3587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 35885b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 3589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.dump) { 3590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dumpTrace(); 3591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 3592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t sumThreadTime = 0; 35956978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 35966978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince Filter** filters = NULL; 35976978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince if (gOptions.filterFileName != NULL) { 35986978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince filters = parseFilters(gOptions.filterFileName); 35996978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince } 36006978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 3601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TraceData data1; 3602fe1d6d586614fa51d82857e09128d6671be21d56Andy McFadden memset(&data1, 0, sizeof(data1)); 3603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DataKeys* dataKeys = parseDataKeys(&data1, gOptions.traceFileName, 36046978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince &sumThreadTime, filters); 3605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dataKeys == NULL) { 3606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "Cannot read trace.\n"); 3607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exit(1); 3608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.diffFileName != NULL) { 3611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t sum2; 3612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TraceData data2; 36136978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince DataKeys* d2 = parseDataKeys(&data2, gOptions.diffFileName, &sum2, filters); 3614de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createDiff(d2, sum2, dataKeys, sumThreadTime); 3616de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project freeDataKeys(d2); 3618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 3619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry** methods = parseMethodEntries(dataKeys); 36205b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince profileTrace(&data1, methods, dataKeys->numMethods, sumThreadTime, 36216978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince dataKeys->threads, dataKeys->numThreads, filters); 3622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.graphFileName != NULL) { 3623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createInclusiveProfileGraphNew(dataKeys); 3624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(methods); 3626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 3627de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 3628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project freeDataKeys(dataKeys); 3629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 3630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 3631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 3632