Esempio n. 1
0
// Accumulate data from children into their parent.
void LocalState::TrieNode::propagate_data_upwards (void)
{
  for (auto citer = children.begin(); citer != children.end(); citer++) {
    TrieNode* child = citer->second;
    child->propagate_data_upwards();
    for (size_t i = 0; i < self_data.size(); i++)
      path_data[i] += child->path_data[i];
    invocations += child->invocations;
  }
}
Esempio n. 2
0
// Construct various tables in preparation for output.
void LocalState::finalize (void)
{
  // Find the line-number column.
  lineno_col = nullptr;
  for (auto citer = table_data.begin(); citer != table_data.end(); citer++) {
    Column* column = *citer;
    string colname(column->name);
    if (colname == "Line number" || colname == "Leaf line number")
      lineno_col = column;
  }
  if (lineno_col == nullptr)
    cerr << progname << ": Failed to find a \"Line number\" or \"Leaf line number\" column in the \"Functions\" table_data\n" << die;
  if (lineno_col->type != Column::UINT64_T)
    cerr << progname << ": The \""
         << lineno_col->name
         << "\" column does not contain integer data\n" << die;

  // Find the invocation-count column.
  invoke_col = nullptr;
  for (auto citer = table_data.begin(); citer != table_data.end(); citer++) {
    Column* column = *citer;
    string colname(column->name);
    if (colname == "Invocations")
      invoke_col = column;
  }
  if (invoke_col == nullptr)
    cerr << progname << ": Failed to find an \"Invocations\" column in the \"Functions\" table_data\n" << die;
  if (invoke_col->type != Column::UINT64_T)
    cerr << progname << ": The \""
         << invoke_col->name
         << "\" column does not contain integer data\n" << die;

  // Construct a mapping from file name to ID and back.
  size_t id = 1;
  file_col = nullptr;
  for (size_t i = 0; i < table_data.size(); i++)
    if (table_data[i]->name == "File name" || table_data[i]->name == "Leaf file name") {
      file_col = table_data[i];
      break;
    }
  if (file_col == nullptr)
    cerr << progname << ": Failed to find a \"File name\" or \"Leaf file name\" column in the \"Functions\" table_data\n" << die;
  if (file_col->type != Column::STRING_T)
    cerr << progname << ": The \""
         << file_col->name
         << "\" column does not contain string data\n" << die;
  for (auto riter = file_col->string_data->begin();
       riter != file_col->string_data->end();
       riter++) {
    string fname = *riter;
    if (fname2id.find(fname) != fname2id.end())
      continue;
    fname2id[fname] = id;
    id2fname[id] = fname;
    id++;
  }

  // Construct a mapping from demangled function name or demangled call stack
  // to ID and back.
  id = 1;
  func_col = nullptr;
  for (size_t i = 0; i < table_data.size(); i++)
    if (table_data[i]->name == "Demangled function name" || table_data[i]->name == "Demangled call stack") {
      func_col = table_data[i];
      break;
    }
  if (func_col == nullptr)
    cerr << progname << ": Failed to find a \"Demangled function name\" or \"Demangled call stack\" column in the \"Functions\" table\n" << die;
  if (func_col->type != Column::STRING_T)
    cerr << progname << ": The \""
         << func_col->name
         << "\" column does not contain string data\n" << die;
  size_t row = 0;
  for (auto riter = func_col->string_data->begin();
       riter != func_col->string_data->end();
       riter++, row++) {
    string func = *riter;
    string func_only(func.substr(0, func.find(" # ")));
    if (func2id.find(func_only) != func2id.end())
      continue;
    func2id[func_only] = id;
    id2func[id] = func_only;
    funcid2fnameid[id] = fname2id[(*file_col->string_data)[row]];
    id++;
  }

  // Insert each call path into a trie forest.  Compute inclusive and exclude
  // metrics.
  size_t func_col_num = func_col->number;
  size_t nrows = func_col->string_data->size();
  call_forest = new LocalState::TrieNode(this);
  for (size_t r = 0; r < nrows; r++)
    call_forest->insert(func_col_num, r);
  auto citer = call_forest->children.begin();
  if (citer != call_forest->children.end()) {
    // Initialize the root to have all-zero data.
    TrieNode* child = citer->second;
    call_forest->self_data.resize(child->self_data.size(), 0);
    call_forest->path_data.resize(child->path_data.size(), 0);
  }
  call_forest->propagate_data_upwards();
}