summaryrefslogtreecommitdiffstats
path: root/base/trace_event/heap_profiler_allocation_context_tracker.cc
diff options
context:
space:
mode:
authorruuda <ruuda@google.com>2015-11-16 02:43:39 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-16 10:44:36 +0000
commit6b25c30385ea59eff4199ca1e07c165413283b74 (patch)
tree05f191d7bdcd8781de32af7165d3b066aaf551da /base/trace_event/heap_profiler_allocation_context_tracker.cc
parent89308c9af62c4ccf24a05e7996e4d6e5c479b3ac (diff)
downloadchromium_src-6b25c30385ea59eff4199ca1e07c165413283b74.zip
chromium_src-6b25c30385ea59eff4199ca1e07c165413283b74.tar.gz
chromium_src-6b25c30385ea59eff4199ca1e07c165413283b74.tar.bz2
[Tracing] Clean up heap profiler files
Over time, base/trace_event/memory_profiler_allocation_context.h had become a god header that contained nearly all heap profiler classes. This CL splits the file (along with its tests) into multiple smaller files. Furthermore, there are small comment and readability fixes. No behavior is changed by this CL. * Change prefix of heap profiler files from |memory_profiler_*| to |heap_profiler_*|. * Move |AllocationContextTracker| and its tests into its own file. * Move |StackFrameDeduplicator| and its tests into its own file. * Remove |AllocationStack|, which was just a very thin wrapper around |std::vector|. Inline its logic into |AllocationContextTracker| instead. * Rename the |SortDescending| function in the heap dump writer source file to |SortBySizeDescending|. * Fix variable names in comments in |AllocationRegister|. * Fix and clarify comments in |AllocationContextTracker| and |StackFrameDeduplicator|. * Include what you use fixes. BUG=524631 Review URL: https://codereview.chromium.org/1431103004 Cr-Commit-Position: refs/heads/master@{#359813}
Diffstat (limited to 'base/trace_event/heap_profiler_allocation_context_tracker.cc')
-rw-r--r--base/trace_event/heap_profiler_allocation_context_tracker.cc121
1 files changed, 121 insertions, 0 deletions
diff --git a/base/trace_event/heap_profiler_allocation_context_tracker.cc b/base/trace_event/heap_profiler_allocation_context_tracker.cc
new file mode 100644
index 0000000..b58fb60
--- /dev/null
+++ b/base/trace_event/heap_profiler_allocation_context_tracker.cc
@@ -0,0 +1,121 @@
+// 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_allocation_context_tracker.h"
+
+#include <algorithm>
+
+#include "base/atomicops.h"
+#include "base/threading/thread_local_storage.h"
+#include "base/trace_event/heap_profiler_allocation_context.h"
+
+namespace base {
+namespace trace_event {
+
+subtle::Atomic32 AllocationContextTracker::capture_enabled_ = 0;
+
+namespace {
+
+ThreadLocalStorage::StaticSlot g_tls_alloc_ctx_tracker = TLS_INITIALIZER;
+
+// This function is added to the TLS slot to clean up the instance when the
+// thread exits.
+void DestructAllocationContextTracker(void* alloc_ctx_tracker) {
+ delete static_cast<AllocationContextTracker*>(alloc_ctx_tracker);
+}
+
+// Returns a pointer past the end of the fixed-size array |array| of |T| of
+// length |N|, identical to C++11 |std::end|.
+template <typename T, int N>
+T* End(T(&array)[N]) {
+ return array + N;
+}
+
+} // namespace
+
+AllocationContextTracker::AllocationContextTracker() {}
+AllocationContextTracker::~AllocationContextTracker() {}
+
+// static
+AllocationContextTracker* AllocationContextTracker::GetThreadLocalTracker() {
+ auto tracker =
+ static_cast<AllocationContextTracker*>(g_tls_alloc_ctx_tracker.Get());
+
+ if (!tracker) {
+ tracker = new AllocationContextTracker();
+ g_tls_alloc_ctx_tracker.Set(tracker);
+ }
+
+ return tracker;
+}
+
+// static
+void AllocationContextTracker::SetCaptureEnabled(bool enabled) {
+ // When enabling capturing, also initialize the TLS slot. This does not create
+ // a TLS instance yet.
+ if (enabled && !g_tls_alloc_ctx_tracker.initialized())
+ g_tls_alloc_ctx_tracker.Initialize(DestructAllocationContextTracker);
+
+ // Release ordering ensures that when a thread observes |capture_enabled_| to
+ // be true through an acquire load, the TLS slot has been initialized.
+ subtle::Release_Store(&capture_enabled_, enabled);
+}
+
+// static
+void AllocationContextTracker::PushPseudoStackFrame(StackFrame frame) {
+ auto tracker = AllocationContextTracker::GetThreadLocalTracker();
+
+ // Impose a limit on the height to verify that every push is popped, because
+ // in practice the pseudo stack never grows higher than ~20 frames.
+ DCHECK_LT(tracker->pseudo_stack_.size(), 128u);
+ tracker->pseudo_stack_.push_back(frame);
+}
+
+// static
+void AllocationContextTracker::PopPseudoStackFrame(StackFrame frame) {
+ auto tracker = AllocationContextTracker::GetThreadLocalTracker();
+
+ // Guard for stack underflow. If tracing was started with a TRACE_EVENT in
+ // scope, the frame was never pushed, so it is possible that pop is called
+ // on an empty stack.
+ if (tracker->pseudo_stack_.empty())
+ return;
+
+ // Assert that pushes and pops are nested correctly. This DCHECK can be
+ // hit if some TRACE_EVENT macro is unbalanced (a TRACE_EVENT_END* call
+ // without a corresponding TRACE_EVENT_BEGIN).
+ DCHECK_EQ(frame, tracker->pseudo_stack_.back())
+ << "Encountered an unmatched TRACE_EVENT_END";
+
+ tracker->pseudo_stack_.pop_back();
+}
+
+// static
+AllocationContext AllocationContextTracker::GetContextSnapshot() {
+ AllocationContextTracker* tracker = GetThreadLocalTracker();
+ AllocationContext ctx;
+
+ // Fill the backtrace.
+ {
+ auto src = tracker->pseudo_stack_.begin();
+ auto dst = ctx.backtrace.frames;
+ auto src_end = tracker->pseudo_stack_.end();
+ auto dst_end = End(ctx.backtrace.frames);
+
+ // Copy as much of the bottom of the pseudo stack into the backtrace as
+ // possible.
+ for (; src != src_end && dst != dst_end; src++, dst++)
+ *dst = *src;
+
+ // If there is room for more, fill the remaining slots with empty frames.
+ std::fill(dst, dst_end, nullptr);
+ }
+
+ ctx.type_id = 0;
+
+ return ctx;
+}
+
+} // namespace trace_event
+} // namespace base