17b522639a499f63ccb5162576830d0c20539bd05Andy McFadden/* 27b522639a499f63ccb5162576830d0c20539bd05Andy McFadden * Copyright (C) 2006 The Android Open Source Project 37b522639a499f63ccb5162576830d0c20539bd05Andy McFadden * 47b522639a499f63ccb5162576830d0c20539bd05Andy McFadden * Licensed under the Apache License, Version 2.0 (the "License"); 57b522639a499f63ccb5162576830d0c20539bd05Andy McFadden * you may not use this file except in compliance with the License. 67b522639a499f63ccb5162576830d0c20539bd05Andy McFadden * You may obtain a copy of the License at 77b522639a499f63ccb5162576830d0c20539bd05Andy McFadden * 87b522639a499f63ccb5162576830d0c20539bd05Andy McFadden * http://www.apache.org/licenses/LICENSE-2.0 97b522639a499f63ccb5162576830d0c20539bd05Andy McFadden * 107b522639a499f63ccb5162576830d0c20539bd05Andy McFadden * Unless required by applicable law or agreed to in writing, software 117b522639a499f63ccb5162576830d0c20539bd05Andy McFadden * distributed under the License is distributed on an "AS IS" BASIS, 127b522639a499f63ccb5162576830d0c20539bd05Andy McFadden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137b522639a499f63ccb5162576830d0c20539bd05Andy McFadden * See the License for the specific language governing permissions and 147b522639a499f63ccb5162576830d0c20539bd05Andy McFadden * limitations under the License. 157b522639a499f63ccb5162576830d0c20539bd05Andy McFadden */ 165b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Process dmtrace output. 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is the wrong way to go about it -- C is a clumsy language for 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * shuffling data around. It'll do for a first pass. 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define NOT_VM 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Profile.h" // from VM header 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdio.h> 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdlib.h> 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <string.h> 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <unistd.h> 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <inttypes.h> 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <time.h> 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <errno.h> 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <assert.h> 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 35949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown/* Version number in the key file. 36949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown * Version 1 uses one byte for the thread id. 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Version 2 uses two bytes for the thread ids. 38949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown * Version 3 encodes the record size and adds an optional extra timestamp field. 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint versionNumber; 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* arbitrarily limit indentation */ 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define MAX_STACK_DEPTH 10000 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* thread list in key file is not reliable, so just max out */ 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define MAX_THREADS 32768 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Size of temporary buffers for escaping html strings */ 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define HTML_BUFSIZE 10240 50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 51de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapirochar *htmlHeader = 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"<html>\n<head>\n<script type=\"text/javascript\" src=\"%ssortable.js\"></script>\n" 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"<script langugage=\"javascript\">\n" 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"function toggle(item) {\n" 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" obj=document.getElementById(item);\n" 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" visible=(obj.style.display!=\"none\" && obj.style.display!=\"\");\n" 57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" key=document.getElementById(\"x\" + item);\n" 58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" if (visible) {\n" 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" obj.style.display=\"none\";\n" 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" key.innerHTML=\"+\";\n" 61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" } else {\n" 62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" obj.style.display=\"block\";\n" 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" key.innerHTML=\"-\";\n" 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" }\n" 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"}\n" 66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"function onMouseOver(obj) {\n" 67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" obj.style.background=\"lightblue\";\n" 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"}\n" 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"function onMouseOut(obj) {\n" 70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project" obj.style.background=\"white\";\n" 71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"}\n" 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"</script>\n" 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"<style type=\"text/css\">\n" 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"div { font-family: courier; font-size: 13 }\n" 75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"div.parent { margin-left: 15; display: none }\n" 76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"div.leaf { margin-left: 10 }\n" 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"div.header { margin-left: 10 }\n" 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"div.link { margin-left: 10; cursor: move }\n" 79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"span.parent { padding-right: 10; }\n" 80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"span.leaf { padding-right: 10; }\n" 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"a img { border: 0;}\n" 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"table.sortable th { border-width: 0px 1px 1px 1px; background-color: #ccc;}\n" 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"a { text-decoration: none; }\n" 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"a:hover { text-decoration: underline; }\n" 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"table.sortable th, table.sortable td { text-align: left;}" 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"table.sortable tr.odd td { background-color: #ddd; }\n" 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"table.sortable tr.even td { background-color: #fff; }\n" 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"</style>\n" 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project"</head><body>\n\n"; 90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar *htmlFooter = "\n</body>\n</html>\n"; 92de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapirochar *profileSeparator = 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "======================================================================"; 94de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 95de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiroconst char* tableHeader = 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<table class='sortable' id='%s'><tr>\n" 97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>Method</th>\n" 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>Run 1 (us)</th>\n" 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>Run 2 (us)</th>\n" 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>Diff (us)</th>\n" 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>Diff (%%)</th>\n" 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>1: # calls</th>\n" 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>2: # calls</th>\n" 104de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro "</tr>\n"; 105de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 106de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiroconst char* tableHeaderMissing = 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<table class='sortable' id='%s'>\n" 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>Method</th>\n" 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>Exclusive</th>\n" 110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th>Inclusive</th>\n" 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "<th># calls</th>\n"; 112de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 113de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro#define GRAPH_LABEL_VISITED 0x0001 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GRAPH_NODE_VISITED 0x0002 115de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Values from the header of the data file. 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct DataHeader { 120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int magic; 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project short version; 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project short offsetToData; 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long long startWhen; 124949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown short recordSize; 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} DataHeader; 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Entry from the thread list. 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct ThreadEntry { 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int threadId; 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* threadName; 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} ThreadEntry; 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstruct MethodEntry; 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct TimedMethod { 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct TimedMethod *next; 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsedInclusive; 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numCalls; 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct MethodEntry *method; 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} TimedMethod; 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct ClassEntry { 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char *className; 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsedExclusive; 146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numMethods; 147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct MethodEntry **methods; /* list of methods in this class */ 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numCalls[2]; /* 0=normal, 1=recursive */ 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} ClassEntry; 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct UniqueMethodEntry { 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsedExclusive; 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numMethods; 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct MethodEntry **methods; /* list of methods with same name */ 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numCalls[2]; /* 0=normal, 1=recursive */ 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} UniqueMethodEntry; 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Entry from the method list. 160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct MethodEntry { 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int methodId; 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* className; 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* methodName; 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* signature; 166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* fileName; 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int lineNum; 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsedExclusive; 169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsedInclusive; 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t topExclusive; /* non-recursive exclusive time */ 171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t recursiveInclusive; 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct TimedMethod *parents[2]; /* 0=normal, 1=recursive */ 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project struct TimedMethod *children[2]; /* 0=normal, 1=recursive */ 174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numCalls[2]; /* 0=normal, 1=recursive */ 175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int index; /* used after sorting to number methods */ 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int recursiveEntries; /* number of entries on the stack */ 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int graphState; /* used when graphing to see if this method has been visited before */ 178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} MethodEntry; 179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The parsed contents of the key file. 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct DataKeys { 1845b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince char* fileData; /* contents of the entire file */ 185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long fileLen; 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numThreads; 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ThreadEntry* threads; 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numMethods; 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* methods; /* 2 extra methods: "toplevel" and "unknown" */ 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} DataKeys; 191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define TOPLEVEL_INDEX 0 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define UNKNOWN_INDEX 1 194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct StackEntry { 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry *method; 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t entryTime; 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} StackEntry; 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct CallStack { 2017b522639a499f63ccb5162576830d0c20539bd05Andy McFadden int top; 2027b522639a499f63ccb5162576830d0c20539bd05Andy McFadden StackEntry calls[MAX_STACK_DEPTH]; 2037b522639a499f63ccb5162576830d0c20539bd05Andy McFadden uint64_t lastEventTime; 2047b522639a499f63ccb5162576830d0c20539bd05Andy McFadden uint64_t threadStartTime; 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} CallStack; 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct DiffEntry { 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method1; 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method2; 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int64_t differenceExclusive; 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int64_t differenceInclusive; 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double differenceExclusivePercentage; 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double differenceInclusivePercentage; 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} DiffEntry; 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// Global options 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct Options { 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* traceFileName; 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* diffFileName; 220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* graphFileName; 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int keepDotFile; 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int dump; 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int outputHtml; 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* sortableUrl; 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int threshold; 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} Options; 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct TraceData { 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numClasses; 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassEntry *classes; 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CallStack *stacks[MAX_THREADS]; 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int depth[MAX_THREADS]; 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numUniqueMethods; 234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UniqueMethodEntry *uniqueMethods; 235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} TraceData; 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic Options gOptions; 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Escapes characters in the source string that are html special entities. 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The escaped string is written to "dest" which must be large enough to 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * hold the result. A pointer to "dest" is returned. The characters and 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * their corresponding escape sequences are: 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * '<' < 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * '>' > 245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * '&' & 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectchar *htmlEscape(const char *src, char *dest, int len) 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *destStart = dest; 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (src == NULL) 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nbytes = 0; 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (*src) { 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*src == '<') { 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nbytes += 4; 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nbytes >= len) 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = '&'; 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = 'l'; 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = 't'; 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = ';'; 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (*src == '>') { 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nbytes += 4; 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nbytes >= len) 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = '&'; 269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = 'g'; 270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = 't'; 271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = ';'; 272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (*src == '&') { 273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nbytes += 5; 274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nbytes >= len) 275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = '&'; 277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = 'a'; 278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = 'm'; 279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = 'p'; 280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = ';'; 281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nbytes += 1; 283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nbytes >= len) 284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest++ = *src; 286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project src += 1; 288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nbytes >= len) { 290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "htmlEscape(): buffer overflow\n"); 291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exit(1); 292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *dest = 0; 294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return destStart; 296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Initializes a MethodEntry 299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid initMethodEntry(MethodEntry *method, unsigned int methodId, 301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char *className, const char *methodName, 302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char *signature, const char* fileName, 303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* lineNumStr) 304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->methodId = methodId; 306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->className = className; 307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->methodName = methodName; 308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->signature = signature; 309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->fileName = fileName; 310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->lineNum = (lineNumStr != NULL) ? atoi(lineNumStr) : -1; 311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedExclusive = 0; 312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedInclusive = 0; 313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->topExclusive = 0; 314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->recursiveInclusive = 0; 315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->parents[0] = NULL; 316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->parents[1] = NULL; 317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->children[0] = NULL; 318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->children[1] = NULL; 319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->numCalls[0] = 0; 320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->numCalls[1] = 0; 321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->index = 0; 322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->recursiveEntries = 0; 323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This comparison function is called from qsort() to sort 327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * methods into decreasing order of exclusive elapsed time. 328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareElapsedExclusive(const void *a, const void *b) { 330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsed1, elapsed2; 331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodA = *(const MethodEntry**)a; 334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodB = *(const MethodEntry**)b; 335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed1 = methodA->elapsedExclusive; 336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed2 = methodB->elapsedExclusive; 337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 < elapsed2) 338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 > elapsed2) 340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If the elapsed times of two methods are equal, then sort them 343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * into alphabetical order. 344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->className, methodB->className); 346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodA->methodName == NULL || methodB->methodName == NULL) { 348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idA = methodA->methodId; 349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idB = methodB->methodId; 350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA < idB) 351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA > idB) 353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->methodName, methodB->methodName); 357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) 358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->signature, methodB->signature); 359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This comparison function is called from qsort() to sort 365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * methods into decreasing order of inclusive elapsed time. 366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareElapsedInclusive(const void *a, const void *b) { 368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodA, *methodB; 369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsed1, elapsed2; 370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodA = *(MethodEntry const **)a; 373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodB = *(MethodEntry const **)b; 374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed1 = methodA->elapsedInclusive; 375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed2 = methodB->elapsedInclusive; 376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 < elapsed2) 377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 > elapsed2) 379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If the elapsed times of two methods are equal, then sort them 382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * into alphabetical order. 383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->className, methodB->className); 385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodA->methodName == NULL || methodB->methodName == NULL) { 387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idA = methodA->methodId; 388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idB = methodB->methodId; 389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA < idB) 390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA > idB) 392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->methodName, methodB->methodName); 396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) 397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->signature, methodB->signature); 398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This comparison function is called from qsort() to sort 404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TimedMethods into decreasing order of inclusive elapsed time. 405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareTimedMethod(const void *a, const void *b) { 407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const TimedMethod *timedA, *timedB; 408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsed1, elapsed2; 409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project timedA = (TimedMethod const *)a; 412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project timedB = (TimedMethod const *)b; 413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed1 = timedA->elapsedInclusive; 414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed2 = timedB->elapsedInclusive; 415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 < elapsed2) 416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 > elapsed2) 418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If the elapsed times of two methods are equal, then sort them 421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * into alphabetical order. 422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry *methodA = timedA->method; 424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry *methodB = timedB->method; 425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->className, methodB->className); 426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodA->methodName == NULL || methodB->methodName == NULL) { 428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idA = methodA->methodId; 429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idB = methodB->methodId; 430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA < idB) 431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA > idB) 433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->methodName, methodB->methodName); 437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) 438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->signature, methodB->signature); 439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This comparison function is called from qsort() to sort 445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * MethodEntry pointers into alphabetical order of class names. 446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareClassNames(const void *a, const void *b) { 448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodA = *(const MethodEntry**)a; 451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodB = *(const MethodEntry**)b; 452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->className, methodB->className); 453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idA = methodA->methodId; 455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idB = methodB->methodId; 456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA < idB) 457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA > idB) 459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This comparison function is called from qsort() to sort 467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * classes into decreasing order of exclusive elapsed time. 468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareClassExclusive(const void *a, const void *b) { 470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsed1, elapsed2; 471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const ClassEntry *classA = *(const ClassEntry**)a; 474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const ClassEntry *classB = *(const ClassEntry**)b; 475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed1 = classA->elapsedExclusive; 476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed2 = classB->elapsedExclusive; 477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 < elapsed2) 478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 > elapsed2) 480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If the elapsed times of two classs are equal, then sort them 483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * into alphabetical order. 484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(classA->className, classB->className); 486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Break ties with the first method id. This is probably not 488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * needed. 489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idA = classA->methods[0]->methodId; 491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idB = classB->methods[0]->methodId; 492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA < idB) 493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA > idB) 495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This comparison function is called from qsort() to sort 503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * MethodEntry pointers into alphabetical order by method name, 504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * then by class name. 505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareMethodNames(const void *a, const void *b) { 507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodA = *(const MethodEntry**)a; 510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodB = *(const MethodEntry**)b; 511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodA->methodName == NULL || methodB->methodName == NULL) { 512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return compareClassNames(a, b); 513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->methodName, methodB->methodName); 515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->className, methodB->className); 517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idA = methodA->methodId; 519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idB = methodB->methodId; 520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA < idB) 521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA > idB) 523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This comparison function is called from qsort() to sort 532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * unique methods into decreasing order of exclusive elapsed time. 533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareUniqueExclusive(const void *a, const void *b) { 535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsed1, elapsed2; 536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const UniqueMethodEntry *uniqueA = *(const UniqueMethodEntry**)a; 539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const UniqueMethodEntry *uniqueB = *(const UniqueMethodEntry**)b; 540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed1 = uniqueA->elapsedExclusive; 541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsed2 = uniqueB->elapsedExclusive; 542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 < elapsed2) 543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (elapsed1 > elapsed2) 545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If the elapsed times of two methods are equal, then sort them 548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * into alphabetical order. 549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(uniqueA->methods[0]->className, 551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uniqueB->methods[0]->className); 552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idA = uniqueA->methods[0]->methodId; 554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int idB = uniqueB->methods[0]->methodId; 555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA < idB) 556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (idA > idB) 558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free a DataKeys struct. 566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid freeDataKeys(DataKeys* pKeys) 568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pKeys == NULL) 570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pKeys->fileData); 573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pKeys->threads); 574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pKeys->methods); 575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(pKeys); 576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Find the offset to the next occurrence of the specified character. 580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "data" should point somewhere within the current line. "len" is the 582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * number of bytes left in the buffer. 583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns -1 if we hit the end of the buffer. 585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint findNextChar(const char* data, int len, char lookFor) 587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* start = data; 589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (len > 0) { 591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*data == lookFor) 592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return data - start; 593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data++; 595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len--; 596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6017b522639a499f63ccb5162576830d0c20539bd05Andy McFadden/* 6027b522639a499f63ccb5162576830d0c20539bd05Andy McFadden * Count the number of lines until the next token. 6037b522639a499f63ccb5162576830d0c20539bd05Andy McFadden * 6047b522639a499f63ccb5162576830d0c20539bd05Andy McFadden * Returns -1 if none found before EOF. 6057b522639a499f63ccb5162576830d0c20539bd05Andy McFadden */ 6067b522639a499f63ccb5162576830d0c20539bd05Andy McFaddenint countLinesToToken(const char* data, int len) 607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int count = 0; 609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int next; 610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 6117b522639a499f63ccb5162576830d0c20539bd05Andy McFadden while (*data != TOKEN_CHAR) { 612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = findNextChar(data, len, '\n'); 613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (next < 0) 6147b522639a499f63ccb5162576830d0c20539bd05Andy McFadden return -1; 615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count++; 616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next+1; 617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len -= next+1; 618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return count; 621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Make sure we're at the start of the right section. 625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns the length of the token line, or -1 if something is wrong. 627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint checkToken(const char* data, int len, const char* cmpStr) 629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cmpLen = strlen(cmpStr); 631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int next; 632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*data != TOKEN_CHAR) { 634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, 635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "ERROR: not at start of %s (found '%.10s')\n", cmpStr, data); 636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = findNextChar(data, len, '\n'); 640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (next < cmpLen+1) 641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strncmp(data+1, cmpStr, cmpLen) != 0) { 644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "ERROR: '%s' not found (got '%.7s')\n", cmpStr, data+1); 645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return next+1; 649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse the "*version" section. 653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectlong parseVersion(DataKeys* pKeys, long offset, int verbose) 655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* data; 657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* dataEnd; 658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, count, next; 659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (offset < 0) 661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data = pKeys->fileData + offset; 664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataEnd = pKeys->fileData + pKeys->fileLen; 665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = checkToken(data, dataEnd - data, "version"); 666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (next <= 0) 667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next; 670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Count the number of items in the "version" section. 673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count = countLinesToToken(data, dataEnd - data); 675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count <= 0) { 676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, 677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "ERROR: failed while reading version (found %d)\n", count); 678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* find the end of the line */ 682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = findNextChar(data, dataEnd - data, '\n'); 683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (next < 0) 684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data[next] = '\0'; 687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project versionNumber = strtoul(data, NULL, 0); 688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (verbose) 689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("VERSION: %d\n", versionNumber); 690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next+1; 692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* skip over the rest of the stuff, which is "name=value" lines */ 694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 1; i < count; i++) { 695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = findNextChar(data, dataEnd - data, '\n'); 696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (next < 0) 697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //data[next] = '\0'; 699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf("IGNORING: '%s'\n", data); 700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next+1; 701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return data - pKeys->fileData; 704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse the "*threads" section. 708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectlong parseThreads(DataKeys* pKeys, long offset) 710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* data; 712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* dataEnd; 713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, next, tab, count; 714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (offset < 0) 716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data = pKeys->fileData + offset; 719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataEnd = pKeys->fileData + pKeys->fileLen; 720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = checkToken(data, dataEnd - data, "threads"); 721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next; 723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Count the number of thread entries (one per line). 726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count = countLinesToToken(data, dataEnd - data); 728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count <= 0) { 729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, 730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "ERROR: failed while reading threads (found %d)\n", count); 731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf("+++ found %d threads\n", count); 735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->threads = (ThreadEntry*) malloc(sizeof(ThreadEntry) * count); 736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pKeys->threads == NULL) 737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract all entries. 741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < count; i++) { 743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = findNextChar(data, dataEnd - data, '\n'); 744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(next > 0); 745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data[next] = '\0'; 746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab = findNextChar(data, next, '\t'); 748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data[tab] = '\0'; 749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->threads[i].threadId = atoi(data); 751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->threads[i].threadName = data + tab +1; 752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next+1; 754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->numThreads = count; 757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return data - pKeys->fileData; 758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse the "*methods" section. 762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectlong parseMethods(DataKeys* pKeys, long offset) 764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* data; 766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* dataEnd; 767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i, next, count; 768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (offset < 0) 770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data = pKeys->fileData + offset; 773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataEnd = pKeys->fileData + pKeys->fileLen; 774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = checkToken(data, dataEnd - data, "methods"); 775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (next < 0) 776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next; 779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Count the number of method entries (one per line). 782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count = countLinesToToken(data, dataEnd - data); 784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (count <= 0) { 785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, 786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "ERROR: failed while reading methods (found %d)\n", count); 787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Reserve an extra method at location 0 for the "toplevel" method, 791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and another extra method for all other "unknown" methods. 792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project count += 2; 794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->methods = (MethodEntry*) malloc(sizeof(MethodEntry) * count); 795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pKeys->methods == NULL) 796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project initMethodEntry(&pKeys->methods[TOPLEVEL_INDEX], 0, "(toplevel)", 798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project NULL, NULL, NULL, NULL); 799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project initMethodEntry(&pKeys->methods[UNKNOWN_INDEX], 0, "(unknown)", 800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project NULL, NULL, NULL, NULL); 801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract all entries, starting with index 2. 804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = UNKNOWN_INDEX + 1; i < count; i++) { 806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int tab1, tab2, tab3, tab4, tab5; 807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int id; 808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* endptr; 809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = findNextChar(data, dataEnd - data, '\n'); 811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(next > 0); 812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data[next] = '\0'; 813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab1 = findNextChar(data, next, '\t'); 815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab2 = findNextChar(data+(tab1+1), next-(tab1+1), '\t'); 816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab3 = findNextChar(data+(tab1+tab2+2), next-(tab1+tab2+2), '\t'); 817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab4 = findNextChar(data+(tab1+tab2+tab3+3), 818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next-(tab1+tab2+tab3+3), '\t'); 819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab5 = findNextChar(data+(tab1+tab2+tab3+tab4+4), 820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next-(tab1+tab2+tab3+tab4+4), '\t'); 821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (tab1 < 0) { 822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "ERROR: missing field on method line: '%s'\n", 823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data); 824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(data[tab1] == '\t'); 827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data[tab1] = '\0'; 828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id = strtoul(data, &endptr, 0); 830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*endptr != '\0') { 831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "ERROR: bad method ID '%s'\n", data); 832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Allow files that specify just a function name, instead of requiring 836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // "class \t method \t signature" 837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (tab2 > 0 && tab3 > 0) { 838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab2 += tab1+1; 839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab3 += tab2+1; 840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(data[tab2] == '\t'); 841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(data[tab3] == '\t'); 842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data[tab2] = data[tab3] = '\0'; 843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // This is starting to get awkward. Allow filename and line #. 845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (tab4 > 0 && tab5 > 0) { 846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab4 += tab3+1; 847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tab5 += tab4+1; 848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(data[tab4] == '\t'); 850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(data[tab5] == '\t'); 851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data[tab4] = data[tab5] = '\0'; 852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project initMethodEntry(&pKeys->methods[i], id, data + tab1 +1, 854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data + tab2 +1, data + tab3 +1, data + tab4 +1, 855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data + tab5 +1); 856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project initMethodEntry(&pKeys->methods[i], id, data + tab1 +1, 858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data + tab2 +1, data + tab3 +1, NULL, NULL); 859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project initMethodEntry(&pKeys->methods[i], id, data + tab1 +1, 862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project NULL, NULL, NULL, NULL); 863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next+1; 866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->numMethods = count; 869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return data - pKeys->fileData; 870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse the "*end" section. 874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectlong parseEnd(DataKeys* pKeys, long offset) 876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* data; 878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* dataEnd; 879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int next; 880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (offset < 0) 882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data = pKeys->fileData + offset; 885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataEnd = pKeys->fileData + pKeys->fileLen; 886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project next = checkToken(data, dataEnd - data, "end"); 887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (next < 0) 888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data += next; 891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return data - pKeys->fileData; 893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sort the thread list entries. 897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int compareThreads(const void* thread1, const void* thread2) 899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return ((const ThreadEntry*) thread1)->threadId - 901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ((const ThreadEntry*) thread2)->threadId; 902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid sortThreadList(DataKeys* pKeys) 905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pKeys->threads, pKeys->numThreads, sizeof(pKeys->threads[0]), 907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project compareThreads); 908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Sort the method list entries. 912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int compareMethods(const void* meth1, const void* meth2) 914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int id1, id2; 916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id1 = ((const MethodEntry*) meth1)->methodId; 918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id2 = ((const MethodEntry*) meth2)->methodId; 919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (id1 < id2) 920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (id1 > id2) 922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid sortMethodList(DataKeys* pKeys) 927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pKeys->methods, pKeys->numMethods, sizeof(MethodEntry), 929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project compareMethods); 930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse the key section, and return a copy of the parsed contents. 934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectDataKeys* parseKeys(FILE *fp, int verbose) 936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DataKeys* pKeys = NULL; 938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project long offset; 939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys = (DataKeys*) calloc(1, sizeof(DataKeys)); 942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pKeys == NULL) 943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We load the entire file into memory. We do this, rather than memory- 947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * mapping it, because we want to change some whitespace to NULs. 948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fseek(fp, 0L, SEEK_END) != 0) { 950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project perror("fseek"); 951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->fileLen = ftell(fp); 954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pKeys->fileLen == 0) { 955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "Key file is empty.\n"); 956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project rewind(fp); 959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->fileData = (char*) malloc(pKeys->fileLen); 961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pKeys->fileData == NULL) { 962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "ERROR: unable to alloc %ld bytes\n", pKeys->fileLen); 963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fread(pKeys->fileData, 1, pKeys->fileLen, fp) != (size_t) pKeys->fileLen) 967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project { 968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "ERROR: unable to read %ld bytes from trace file\n", 969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->fileLen); 970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = 0; 974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = parseVersion(pKeys, offset, verbose); 976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = parseThreads(pKeys, offset); 977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = parseMethods(pKeys, offset); 978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project offset = parseEnd(pKeys, offset); 979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (offset < 0) 980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto fail; 981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 9827b522639a499f63ccb5162576830d0c20539bd05Andy McFadden /* Reduce our allocation now that we know where the end of the key section is. */ 9837b522639a499f63ccb5162576830d0c20539bd05Andy McFadden pKeys->fileData = (char *)realloc(pKeys->fileData, offset); 9847b522639a499f63ccb5162576830d0c20539bd05Andy McFadden pKeys->fileLen = offset; 985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Leave fp pointing to the beginning of the data section. */ 986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fseek(fp, offset, SEEK_SET); 987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sortThreadList(pKeys); 989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sortMethodList(pKeys); 990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Dump list of threads. 993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (verbose) { 995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Threads (%d):\n", pKeys->numThreads); 996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < pKeys->numThreads; i++) { 997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%2d %s\n", 998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->threads[i].threadId, pKeys->threads[i].threadName); 999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Dump list of methods. 1005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (verbose) { 1007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Methods (%d):\n", pKeys->numMethods); 1008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < pKeys->numMethods; i++) { 1009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("0x%08x %s : %s : %s\n", 10107b522639a499f63ccb5162576830d0c20539bd05Andy McFadden pKeys->methods[i].methodId, pKeys->methods[i].className, 1011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pKeys->methods[i].methodName, pKeys->methods[i].signature); 1012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 1015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return pKeys; 1017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfail: 1019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project freeDataKeys(pKeys); 1020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Read values from the binary data file. 1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Make the return value "unsigned int" instead of "unsigned short" so that 1029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we can detect EOF. 1030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectunsigned int read2LE(FILE* fp) 1032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int val; 1034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val = getc(fp); 1036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= getc(fp) << 8; 1037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return val; 1038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectunsigned int read4LE(FILE* fp) 1040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int val; 1042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val = getc(fp); 1044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= getc(fp) << 8; 1045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= getc(fp) << 16; 1046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= getc(fp) << 24; 1047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return val; 1048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectunsigned long long read8LE(FILE* fp) 1050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned long long val; 1052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val = getc(fp); 1054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= (unsigned long long) getc(fp) << 8; 1055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= (unsigned long long) getc(fp) << 16; 1056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= (unsigned long long) getc(fp) << 24; 1057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= (unsigned long long) getc(fp) << 32; 1058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= (unsigned long long) getc(fp) << 40; 1059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= (unsigned long long) getc(fp) << 48; 1060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project val |= (unsigned long long) getc(fp) << 56; 1061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return val; 1062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse the header of the data section. 1066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns with the file positioned at the start of the record data. 1068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint parseDataHeader(FILE *fp, DataHeader* pHeader) 1070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1071949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown int bytesToRead; 1072949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown 1073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pHeader->magic = read4LE(fp); 1074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pHeader->version = read2LE(fp); 1075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pHeader->offsetToData = read2LE(fp); 1076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pHeader->startWhen = read8LE(fp); 1077949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown bytesToRead = pHeader->offsetToData - 16; 1078949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown if (pHeader->version == 1) { 1079949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown pHeader->recordSize = 9; 1080949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown } else if (pHeader->version == 2) { 1081949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown pHeader->recordSize = 10; 1082949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown } else if (pHeader->version == 3) { 1083949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown pHeader->recordSize = read2LE(fp); 1084949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown bytesToRead -= 2; 1085949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown } else { 1086949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown fprintf(stderr, "Unsupported trace file version: %d\n", pHeader->version); 1087949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown return -1; 1088949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown } 1089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1090949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown if (fseek(fp, bytesToRead, SEEK_CUR) != 0) { 1091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 1092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 1095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 10987b522639a499f63ccb5162576830d0c20539bd05Andy McFadden * Look up a method by it's method ID. 1099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 1100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns NULL if no matching method was found. 1101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectMethodEntry* lookupMethod(DataKeys* pKeys, unsigned int methodId) 1103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int hi, lo, mid; 1105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int id; 1106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lo = 0; 1108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hi = pKeys->numMethods - 1; 1109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (hi >= lo) { 1111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mid = (hi + lo) / 2; 1112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id = pKeys->methods[mid].methodId; 11147b522639a499f63ccb5162576830d0c20539bd05Andy McFadden if (id == methodId) /* match */ 11157b522639a499f63ccb5162576830d0c20539bd05Andy McFadden return &pKeys->methods[mid]; 11167b522639a499f63ccb5162576830d0c20539bd05Andy McFadden else if (id < methodId) /* too low */ 1117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lo = mid + 1; 1118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else /* too high */ 1119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project hi = mid - 1; 1120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Reads the next data record, and assigns the data values to threadId, 1127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * methodVal and elapsedTime. On end-of-file, the threadId, methodVal, 1128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * and elapsedTime are unchanged. Returns 1 on end-of-file, otherwise 1129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * returns 0. 1130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1131949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brownint readDataRecord(FILE *dataFp, DataHeader* dataHeader, 1132949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown int *threadId, unsigned int *methodVal, uint64_t *elapsedTime) 1133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int id; 1135949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown int bytesToRead; 1136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1137949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown bytesToRead = dataHeader->recordSize; 1138949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown if (dataHeader->version == 1) { 1139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id = getc(dataFp); 1140949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown bytesToRead -= 1; 1141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project id = read2LE(dataFp); 1143949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown bytesToRead -= 2; 1144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (id == EOF) 1146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 1147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *threadId = id; 1148de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *methodVal = read4LE(dataFp); 1150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *elapsedTime = read4LE(dataFp); 1151949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown bytesToRead -= 8; 1152949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown 1153949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown while (bytesToRead-- > 0) { 1154949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown getc(dataFp); 1155949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown } 1156949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown 1157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (feof(dataFp)) { 1158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "WARNING: hit EOF mid-record\n"); 1159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 1160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 1162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 1165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Read the key file and use it to produce formatted output from the 1166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * data file. 1167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dumpTrace() 1169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project static const char* actionStr[] = { "ent", "xit", "unr", "???" }; 1171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry bogusMethod = { 0, "???", "???", "???", "???", -1, 0, 0, 0, 0, 1172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project {NULL, NULL}, {NULL, NULL}, {0, 0}, 0, 0, -1 }; 1173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char bogusBuf[80]; 1174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char spaces[MAX_STACK_DEPTH+1]; 1175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FILE* dataFp = NULL; 1176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DataHeader dataHeader; 1177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DataKeys* pKeys = NULL; 1178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 1179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TraceData traceData; 1180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf("Dumping '%s' '%s'\n", dataFileName, keyFileName); 1182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(spaces, '.', MAX_STACK_DEPTH); 1184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project spaces[MAX_STACK_DEPTH] = '\0'; 1185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < MAX_THREADS; i++) 1187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData.depth[i] = 2; // adjust for return from start function 1188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataFp = fopen(gOptions.traceFileName, "r"); 1190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dataFp == NULL) 1191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((pKeys = parseKeys(dataFp, 1)) == NULL) 1194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (parseDataHeader(dataFp, &dataHeader) < 0) 1197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 1198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Trace (threadID action usecs class.method signature):\n"); 1200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (1) { 1202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method; 1203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int threadId; 1204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int methodVal; 1205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsedTime; 1206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int action, printDepth; 1207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int methodId, lastEnter = 0; 1208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int mismatch = 0; 1209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char depthNote; 1210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract values from file. 1213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1214949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown if (readDataRecord(dataFp, &dataHeader, &threadId, &methodVal, &elapsedTime)) 1215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project action = METHOD_ACTION(methodVal); 1218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodId = METHOD_ID(methodVal); 1219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 1221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Generate a line of output. 1222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (action == METHOD_TRACE_ENTER) { 1224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData.depth[threadId]++; 1225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lastEnter = methodId; 1226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* quick test for mismatched adjacent enter/exit */ 1228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (lastEnter != 0 && lastEnter != methodId) 1229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mismatch = 1; 1230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printDepth = traceData.depth[threadId]; 1233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project depthNote = ' '; 1234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (printDepth < 0) { 1235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printDepth = 0; 1236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project depthNote = '-'; 1237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (printDepth > MAX_STACK_DEPTH) { 1238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printDepth = MAX_STACK_DEPTH; 1239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project depthNote = '+'; 1240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = lookupMethod(pKeys, methodId); 1243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method == NULL) { 1244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = &bogusMethod; 1245291c84f60853d30e1c0d79dd08c5e5164f588e26Dan Bornstein sprintf(bogusBuf, "methodId: %#x", methodId); 1246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->signature = bogusBuf; 1247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->methodName) { 1250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%2d %s%c %8lld%c%s%s.%s %s\n", threadId, 1251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actionStr[action], mismatch ? '!' : ' ', 1252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsedTime, depthNote, 1253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project spaces + (MAX_STACK_DEPTH - printDepth), 1254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->className, method->methodName, method->signature); 1255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%2d %s%c %8lld%c%s%s\n", threadId, 1257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actionStr[action], mismatch ? '!' : ' ', 1258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsedTime, depthNote, 1259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project spaces + (MAX_STACK_DEPTH - printDepth), 1260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->className); 1261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (action != METHOD_TRACE_ENTER) { 1264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData.depth[threadId]--; /* METHOD_TRACE_EXIT or METHOD_TRACE_UNROLL */ 1265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project lastEnter = 0; 1266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project mismatch = 0; 1269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 1272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dataFp != NULL) 1273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fclose(dataFp); 1274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pKeys != NULL) 1275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project freeDataKeys(pKeys); 1276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* This routine adds the given time to the parent and child methods. 1279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is called when the child routine exits, after the child has 1280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * been popped from the stack. The elapsedTime parameter is the 1281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * duration of the child routine, including time spent in called routines. 1282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid addInclusiveTime(MethodEntry *parent, MethodEntry *child, 1284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsedTime) 1285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod *pTimed; 1287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 1289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool verbose = false; 1290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(child->className, debugClassName) == 0) 1291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project verbose = true; 1292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 1293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int childIsRecursive = (child->recursiveEntries > 0); 1295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int parentIsRecursive = (parent->recursiveEntries > 1); 1296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (child->recursiveEntries == 0) { 1298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project child->elapsedInclusive += elapsedTime; 1299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (child->recursiveEntries == 1) { 1300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project child->recursiveInclusive += elapsedTime; 1301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project child->numCalls[childIsRecursive] += 1; 1303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 1305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (verbose) { 1306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, 1307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "%s %d elapsedTime: %lld eI: %lld, rI: %lld\n", 1308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project child->className, child->recursiveEntries, 1309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project elapsedTime, child->elapsedInclusive, 1310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project child->recursiveInclusive); 1311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 1313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Find the child method in the parent */ 1315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod *children = parent->children[parentIsRecursive]; 1316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (pTimed = children; pTimed; pTimed = pTimed->next) { 1317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pTimed->method == child) { 1318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive += elapsedTime; 1319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->numCalls += 1; 1320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pTimed == NULL) { 1324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Allocate a new TimedMethod */ 1325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed = (TimedMethod *) malloc(sizeof(TimedMethod)); 1326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive = elapsedTime; 1327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->numCalls = 1; 1328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->method = child; 1329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Add it to the front of the list */ 1331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->next = children; 1332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parent->children[parentIsRecursive] = pTimed; 1333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Find the parent method in the child */ 1336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod *parents = child->parents[childIsRecursive]; 1337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (pTimed = parents; pTimed; pTimed = pTimed->next) { 1338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pTimed->method == parent) { 1339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive += elapsedTime; 1340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->numCalls += 1; 1341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pTimed == NULL) { 1345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Allocate a new TimedMethod */ 1346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed = (TimedMethod *) malloc(sizeof(TimedMethod)); 1347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive = elapsedTime; 1348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->numCalls = 1; 1349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->method = parent; 1350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Add it to the front of the list */ 1352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->next = parents; 1353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project child->parents[childIsRecursive] = pTimed; 1354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 1357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (verbose) { 1358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, 1359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project " %s %d eI: %lld\n", 1360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project parent->className, parent->recursiveEntries, 1361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive); 1362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 1364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Sorts a linked list and returns a newly allocated array containing 1367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the sorted entries. 1368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectTimedMethod *sortTimedMethodList(TimedMethod *list, int *num) 1370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 1372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod *pTimed, *sorted; 1373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Count the elements */ 1375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int num_entries = 0; 1376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (pTimed = list; pTimed; pTimed = pTimed->next) 1377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project num_entries += 1; 1378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *num = num_entries; 1379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (num_entries == 0) 1380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 1381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Copy all the list elements to a new array and sort them */ 1383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sorted = (TimedMethod *) malloc(sizeof(TimedMethod) * num_entries); 1384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0, pTimed = list; pTimed; pTimed = pTimed->next, ++ii) 1385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memcpy(&sorted[ii], pTimed, sizeof(TimedMethod)); 1386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(sorted, num_entries, sizeof(TimedMethod), compareTimedMethod); 1387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Fix up the "next" pointers so that they work. */ 1389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < num_entries - 1; ++ii) 1390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sorted[ii].next = &sorted[ii + 1]; 1391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sorted[num_entries - 1].next = NULL; 1392de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return sorted; 1394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Define flag values for printInclusiveMethod() */ 1397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const int kIsRecursive = 1; 1398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* This prints the inclusive stats for all the parents or children of a 1400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method, depending on the list that is passed in. 1401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid printInclusiveMethod(MethodEntry *method, TimedMethod *list, int numCalls, 1403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int flags) 1404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int num; 1406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod *pTimed; 1407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buf[80]; 1408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *anchor_close; 1409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *spaces = " "; /* 6 spaces */ 1410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int num_spaces = strlen(spaces); 1411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *space_ptr = &spaces[num_spaces]; 1412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *className, *methodName, *signature; 1413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char classBuf[HTML_BUFSIZE], methodBuf[HTML_BUFSIZE]; 1414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char signatureBuf[HTML_BUFSIZE]; 1415de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project anchor_close = ""; 1417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) 1418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project anchor_close = "</a>"; 1419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod *sorted = sortTimedMethodList(list, &num); 1421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double methodTotal = method->elapsedInclusive; 1422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (pTimed = sorted; pTimed; pTimed = pTimed->next) { 1423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry *relative = pTimed->method; 1424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = (char*)(relative->className); 1425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = (char*)(relative->methodName); 1426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = (char*)(relative->signature); 1427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double per = 100.0 * pTimed->elapsedInclusive / methodTotal; 1428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "[%d]", relative->index); 1429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len = strlen(buf); 1431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (len > num_spaces) 1432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project len = num_spaces; 1433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "<a href=\"#m%d\">[%d]", 1434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project relative->index, relative->index); 1435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project space_ptr = &spaces[len]; 1436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = htmlEscape(className, classBuf, HTML_BUFSIZE); 1437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = htmlEscape(methodName, methodBuf, HTML_BUFSIZE); 1438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = htmlEscape(signature, signatureBuf, HTML_BUFSIZE); 1439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nCalls = numCalls; 1441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (nCalls == 0) 1442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nCalls = relative->numCalls[0] + relative->numCalls[1]; 1443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (relative->methodName) { 1444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (flags & kIsRecursive) { 1445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Don't display percentages for recursive functions 1446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%6s %5s %6s %s%6s%s %6d/%-6d %9llu %s.%s %s\n", 1447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "", "", "", 1448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project space_ptr, buf, anchor_close, 1449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->numCalls, nCalls, 1450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive, 1451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className, methodName, signature); 1452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%6s %5s %5.1f%% %s%6s%s %6d/%-6d %9llu %s.%s %s\n", 1454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "", "", per, 1455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project space_ptr, buf, anchor_close, 1456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->numCalls, nCalls, 1457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive, 1458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className, methodName, signature); 1459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (flags & kIsRecursive) { 1462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Don't display percentages for recursive functions 1463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%6s %5s %6s %s%6s%s %6d/%-6d %9llu %s\n", 1464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "", "", "", 1465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project space_ptr, buf, anchor_close, 1466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->numCalls, nCalls, 1467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive, 1468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className); 1469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%6s %5s %5.1f%% %s%6s%s %6d/%-6d %9llu %s\n", 1471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "", "", per, 1472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project space_ptr, buf, anchor_close, 1473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->numCalls, nCalls, 1474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pTimed->elapsedInclusive, 1475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className); 1476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid countRecursiveEntries(CallStack *pStack, int top, MethodEntry *method) 1482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 1484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->recursiveEntries = 0; 1486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < top; ++ii) { 1487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pStack->calls[ii].method == method) 1488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->recursiveEntries += 1; 1489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid stackDump(CallStack *pStack, int top) 1493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 1495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < top; ++ii) { 1497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry *method = pStack->calls[ii].method; 1498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t entryTime = pStack->calls[ii].entryTime; 1499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->methodName) { 1500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " %2d: %8llu %s.%s %s\n", ii, entryTime, 1501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->className, method->methodName, method->signature); 1502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " %2d: %8llu %s\n", ii, entryTime, method->className); 1504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid outputTableOfContents() 1509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a name=\"contents\"></a>\n"); 1511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<h2>Table of Contents</h2>\n"); 1512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<ul>\n"); 1513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" <li><a href=\"#exclusive\">Exclusive profile</a></li>\n"); 1514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" <li><a href=\"#inclusive\">Inclusive profile</a></li>\n"); 1515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" <li><a href=\"#class\">Class/method profile</a></li>\n"); 1516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" <li><a href=\"#method\">Method/class profile</a></li>\n"); 1517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</ul>\n\n"); 1518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid outputNavigationBar() 1521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a href=\"#contents\">[Top]</a>\n"); 1523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a href=\"#exclusive\">[Exclusive]</a>\n"); 1524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a href=\"#inclusive\">[Inclusive]</a>\n"); 1525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a href=\"#class\">[Class]</a>\n"); 1526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a href=\"#method\">[Method]</a>\n"); 1527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<br><br>\n"); 1528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid printExclusiveProfile(MethodEntry **pMethods, int numMethods, 1531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t sumThreadTime) 1532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 1534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method; 1535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double total, sum, per, sum_per; 1536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char classBuf[HTML_BUFSIZE], methodBuf[HTML_BUFSIZE]; 1537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char signatureBuf[HTML_BUFSIZE]; 1538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char anchor_buf[80]; 1539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *anchor_close = ""; 1540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project total = sumThreadTime; 1542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project anchor_buf[0] = 0; 1543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project anchor_close = "</a>"; 1545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a name=\"exclusive\"></a>\n"); 1546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<hr>\n"); 1547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outputNavigationBar(); 1548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("\n%s\n", profileSeparator); 1550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* First, sort the methods into decreasing order of inclusive 1553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * elapsed time so that we can assign the method indices. 1554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pMethods, numMethods, sizeof(MethodEntry*), compareElapsedInclusive); 1556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) 1558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMethods[ii]->index = ii; 1559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort the methods into decreasing order of exclusive elapsed time. 1561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pMethods, numMethods, sizeof(MethodEntry*), 1563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project compareElapsedExclusive); 1564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Total cycles: %llu\n\n", sumThreadTime); 1566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<br><br>\n"); 1568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Exclusive elapsed times for each method, not including time spent in\n"); 1570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("children, sorted by exclusive time.\n\n"); 1571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<br><br>\n<pre>\n"); 1573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" Usecs self %% sum %% Method\n"); 1576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum = 0; 1577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) { 1579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *className, *methodName, *signature; 1580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = pMethods[ii]; 1582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Don't show methods with zero cycles */ 1583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->elapsedExclusive == 0) 1584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = (char*)(method->className); 1586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = (char*)(method->methodName); 1587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = (char*)(method->signature); 1588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum += method->elapsedExclusive; 1589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per = 100.0 * method->elapsedExclusive / total; 1590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum_per = 100.0 * sum / total; 1591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(anchor_buf, "<a href=\"#m%d\">", method->index); 1593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = htmlEscape(className, classBuf, HTML_BUFSIZE); 1594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = htmlEscape(methodName, methodBuf, HTML_BUFSIZE); 1595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = htmlEscape(signature, signatureBuf, HTML_BUFSIZE); 1596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->methodName) { 1598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%9llu %6.2f %6.2f %s[%d]%s %s.%s %s\n", 1599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedExclusive, per, sum_per, 1600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project anchor_buf, method->index, anchor_close, 1601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className, methodName, signature); 1602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%9llu %6.2f %6.2f %s[%d]%s %s\n", 1604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedExclusive, per, sum_per, 1605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project anchor_buf, method->index, anchor_close, 1606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className); 1607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</pre>\n"); 1611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* check to make sure that the child method meets the threshold of the parent */ 1615de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiroint checkThreshold(MethodEntry* parent, MethodEntry* child) 1616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double parentTime = parent->elapsedInclusive; 1618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double childTime = child->elapsedInclusive; 1619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int64_t percentage = (childTime / parentTime) * 100.0; 1620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return (percentage < gOptions.threshold) ? 0 : 1; 1621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid createLabels(FILE* file, MethodEntry* method) 1624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1625de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro fprintf(file, "node%d[label = \"[%d] %s.%s (%llu, %llu, %d)\"]\n", 1626de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro method->index, method->index, method->className, method->methodName, 1627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedInclusive / 1000, 1628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedExclusive / 1000, 1629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->numCalls[0]); 1630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1631de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro method->graphState = GRAPH_LABEL_VISITED; 1632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod* child; 1634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (child = method->children[0] ; child ; child = child->next) { 1635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* childMethod = child->method; 1636de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((childMethod->graphState & GRAPH_LABEL_VISITED) == 0 && checkThreshold(method, childMethod)) { 1638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createLabels(file, child->method); 1639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid createLinks(FILE* file, MethodEntry* method) 1644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->graphState |= GRAPH_NODE_VISITED; 1646de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod* child; 1648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (child = method->children[0] ; child ; child = child->next) { 1649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* childMethod = child->method; 1650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (checkThreshold(method, child->method)) { 1651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(file, "node%d -> node%d\n", method->index, child->method->index); 1652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // only visit children that haven't been visited before 1653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((childMethod->graphState & GRAPH_NODE_VISITED) == 0) { 1654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createLinks(file, child->method); 1655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid createInclusiveProfileGraphNew(DataKeys* dataKeys) 1661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // create a temporary file in /tmp 1663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char path[FILENAME_MAX]; 1664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.keepDotFile) { 1665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project snprintf(path, FILENAME_MAX, "%s.dot", gOptions.graphFileName); 1666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project snprintf(path, FILENAME_MAX, "/tmp/dot-%d-%d.dot", (int)time(NULL), rand()); 1668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FILE* file = fopen(path, "w+"); 1671de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(file, "digraph g {\nnode [shape = record,height=.1];\n"); 1673de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createLabels(file, dataKeys->methods); 1675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createLinks(file, dataKeys->methods); 1676de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(file, "}"); 1678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fclose(file); 1679de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // now that we have the dot file generate the image 1681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char command[1024]; 1682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project snprintf(command, 1024, "dot -Tpng -o '%s' '%s'", gOptions.graphFileName, path); 1683de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 1684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project system(command); 1685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (! gOptions.keepDotFile) { 1687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project remove(path); 1688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid printInclusiveProfile(MethodEntry **pMethods, int numMethods, 1692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t sumThreadTime) 1693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 1695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method; 1696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double total, sum, per, sum_per; 1697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char classBuf[HTML_BUFSIZE], methodBuf[HTML_BUFSIZE]; 1698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char signatureBuf[HTML_BUFSIZE]; 1699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char anchor_buf[80]; 17007b522639a499f63ccb5162576830d0c20539bd05Andy McFadden char *anchor_close = ""; 1701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project total = sumThreadTime; 1703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project anchor_buf[0] = 0; 1704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 17057b522639a499f63ccb5162576830d0c20539bd05Andy McFadden anchor_close = "</a>"; 1706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a name=\"inclusive\"></a>\n"); 1707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<hr>\n"); 1708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outputNavigationBar(); 1709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("\n%s\n", profileSeparator); 1711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort the methods into decreasing order of inclusive elapsed time. */ 1714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pMethods, numMethods, sizeof(MethodEntry*), 1715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project compareElapsedInclusive); 1716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("\nInclusive elapsed times for each method and its parents and children,\n"); 1718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("sorted by inclusive time.\n\n"); 1719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<br><br>\n<pre>\n"); 1722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("index %%/total %%/self index calls usecs name\n"); 1725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) { 1726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int num; 1727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TimedMethod *pTimed; 1728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double excl_per; 1729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buf[40]; 1730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *className, *methodName, *signature; 1731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = pMethods[ii]; 1733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Don't show methods with zero cycles */ 1734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->elapsedInclusive == 0) 1735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = (char*)(method->className); 1738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = (char*)(method->methodName); 1739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = (char*)(method->signature); 1740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a name=\"m%d\"></a>", method->index); 1743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = htmlEscape(className, classBuf, HTML_BUFSIZE); 1744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = htmlEscape(methodName, methodBuf, HTML_BUFSIZE); 1745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = htmlEscape(signature, signatureBuf, HTML_BUFSIZE); 1746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("----------------------------------------------------\n"); 1748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort and print the parents */ 1750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numCalls = method->numCalls[0] + method->numCalls[1]; 1751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printInclusiveMethod(method, method->parents[0], numCalls, 0); 1752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->parents[1]) { 1753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" +++++++++++++++++++++++++\n"); 1754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printInclusiveMethod(method, method->parents[1], numCalls, 1755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kIsRecursive); 1756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per = 100.0 * method->elapsedInclusive / total; 1759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "[%d]", ii); 1760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->methodName) { 1761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%-6s %5.1f%% %5s %6s %6d+%-6d %9llu %s.%s %s\n", 1762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf, 1763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per, "", "", method->numCalls[0], method->numCalls[1], 1764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedInclusive, 1765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className, methodName, signature); 1766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%-6s %5.1f%% %5s %6s %6d+%-6d %9llu %s\n", 1768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project buf, 1769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per, "", "", method->numCalls[0], method->numCalls[1], 1770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedInclusive, 1771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className); 1772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project excl_per = 100.0 * method->topExclusive / method->elapsedInclusive; 1774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%6s %5s %5.1f%% %6s %6s %6s %9llu\n", 1775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "", "", excl_per, "excl", "", "", method->topExclusive); 1776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort and print the children */ 1778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printInclusiveMethod(method, method->children[0], 0, 0); 1779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->children[1]) { 1780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" +++++++++++++++++++++++++\n"); 1781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printInclusiveMethod(method, method->children[1], 0, 1782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project kIsRecursive); 1783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</pre>\n"); 1787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid createClassList(TraceData* traceData, MethodEntry **pMethods, int numMethods) 1791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 1793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort the methods into alphabetical order to find the unique class 1795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * names. 1796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pMethods, numMethods, sizeof(MethodEntry*), compareClassNames); 1798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Count the number of unique class names. */ 1800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char *currentClassName = ""; 1801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char *firstClassName = NULL; 1802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData->numClasses = 0; 1803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) { 1804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMethods[ii]->methodName == NULL) { 1805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 1806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(pMethods[ii]->className, currentClassName) != 0) { 1808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Remember the first one 1809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (firstClassName == NULL) { 1810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project firstClassName = pMethods[ii]->className; 1811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData->numClasses += 1; 1813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentClassName = pMethods[ii]->className; 1814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (traceData->numClasses == 0) { 1818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData->classes = NULL; 1819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 1820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Allocate space for all of the unique class names */ 1823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData->classes = (ClassEntry *) malloc(sizeof(ClassEntry) * traceData->numClasses); 1824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Initialize the classes array */ 1826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(traceData->classes, 0, sizeof(ClassEntry) * traceData->numClasses); 1827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassEntry *pClass = traceData->classes; 1828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->className = currentClassName = firstClassName; 1829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int prevNumMethods = 0; 1830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) { 1831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMethods[ii]->methodName == NULL) { 1832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 1833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(pMethods[ii]->className, currentClassName) != 0) { 1835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->numMethods = prevNumMethods; 1836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project (++pClass)->className = currentClassName = pMethods[ii]->className; 1837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project prevNumMethods = 0; 1838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project prevNumMethods += 1; 1840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->numMethods = prevNumMethods; 1842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Create the array of MethodEntry pointers for each class */ 1844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass = NULL; 1845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentClassName = ""; 1846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nextMethod = 0; 1847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) { 1848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMethods[ii]->methodName == NULL) { 1849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 1850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(pMethods[ii]->className, currentClassName) != 0) { 1852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentClassName = pMethods[ii]->className; 1853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pClass == NULL) 1854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass = traceData->classes; 1855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 1856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass++; 1857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Allocate space for the methods array */ 1858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nbytes = sizeof(MethodEntry*) * pClass->numMethods; 1859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->methods = (MethodEntry**) malloc(nbytes); 1860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextMethod = 0; 1861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->methods[nextMethod++] = pMethods[ii]; 1863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Prints a number of html non-breaking spaces according so that the length 1867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of the string "buf" is at least "width" characters wide. If width is 1868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * negative, then trailing spaces are added instead of leading spaces. 1869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid printHtmlField(char *buf, int width) 1871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 1873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int leadingSpaces = 1; 1875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (width < 0) { 1876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project width = -width; 1877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project leadingSpaces = 0; 1878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int len = strlen(buf); 1880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numSpaces = width - len; 1881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (numSpaces <= 0) { 1882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s", buf); 1883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 1884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (leadingSpaces == 0) 1886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s", buf); 1887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numSpaces; ++ii) 1888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 1889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (leadingSpaces == 1) 1890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s", buf); 1891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 1892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid printClassProfiles(TraceData* traceData, uint64_t sumThreadTime) 1894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 1895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii, jj; 1896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method; 1897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double total, sum, per, sum_per; 1898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char classBuf[HTML_BUFSIZE], methodBuf[HTML_BUFSIZE]; 1899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char signatureBuf[HTML_BUFSIZE]; 1900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project total = sumThreadTime; 1902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a name=\"class\"></a>\n"); 1904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<hr>\n"); 1905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outputNavigationBar(); 1906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("\n%s\n", profileSeparator); 1908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (traceData->numClasses == 0) { 1911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("\nNo classes.\n"); 1912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<br><br>\n"); 1914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 1916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("\nExclusive elapsed time for each class, summed over all the methods\n"); 1919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("in the class.\n\n"); 1920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<br><br>\n"); 1922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* For each class, sum the exclusive times in all of the methods 1925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in that class. Also sum the number of method calls. Also 1926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sort the methods so the most expensive appear at the top. 1927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassEntry *pClass = traceData->classes; 1929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < traceData->numClasses; ++ii, ++pClass) { 1930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project //printf("%s %d methods\n", pClass->className, pClass->numMethods); 1931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numMethods = pClass->numMethods; 1932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (jj = 0; jj < numMethods; ++jj) { 1933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = pClass->methods[jj]; 1934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->elapsedExclusive += method->elapsedExclusive; 1935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->numCalls[0] += method->numCalls[0]; 1936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->numCalls[1] += method->numCalls[1]; 1937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort the methods into decreasing order of exclusive time */ 1940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pClass->methods, numMethods, sizeof(MethodEntry*), 1941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project compareElapsedExclusive); 1942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Allocate an array of pointers to the classes for more efficient 1945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sorting. 1946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ClassEntry **pClasses; 1948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClasses = (ClassEntry**) malloc(sizeof(ClassEntry*) * traceData->numClasses); 1949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < traceData->numClasses; ++ii) 1950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClasses[ii] = &traceData->classes[ii]; 1951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort the classes into decreasing order of exclusive time */ 1953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pClasses, traceData->numClasses, sizeof(ClassEntry*), compareClassExclusive); 1954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<div class=\"header\"><span class=\"parent\"> </span> "); 1957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Cycles %%/total Cumul.%% Calls+Recur Class</div>\n"); 1958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" Cycles %%/total Cumul.%% Calls+Recur Class\n"); 1960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum = 0; 1963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < traceData->numClasses; ++ii) { 1964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *className, *methodName, *signature; 1965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Skip classes with zero cycles */ 1967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass = pClasses[ii]; 1968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pClass->elapsedExclusive == 0) 1969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 1970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per = 100.0 * pClass->elapsedExclusive / total; 1972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum += pClass->elapsedExclusive; 1973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum_per = 100.0 * sum / total; 1974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = (char*)(pClass->className); 1975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 1976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buf[80]; 1977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = htmlEscape(className, classBuf, HTML_BUFSIZE); 1979f6c387128427e121477c1b32ad35cdcaa5101ba3The 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); 1980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%llu", pClass->elapsedExclusive); 1981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 9); 1982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 1983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%.1f", per); 1984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 7); 1985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 1986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%.1f", sum_per); 1987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 7); 1988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 1989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%d", pClass->numCalls[0]); 1990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 6); 1991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("+"); 1992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%d", pClass->numCalls[1]); 1993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, -6); 1994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 1995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s", className); 1996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</div>\n"); 1997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<div class=\"parent\" id=\"d%d\">\n", ii); 1998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 1999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("---------------------------------------------\n"); 2000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%9llu %7.1f %7.1f %6d+%-6d %s\n", 2001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->elapsedExclusive, per, sum_per, 2002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pClass->numCalls[0], pClass->numCalls[1], 2003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className); 2004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numMethods = pClass->numMethods; 2007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double classExclusive = pClass->elapsedExclusive; 2008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double sumMethods = 0; 2009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (jj = 0; jj < numMethods; ++jj) { 2010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = pClass->methods[jj]; 2011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = (char*)(method->methodName); 2012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = (char*)(method->signature); 2013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per = 100.0 * method->elapsedExclusive / classExclusive; 2014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sumMethods += method->elapsedExclusive; 2015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum_per = 100.0 * sumMethods / classExclusive; 2016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buf[80]; 2018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = htmlEscape(methodName, methodBuf, HTML_BUFSIZE); 2020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = htmlEscape(signature, signatureBuf, HTML_BUFSIZE); 2021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<div class=\"leaf\"><span class=\"leaf\"> </span>"); 2022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%llu", method->elapsedExclusive); 2023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 9); 2024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%llu", method->elapsedInclusive); 2026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 9); 2027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%.1f", per); 2029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 7); 2030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%.1f", sum_per); 2032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 7); 2033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%d", method->numCalls[0]); 2035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 6); 2036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("+"); 2037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%d", method->numCalls[1]); 2038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, -6); 2039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a href=\"#m%d\">[%d]</a> %s %s", 2041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->index, method->index, methodName, signature); 2042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</div>\n"); 2043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%9llu %9llu %7.1f %7.1f %6d+%-6d [%d] %s %s\n", 2045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedExclusive, 2046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedInclusive, 2047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per, sum_per, 2048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->numCalls[0], method->numCalls[1], 2049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->index, methodName, signature); 2050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</div>\n"); 2054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid createUniqueMethodList(TraceData* traceData, MethodEntry **pMethods, int numMethods) 2059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 2061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort the methods into alphabetical order of method names 2063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to find the unique method names. 2064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pMethods, numMethods, sizeof(MethodEntry*), compareMethodNames); 2066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Count the number of unique method names, ignoring class and 2068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * signature. 2069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char *currentMethodName = ""; 2071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData->numUniqueMethods = 0; 2072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) { 2073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMethods[ii]->methodName == NULL) 2074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 2075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(pMethods[ii]->methodName, currentMethodName) != 0) { 2076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData->numUniqueMethods += 1; 2077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentMethodName = pMethods[ii]->methodName; 2078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (traceData->numUniqueMethods == 0) 2081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Allocate space for pointers to all of the unique methods */ 2084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nbytes = sizeof(UniqueMethodEntry) * traceData->numUniqueMethods; 2085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData->uniqueMethods = (UniqueMethodEntry *) malloc(nbytes); 2086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Initialize the uniqueMethods array */ 2088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(traceData->uniqueMethods, 0, nbytes); 2089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UniqueMethodEntry *pUnique = traceData->uniqueMethods; 2090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentMethodName = NULL; 2091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int prevNumMethods = 0; 2092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) { 2093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMethods[ii]->methodName == NULL) 2094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 2095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (currentMethodName == NULL) 2096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentMethodName = pMethods[ii]->methodName; 2097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(pMethods[ii]->methodName, currentMethodName) != 0) { 2098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentMethodName = pMethods[ii]->methodName; 2099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->numMethods = prevNumMethods; 2100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique++; 2101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project prevNumMethods = 0; 2102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project prevNumMethods += 1; 2104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->numMethods = prevNumMethods; 2106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Create the array of MethodEntry pointers for each unique method */ 2108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique = NULL; 2109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentMethodName = ""; 2110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nextMethod = 0; 2111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < numMethods; ++ii) { 2112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pMethods[ii]->methodName == NULL) 2113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 2114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (strcmp(pMethods[ii]->methodName, currentMethodName) != 0) { 2115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentMethodName = pMethods[ii]->methodName; 2116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pUnique == NULL) 2117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique = traceData->uniqueMethods; 2118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique++; 2120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Allocate space for the methods array */ 2121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nbytes = sizeof(MethodEntry*) * pUnique->numMethods; 2122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->methods = (MethodEntry**) malloc(nbytes); 2123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project nextMethod = 0; 2124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->methods[nextMethod++] = pMethods[ii]; 2126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid printMethodProfiles(TraceData* traceData, uint64_t sumThreadTime) 2130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii, jj; 2132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method; 2133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double total, sum, per, sum_per; 2134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char classBuf[HTML_BUFSIZE], methodBuf[HTML_BUFSIZE]; 2135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char signatureBuf[HTML_BUFSIZE]; 2136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (traceData->numUniqueMethods == 0) 2138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 2139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project total = sumThreadTime; 2141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a name=\"method\"></a>\n"); 2143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<hr>\n"); 2144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outputNavigationBar(); 2145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("\n%s\n", profileSeparator); 2147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("\nExclusive elapsed time for each method, summed over all the classes\n"); 2150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("that contain a method with the same name.\n\n"); 2151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<br><br>\n"); 2153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* For each unique method, sum the exclusive times in all of the methods 2156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * with the same name. Also sum the number of method calls. Also 2157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sort the methods so the most expensive appear at the top. 2158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UniqueMethodEntry *pUnique = traceData->uniqueMethods; 2160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < traceData->numUniqueMethods; ++ii, ++pUnique) { 2161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numMethods = pUnique->numMethods; 2162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (jj = 0; jj < numMethods; ++jj) { 2163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = pUnique->methods[jj]; 2164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->elapsedExclusive += method->elapsedExclusive; 2165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->numCalls[0] += method->numCalls[0]; 2166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->numCalls[1] += method->numCalls[1]; 2167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort the methods into decreasing order of exclusive time */ 2170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pUnique->methods, numMethods, sizeof(MethodEntry*), 2171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project compareElapsedExclusive); 2172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Allocate an array of pointers to the methods for more efficient 2175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * sorting. 2176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project UniqueMethodEntry **pUniqueMethods; 2178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int nbytes = sizeof(UniqueMethodEntry*) * traceData->numUniqueMethods; 2179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUniqueMethods = (UniqueMethodEntry**) malloc(nbytes); 2180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < traceData->numUniqueMethods; ++ii) 2181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUniqueMethods[ii] = &traceData->uniqueMethods[ii]; 2182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Sort the methods into decreasing order of exclusive time */ 2184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(pUniqueMethods, traceData->numUniqueMethods, sizeof(UniqueMethodEntry*), 2185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project compareUniqueExclusive); 2186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<div class=\"header\"><span class=\"parent\"> </span> "); 2189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Cycles %%/total Cumul.%% Calls+Recur Method</div>\n"); 2190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" Cycles %%/total Cumul.%% Calls+Recur Method\n"); 2192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum = 0; 2195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < traceData->numUniqueMethods; ++ii) { 2196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char *className, *methodName, *signature; 2197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Skip methods with zero cycles */ 2199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique = pUniqueMethods[ii]; 2200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pUnique->elapsedExclusive == 0) 2201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per = 100.0 * pUnique->elapsedExclusive / total; 2204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum += pUnique->elapsedExclusive; 2205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum_per = 100.0 * sum / total; 2206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = (char*)(pUnique->methods[0]->methodName); 2207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buf[80]; 2209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = htmlEscape(methodName, methodBuf, HTML_BUFSIZE); 2211f6c387128427e121477c1b32ad35cdcaa5101ba3The 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); 2212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%llu", pUnique->elapsedExclusive); 2213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 9); 2214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%.1f", per); 2216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 7); 2217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%.1f", sum_per); 2219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 7); 2220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%d", pUnique->numCalls[0]); 2222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 6); 2223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("+"); 2224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%d", pUnique->numCalls[1]); 2225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, -6); 2226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s", methodName); 2228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</div>\n"); 2229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<div class=\"parent\" id=\"e%d\">\n", ii); 2230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("---------------------------------------------\n"); 2232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%9llu %7.1f %7.1f %6d+%-6d %s\n", 2233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->elapsedExclusive, per, sum_per, 2234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pUnique->numCalls[0], pUnique->numCalls[1], 2235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName); 2236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int numMethods = pUnique->numMethods; 2238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double methodExclusive = pUnique->elapsedExclusive; 2239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project double sumMethods = 0; 2240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (jj = 0; jj < numMethods; ++jj) { 2241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = pUnique->methods[jj]; 2242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = (char*)(method->className); 2243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = (char*)(method->signature); 2244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per = 100.0 * method->elapsedExclusive / methodExclusive; 2245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sumMethods += method->elapsedExclusive; 2246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sum_per = 100.0 * sumMethods / methodExclusive; 2247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buf[80]; 2249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = htmlEscape(className, classBuf, HTML_BUFSIZE); 2251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project signature = htmlEscape(signature, signatureBuf, HTML_BUFSIZE); 2252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<div class=\"leaf\"><span class=\"leaf\"> </span>"); 2253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%llu", method->elapsedExclusive); 2254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 9); 2255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%llu", method->elapsedInclusive); 2257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 9); 2258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%.1f", per); 2260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 7); 2261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%.1f", sum_per); 2263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 7); 2264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%d", method->numCalls[0]); 2266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, 6); 2267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("+"); 2268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project sprintf(buf, "%d", method->numCalls[1]); 2269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printHtmlField(buf, -6); 2270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(" "); 2271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a href=\"#m%d\">[%d]</a> %s.%s %s", 2272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->index, method->index, 2273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className, methodName, signature); 2274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</div>\n"); 2275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%9llu %9llu %7.1f %7.1f %6d+%-6d [%d] %s.%s %s\n", 2277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedExclusive, 2278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedInclusive, 2279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project per, sum_per, 2280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->numCalls[0], method->numCalls[1], 2281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->index, className, methodName, signature); 2282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</div>\n"); 2286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Read the key and data files and return the MethodEntries for those files 2292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 22937b522639a499f63ccb5162576830d0c20539bd05Andy McFaddenDataKeys* parseDataKeys(TraceData* traceData, const char* traceFileName, uint64_t* threadTime) 2294de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro{ 2295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DataKeys* dataKeys = NULL; 2296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry **pMethods = NULL; 2297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method; 2298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FILE* dataFp = NULL; 2299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DataHeader dataHeader; 23007b522639a499f63ccb5162576830d0c20539bd05Andy McFadden int ii; 2301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t currentTime; 2302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* caller; 2303de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dataFp = fopen(traceFileName, "r"); 2305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dataFp == NULL) 2306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if ((dataKeys = parseKeys(dataFp, 0)) == NULL) 23097b522639a499f63ccb5162576830d0c20539bd05Andy McFadden goto bail; 2310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (parseDataHeader(dataFp, &dataHeader) < 0) 2312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project goto bail; 2313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 2315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FILE *dumpStream = fopen("debug", "w"); 2316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 2317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (1) { 2318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int threadId; 2319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int methodVal; 2320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int action; 2321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project unsigned int methodId; 2322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CallStack *pStack; 2323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 2324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Extract values from file. 2325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2326949c3ec207a7720fb47f7b3ca1f84dfcfd70aaa9Jeff Brown if (readDataRecord(dataFp, &dataHeader, &threadId, &methodVal, ¤tTime)) 2327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 23286978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 2329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project action = METHOD_ACTION(methodVal); 2330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodId = METHOD_ID(methodVal); 2331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Get the call stack for this thread */ 2333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack = traceData->stacks[threadId]; 2334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If there is no call stack yet for this thread, then allocate one */ 2336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pStack == NULL) { 2337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack = malloc(sizeof(CallStack)); 2338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack->top = 0; 2339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack->lastEventTime = currentTime; 2340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack->threadStartTime = currentTime; 2341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project traceData->stacks[threadId] = pStack; 2342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Lookup the current method */ 2345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = lookupMethod(dataKeys, methodId); 2346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method == NULL) 2347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = &dataKeys->methods[UNKNOWN_INDEX]; 2348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 2350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->methodName) { 23517b522639a499f63ccb5162576830d0c20539bd05Andy McFadden fprintf(dumpStream, "%2d %-8llu %d %8llu r %d c %d %s.%s %s\n", 23527b522639a499f63ccb5162576830d0c20539bd05Andy McFadden threadId, currentTime, action, pStack->threadStartTime, 23537b522639a499f63ccb5162576830d0c20539bd05Andy McFadden method->recursiveEntries, 23547b522639a499f63ccb5162576830d0c20539bd05Andy McFadden pStack->top, method->className, method->methodName, 23557b522639a499f63ccb5162576830d0c20539bd05Andy McFadden method->signature); 2356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 23577b522639a499f63ccb5162576830d0c20539bd05Andy McFadden fprintf(dumpStream, "%2d %-8llu %d %8llu r %d c %d %s\n", 23587b522639a499f63ccb5162576830d0c20539bd05Andy McFadden threadId, currentTime, action, pStack->threadStartTime, 23597b522639a499f63ccb5162576830d0c20539bd05Andy McFadden method->recursiveEntries, 23607b522639a499f63ccb5162576830d0c20539bd05Andy McFadden pStack->top, method->className); 2361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 2363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (action == METHOD_TRACE_ENTER) { 2365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* This is a method entry */ 2366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pStack->top >= MAX_STACK_DEPTH) { 2367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "Stack overflow (exceeded %d frames)\n", 2368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MAX_STACK_DEPTH); 2369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exit(1); 2370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Get the caller method */ 2373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pStack->top >= 1) 2374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller = pStack->calls[pStack->top - 1].method; 2375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller = &dataKeys->methods[TOPLEVEL_INDEX]; 2377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project countRecursiveEntries(pStack, pStack->top, caller); 2378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller->elapsedExclusive += currentTime - pStack->lastEventTime; 2379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 2380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (caller->elapsedExclusive > 10000000) 2381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(dumpStream, "%llu current %llu last %llu diff %llu\n", 2382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller->elapsedExclusive, currentTime, 2383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack->lastEventTime, 2384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project currentTime - pStack->lastEventTime); 2385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 2386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (caller->recursiveEntries <= 1) { 2387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller->topExclusive += currentTime - pStack->lastEventTime; 2388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Push the method on the stack for this thread */ 2391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack->calls[pStack->top].method = method; 2392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack->calls[pStack->top++].entryTime = currentTime; 2393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* This is a method exit */ 2395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t entryTime = 0; 2396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Pop the method off the stack for this thread */ 2398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pStack->top > 0) { 2399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack->top -= 1; 2400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project entryTime = pStack->calls[pStack->top].entryTime; 2401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method != pStack->calls[pStack->top].method) { 2402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->methodName) { 2403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, 2404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Exit from method %s.%s %s does not match stack:\n", 2405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->className, method->methodName, 2406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->signature); 2407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, 2409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "Exit from method %s does not match stack:\n", 2410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->className); 2411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stackDump(pStack, pStack->top + 1); 2413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exit(1); 2414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Get the caller method */ 2418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pStack->top >= 1) 2419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller = pStack->calls[pStack->top - 1].method; 2420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller = &dataKeys->methods[TOPLEVEL_INDEX]; 2422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project countRecursiveEntries(pStack, pStack->top, caller); 2423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project countRecursiveEntries(pStack, pStack->top, method); 2424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsed = currentTime - entryTime; 2425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project addInclusiveTime(caller, method, elapsed); 2426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->elapsedExclusive += currentTime - pStack->lastEventTime; 2427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method->recursiveEntries == 0) { 2428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method->topExclusive += currentTime - pStack->lastEventTime; 2429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Remember the time of the last entry or exit event */ 2432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack->lastEventTime = currentTime; 2433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If we have calls on the stack when the trace ends, then clean 2436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * up the stack and add time to the callers by pretending that we 2437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * are exiting from their methods now. 2438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project CallStack *pStack; 2440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int threadId; 2441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t sumThreadTime = 0; 2442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (threadId = 0; threadId < MAX_THREADS; ++threadId) { 2443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pStack = traceData->stacks[threadId]; 2444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* If this thread never existed, then continue with next thread */ 2446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (pStack == NULL) 2447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project continue; 2448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 24497b522639a499f63ccb5162576830d0c20539bd05Andy McFadden /* Also, add up the time taken by all of the threads */ 24507b522639a499f63ccb5162576830d0c20539bd05Andy McFadden sumThreadTime += pStack->lastEventTime - pStack->threadStartTime; 24515b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 2452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < pStack->top; ++ii) { 2453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (ii == 0) 2454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller = &dataKeys->methods[TOPLEVEL_INDEX]; 2455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project else 2456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller = pStack->calls[ii - 1].method; 2457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project method = pStack->calls[ii].method; 2458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project countRecursiveEntries(pStack, ii, caller); 2459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project countRecursiveEntries(pStack, ii, method); 2460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t entryTime = pStack->calls[ii].entryTime; 2462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t elapsed = pStack->lastEventTime - entryTime; 2463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project addInclusiveTime(caller, method, elapsed); 2464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller = &dataKeys->methods[TOPLEVEL_INDEX]; 2467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project caller->elapsedInclusive = sumThreadTime; 2468de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if 0 2470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fclose(dumpStream); 2471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 2472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (threadTime != NULL) { 2474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *threadTime = sumThreadTime; 2475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbail: 2478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dataFp != NULL) 2479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fclose(dataFp); 2480de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return dataKeys; 2482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectMethodEntry** parseMethodEntries(DataKeys* dataKeys) 2485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int ii; 2487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* Create a new array of pointers to the methods and sort the pointers 2488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instead of the actual MethodEntry structs. We need to do this 2489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because there are other lists that contain pointers to the 2490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * MethodEntry structs. 2491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry** pMethods = (MethodEntry**) malloc(sizeof(MethodEntry*) * dataKeys->numMethods); 2493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (ii = 0; ii < dataKeys->numMethods; ++ii) { 2494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* entry = &dataKeys->methods[ii]; 2495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pMethods[ii] = entry; 2496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2497de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return pMethods; 2499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Produce a function profile from the following methods 2503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 25047b522639a499f63ccb5162576830d0c20539bd05Andy McFaddenvoid profileTrace(TraceData* traceData, MethodEntry **pMethods, int numMethods, uint64_t sumThreadTime) 2505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 25067b522639a499f63ccb5162576830d0c20539bd05Andy McFadden /* Print the html header, if necessary */ 2507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(htmlHeader, gOptions.sortableUrl); 2509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project outputTableOfContents(); 2510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printExclusiveProfile(pMethods, numMethods, sumThreadTime); 2513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printInclusiveProfile(pMethods, numMethods, sumThreadTime); 2514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createClassList(traceData, pMethods, numMethods); 2516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printClassProfiles(traceData, sumThreadTime); 2517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createUniqueMethodList(traceData, pMethods, numMethods); 2519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printMethodProfiles(traceData, sumThreadTime); 2520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s", htmlFooter); 2523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareMethodNamesForDiff(const void *a, const void *b) 2527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 2529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodA = *(const MethodEntry**)a; 2531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const MethodEntry *methodB = *(const MethodEntry**)b; 2532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methodA->methodName == NULL || methodB->methodName == NULL) { 2533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return compareClassNames(a, b); 2534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->methodName, methodB->methodName); 2536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 2537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project result = strcmp(methodA->signature, methodB->signature); 2538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (result == 0) { 2539de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro return strcmp(methodA->className, methodB->className); 2540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return result; 2543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint findMatch(MethodEntry** methods, int size, MethodEntry* matchThis) 2546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 2548de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0 ; i < size ; i++) { 2550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry* method = methods[i]; 2551de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (method != NULL && !compareMethodNamesForDiff(&method, &matchThis)) { 2553de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro// printf("%s.%s == %s.%s<br>\n", matchThis->className, matchThis->methodName, 2554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // method->className, method->methodName); 2555de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return i; 2557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* if (!compareMethodNames(&method, &matchThis)) { 2558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return i; 2559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/ } 2561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2562de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 2564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareDiffEntriesExculsive(const void *a, const void *b) 2567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 2569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DiffEntry* entryA = (const DiffEntry*)a; 2571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DiffEntry* entryB = (const DiffEntry*)b; 2572de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (entryA->differenceExclusive < entryB->differenceExclusive) { 2574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 2575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (entryA->differenceExclusive > entryB->differenceExclusive) { 2576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 2577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2578de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 2580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint compareDiffEntriesInculsive(const void *a, const void *b) 2583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int result; 2585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DiffEntry* entryA = (const DiffEntry*)a; 2587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const DiffEntry* entryB = (const DiffEntry*)b; 2588de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (entryA->differenceInclusive < entryB->differenceInclusive) { 2590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 2591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (entryA->differenceInclusive > entryB->differenceInclusive) { 2592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return -1; 2593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2594de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 2596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2598de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapirovoid printMissingMethod(MethodEntry* method) 2599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char classBuf[HTML_BUFSIZE]; 2601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char methodBuf[HTML_BUFSIZE]; 2602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* className; 2603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* methodName; 2604de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = htmlEscape(method->className, classBuf, HTML_BUFSIZE); 2606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = htmlEscape(method->methodName, methodBuf, HTML_BUFSIZE); 2607de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2608de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro if (gOptions.outputHtml) printf("<tr><td>\n"); 2609de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s.%s ", className, methodName); 2611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 2612de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%lld ", method->elapsedExclusive); 2614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 2615de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%lld ", method->elapsedInclusive); 2617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 2618de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%d\n", method->numCalls[0]); 2620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>\n"); 2621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid createDiff(DataKeys* d1, uint64_t sum1, DataKeys* d2, uint64_t sum2) 2625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry** methods1 = parseMethodEntries(d1); 2627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry** methods2 = parseMethodEntries(d2); 2628de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2629de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro // sort and assign the indicies 2630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i; 2631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(methods1, d1->numMethods, sizeof(MethodEntry*), compareElapsedInclusive); 2632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < d1->numMethods; ++i) { 2633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methods1[i]->index = i; 2634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(methods2, d2->numMethods, sizeof(MethodEntry*), compareElapsedInclusive); 2637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < d2->numMethods; ++i) { 2638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methods2[i]->index = i; 2639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2640de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int max = (d1->numMethods < d2->numMethods) ? d2->numMethods : d1->numMethods; 2642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project max++; 2643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DiffEntry* diffs = (DiffEntry*)malloc(max * sizeof(DiffEntry)); 2644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memset(diffs, 0, max * sizeof(DiffEntry)); 2645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DiffEntry* ptr = diffs; 2646de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// printf("<br>d1->numMethods: %d d1->numMethods: %d<br>\n", d1->numMethods, d2->numMethods); 2648de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int matches = 0; 2650de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0 ; i < d1->numMethods ; i++) { 2652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int match = findMatch(methods2, d2->numMethods, methods1[i]); 2653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (match >= 0) { 2654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr->method1 = methods1[i]; 2655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr->method2 = methods2[match]; 2656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t e1 = ptr->method1->elapsedExclusive; 2658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t e2 = ptr->method2->elapsedExclusive; 2659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (e1 > 0) { 2660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr->differenceExclusive = e2 - e1; 2661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr->differenceExclusivePercentage = ((double)e2 / (double)e1) * 100.0; 2662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t i1 = ptr->method1->elapsedInclusive; 2665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t i2 = ptr->method2->elapsedInclusive; 2666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (i1 > 0) { 2667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr->differenceInclusive = i2 - i1; 2668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr->differenceInclusivePercentage = ((double)i2 / (double)i1) * 100.0; 2669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2670de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // clear these out so we don't find them again and we know which ones 2672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // we have left over 2673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methods1[i] = NULL; 2674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methods2[match] = NULL; 2675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr++; 2676de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project matches++; 2678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr->method1 = NULL; 2681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr->method2 = NULL; 2682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(diffs, matches, sizeof(DiffEntry), compareDiffEntriesExculsive); 2684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr = diffs; 2685de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(htmlHeader, gOptions.sortableUrl); 2688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<h3>Table of Contents</h3>\n"); 2689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<ul>\n"); 2690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<li><a href='#exclusive'>Exclusive</a>\n"); 2691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<li><a href='#inclusive'>Inclusive</a>\n"); 2692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</ul>\n"); 2693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Run 1: %s<br>\n", gOptions.diffFileName); 2694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Run 2: %s<br>\n", gOptions.traceFileName); 2695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a name=\"exclusive\"></a><h3 id=\"exclusive\">Exclusive</h3>\n"); 2696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(tableHeader, "exclusive_table"); 2697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2698de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char classBuf[HTML_BUFSIZE]; 2700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char methodBuf[HTML_BUFSIZE]; 2701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* className; 2702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* methodName; 2703de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (ptr->method1 != NULL && ptr->method2 != NULL) { 2705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("<tr><td>\n"); 2706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = htmlEscape(ptr->method1->className, classBuf, HTML_BUFSIZE); 2708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = htmlEscape(ptr->method1->methodName, methodBuf, HTML_BUFSIZE); 2709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s.%s ", className, methodName); 2711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 2712de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%lld ", ptr->method1->elapsedExclusive); 2714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 2715de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%llu ", ptr->method2->elapsedExclusive); 2717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 2718de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%lld ", ptr->differenceExclusive); 2720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 2721de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%.2f\n", ptr->differenceExclusivePercentage); 2723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>\n"); 2724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%d\n", ptr->method1->numCalls[0]); 2726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>\n"); 2727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%d\n", ptr->method2->numCalls[0]); 2729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td></tr>\n"); 2730de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr++; 2732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2733de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</table>\n"); 2735de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(htmlHeader, gOptions.sortableUrl); 2738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Run 1: %s<br>\n", gOptions.diffFileName); 2739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Run 2: %s<br>\n", gOptions.traceFileName); 2740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<a name=\"inclusive\"></a><h3 id=\"inculisve\">Inclusive</h3>\n"); 2741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf(tableHeader, "inclusive_table"); 2742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2743de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project qsort(diffs, matches, sizeof(DiffEntry), compareDiffEntriesInculsive); 2745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr = diffs; 2746de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (ptr->method1 != NULL && ptr->method2 != NULL) { 2748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("<tr><td>\n"); 2749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project className = htmlEscape(ptr->method1->className, classBuf, HTML_BUFSIZE); 2751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project methodName = htmlEscape(ptr->method1->methodName, methodBuf, HTML_BUFSIZE); 2752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%s.%s ", className, methodName); 2754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 2755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%lld ", ptr->method1->elapsedInclusive); 2757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 2758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%llu ", ptr->method2->elapsedInclusive); 2760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 2761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%lld ", ptr->differenceInclusive); 2763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>"); 2764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%.2f\n", ptr->differenceInclusivePercentage); 2766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>\n"); 2767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%d\n", ptr->method1->numCalls[0]); 2769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td><td>\n"); 2770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("%d\n", ptr->method2->numCalls[0]); 2772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</td></tr>\n"); 2773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ptr++; 2775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</table>\n"); 2779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<h3>Run 1 methods not found in Run 2</h3>"); 27807b522639a499f63ccb5162576830d0c20539bd05Andy McFadden printf(tableHeaderMissing, "?"); 2781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2782de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < d1->numMethods; ++i) { 2784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methods1[i] != NULL) { 2785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printMissingMethod(methods1[i]); 2786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2788de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) { 2790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("</table>\n"); 2791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("<h3>Run 2 methods not found in Run 1</h3>"); 27927b522639a499f63ccb5162576830d0c20539bd05Andy McFadden printf(tableHeaderMissing, "?"); 2793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2794de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = 0; i < d2->numMethods; ++i) { 2796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (methods2[i] != NULL) { 2797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printMissingMethod(methods2[i]); 2798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2800de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.outputHtml) printf("</body></html\n"); 2802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint usage(const char *program) 2805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 28067b522639a499f63ccb5162576830d0c20539bd05Andy McFadden fprintf(stderr, "Copyright (C) 2006 The Android Open Source Project\n\n"); 28077b522639a499f63ccb5162576830d0c20539bd05Andy McFadden fprintf(stderr, "usage: %s [-ho] [-s sortable] [-d trace-file-name] [-g outfile] trace-file-name\n", program); 2808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " -d trace-file-name - Diff with this trace\n"); 2809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " -g outfile - Write graph to 'outfile'\n"); 2810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " -k - When writing a graph, keep the intermediate DOT file\n"); 2811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " -h - Turn on HTML output\n"); 2812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " -o - Dump the dmtrace file instead of profiling\n"); 2813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " -s - URL base to where the sortable javascript file\n"); 2814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, " -t threshold - Threshold percentage for including nodes in the graph\n"); 2815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 2; 2816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// Returns true if there was an error 2819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint parseOptions(int argc, char **argv) 2820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (1) { 28227b522639a499f63ccb5162576830d0c20539bd05Andy McFadden int opt = getopt(argc, argv, "d:hg:kos:t:"); 2823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (opt == -1) 2824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project switch (opt) { 2826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'd': 2827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.diffFileName = optarg; 2828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'g': 2830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.graphFileName = optarg; 2831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'k': 2833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.keepDotFile = 1; 2834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'h': 2836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.outputHtml = 1; 2837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 'o': 2839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.dump = 1; 2840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 's': 2842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.sortableUrl = optarg; 2843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project case 't': 2845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.threshold = atoi(optarg); 2846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 2847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project default: 2848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 1; 2849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 2852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Parse args. 2856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 2857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint main(int argc, char** argv) 2858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 2859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.threshold = -1; 28606978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 2861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project // Parse the options 2862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (parseOptions(argc, argv) || argc - optind != 1) 2863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return usage(argv[0]); 2864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.traceFileName = argv[optind]; 2866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.threshold < 0 || 100 <= gOptions.threshold) { 2868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gOptions.threshold = 20; 2869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 28705b55af706cf3823494123da092a0a0319297a93eRodrigo Ipince 2871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.dump) { 2872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dumpTrace(); 2873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 2874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t sumThreadTime = 0; 28776978d9dd28968b3817533d036ae7b53309053faaRodrigo Ipince 2878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TraceData data1; 2879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project DataKeys* dataKeys = parseDataKeys(&data1, gOptions.traceFileName, 28807b522639a499f63ccb5162576830d0c20539bd05Andy McFadden &sumThreadTime); 2881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (dataKeys == NULL) { 2882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fprintf(stderr, "Cannot read trace.\n"); 2883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project exit(1); 2884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.diffFileName != NULL) { 2887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project uint64_t sum2; 2888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project TraceData data2; 28897b522639a499f63ccb5162576830d0c20539bd05Andy McFadden DataKeys* d2 = parseDataKeys(&data2, gOptions.diffFileName, &sum2); 2890de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createDiff(d2, sum2, dataKeys, sumThreadTime); 2892de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project freeDataKeys(d2); 2894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project MethodEntry** methods = parseMethodEntries(dataKeys); 28967b522639a499f63ccb5162576830d0c20539bd05Andy McFadden profileTrace(&data1, methods, dataKeys->numMethods, sumThreadTime); 2897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gOptions.graphFileName != NULL) { 2898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project createInclusiveProfileGraphNew(dataKeys); 2899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project free(methods); 2901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 2902de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro 2903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project freeDataKeys(dataKeys); 2904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 2905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return 0; 2906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 2907