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 19 TypeNameDeduplicator::TypeNameDeduplicator() { 20 // A null pointer has type ID 0 ("unknown type"); 21 type_ids_.insert(std::make_pair(nullptr, 0)); 22 } 23 24 TypeNameDeduplicator::~TypeNameDeduplicator() {} 25 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 40 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 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