profile.cc revision 2665
11917SN/A/* 21917SN/A * Copyright (c) 2005 The Regents of The University of Michigan 31917SN/A * All rights reserved. 41917SN/A * 51917SN/A * Redistribution and use in source and binary forms, with or without 61917SN/A * modification, are permitted provided that the following conditions are 71917SN/A * met: redistributions of source code must retain the above copyright 81917SN/A * notice, this list of conditions and the following disclaimer; 91917SN/A * redistributions in binary form must reproduce the above copyright 101917SN/A * notice, this list of conditions and the following disclaimer in the 111917SN/A * documentation and/or other materials provided with the distribution; 121917SN/A * neither the name of the copyright holders nor the names of its 131917SN/A * contributors may be used to endorse or promote products derived from 141917SN/A * this software without specific prior written permission. 151917SN/A * 161917SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171917SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181917SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191917SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201917SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211917SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221917SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231917SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241917SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251917SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261917SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu * 282665Ssaidi@eecs.umich.edu * Authors: Nathan Binkert 291917SN/A */ 301917SN/A 311917SN/A#include <string> 321917SN/A 331917SN/A#include "base/bitfield.hh" 341981SN/A#include "base/callback.hh" 351981SN/A#include "base/statistics.hh" 361917SN/A#include "base/trace.hh" 372235SN/A#include "base/loader/symtab.hh" 381917SN/A#include "cpu/base.hh" 391917SN/A#include "cpu/exec_context.hh" 401917SN/A#include "cpu/profile.hh" 411917SN/A 421917SN/Ausing namespace std; 431917SN/A 441917SN/AProfileNode::ProfileNode() 451917SN/A : count(0) 461917SN/A{ } 471917SN/A 481917SN/Avoid 491917SN/AProfileNode::dump(const string &symbol, uint64_t id, const SymbolTable *symtab, 501917SN/A ostream &os) const 511917SN/A{ 521917SN/A ccprintf(os, "%#x %s %d ", id, symbol, count); 531917SN/A ChildList::const_iterator i, end = children.end(); 541917SN/A for (i = children.begin(); i != end; ++i) { 551977SN/A const ProfileNode *node = i->second; 561977SN/A ccprintf(os, "%#x ", (intptr_t)node); 571917SN/A } 581917SN/A 591917SN/A ccprintf(os, "\n"); 601917SN/A 611917SN/A for (i = children.begin(); i != end; ++i) { 621917SN/A Addr addr = i->first; 631917SN/A string symbol; 641917SN/A if (addr == 1) 651917SN/A symbol = "user"; 661917SN/A else if (addr == 2) 671917SN/A symbol = "console"; 681917SN/A else if (addr == 3) 691917SN/A symbol = "unknown"; 701917SN/A else if (!symtab->findSymbol(addr, symbol)) 711917SN/A panic("could not find symbol for address %#x\n", addr); 721917SN/A 731977SN/A const ProfileNode *node = i->second; 741977SN/A node->dump(symbol, (intptr_t)node, symtab, os); 751917SN/A } 761917SN/A} 771917SN/A 781917SN/Avoid 791917SN/AProfileNode::clear() 801917SN/A{ 811917SN/A count = 0; 821917SN/A ChildList::iterator i, end = children.end(); 831977SN/A for (i = children.begin(); i != end; ++i) 841977SN/A i->second->clear(); 851917SN/A} 861917SN/A 871917SN/AFunctionProfile::FunctionProfile(const SymbolTable *_symtab) 881981SN/A : reset(0), symtab(_symtab) 891917SN/A{ 901981SN/A reset = new MakeCallback<FunctionProfile, &FunctionProfile::clear>(this); 911981SN/A Stats::registerResetCallback(reset); 921917SN/A} 931917SN/A 941917SN/AFunctionProfile::~FunctionProfile() 951917SN/A{ 961981SN/A if (reset) 971981SN/A delete reset; 981917SN/A} 991917SN/A 1001917SN/AProfileNode * 1011977SN/AFunctionProfile::consume(const vector<Addr> &stack) 1021917SN/A{ 1031917SN/A ProfileNode *current = ⊤ 1041977SN/A for (int i = 0, size = stack.size(); i < size; ++i) { 1051977SN/A ProfileNode *&ptr = current->children[stack[size - i - 1]]; 1061977SN/A if (ptr == NULL) 1071977SN/A ptr = new ProfileNode; 1081977SN/A 1091977SN/A current = ptr; 1101977SN/A } 1111917SN/A 1121917SN/A return current; 1131917SN/A} 1141917SN/A 1151917SN/Avoid 1161917SN/AFunctionProfile::clear() 1171917SN/A{ 1181917SN/A top.clear(); 1191917SN/A pc_count.clear(); 1201917SN/A} 1211917SN/A 1221917SN/Avoid 1231917SN/AFunctionProfile::dump(ExecContext *xc, ostream &os) const 1241917SN/A{ 1251917SN/A ccprintf(os, ">>>PC data\n"); 1261917SN/A map<Addr, Counter>::const_iterator i, end = pc_count.end(); 1271917SN/A for (i = pc_count.begin(); i != end; ++i) { 1281917SN/A Addr pc = i->first; 1291917SN/A Counter count = i->second; 1301917SN/A 1311917SN/A std::string symbol; 1321917SN/A if (pc == 1) 1331917SN/A ccprintf(os, "user %d\n", count); 1341917SN/A else if (symtab->findSymbol(pc, symbol) && !symbol.empty()) 1351917SN/A ccprintf(os, "%s %d\n", symbol, count); 1361917SN/A else 1371917SN/A ccprintf(os, "%#x %d\n", pc, count); 1381917SN/A } 1391917SN/A 1401917SN/A ccprintf(os, ">>>function data\n"); 1411917SN/A top.dump("top", 0, symtab, os); 1421917SN/A} 1431917SN/A 1441917SN/Avoid 1451917SN/AFunctionProfile::sample(ProfileNode *node, Addr pc) 1461917SN/A{ 1471917SN/A node->count++; 1481917SN/A 1491917SN/A Addr symaddr; 1501917SN/A if (symtab->findNearestAddr(pc, symaddr)) { 1511917SN/A pc_count[symaddr]++; 1521917SN/A } else { 1531917SN/A // record PC even if we don't have a symbol to avoid 1541917SN/A // silently biasing the histogram 1551917SN/A pc_count[pc]++; 1561917SN/A } 1571917SN/A} 158