• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
TypeNameDeduplicator()19 TypeNameDeduplicator::TypeNameDeduplicator() {
20   // A null pointer has type ID 0 ("unknown type");
21   type_ids_.insert(std::make_pair(nullptr, 0));
22 }
23 
~TypeNameDeduplicator()24 TypeNameDeduplicator::~TypeNameDeduplicator() {}
25 
Insert(const char * type_name)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 
AppendAsTraceFormat(std::string * out) const40 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 
EstimateTraceMemoryOverhead(TraceEventMemoryOverhead * overhead)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