profile.cc revision 1981
11689SN/A/* 22329SN/A * Copyright (c) 2005 The Regents of The University of Michigan 31689SN/A * All rights reserved. 41689SN/A * 51689SN/A * Redistribution and use in source and binary forms, with or without 61689SN/A * modification, are permitted provided that the following conditions are 71689SN/A * met: redistributions of source code must retain the above copyright 81689SN/A * notice, this list of conditions and the following disclaimer; 91689SN/A * redistributions in binary form must reproduce the above copyright 101689SN/A * notice, this list of conditions and the following disclaimer in the 111689SN/A * documentation and/or other materials provided with the distribution; 121689SN/A * neither the name of the copyright holders nor the names of its 131689SN/A * contributors may be used to endorse or promote products derived from 141689SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292756Sksewell@umich.edu#include <string> 301689SN/A 311689SN/A#include "base/bitfield.hh" 322292SN/A#include "base/callback.hh" 332292SN/A#include "base/statistics.hh" 341060SN/A#include "base/trace.hh" 352669Sktlim@umich.edu#include "cpu/base.hh" 361461SN/A#include "cpu/exec_context.hh" 371060SN/A#include "cpu/profile.hh" 381060SN/A 392808Ssaidi@eecs.umich.eduusing namespace std; 402669Sktlim@umich.edu 411461SN/AProfileNode::ProfileNode() 421060SN/A : count(0) 431060SN/A{ } 442329SN/A 452329SN/Avoid 462329SN/AProfileNode::dump(const string &symbol, uint64_t id, const SymbolTable *symtab, 472329SN/A ostream &os) const 482348SN/A{ 492329SN/A ccprintf(os, "%#x %s %d ", id, symbol, count); 501060SN/A ChildList::const_iterator i, end = children.end(); 511060SN/A for (i = children.begin(); i != end; ++i) { 522292SN/A const ProfileNode *node = i->second; 531060SN/A ccprintf(os, "%#x ", (intptr_t)node); 541060SN/A } 551060SN/A 561061SN/A ccprintf(os, "\n"); 571060SN/A 581061SN/A for (i = children.begin(); i != end; ++i) { 592733Sktlim@umich.edu Addr addr = i->first; 601060SN/A string symbol; 611060SN/A if (addr == 1) 622292SN/A symbol = "user"; 631061SN/A else if (addr == 2) 641061SN/A symbol = "console"; 651061SN/A else if (addr == 3) 661060SN/A symbol = "unknown"; 671060SN/A else if (!symtab->findSymbol(addr, symbol)) 682107SN/A panic("could not find symbol for address %#x\n", addr); 692292SN/A 702632Sstever@eecs.umich.edu const ProfileNode *node = i->second; 712698Sktlim@umich.edu node->dump(symbol, (intptr_t)node, symtab, os); 722698Sktlim@umich.edu } 732698Sktlim@umich.edu} 742669Sktlim@umich.edu 752669Sktlim@umich.eduvoid 762669Sktlim@umich.eduProfileNode::clear() 772698Sktlim@umich.edu{ 782669Sktlim@umich.edu count = 0; 792669Sktlim@umich.edu ChildList::iterator i, end = children.end(); 802669Sktlim@umich.edu for (i = children.begin(); i != end; ++i) 812698Sktlim@umich.edu i->second->clear(); 822669Sktlim@umich.edu} 832669Sktlim@umich.edu 842669Sktlim@umich.eduFunctionProfile::FunctionProfile(const SymbolTable *_symtab) 852669Sktlim@umich.edu : reset(0), symtab(_symtab) 862669Sktlim@umich.edu{ 872698Sktlim@umich.edu reset = new MakeCallback<FunctionProfile, &FunctionProfile::clear>(this); 882669Sktlim@umich.edu Stats::registerResetCallback(reset); 892669Sktlim@umich.edu} 902698Sktlim@umich.edu 912669Sktlim@umich.eduFunctionProfile::~FunctionProfile() 922669Sktlim@umich.edu{ 932698Sktlim@umich.edu if (reset) 942669Sktlim@umich.edu delete reset; 952669Sktlim@umich.edu} 962698Sktlim@umich.edu 972669Sktlim@umich.eduProfileNode * 982669Sktlim@umich.eduFunctionProfile::consume(const vector<Addr> &stack) 992669Sktlim@umich.edu{ 1002669Sktlim@umich.edu ProfileNode *current = ⊤ 1012698Sktlim@umich.edu for (int i = 0, size = stack.size(); i < size; ++i) { 1022698Sktlim@umich.edu ProfileNode *&ptr = current->children[stack[size - i - 1]]; 1032669Sktlim@umich.edu if (ptr == NULL) 1042669Sktlim@umich.edu ptr = new ProfileNode; 1052698Sktlim@umich.edu 1062669Sktlim@umich.edu current = ptr; 1072669Sktlim@umich.edu } 1081060SN/A 1091060SN/A return current; 1102329SN/A} 1112329SN/A 1122292SN/Avoid 1132292SN/AFunctionProfile::clear() 1142292SN/A{ 1152292SN/A top.clear(); 1162292SN/A pc_count.clear(); 1172292SN/A} 1182292SN/A 1192292SN/Avoid 1201060SN/AFunctionProfile::dump(ExecContext *xc, ostream &os) const 1211060SN/A{ 1221060SN/A ccprintf(os, ">>>PC data\n"); 1231060SN/A map<Addr, Counter>::const_iterator i, end = pc_count.end(); 1242292SN/A for (i = pc_count.begin(); i != end; ++i) { 1252292SN/A Addr pc = i->first; 1262292SN/A Counter count = i->second; 1272307SN/A 1282669Sktlim@umich.edu std::string symbol; 1292696Sktlim@umich.edu if (pc == 1) 1302669Sktlim@umich.edu ccprintf(os, "user %d\n", count); 1311060SN/A else if (symtab->findSymbol(pc, symbol) && !symbol.empty()) 1321060SN/A ccprintf(os, "%s %d\n", symbol, count); 1332292SN/A else 1342292SN/A ccprintf(os, "%#x %d\n", pc, count); 1352292SN/A } 1362292SN/A 1372292SN/A ccprintf(os, ">>>function data\n"); 1382292SN/A top.dump("top", 0, symtab, os); 1392292SN/A} 1402292SN/A 1411060SN/Avoid 1422292SN/AFunctionProfile::sample(ProfileNode *node, Addr pc) 1432292SN/A{ 1442292SN/A node->count++; 1452292SN/A 1462292SN/A Addr symaddr; 1472292SN/A if (symtab->findNearestAddr(pc, symaddr)) { 1482292SN/A pc_count[symaddr]++; 1492292SN/A } else { 1502292SN/A // record PC even if we don't have a symbol to avoid 1512292SN/A // silently biasing the histogram 1522292SN/A pc_count[pc]++; 1532292SN/A } 1541060SN/A} 1551060SN/A