OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/trace_event/heap_profiler_type_name_deduplicator.h" | 5 #include "base/trace_event/heap_profiler_type_name_deduplicator.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 #include <string> | 9 #include <string> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "base/json/string_escape.h" | |
13 #include "base/strings/string_split.h" | 12 #include "base/strings/string_split.h" |
14 #include "base/strings/stringprintf.h" | 13 #include "base/trace_event/heap_profiler_string_deduplicator.h" |
15 #include "base/trace_event/memory_usage_estimator.h" | 14 #include "base/trace_event/memory_usage_estimator.h" |
16 #include "base/trace_event/trace_event.h" | 15 #include "base/trace_event/trace_event.h" |
| 16 #include "base/trace_event/trace_event_argument.h" |
17 #include "base/trace_event/trace_event_memory_overhead.h" | 17 #include "base/trace_event/trace_event_memory_overhead.h" |
18 | 18 |
19 namespace base { | 19 namespace base { |
20 namespace trace_event { | 20 namespace trace_event { |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 // If |type_name| is file name then extract directory name. Or if |type_name| is | 24 // If |type_name| is file name then extract directory name. Or if |type_name| is |
25 // category name, then disambiguate multple categories and remove | 25 // category name, then disambiguate multple categories and remove |
26 // "disabled-by-default" prefix if present. | 26 // "disabled-by-default" prefix if present. |
(...skipping 28 matching lines...) Expand all Loading... |
55 const char kParentDirectory[] = ".."; | 55 const char kParentDirectory[] = ".."; |
56 const size_t kParentDirectoryLength = 3; // '../' or '..\'. | 56 const size_t kParentDirectoryLength = 3; // '../' or '..\'. |
57 while (result.starts_with(kParentDirectory)) { | 57 while (result.starts_with(kParentDirectory)) { |
58 result.remove_prefix(kParentDirectoryLength); | 58 result.remove_prefix(kParentDirectoryLength); |
59 } | 59 } |
60 return result; | 60 return result; |
61 } | 61 } |
62 | 62 |
63 } // namespace | 63 } // namespace |
64 | 64 |
65 TypeNameDeduplicator::TypeNameDeduplicator() { | 65 TypeNameDeduplicator::TypeNameDeduplicator( |
66 // A null pointer has type ID 0 ("unknown type"); | 66 StringDeduplicator* string_deduplicator) |
67 type_ids_.insert(std::make_pair(nullptr, 0)); | 67 : string_deduplicator_(string_deduplicator) { |
| 68 // Add implicit entry for id 0 (NULL type names). |
| 69 Insert(nullptr); |
68 } | 70 } |
69 | 71 |
70 TypeNameDeduplicator::~TypeNameDeduplicator() {} | 72 TypeNameDeduplicator::~TypeNameDeduplicator() {} |
71 | 73 |
72 int TypeNameDeduplicator::Insert(const char* type_name) { | 74 int TypeNameDeduplicator::Insert(const char* type_name) { |
73 auto result = type_ids_.insert(std::make_pair(type_name, 0)); | 75 auto result = type_ids_.insert(std::make_pair(type_name, 0)); |
74 auto& elem = result.first; | 76 auto& elem = result.first; |
75 bool did_not_exist_before = result.second; | 77 bool did_not_exist_before = result.second; |
76 | 78 |
77 if (did_not_exist_before) { | 79 if (did_not_exist_before) { |
78 // The type IDs are assigned sequentially and they are zero-based, so | 80 // The type IDs are assigned sequentially and they are zero-based, so |
79 // |size() - 1| is the ID of the new element. | 81 // |size() - 1| is the ID of the new element. |
80 elem->second = static_cast<int>(type_ids_.size() - 1); | 82 elem->second = static_cast<int>(type_ids_.size() - 1); |
| 83 new_type_ids_.push_back(&*result.first); |
81 } | 84 } |
82 | 85 |
83 return elem->second; | 86 return elem->second; |
84 } | 87 } |
85 | 88 |
86 void TypeNameDeduplicator::AppendAsTraceFormat(std::string* out) const { | 89 void TypeNameDeduplicator::SerializeIncrementally(TracedValue* traced_value) { |
87 out->append("{"); // Begin the type names dictionary. | 90 for (const auto* name_and_id : new_type_ids_) { |
| 91 traced_value->BeginDictionary(); |
88 | 92 |
89 auto it = type_ids_.begin(); | 93 traced_value->SetInteger("id", name_and_id->second); |
90 std::string buffer; | |
91 | |
92 // Write the first entry manually; the null pointer must not be dereferenced. | |
93 // (The first entry is the null pointer because a |std::map| is ordered.) | |
94 it++; | |
95 out->append("\"0\":\"[unknown]\""); | |
96 | |
97 for (; it != type_ids_.end(); it++) { | |
98 // Type IDs in the trace are strings, write them as stringified keys of | |
99 // a dictionary. | |
100 SStringPrintf(&buffer, ",\"%d\":", it->second); | |
101 | 94 |
102 // TODO(ssid): crbug.com/594803 the type name is misused for file name in | 95 // TODO(ssid): crbug.com/594803 the type name is misused for file name in |
103 // some cases. | 96 // some cases. |
104 StringPiece type_info = ExtractCategoryFromTypeName(it->first); | 97 StringPiece name = name_and_id->first |
| 98 ? ExtractCategoryFromTypeName(name_and_id->first) |
| 99 : "[unknown]"; |
| 100 int name_string_id = string_deduplicator_->Insert(name); |
| 101 traced_value->SetInteger("name_sid", name_string_id); |
105 | 102 |
106 // |EscapeJSONString| appends, it does not overwrite |buffer|. | 103 traced_value->EndDictionary(); |
107 bool put_in_quotes = true; | |
108 EscapeJSONString(type_info, put_in_quotes, &buffer); | |
109 out->append(buffer); | |
110 } | 104 } |
111 | 105 new_type_ids_.clear(); |
112 out->append("}"); // End the type names dictionary. | |
113 } | 106 } |
114 | 107 |
115 void TypeNameDeduplicator::EstimateTraceMemoryOverhead( | 108 void TypeNameDeduplicator::EstimateTraceMemoryOverhead( |
116 TraceEventMemoryOverhead* overhead) { | 109 TraceEventMemoryOverhead* overhead) { |
117 size_t memory_usage = EstimateMemoryUsage(type_ids_); | 110 size_t memory_usage = |
| 111 EstimateMemoryUsage(type_ids_) + EstimateMemoryUsage(new_type_ids_); |
118 overhead->Add(TraceEventMemoryOverhead::kHeapProfilerTypeNameDeduplicator, | 112 overhead->Add(TraceEventMemoryOverhead::kHeapProfilerTypeNameDeduplicator, |
119 sizeof(TypeNameDeduplicator) + memory_usage); | 113 sizeof(TypeNameDeduplicator) + memory_usage); |
120 } | 114 } |
121 | 115 |
122 } // namespace trace_event | 116 } // namespace trace_event |
123 } // namespace base | 117 } // namespace base |
OLD | NEW |