| 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 |