Home | History | Annotate | Download | only in trace_event
      1 // Copyright 2015 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/trace_event/heap_profiler_type_name_deduplicator.h"
      6 
      7 #include <stddef.h>
      8 #include <stdlib.h>
      9 #include <string>
     10 #include <utility>
     11 
     12 #include "base/json/string_escape.h"
     13 #include "base/strings/stringprintf.h"
     14 #include "base/trace_event/trace_event_memory_overhead.h"
     15 
     16 namespace base {
     17 namespace trace_event {
     18 
     19 TypeNameDeduplicator::TypeNameDeduplicator() {
     20   // A null pointer has type ID 0 ("unknown type");
     21   type_ids_.insert(std::make_pair(nullptr, 0));
     22 }
     23 
     24 TypeNameDeduplicator::~TypeNameDeduplicator() {}
     25 
     26 int TypeNameDeduplicator::Insert(const char* type_name) {
     27   auto result = type_ids_.insert(std::make_pair(type_name, 0));
     28   auto& elem = result.first;
     29   bool did_not_exist_before = result.second;
     30 
     31   if (did_not_exist_before) {
     32     // The type IDs are assigned sequentially and they are zero-based, so
     33     // |size() - 1| is the ID of the new element.
     34     elem->second = static_cast<int>(type_ids_.size() - 1);
     35   }
     36 
     37   return elem->second;
     38 }
     39 
     40 void TypeNameDeduplicator::AppendAsTraceFormat(std::string* out) const {
     41   out->append("{");  // Begin the type names dictionary.
     42 
     43   auto it = type_ids_.begin();
     44   std::string buffer;
     45 
     46   // Write the first entry manually; the null pointer must not be dereferenced.
     47   // (The first entry is the null pointer because a |std::map| is ordered.)
     48   it++;
     49   out->append("\"0\":\"[unknown]\"");
     50 
     51   for (; it != type_ids_.end(); it++) {
     52     // Type IDs in the trace are strings, write them as stringified keys of
     53     // a dictionary.
     54     SStringPrintf(&buffer, ",\"%d\":", it->second);
     55 
     56     // |EscapeJSONString| appends, it does not overwrite |buffer|.
     57     bool put_in_quotes = true;
     58     EscapeJSONString(it->first, put_in_quotes, &buffer);
     59     out->append(buffer);
     60   }
     61 
     62   out->append("}");  // End the type names dictionary.
     63 }
     64 
     65 void TypeNameDeduplicator::EstimateTraceMemoryOverhead(
     66     TraceEventMemoryOverhead* overhead) {
     67   // The size here is only an estimate; it fails to take into account the size
     68   // of the tree nodes for the map, but as an estimate this should be fine.
     69   size_t map_size = type_ids_.size() * sizeof(std::pair<const char*, int>);
     70 
     71   overhead->Add("TypeNameDeduplicator",
     72                 sizeof(TypeNameDeduplicator) + map_size);
     73 }
     74 
     75 }  // namespace trace_event
     76 }  // namespace base
     77