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 20 matching lines...) Expand all Loading... |
47 const char kParentDirectory[] = ".."; | 47 const char kParentDirectory[] = ".."; |
48 const size_t kParentDirectoryLength = 3; // '../' or '..\'. | 48 const size_t kParentDirectoryLength = 3; // '../' or '..\'. |
49 while (result.starts_with(kParentDirectory)) { | 49 while (result.starts_with(kParentDirectory)) { |
50 result.remove_prefix(kParentDirectoryLength); | 50 result.remove_prefix(kParentDirectoryLength); |
51 } | 51 } |
52 return result; | 52 return result; |
53 } | 53 } |
54 | 54 |
55 } // namespace | 55 } // namespace |
56 | 56 |
57 TypeNameDeduplicator::TypeNameDeduplicator() { | 57 TypeNameDeduplicator::TypeNameDeduplicator( |
58 // A null pointer has type ID 0 ("unknown type"); | 58 StringDeduplicator* string_deduplicator) |
59 type_ids_.insert(std::make_pair(nullptr, 0)); | 59 : string_deduplicator_(string_deduplicator) { |
| 60 // Add implicit entry for id 0 (NULL type names). |
| 61 Insert(nullptr); |
60 } | 62 } |
61 | 63 |
62 TypeNameDeduplicator::~TypeNameDeduplicator() {} | 64 TypeNameDeduplicator::~TypeNameDeduplicator() {} |
63 | 65 |
64 int TypeNameDeduplicator::Insert(const char* type_name) { | 66 int TypeNameDeduplicator::Insert(const char* type_name) { |
65 auto result = type_ids_.insert(std::make_pair(type_name, 0)); | 67 auto result = type_ids_.insert(std::make_pair(type_name, 0)); |
66 auto& elem = result.first; | 68 auto& elem = result.first; |
67 bool did_not_exist_before = result.second; | 69 bool did_not_exist_before = result.second; |
68 | 70 |
69 if (did_not_exist_before) { | 71 if (did_not_exist_before) { |
70 // The type IDs are assigned sequentially and they are zero-based, so | 72 // The type IDs are assigned sequentially and they are zero-based, so |
71 // |size() - 1| is the ID of the new element. | 73 // |size() - 1| is the ID of the new element. |
72 elem->second = static_cast<int>(type_ids_.size() - 1); | 74 elem->second = static_cast<int>(type_ids_.size() - 1); |
| 75 new_type_ids_.push_back(&*result.first); |
73 } | 76 } |
74 | 77 |
75 return elem->second; | 78 return elem->second; |
76 } | 79 } |
77 | 80 |
78 void TypeNameDeduplicator::AppendAsTraceFormat(std::string* out) const { | 81 void TypeNameDeduplicator::SerializeIncrementally(TracedValue* traced_value) { |
79 out->append("{"); // Begin the type names dictionary. | 82 for (const auto* name_and_id : new_type_ids_) { |
| 83 traced_value->BeginDictionary(); |
80 | 84 |
81 auto it = type_ids_.begin(); | 85 traced_value->SetInteger("id", name_and_id->second); |
82 std::string buffer; | |
83 | |
84 // Write the first entry manually; the null pointer must not be dereferenced. | |
85 // (The first entry is the null pointer because a |std::map| is ordered.) | |
86 it++; | |
87 out->append("\"0\":\"[unknown]\""); | |
88 | |
89 for (; it != type_ids_.end(); it++) { | |
90 // Type IDs in the trace are strings, write them as stringified keys of | |
91 // a dictionary. | |
92 SStringPrintf(&buffer, ",\"%d\":", it->second); | |
93 | 86 |
94 // TODO(ssid): crbug.com/594803 the type name is misused for file name in | 87 // TODO(ssid): crbug.com/594803 the type name is misused for file name in |
95 // some cases. | 88 // some cases. |
96 StringPiece type_info = ExtractCategoryFromTypeName(it->first); | 89 StringPiece name = name_and_id->first |
| 90 ? ExtractCategoryFromTypeName(name_and_id->first) |
| 91 : "[unknown]"; |
| 92 int name_string_id = string_deduplicator_->Insert(name); |
| 93 traced_value->SetInteger("name_sid", name_string_id); |
97 | 94 |
98 // |EscapeJSONString| appends, it does not overwrite |buffer|. | 95 traced_value->EndDictionary(); |
99 bool put_in_quotes = true; | |
100 EscapeJSONString(type_info, put_in_quotes, &buffer); | |
101 out->append(buffer); | |
102 } | 96 } |
103 | 97 new_type_ids_.clear(); |
104 out->append("}"); // End the type names dictionary. | |
105 } | 98 } |
106 | 99 |
107 void TypeNameDeduplicator::EstimateTraceMemoryOverhead( | 100 void TypeNameDeduplicator::EstimateTraceMemoryOverhead( |
108 TraceEventMemoryOverhead* overhead) { | 101 TraceEventMemoryOverhead* overhead) { |
109 size_t memory_usage = EstimateMemoryUsage(type_ids_); | 102 size_t memory_usage = |
| 103 EstimateMemoryUsage(type_ids_) + EstimateMemoryUsage(new_type_ids_); |
110 overhead->Add("TypeNameDeduplicator", | 104 overhead->Add("TypeNameDeduplicator", |
111 sizeof(TypeNameDeduplicator) + memory_usage); | 105 sizeof(TypeNameDeduplicator) + memory_usage); |
112 } | 106 } |
113 | 107 |
114 } // namespace trace_event | 108 } // namespace trace_event |
115 } // namespace base | 109 } // namespace base |
OLD | NEW |