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