Add support for sampled PC profiling to FullCPU.
authorSteve Reinhardt <stever@eecs.umich.edu>
Mon, 15 Nov 2004 06:56:40 +0000 (01:56 -0500)
committerSteve Reinhardt <stever@eecs.umich.edu>
Mon, 15 Nov 2004 06:56:40 +0000 (01:56 -0500)
Simple text list of symbol (or address) and count
will be dumped to m5prof.<cpu-name> if the cpu's
pc_sample_interval param is set.

SConscript:
    Add cpu/full_cpu/pc_sample_profile.cc
base/callback.hh:
    Add a comment about MakeCallback.
    Fix type in another comment.
base/loader/symtab.cc:
    Revamp findNearestSymbol() to provide addresses of both
    nearest symbols (preceding and following) as well as
    string for former.

    Move global definition of debugSymbolTable here too.
base/loader/symtab.hh:
    Revamp findNearestSymbol() to provide addresses of both
    nearest symbols (preceding and following) as well as
    string for former.

    Move global declaration of debugSymbolTable here too.
cpu/exetrace.cc:
    Use new findNearestSymbol() interface for trace symbols.
kern/linux/linux_system.cc:
sim/system.cc:
    Remove extern of debugSymbolTable (now in symtab.hh)
sim/process.cc:
    Initialize debugSymbolTable if binary has a symbol table.

--HG--
extra : convert_revision : 0b5393dc39c40ac88c953684708f1125da550671

SConscript
base/callback.hh
base/loader/symtab.cc
base/loader/symtab.hh
cpu/exetrace.cc
kern/linux/linux_system.cc
sim/process.cc
sim/system.cc

index 7769d0708304ca0708dad716fa496d609ddb7c7b..3938f792fee4d8f280bc38cf2f4a03428925ce83 100644 (file)
@@ -109,6 +109,7 @@ base_sources = Split('''
        cpu/full_cpu/issue.cc
        cpu/full_cpu/ls_queue.cc
        cpu/full_cpu/machine_queue.cc
+        cpu/full_cpu/pc_sample_profile.cc
        cpu/full_cpu/pipetrace.cc
        cpu/full_cpu/readyq.cc
        cpu/full_cpu/reg_info.cc
index 342ab7e0fed8b82e0f9beffd9432cc232069ca37..cc2a2f4295a995c89226ca0bb8766456b0ba75bd 100644 (file)
@@ -32,7 +32,7 @@
 #include <list>
 
 /**
- * Generic callback class.  This base class provides a virutal process
+ * Generic callback class.  This base class provides a virtual process
  * function that gets called when the callback queue is processed.
  */
 class Callback
@@ -103,6 +103,8 @@ class CallbackQueue
     }
 };
 
+/// Helper template class to turn a simple class member function into
+/// a callback.
 template <class T, void (T::* F)()>
 class MakeCallback : public Callback
 {
@@ -111,8 +113,9 @@ class MakeCallback : public Callback
 
   public:
     MakeCallback(T *o)
-    : object(o)
+        : object(o)
     { }
+
     void process() { (object->*F)(); }
 };
 
index f6abf7e3dda9782c29d92ab1f52062434305de5c..c018ae4f864623f1c68dc8f0078e9360704680ad 100644 (file)
@@ -38,6 +38,8 @@
 
 using namespace std;
 
+SymbolTable *debugSymbolTable = NULL;
+
 bool
 SymbolTable::insert(Addr address, string symbol)
 {
@@ -95,26 +97,20 @@ SymbolTable::load(const string &filename)
 }
 
 bool
-SymbolTable::findNearestSymbol(Addr address, string &symbol) const
+SymbolTable::findNearestSymbol(Addr address, string &symbol,
+                               Addr &sym_address, Addr &next_sym_address) const
 {
-    ATable::const_iterator i = addrTable.lower_bound(address);
-
-    // check for PALCode
-    if (address & 0x1)
-        return false;
+    // find first key *larger* than desired address
+    ATable::const_iterator i = addrTable.upper_bound(address);
 
-    // first check for the end
-    if (i == addrTable.end())
-        i--;
-    else if (i == addrTable.begin() && (*i).first != address)
+    // if very first key is larger, we're out of luck
+    if (i == addrTable.begin())
         return false;
-    else if ((*i).first != address)
-        i--;
-
-    symbol = (*i).second;
 
-    if (address != (*i).first)
-        symbol += csprintf("+%d", address - (*i).first);
+    next_sym_address = i->first;
+    --i;
+    sym_address = i->first;
+    symbol = i->second;
 
     return true;
 }
index 48230c7a23ec12fb6dcca9c5a4c6d20e11719055..df3783991af757decaf7a73050c963dd587616c4 100644 (file)
@@ -49,7 +49,27 @@ class SymbolTable
     bool insert(Addr address, std::string symbol);
     bool load(const std::string &file);
 
-    bool findNearestSymbol(Addr address, std::string &symbol) const;
+    /// Find the nearest symbol equal to or less than the supplied
+    /// address (e.g., the label for the enclosing function).
+    /// @param address The address to look up.
+    /// @param symbol  Return reference for symbol string.
+    /// @param sym_address Return reference for symbol address.
+    /// @param next_sym_address Address of following symbol (for
+    /// determining valid range of symbol).
+    /// @retval True if a symbol was found.
+    bool findNearestSymbol(Addr address, std::string &symbol,
+                           Addr &sym_address, Addr &next_sym_address) const;
+
+    /// Overload for findNearestSymbol() for callers who don't care
+    /// about next_sym_address.
+    bool findNearestSymbol(Addr address, std::string &symbol,
+                           Addr &sym_address) const
+    {
+        Addr dummy;
+        return findNearestSymbol(address, symbol, sym_address, dummy);
+    }
+
+
     bool findSymbol(Addr address, std::string &symbol) const;
     bool findAddress(const std::string &symbol, Addr &address) const;
 
@@ -57,4 +77,10 @@ class SymbolTable
     Addr find(const std::string &symbol) const;
 };
 
+/// Global unified debugging symbol table (for target).  Conceptually
+/// there should be one of these per System object for full system,
+/// and per Process object for non-full-system, but so far one big
+/// global one has worked well enough.
+extern SymbolTable *debugSymbolTable;
+
 #endif // __SYMTAB_HH__
index e31c3590cd52e05c83a42e316faaee9dc67e9e37..58fb7d668879a9ab405410adce60ba91dc0dff66 100644 (file)
@@ -48,8 +48,6 @@ using namespace std;
 //
 
 
-SymbolTable *debugSymbolTable = NULL;
-
 void
 Trace::InstRecord::dump(ostream &outs)
 {
@@ -66,11 +64,17 @@ Trace::InstRecord::dump(ostream &outs)
         outs << "T" << thread << " : ";
 
 
-    std::string str;
-    if ((debugSymbolTable) && (debugSymbolTable->findNearestSymbol(PC, str)))
-        outs << "@" << setw(17) << str << " : ";
-    else
+    std::string sym_str;
+    Addr sym_addr;
+    if (debugSymbolTable
+        && debugSymbolTable->findNearestSymbol(PC, sym_str, sym_addr)) {
+        if (PC != sym_addr)
+            sym_str += csprintf("+%d", addr - sym_addr);
+        outs << "@" << setw(17) << sym_str << " : ";
+    }
+    else {
         outs << "0x" << hex << PC << " : ";
+    }
 
     //
     //  Print decoded instruction
index 12bfafd6b89ddb6e5e4f5db9edbf591d87b644ae..c5d35a4fc53d94e5e0eac7cb09d5f44620381a93 100644 (file)
@@ -49,8 +49,6 @@
 #include "targetarch/vtophys.hh"
 #include "sim/debug.hh"
 
-extern SymbolTable *debugSymbolTable;
-
 using namespace std;
 
 LinuxSystem::LinuxSystem(Params *p)
index 98db1f2e063a94836d0740182f68f6e9e1d8eafe..bd1a2d8fd197843b6936f3374a3cb8462b78366c 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "base/intmath.hh"
 #include "base/loader/object_file.hh"
+#include "base/loader/symtab.hh"
 #include "base/statistics.hh"
 #include "cpu/exec_context.hh"
 #include "cpu/full_cpu/smt.hh"
@@ -263,6 +264,18 @@ LiveProcess::LiveProcess(const string &name, ObjectFile *objFile,
     // load object file into target memory
     objFile->loadSections(memory);
 
+    // load up symbols, if any... these may be used for debugging or
+    // profiling.
+    if (!debugSymbolTable) {
+        debugSymbolTable = new SymbolTable();
+        if (!objFile->loadGlobalSymbols(debugSymbolTable) ||
+            !objFile->loadLocalSymbols(debugSymbolTable)) {
+            // didn't load any symbols
+            delete debugSymbolTable;
+            debugSymbolTable = NULL;
+        }
+    }
+
     // Set up stack.  On Alpha, stack goes below text section.  This
     // code should get moved to some architecture-specific spot.
     stack_base = text_base - (409600+4096);
index 1b1a145c6df7f83c0da094ce987dfc33b20b1f88..c6a65f9d9afdf09cfafcf53a4c8a41e7dbca70e6 100644 (file)
@@ -44,8 +44,6 @@ vector<System *> System::systemList;
 
 int System::numSystemsRunning = 0;
 
-extern SymbolTable *debugSymbolTable;
-
 System::System(Params *p)
     : SimObject(p->name), memctrl(p->memctrl), physmem(p->physmem),
       init_param(p->init_param), params(p)