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" | 12 #include "base/json/string_escape.h" |
13 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
14 #include "base/trace_event/trace_event_memory_overhead.h" | 14 #include "base/trace_event/trace_event_memory_overhead.h" |
15 | 15 |
16 namespace base { | 16 namespace base { |
17 namespace trace_event { | 17 namespace trace_event { |
18 | 18 |
| 19 namespace { |
| 20 |
| 21 // Extract directory name if |type_name| was file name. Otherwise, return |
| 22 // |type_name|. |
| 23 StringPiece ExtractDirNameFromFileName(const char* type_name) { |
| 24 StringPiece result(type_name); |
| 25 size_t last_seperator = result.find_last_of("\\/"); |
| 26 |
| 27 // If |type_name| was a not a file path, the seperator will not be found, so |
| 28 // the whole type name is returned. |
| 29 if (last_seperator == StringPiece::npos) |
| 30 return result; |
| 31 |
| 32 // Remove the file name from the path. |
| 33 result.remove_suffix(result.length() - last_seperator); |
| 34 |
| 35 // Remove the parent directory references. |
| 36 const char kParentDirectory[] = ".."; |
| 37 const size_t kParentDirectoryLength = 3; // '../' or '..\'. |
| 38 while (result.starts_with(kParentDirectory)) { |
| 39 result.remove_prefix(kParentDirectoryLength); |
| 40 } |
| 41 return result; |
| 42 } |
| 43 |
| 44 } // namespace |
| 45 |
19 TypeNameDeduplicator::TypeNameDeduplicator() { | 46 TypeNameDeduplicator::TypeNameDeduplicator() { |
20 // A null pointer has type ID 0 ("unknown type"); | 47 // A null pointer has type ID 0 ("unknown type"); |
21 type_ids_.insert(std::make_pair(nullptr, 0)); | 48 type_ids_.insert(std::make_pair(nullptr, 0)); |
22 } | 49 } |
23 | 50 |
24 TypeNameDeduplicator::~TypeNameDeduplicator() {} | 51 TypeNameDeduplicator::~TypeNameDeduplicator() {} |
25 | 52 |
26 int TypeNameDeduplicator::Insert(const char* type_name) { | 53 int TypeNameDeduplicator::Insert(const char* type_name) { |
27 auto result = type_ids_.insert(std::make_pair(type_name, 0)); | 54 auto result = type_ids_.insert(std::make_pair(type_name, 0)); |
28 auto& elem = result.first; | 55 auto& elem = result.first; |
(...skipping 17 matching lines...) Expand all Loading... |
46 // Write the first entry manually; the null pointer must not be dereferenced. | 73 // 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.) | 74 // (The first entry is the null pointer because a |std::map| is ordered.) |
48 it++; | 75 it++; |
49 out->append("\"0\":\"[unknown]\""); | 76 out->append("\"0\":\"[unknown]\""); |
50 | 77 |
51 for (; it != type_ids_.end(); it++) { | 78 for (; it != type_ids_.end(); it++) { |
52 // Type IDs in the trace are strings, write them as stringified keys of | 79 // Type IDs in the trace are strings, write them as stringified keys of |
53 // a dictionary. | 80 // a dictionary. |
54 SStringPrintf(&buffer, ",\"%d\":", it->second); | 81 SStringPrintf(&buffer, ",\"%d\":", it->second); |
55 | 82 |
| 83 // TODO(ssid): crbug.com/594803 the type name is misused for file name in |
| 84 // some cases. |
| 85 StringPiece type_info = ExtractDirNameFromFileName(it->first); |
| 86 |
56 // |EscapeJSONString| appends, it does not overwrite |buffer|. | 87 // |EscapeJSONString| appends, it does not overwrite |buffer|. |
57 bool put_in_quotes = true; | 88 bool put_in_quotes = true; |
58 EscapeJSONString(it->first, put_in_quotes, &buffer); | 89 EscapeJSONString(type_info, put_in_quotes, &buffer); |
59 out->append(buffer); | 90 out->append(buffer); |
60 } | 91 } |
61 | 92 |
62 out->append("}"); // End the type names dictionary. | 93 out->append("}"); // End the type names dictionary. |
63 } | 94 } |
64 | 95 |
65 void TypeNameDeduplicator::EstimateTraceMemoryOverhead( | 96 void TypeNameDeduplicator::EstimateTraceMemoryOverhead( |
66 TraceEventMemoryOverhead* overhead) { | 97 TraceEventMemoryOverhead* overhead) { |
67 // The size here is only an estimate; it fails to take into account the size | 98 // 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. | 99 // 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>); | 100 size_t map_size = type_ids_.size() * sizeof(std::pair<const char*, int>); |
70 | 101 |
71 overhead->Add("TypeNameDeduplicator", | 102 overhead->Add("TypeNameDeduplicator", |
72 sizeof(TypeNameDeduplicator) + map_size); | 103 sizeof(TypeNameDeduplicator) + map_size); |
73 } | 104 } |
74 | 105 |
75 } // namespace trace_event | 106 } // namespace trace_event |
76 } // namespace base | 107 } // namespace base |
OLD | NEW |