summaryrefslogtreecommitdiffstats
path: root/base/trace_event
diff options
context:
space:
mode:
authorruuda <ruuda@google.com>2015-11-26 08:29:51 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-26 16:31:09 +0000
commit04511cb6300db2b3cf886bb7d147e1ae72fb8ce6 (patch)
tree0c1ba0ac9d9fdda909685f203a540b08b27499bd /base/trace_event
parent0c25d053b2e03437ae72b72253c12a7d10e2dee4 (diff)
downloadchromium_src-04511cb6300db2b3cf886bb7d147e1ae72fb8ce6.zip
chromium_src-04511cb6300db2b3cf886bb7d147e1ae72fb8ce6.tar.gz
chromium_src-04511cb6300db2b3cf886bb7d147e1ae72fb8ce6.tar.bz2
Remove memory category from chrome://tracing
The tcmalloc heap profiler will be replaced with the heap profiler in memory-infra. This removes the old "memory" category in chrome://tracing. (For now, the checkbox still exists in the UI.) A few places still reference the heap profiling functionality of tcmalloc. This is left untouched. Related trace viewer issues: https://github.com/catapult-project/catapult/issues/1050 https://github.com/catapult-project/catapult/issues/1804 BUG=560300, 524631 TBR=brettw Review URL: https://codereview.chromium.org/1468883003 Cr-Commit-Position: refs/heads/master@{#361903}
Diffstat (limited to 'base/trace_event')
-rw-r--r--base/trace_event/BUILD.gn3
-rw-r--r--base/trace_event/common/trace_event_common.h20
-rw-r--r--base/trace_event/trace_event.gypi3
-rw-r--r--base/trace_event/trace_event.h1
-rw-r--r--base/trace_event/trace_event_memory.cc438
-rw-r--r--base/trace_event/trace_event_memory.h171
-rw-r--r--base/trace_event/trace_event_memory_unittest.cc236
7 files changed, 3 insertions, 869 deletions
diff --git a/base/trace_event/BUILD.gn b/base/trace_event/BUILD.gn
index 07d28fe..f0e90a7 100644
--- a/base/trace_event/BUILD.gn
+++ b/base/trace_event/BUILD.gn
@@ -53,8 +53,6 @@ source_set("trace_event") {
"trace_event_etw_export_win.h",
"trace_event_impl.cc",
"trace_event_impl.h",
- "trace_event_memory.cc",
- "trace_event_memory.h",
"trace_event_memory_overhead.cc",
"trace_event_memory_overhead.h",
"trace_event_synthetic_delay.cc",
@@ -127,7 +125,6 @@ source_set("trace_event_unittests") {
"trace_config_memory_test_util.h",
"trace_config_unittest.cc",
"trace_event_argument_unittest.cc",
- "trace_event_memory_unittest.cc",
"trace_event_synthetic_delay_unittest.cc",
"trace_event_system_stats_monitor_unittest.cc",
"trace_event_unittest.cc",
diff --git a/base/trace_event/common/trace_event_common.h b/base/trace_event/common/trace_event_common.h
index cae3670..72202f3 100644
--- a/base/trace_event/common/trace_event_common.h
+++ b/base/trace_event/common/trace_event_common.h
@@ -203,40 +203,26 @@
// - category and name strings must have application lifetime (statics or
// literals). They may not include " chars.
#define TRACE_EVENT0(category_group, name) \
- INTERNAL_TRACE_MEMORY(category_group, name) \
INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name)
#define TRACE_EVENT_WITH_FLOW0(category_group, name, bind_id, flow_flags) \
- INTERNAL_TRACE_MEMORY(category_group, name) \
INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, bind_id, \
flow_flags)
#define TRACE_EVENT1(category_group, name, arg1_name, arg1_val) \
- INTERNAL_TRACE_MEMORY(category_group, name) \
INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val)
#define TRACE_EVENT_WITH_FLOW1(category_group, name, bind_id, flow_flags, \
arg1_name, arg1_val) \
- INTERNAL_TRACE_MEMORY(category_group, name) \
INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, bind_id, \
flow_flags, arg1_name, arg1_val)
#define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, \
arg2_val) \
- INTERNAL_TRACE_MEMORY(category_group, name) \
INTERNAL_TRACE_EVENT_ADD_SCOPED(category_group, name, arg1_name, arg1_val, \
arg2_name, arg2_val)
#define TRACE_EVENT_WITH_FLOW2(category_group, name, bind_id, flow_flags, \
arg1_name, arg1_val, arg2_name, arg2_val) \
- INTERNAL_TRACE_MEMORY(category_group, name) \
INTERNAL_TRACE_EVENT_ADD_SCOPED_WITH_FLOW(category_group, name, bind_id, \
flow_flags, arg1_name, arg1_val, \
arg2_name, arg2_val)
-// Records events like TRACE_EVENT2 but uses |memory_tag| for memory tracing.
-// Use this where |name| is too generic to accurately aggregate allocations.
-#define TRACE_EVENT_WITH_MEMORY_TAG2(category, name, memory_tag, arg1_name, \
- arg1_val, arg2_name, arg2_val) \
- INTERNAL_TRACE_MEMORY(category, memory_tag) \
- INTERNAL_TRACE_EVENT_ADD_SCOPED(category, name, arg1_name, arg1_val, \
- arg2_name, arg2_val)
-
// UNSHIPPED_TRACE_EVENT* are like TRACE_EVENT* except that they are not
// included in official builds.
@@ -310,9 +296,9 @@
arg2_name, arg2_val)
#define TRACE_EVENT_INSTANT_WITH_TIMESTAMP0(category_group, name, scope, \
- timestamp) \
- INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
- TRACE_EVENT_PHASE_INSTANT, category_group, name, 0, 0, timestamp, \
+ timestamp) \
+ INTERNAL_TRACE_EVENT_ADD_WITH_ID_TID_AND_TIMESTAMP( \
+ TRACE_EVENT_PHASE_INSTANT, category_group, name, 0, 0, timestamp, \
TRACE_EVENT_FLAG_NONE | scope)
// Syntactic sugars for the sampling tracing in the main thread.
diff --git a/base/trace_event/trace_event.gypi b/base/trace_event/trace_event.gypi
index ca37015..0c43ae1 100644
--- a/base/trace_event/trace_event.gypi
+++ b/base/trace_event/trace_event.gypi
@@ -53,8 +53,6 @@
'trace_event/trace_event_etw_export_win.h',
'trace_event/trace_event_impl.cc',
'trace_event/trace_event_impl.h',
- 'trace_event/trace_event_memory.cc',
- 'trace_event/trace_event_memory.h',
'trace_event/trace_event_memory_overhead.cc',
'trace_event/trace_event_memory_overhead.h',
'trace_event/trace_event_synthetic_delay.cc',
@@ -83,7 +81,6 @@
'trace_event/trace_config_memory_test_util.h',
'trace_event/trace_config_unittest.cc',
'trace_event/trace_event_argument_unittest.cc',
- 'trace_event/trace_event_memory_unittest.cc',
'trace_event/trace_event_synthetic_delay_unittest.cc',
'trace_event/trace_event_system_stats_monitor_unittest.cc',
'trace_event/trace_event_unittest.cc',
diff --git a/base/trace_event/trace_event.h b/base/trace_event/trace_event.h
index 14448e2..7a2a656 100644
--- a/base/trace_event/trace_event.h
+++ b/base/trace_event/trace_event.h
@@ -14,7 +14,6 @@
#include "base/atomicops.h"
#include "base/time/time.h"
#include "base/trace_event/common/trace_event_common.h"
-#include "base/trace_event/trace_event_memory.h"
#include "base/trace_event/trace_event_system_stats_monitor.h"
#include "base/trace_event/trace_log.h"
#include "build/build_config.h"
diff --git a/base/trace_event/trace_event_memory.cc b/base/trace_event/trace_event_memory.cc
deleted file mode 100644
index 187bf74..0000000
--- a/base/trace_event/trace_event_memory.cc
+++ /dev/null
@@ -1,438 +0,0 @@
-// Copyright 2013 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/trace_event_memory.h"
-
-#include <utility>
-
-#include "base/debug/leak_annotations.h"
-#include "base/lazy_instance.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/single_thread_task_runner.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/string_split.h"
-#include "base/strings/string_util.h"
-#include "base/threading/thread_local_storage.h"
-#include "base/trace_event/trace_event.h"
-
-namespace base {
-namespace trace_event {
-
-namespace {
-
-// Maximum number of nested TRACE_EVENT scopes to record. Must be less than
-// or equal to HeapProfileTable::kMaxStackDepth / 2 because we record two
-// entries on the pseudo-stack per scope.
-const size_t kMaxScopeDepth = 16;
-
-/////////////////////////////////////////////////////////////////////////////
-// Holds a memory dump until the tracing system needs to serialize it.
-class MemoryDumpHolder : public base::trace_event::ConvertableToTraceFormat {
- public:
- // Takes ownership of dump, which must be a JSON string, allocated with
- // malloc() and NULL terminated.
- explicit MemoryDumpHolder(char* dump) : dump_(dump) {}
-
- // base::trace_event::ConvertableToTraceFormat overrides:
- void AppendAsTraceFormat(std::string* out) const override {
- AppendHeapProfileAsTraceFormat(dump_, out);
- }
-
- private:
- ~MemoryDumpHolder() override { free(dump_); }
-
- char* dump_;
-
- DISALLOW_COPY_AND_ASSIGN(MemoryDumpHolder);
-};
-
-/////////////////////////////////////////////////////////////////////////////
-// Records a stack of TRACE_MEMORY events. One per thread is required.
-struct TraceMemoryStack {
- TraceMemoryStack() : scope_depth(0) {
- memset(scope_data, 0, kMaxScopeDepth * sizeof(scope_data[0]));
- }
-
- // Depth of the currently nested TRACE_EVENT scopes. Allowed to be greater
- // than kMaxScopeDepth so we can match scope pushes and pops even if we don't
- // have enough space to store the EventData.
- size_t scope_depth;
-
- // Stack of categories and names.
- ScopedTraceMemory::ScopeData scope_data[kMaxScopeDepth];
-};
-
-// Pointer to a TraceMemoryStack per thread.
-base::ThreadLocalStorage::StaticSlot tls_trace_memory_stack = TLS_INITIALIZER;
-
-// Clean up memory pointed to by our thread-local storage.
-void DeleteStackOnThreadCleanup(void* value) {
- TraceMemoryStack* stack = static_cast<TraceMemoryStack*>(value);
- delete stack;
-}
-
-// Initializes the thread-local TraceMemoryStack pointer.
-void InitThreadLocalStorage() {
- if (tls_trace_memory_stack.initialized())
- return;
- // Initialize the thread-local storage key.
- tls_trace_memory_stack.Initialize(&DeleteStackOnThreadCleanup);
-}
-
-// Clean up thread-local-storage in the main thread.
-void CleanupThreadLocalStorage() {
- if (!tls_trace_memory_stack.initialized())
- return;
- TraceMemoryStack* stack =
- static_cast<TraceMemoryStack*>(tls_trace_memory_stack.Get());
- delete stack;
- tls_trace_memory_stack.Set(NULL);
- // Intentionally do not release the thread-local-storage key here, that is,
- // do not call tls_trace_memory_stack.Free(). Other threads have lazily
- // created pointers in thread-local-storage via GetTraceMemoryStack() below.
- // Those threads need to run the DeleteStack() destructor function when they
- // exit. If we release the key the destructor will not be called and those
- // threads will not clean up their memory.
-}
-
-// Returns the thread-local trace memory stack for the current thread, creating
-// one if needed. Returns NULL if the thread-local storage key isn't
-// initialized, which indicates that heap profiling isn't running.
-TraceMemoryStack* GetTraceMemoryStack() {
- TraceMemoryStack* stack =
- static_cast<TraceMemoryStack*>(tls_trace_memory_stack.Get());
- // Lazily initialize TraceMemoryStack objects for new threads.
- if (!stack) {
- stack = new TraceMemoryStack;
- tls_trace_memory_stack.Set(stack);
- }
- return stack;
-}
-
-// Returns a "pseudo-stack" of pointers to trace event categories and names.
-// Because tcmalloc stores one pointer per stack frame this converts N nested
-// trace events into N * 2 pseudo-stack entries. Thus this macro invocation:
-// TRACE_EVENT0("category1", "name1");
-// TRACE_EVENT0("category2", "name2");
-// becomes this pseudo-stack:
-// stack_out[0] = "category1"
-// stack_out[1] = "name1"
-// stack_out[2] = "category2"
-// stack_out[3] = "name2"
-// Returns int instead of size_t to match the signature required by tcmalloc.
-int GetPseudoStack(int skip_count_ignored, void** stack_out) {
- // If the tracing system isn't fully initialized, just skip this allocation.
- // Attempting to initialize will allocate memory, causing this function to
- // be called recursively from inside the allocator.
- if (!tls_trace_memory_stack.initialized() || !tls_trace_memory_stack.Get())
- return 0;
- TraceMemoryStack* stack =
- static_cast<TraceMemoryStack*>(tls_trace_memory_stack.Get());
- // Copy at most kMaxScopeDepth scope entries.
- const size_t count = std::min(stack->scope_depth, kMaxScopeDepth);
- // Notes that memcpy() works for zero bytes.
- memcpy(stack_out,
- stack->scope_data,
- count * sizeof(stack->scope_data[0]));
- // Each item in the trace event stack contains both name and category so tell
- // tcmalloc that we have returned |count| * 2 stack frames.
- return static_cast<int>(count * 2);
-}
-
-} // namespace
-
-//////////////////////////////////////////////////////////////////////////////
-
-TraceMemoryController::TraceMemoryController(
- scoped_refptr<SingleThreadTaskRunner> task_runner,
- HeapProfilerStartFunction heap_profiler_start_function,
- HeapProfilerStopFunction heap_profiler_stop_function,
- GetHeapProfileFunction get_heap_profile_function)
- : task_runner_(std::move(task_runner)),
- heap_profiler_start_function_(heap_profiler_start_function),
- heap_profiler_stop_function_(heap_profiler_stop_function),
- get_heap_profile_function_(get_heap_profile_function),
- weak_factory_(this) {
- // Force the "memory" category to show up in the trace viewer.
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("memory"), "init");
- // Watch for the tracing system being enabled.
- TraceLog::GetInstance()->AddEnabledStateObserver(this);
-}
-
-TraceMemoryController::~TraceMemoryController() {
- if (dump_timer_.IsRunning())
- StopProfiling();
- TraceLog::GetInstance()->RemoveEnabledStateObserver(this);
-}
-
-// base::trace_event::TraceLog::EnabledStateChangedObserver overrides:
-void TraceMemoryController::OnTraceLogEnabled() {
- // Check to see if tracing is enabled for the memory category.
- bool enabled;
- TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("memory"),
- &enabled);
- if (!enabled)
- return;
- DVLOG(1) << "OnTraceLogEnabled";
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&TraceMemoryController::StartProfiling,
- weak_factory_.GetWeakPtr()));
-}
-
-void TraceMemoryController::OnTraceLogDisabled() {
- // The memory category is always disabled before OnTraceLogDisabled() is
- // called, so we cannot tell if it was enabled before. Always try to turn
- // off profiling.
- DVLOG(1) << "OnTraceLogDisabled";
- task_runner_->PostTask(FROM_HERE,
- base::Bind(&TraceMemoryController::StopProfiling,
- weak_factory_.GetWeakPtr()));
-}
-
-void TraceMemoryController::StartProfiling() {
- // Watch for the tracing framework sending enabling more than once.
- if (dump_timer_.IsRunning())
- return;
- DVLOG(1) << "Starting trace memory";
- InitThreadLocalStorage();
- ScopedTraceMemory::set_enabled(true);
- // Call ::HeapProfilerWithPseudoStackStart().
- heap_profiler_start_function_(&GetPseudoStack);
- const int kDumpIntervalSeconds = 5;
- dump_timer_.Start(FROM_HERE,
- TimeDelta::FromSeconds(kDumpIntervalSeconds),
- base::Bind(&TraceMemoryController::DumpMemoryProfile,
- weak_factory_.GetWeakPtr()));
-}
-
-void TraceMemoryController::DumpMemoryProfile() {
- // Don't trace allocations here in the memory tracing system.
- INTERNAL_TRACE_MEMORY(TRACE_DISABLED_BY_DEFAULT("memory"),
- TRACE_MEMORY_IGNORE);
-
- DVLOG(1) << "DumpMemoryProfile";
- // MemoryDumpHolder takes ownership of this string. See GetHeapProfile() in
- // tcmalloc for details.
- char* dump = get_heap_profile_function_();
- const int kSnapshotId = 1;
- TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID(
- TRACE_DISABLED_BY_DEFAULT("memory"),
- "memory::Heap",
- kSnapshotId,
- scoped_refptr<ConvertableToTraceFormat>(new MemoryDumpHolder(dump)));
-}
-
-void TraceMemoryController::StopProfiling() {
- // Watch for the tracing framework sending disabled more than once.
- if (!dump_timer_.IsRunning())
- return;
- DVLOG(1) << "Stopping trace memory";
- dump_timer_.Stop();
- ScopedTraceMemory::set_enabled(false);
- CleanupThreadLocalStorage();
- // Call ::HeapProfilerStop().
- heap_profiler_stop_function_();
-}
-
-bool TraceMemoryController::IsTimerRunningForTest() const {
- return dump_timer_.IsRunning();
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-// static
-bool ScopedTraceMemory::enabled_ = false;
-
-void ScopedTraceMemory::Initialize(const char* category, const char* name) {
- DCHECK(enabled_);
- // Get our thread's copy of the stack.
- TraceMemoryStack* trace_memory_stack = GetTraceMemoryStack();
- const size_t index = trace_memory_stack->scope_depth;
- // Don't record data for deeply nested scopes, but continue to increment
- // |stack_depth| so we can match pushes and pops.
- if (index < kMaxScopeDepth) {
- ScopeData& event = trace_memory_stack->scope_data[index];
- event.category = category;
- event.name = name;
- }
- trace_memory_stack->scope_depth++;
-}
-
-void ScopedTraceMemory::Destroy() {
- DCHECK(enabled_);
- // Get our thread's copy of the stack.
- TraceMemoryStack* trace_memory_stack = GetTraceMemoryStack();
- // The tracing system can be turned on with ScopedTraceMemory objects
- // allocated on the stack, so avoid potential underflow as they are destroyed.
- if (trace_memory_stack->scope_depth > 0)
- trace_memory_stack->scope_depth--;
-}
-
-// static
-void ScopedTraceMemory::InitForTest() {
- InitThreadLocalStorage();
- enabled_ = true;
-}
-
-// static
-void ScopedTraceMemory::CleanupForTest() {
- enabled_ = false;
- CleanupThreadLocalStorage();
-}
-
-// static
-int ScopedTraceMemory::GetStackDepthForTest() {
- TraceMemoryStack* stack = GetTraceMemoryStack();
- return static_cast<int>(stack->scope_depth);
-}
-
-// static
-ScopedTraceMemory::ScopeData ScopedTraceMemory::GetScopeDataForTest(
- int stack_index) {
- TraceMemoryStack* stack = GetTraceMemoryStack();
- return stack->scope_data[stack_index];
-}
-
-/////////////////////////////////////////////////////////////////////////////
-
-void AppendHeapProfileAsTraceFormat(const char* input, std::string* output) {
- // Heap profile output has a header total line, then a list of stacks with
- // memory totals, like this:
- //
- // heap profile: 357: 55227 [ 14653: 2624014] @ heapprofile
- // 95: 40940 [ 649: 114260] @ 0x7fa7f4b3be13
- // 77: 32546 [ 742: 106234] @
- // 68: 4195 [ 1087: 98009] @ 0x7fa7fa9b9ba0 0x7fa7f4b3be13
- //
- // MAPPED_LIBRARIES:
- // 1be411fc1000-1be4139e4000 rw-p 00000000 00:00 0
- // 1be4139e4000-1be4139e5000 ---p 00000000 00:00 0
- // ...
- //
- // Skip input after MAPPED_LIBRARIES.
- std::string input_string;
- const char* mapped_libraries = strstr(input, "MAPPED_LIBRARIES");
- if (mapped_libraries) {
- input_string.assign(input, mapped_libraries - input);
- } else {
- input_string.assign(input);
- }
-
- std::vector<std::string> lines = base::SplitString(
- input_string, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
- if (lines.empty()) {
- DLOG(WARNING) << "No lines found";
- return;
- }
-
- // Handle the initial summary line.
- output->append("[");
- AppendHeapProfileTotalsAsTraceFormat(lines[0], output);
-
- // Handle the following stack trace lines.
- for (size_t i = 1; i < lines.size(); i++)
- AppendHeapProfileLineAsTraceFormat(lines[i], output);
- output->append("]\n");
-}
-
-void AppendHeapProfileTotalsAsTraceFormat(const std::string& line,
- std::string* output) {
- // This is what a line looks like:
- // heap profile: 357: 55227 [ 14653: 2624014] @ heapprofile
- //
- // The numbers represent total allocations since profiling was enabled.
- // From the example above:
- // 357 = Outstanding allocations (mallocs - frees)
- // 55227 = Outstanding bytes (malloc bytes - free bytes)
- // 14653 = Total allocations (mallocs)
- // 2624014 = Total bytes (malloc bytes)
- std::vector<std::string> tokens = base::SplitString(
- line, " :[]@", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
- if (tokens.size() < 4) {
- DLOG(WARNING) << "Invalid totals line " << line;
- return;
- }
- DCHECK_EQ(tokens[0], "heap");
- DCHECK_EQ(tokens[1], "profile");
- output->append("{\"current_allocs\": ");
- output->append(tokens[2]);
- output->append(", \"current_bytes\": ");
- output->append(tokens[3]);
- output->append(", \"trace\": \"\"}");
-}
-
-bool AppendHeapProfileLineAsTraceFormat(const std::string& line,
- std::string* output) {
- // This is what a line looks like:
- // 68: 4195 [ 1087: 98009] @ 0x7fa7fa9b9ba0 0x7fa7f4b3be13
- //
- // The numbers represent allocations for a particular stack trace since
- // profiling was enabled. From the example above:
- // 68 = Outstanding allocations (mallocs - frees)
- // 4195 = Outstanding bytes (malloc bytes - free bytes)
- // 1087 = Total allocations (mallocs)
- // 98009 = Total bytes (malloc bytes)
- //
- // 0x7fa7fa9b9ba0 0x7fa7f4b3be13 = Stack trace represented as pointers to
- // static strings from trace event categories
- // and names.
- std::vector<std::string> tokens = base::SplitString(
- line, " :[]@", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
- // It's valid to have no stack addresses, so only require 4 tokens.
- if (tokens.size() < 4) {
- DLOG(WARNING) << "Invalid line " << line;
- return false;
- }
- // Don't bother with stacks that have no current allocations.
- if (tokens[0] == "0")
- return false;
- output->append(",\n");
- output->append("{\"current_allocs\": ");
- output->append(tokens[0]);
- output->append(", \"current_bytes\": ");
- output->append(tokens[1]);
- output->append(", \"trace\": \"");
-
- // Convert pairs of "stack addresses" into category and name strings.
- const std::string kSingleQuote = "'";
- for (size_t t = 4; t < tokens.size(); t += 2) {
- // Casting strings into pointers is ugly but otherwise tcmalloc would need
- // to gain a special output serializer just for pseudo-stacks.
- const char* trace_category = StringFromHexAddress(tokens[t]);
- DCHECK_LT(t + 1, tokens.size());
- const char* trace_name = StringFromHexAddress(tokens[t + 1]);
-
- // TODO(jamescook): Report the trace category and name separately to the
- // trace viewer and allow it to decide what decorations to apply. For now
- // just hard-code a decoration for posted tasks (toplevel).
- std::string trace_string(trace_name);
- if (!strcmp(trace_category, "toplevel"))
- trace_string.append("->PostTask");
-
- // Some trace name strings have double quotes, convert them to single.
- ReplaceChars(trace_string, "\"", kSingleQuote, &trace_string);
-
- output->append(trace_string);
-
- // Trace viewer expects a trailing space.
- output->append(" ");
- }
- output->append("\"}");
- return true;
-}
-
-const char* StringFromHexAddress(const std::string& hex_address) {
- uint64 address = 0;
- if (!base::HexStringToUInt64(hex_address, &address))
- return "error";
- if (!address)
- return "null";
- // Note that this cast handles 64-bit to 32-bit conversion if necessary.
- return reinterpret_cast<const char*>(address);
-}
-
-} // namespace trace_event
-} // namespace base
diff --git a/base/trace_event/trace_event_memory.h b/base/trace_event/trace_event_memory.h
deleted file mode 100644
index 7088080..0000000
--- a/base/trace_event/trace_event_memory.h
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef BASE_TRACE_EVENT_TRACE_EVENT_MEMORY_H_
-#define BASE_TRACE_EVENT_TRACE_EVENT_MEMORY_H_
-
-#include "base/base_export.h"
-#include "base/gtest_prod_util.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "base/timer/timer.h"
-#include "base/trace_event/trace_log.h"
-
-// TODO(jamescook): Windows support for memory tracing.
-#if !defined(NO_TCMALLOC) && !defined(OS_NACL) && \
- (defined(OS_LINUX) || defined(OS_ANDROID))
-#define TCMALLOC_TRACE_MEMORY_SUPPORTED 1
-#endif
-
-namespace base {
-
-class SingleThreadTaskRunner;
-
-namespace trace_event {
-
-// Watches for chrome://tracing to be enabled or disabled. When tracing is
-// enabled, also enables tcmalloc heap profiling. This class is the preferred
-// way to turn trace-base heap memory profiling on and off.
-class BASE_EXPORT TraceMemoryController
- : public TraceLog::EnabledStateObserver {
- public:
- typedef int (*StackGeneratorFunction)(int skip_count, void** stack);
- typedef void (*HeapProfilerStartFunction)(StackGeneratorFunction callback);
- typedef void (*HeapProfilerStopFunction)();
- typedef char* (*GetHeapProfileFunction)();
-
- // |task_runner| must be a task runner for the primary thread for the client
- // process, e.g. the UI thread in a browser. The function pointers must be
- // pointers to tcmalloc heap profiling functions; by avoiding direct calls to
- // these functions we avoid a dependency on third_party/tcmalloc from base.
- TraceMemoryController(scoped_refptr<SingleThreadTaskRunner> task_runner,
- HeapProfilerStartFunction heap_profiler_start_function,
- HeapProfilerStopFunction heap_profiler_stop_function,
- GetHeapProfileFunction get_heap_profile_function);
- ~TraceMemoryController() override;
-
- // base::trace_event::TraceLog::EnabledStateChangedObserver overrides:
- void OnTraceLogEnabled() override;
- void OnTraceLogDisabled() override;
-
- // Starts heap memory profiling.
- void StartProfiling();
-
- // Captures a heap profile.
- void DumpMemoryProfile();
-
- // If memory tracing is enabled, dumps a memory profile to the tracing system.
- void StopProfiling();
-
- private:
- FRIEND_TEST_ALL_PREFIXES(TraceMemoryTest, TraceMemoryController);
-
- bool IsTimerRunningForTest() const;
-
- // Ensures the observer starts and stops tracing on the primary thread.
- scoped_refptr<SingleThreadTaskRunner> task_runner_;
-
- // Pointers to tcmalloc heap profiling functions. Allows this class to use
- // tcmalloc functions without introducing a dependency from base to tcmalloc.
- HeapProfilerStartFunction heap_profiler_start_function_;
- HeapProfilerStopFunction heap_profiler_stop_function_;
- GetHeapProfileFunction get_heap_profile_function_;
-
- // Timer to schedule memory profile dumps.
- RepeatingTimer dump_timer_;
-
- WeakPtrFactory<TraceMemoryController> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(TraceMemoryController);
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-// A scoped context for memory tracing. Pushes the name onto a stack for
-// recording by tcmalloc heap profiling.
-class BASE_EXPORT ScopedTraceMemory {
- public:
- struct ScopeData {
- const char* category;
- const char* name;
- };
-
- // Memory for |category| and |name| must be static, for example, literal
- // strings in a TRACE_EVENT macro.
- ScopedTraceMemory(const char* category, const char* name) {
- if (!enabled_)
- return;
- Initialize(category, name);
- }
- ~ScopedTraceMemory() {
- if (!enabled_)
- return;
- Destroy();
- }
-
- // Enables the storing of trace names on a per-thread stack.
- static void set_enabled(bool enabled) { enabled_ = enabled; }
-
- // Testing interface:
- static void InitForTest();
- static void CleanupForTest();
- static int GetStackDepthForTest();
- static ScopeData GetScopeDataForTest(int stack_index);
-
- private:
- void Initialize(const char* category, const char* name);
- void Destroy();
-
- static bool enabled_;
- DISALLOW_COPY_AND_ASSIGN(ScopedTraceMemory);
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-// Converts tcmalloc's heap profiler data with pseudo-stacks in |input| to
-// trace event compatible JSON and appends to |output|. Visible for testing.
-BASE_EXPORT void AppendHeapProfileAsTraceFormat(const char* input,
- std::string* output);
-
-// Converts the first |line| of heap profiler data, which contains totals for
-// all allocations in a special format, into trace event compatible JSON and
-// appends to |output|. Visible for testing.
-BASE_EXPORT void AppendHeapProfileTotalsAsTraceFormat(const std::string& line,
- std::string* output);
-
-// Converts a single |line| of heap profiler data into trace event compatible
-// JSON and appends to |output|. Returns true if the line was valid and has a
-// non-zero number of current allocations. Visible for testing.
-BASE_EXPORT bool AppendHeapProfileLineAsTraceFormat(const std::string& line,
- std::string* output);
-
-// Returns a pointer to a string given its hexadecimal address in |hex_address|.
-// Handles both 32-bit and 64-bit addresses. Returns "null" for null pointers
-// and "error" if |address| could not be parsed. Visible for testing.
-BASE_EXPORT const char* StringFromHexAddress(const std::string& hex_address);
-
-} // namespace trace_event
-} // namespace base
-
-// Make local variables with unique names based on the line number. Note that
-// the extra level of redirection is needed.
-#define INTERNAL_TRACE_MEMORY_ID3(line) trace_memory_unique_##line
-#define INTERNAL_TRACE_MEMORY_ID2(line) INTERNAL_TRACE_MEMORY_ID3(line)
-#define INTERNAL_TRACE_MEMORY_ID INTERNAL_TRACE_MEMORY_ID2(__LINE__)
-
-// This is the core macro that adds a scope to each TRACE_EVENT location.
-// It generates a unique local variable name using the macros above.
-#if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
-#define INTERNAL_TRACE_MEMORY(category, name) \
- base::trace_event::ScopedTraceMemory INTERNAL_TRACE_MEMORY_ID(category, name);
-#else
-#define INTERNAL_TRACE_MEMORY(category, name)
-#endif // defined(TRACE_MEMORY_SUPPORTED)
-
-// A special trace name that allows us to ignore memory allocations inside
-// the memory dump system itself. The allocations are recorded, but the
-// visualizer skips them. Must match the value in heap.js.
-#define TRACE_MEMORY_IGNORE "trace-memory-ignore"
-
-#endif // BASE_TRACE_EVENT_TRACE_EVENT_MEMORY_H_
diff --git a/base/trace_event/trace_event_memory_unittest.cc b/base/trace_event/trace_event_memory_unittest.cc
deleted file mode 100644
index 781a054..0000000
--- a/base/trace_event/trace_event_memory_unittest.cc
+++ /dev/null
@@ -1,236 +0,0 @@
-// Copyright 2013 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/trace_event_memory.h"
-
-#include <sstream>
-#include <string>
-
-#include "base/trace_event/trace_event_impl.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
-#include "third_party/tcmalloc/chromium/src/gperftools/heap-profiler.h"
-#endif
-
-namespace base {
-namespace trace_event {
-
-// Tests for the trace event memory tracking system. Exists as a class so it
-// can be a friend of TraceMemoryController.
-class TraceMemoryTest : public testing::Test {
- public:
- TraceMemoryTest() {}
- ~TraceMemoryTest() override {}
-
- private:
- DISALLOW_COPY_AND_ASSIGN(TraceMemoryTest);
-};
-
-//////////////////////////////////////////////////////////////////////////////
-
-#if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
-
-TEST_F(TraceMemoryTest, TraceMemoryController) {
- MessageLoop message_loop;
-
- // Start with no observers of the TraceLog.
- EXPECT_EQ(0u, TraceLog::GetInstance()->GetObserverCountForTest());
-
- // Creating a controller adds it to the TraceLog observer list.
- scoped_ptr<TraceMemoryController> controller(new TraceMemoryController(
- message_loop.task_runner(), ::HeapProfilerWithPseudoStackStart,
- ::HeapProfilerStop, ::GetHeapProfile));
- EXPECT_EQ(1u, TraceLog::GetInstance()->GetObserverCountForTest());
- EXPECT_TRUE(
- TraceLog::GetInstance()->HasEnabledStateObserver(controller.get()));
-
- // By default the observer isn't dumping memory profiles.
- EXPECT_FALSE(controller->IsTimerRunningForTest());
-
- // Simulate enabling tracing.
- controller->StartProfiling();
- message_loop.RunUntilIdle();
- EXPECT_TRUE(controller->IsTimerRunningForTest());
-
- // Simulate disabling tracing.
- controller->StopProfiling();
- message_loop.RunUntilIdle();
- EXPECT_FALSE(controller->IsTimerRunningForTest());
-
- // Deleting the observer removes it from the TraceLog observer list.
- controller.reset();
- EXPECT_EQ(0u, TraceLog::GetInstance()->GetObserverCountForTest());
-}
-
-TEST_F(TraceMemoryTest, ScopedTraceMemory) {
- ScopedTraceMemory::InitForTest();
-
- // Start with an empty stack.
- EXPECT_EQ(0, ScopedTraceMemory::GetStackDepthForTest());
-
- {
- // Push an item.
- ScopedTraceMemory scope1("cat1", "name1");
- EXPECT_EQ(1, ScopedTraceMemory::GetStackDepthForTest());
- EXPECT_EQ("cat1", ScopedTraceMemory::GetScopeDataForTest(0).category);
- EXPECT_EQ("name1", ScopedTraceMemory::GetScopeDataForTest(0).name);
-
- {
- // One more item.
- ScopedTraceMemory scope2("cat2", "name2");
- EXPECT_EQ(2, ScopedTraceMemory::GetStackDepthForTest());
- EXPECT_EQ("cat2", ScopedTraceMemory::GetScopeDataForTest(1).category);
- EXPECT_EQ("name2", ScopedTraceMemory::GetScopeDataForTest(1).name);
- }
-
- // Ended scope 2.
- EXPECT_EQ(1, ScopedTraceMemory::GetStackDepthForTest());
- }
-
- // Ended scope 1.
- EXPECT_EQ(0, ScopedTraceMemory::GetStackDepthForTest());
-
- ScopedTraceMemory::CleanupForTest();
-}
-
-void TestDeepScopeNesting(int current, int depth) {
- EXPECT_EQ(current, ScopedTraceMemory::GetStackDepthForTest());
- ScopedTraceMemory scope("category", "name");
- if (current < depth)
- TestDeepScopeNesting(current + 1, depth);
- EXPECT_EQ(current + 1, ScopedTraceMemory::GetStackDepthForTest());
-}
-
-TEST_F(TraceMemoryTest, DeepScopeNesting) {
- ScopedTraceMemory::InitForTest();
-
- // Ensure really deep scopes don't crash.
- TestDeepScopeNesting(0, 100);
-
- ScopedTraceMemory::CleanupForTest();
-}
-
-#endif // defined(TRACE_MEMORY_SUPPORTED)
-
-/////////////////////////////////////////////////////////////////////////////
-
-TEST_F(TraceMemoryTest, AppendHeapProfileTotalsAsTraceFormat) {
- // Empty input gives empty output.
- std::string empty_output;
- AppendHeapProfileTotalsAsTraceFormat("", &empty_output);
- EXPECT_EQ("", empty_output);
-
- // Typical case.
- const char input[] =
- "heap profile: 357: 55227 [ 14653: 2624014] @ heapprofile";
- const std::string kExpectedOutput =
- "{\"current_allocs\": 357, \"current_bytes\": 55227, \"trace\": \"\"}";
- std::string output;
- AppendHeapProfileTotalsAsTraceFormat(input, &output);
- EXPECT_EQ(kExpectedOutput, output);
-}
-
-TEST_F(TraceMemoryTest, AppendHeapProfileLineAsTraceFormat) {
- // Empty input gives empty output.
- std::string empty_output;
- EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat("", &empty_output));
- EXPECT_EQ("", empty_output);
-
- // Invalid input returns false.
- std::string junk_output;
- EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat("junk", &junk_output));
-
- // Input with normal category and name entries.
- const char kCategory[] = "category";
- const char kName[] = "name";
- std::ostringstream input;
- input << " 68: 4195 [ 1087: 98009] @ " << &kCategory << " "
- << &kName;
- const std::string kExpectedOutput =
- ",\n"
- "{"
- "\"current_allocs\": 68, "
- "\"current_bytes\": 4195, "
- "\"trace\": \"name \""
- "}";
- std::string output;
- EXPECT_TRUE(
- AppendHeapProfileLineAsTraceFormat(input.str().c_str(), &output));
- EXPECT_EQ(kExpectedOutput, output);
-
- // Input with with the category "toplevel".
- // TODO(jamescook): Eliminate this special case and move the logic to the
- // trace viewer code.
- const char kTaskCategory[] = "toplevel";
- const char kTaskName[] = "TaskName";
- std::ostringstream input2;
- input2 << " 68: 4195 [ 1087: 98009] @ " << &kTaskCategory << " "
- << &kTaskName;
- const std::string kExpectedOutput2 =
- ",\n"
- "{"
- "\"current_allocs\": 68, "
- "\"current_bytes\": 4195, "
- "\"trace\": \"TaskName->PostTask \""
- "}";
- std::string output2;
- EXPECT_TRUE(
- AppendHeapProfileLineAsTraceFormat(input2.str().c_str(), &output2));
- EXPECT_EQ(kExpectedOutput2, output2);
-
- // Zero current allocations is skipped.
- std::ostringstream zero_input;
- zero_input << " 0: 0 [ 1087: 98009] @ " << &kCategory << " "
- << &kName;
- std::string zero_output;
- EXPECT_FALSE(AppendHeapProfileLineAsTraceFormat(zero_input.str().c_str(),
- &zero_output));
- EXPECT_EQ("", zero_output);
-}
-
-TEST_F(TraceMemoryTest, AppendHeapProfileAsTraceFormat) {
- // Empty input gives empty output.
- std::string empty_output;
- AppendHeapProfileAsTraceFormat("", &empty_output);
- EXPECT_EQ("", empty_output);
-
- // Typical case.
- const char input[] =
- "heap profile: 357: 55227 [ 14653: 2624014] @ heapprofile\n"
- " 95: 40940 [ 649: 114260] @\n"
- " 77: 32546 [ 742: 106234] @ 0x0 0x0\n"
- " 0: 0 [ 132: 4236] @ 0x0\n"
- "\n"
- "MAPPED_LIBRARIES:\n"
- "1be411fc1000-1be4139e4000 rw-p 00000000 00:00 0\n"
- "1be4139e4000-1be4139e5000 ---p 00000000 00:00 0\n";
- const std::string kExpectedOutput =
- "[{"
- "\"current_allocs\": 357, "
- "\"current_bytes\": 55227, "
- "\"trace\": \"\"},\n"
- "{\"current_allocs\": 95, "
- "\"current_bytes\": 40940, "
- "\"trace\": \"\"},\n"
- "{\"current_allocs\": 77, "
- "\"current_bytes\": 32546, "
- "\"trace\": \"null \""
- "}]\n";
- std::string output;
- AppendHeapProfileAsTraceFormat(input, &output);
- EXPECT_EQ(kExpectedOutput, output);
-}
-
-TEST_F(TraceMemoryTest, StringFromHexAddress) {
- EXPECT_STREQ("null", StringFromHexAddress("0x0"));
- EXPECT_STREQ("error", StringFromHexAddress("not an address"));
- const char kHello[] = "hello";
- std::ostringstream hex_address;
- hex_address << &kHello;
- EXPECT_STREQ(kHello, StringFromHexAddress(hex_address.str()));
-}
-
-} // namespace trace_event
-} // namespace base