Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Unified Diff: base/trace_event/heap_profiler_type_name_deduplicator.cc

Issue 1467453003: [Tracing] Make heap profiler type info a string (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/trace_event/heap_profiler_type_name_deduplicator.cc
diff --git a/base/trace_event/heap_profiler_type_name_deduplicator.cc b/base/trace_event/heap_profiler_type_name_deduplicator.cc
new file mode 100644
index 0000000000000000000000000000000000000000..040528f37311beaa77090ec8090ea3fc8e6c6f36
--- /dev/null
+++ b/base/trace_event/heap_profiler_type_name_deduplicator.cc
@@ -0,0 +1,130 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/trace_event/heap_profiler_type_name_deduplicator.h"
+
+#include <stdlib.h>
+#include <string>
+#include <utility>
+
+#include "base/strings/stringprintf.h"
+#include "base/trace_event/trace_event_memory_overhead.h"
+
+#if !defined(COMPILER_MSVC)
+#include <cxxabi.h>
+#endif
+
+namespace base {
+namespace trace_event {
+
+namespace {
+
+// Wraps C++ symbol name demangling API for safer memory management.
+class Demangler {
+ public:
+ Demangler() : buffer_(nullptr), buffer_size_(0) {}
+
+ ~Demangler() {
+ if (buffer_)
+ free(buffer_);
+ }
+
+#if defined(COMPILER_MSVC)
+
+ // On MSVC, |typeid(T).name()| returns a human-readable, non-mangled type
+ // name, so there is no need to demangle anything.
+ const char* Demangle(const char* mangled_name) {
+ // Silence unused variable warnings.
+ static_cast<void>(buffer_);
+ static_cast<void>(buffer_size_);
+ return mangled_name;
+ }
+
+#else // GCC and Clang use the cross-vendor C++ ABI.
+
+ // Demangles a C++ symbol name returned by |typeid(T).name()|. The returned
+ // pointer is valid until the next call to |Demangle|, or until the the
+ // |Demangler| instance is destructed.
+ const char* Demangle(const char* mangled_name) {
+ // Reuse the buffer across calls. It will automatically be reallocated if
+ // it is not large enough to fit the demangled name.
+ int status = 0;
+ char* result =
+ abi::__cxa_demangle(mangled_name, buffer_, &buffer_size_, &status);
+
+ if (result) {
+ buffer_ = result;
+ return result;
+ }
+
+ return mangled_name;
+ }
+
+#endif // defined(COMPILER_MSVC)
+
+ private:
+ char* buffer_;
+ size_t buffer_size_;
+};
+
+} // namespace
+
+TypeNameDeduplicator::TypeNameDeduplicator() {
+ // A null pointer has type ID 0 ("unknown type");
+ type_ids_.insert(std::make_pair(nullptr, 0));
+ next_id_ = 1;
+}
+
+TypeNameDeduplicator::~TypeNameDeduplicator() {}
+
+int TypeNameDeduplicator::Insert(const char* type_name) {
+ auto result = type_ids_.insert(std::make_pair(type_name, 0));
+ auto& elem = result.first;
+ bool did_not_exist_before = result.second;
+
+ if (did_not_exist_before) {
+ elem->second = next_id_;
+ next_id_++;
+ }
+
+ return elem->second;
+}
+
+void TypeNameDeduplicator::AppendAsTraceFormat(std::string* out) const {
+ out->append("{"); // Begin the type names dictionary.
+
+ auto it = type_ids_.begin();
+ std::string stringify_buffer;
+ Demangler demangler;
+
+ // Write the first entry manually; the null pointer must not be dereferenced.
+ // (The first entry is the null pointer because a |std::map| is ordered.)
+ it++;
+ out->append("\"0\":\"[unknown]\"");
+
+ for (; it != type_ids_.end(); it++) {
+ // Type IDs in the trace are strings, write them as stringified keys of
+ // a dictionary. The type name string does not need to be escaped for the
+ // json to valid, because type names have to be valid C++ identifiers,
+ // which cannot contain quotes, backslashes, or control characters.
+ const char* type_name = demangler.Demangle(it->first);
+ SStringPrintf(&stringify_buffer, ",\"%d\":\"%s\"", it->second, type_name);
Primiano Tucci (use gerrit) 2015/11/23 15:46:48 use EscapeJSONString ? I can already see the day s
Ruud van Asseldonk 2015/11/23 18:23:26 Done.
+ out->append(stringify_buffer);
+ }
+
+ out->append("}"); // End the type names dictionary.
+}
+
+void TypeNameDeduplicator::EstimateTraceMemoryOverhead(
+ TraceEventMemoryOverhead* overhead) {
+ // The size here is only an estimate; it fails to take into account the size
+ // of the tree nodes for the map, but as an estimate this should be fine.
+ size_t map_size = type_ids_.size() * sizeof(std::pair<const char*, int>);
+
+ overhead->Add("TypeNameDeduplicator",
+ sizeof(TypeNameDeduplicator) + map_size);
+}
+
+} // namespace trace_event
+} // namespace base

Powered by Google App Engine
This is Rietveld 408576698