Index: base/trace_event/memory_profiler_allocation_context.cc |
diff --git a/base/trace_event/memory_profiler_allocation_context.cc b/base/trace_event/memory_profiler_allocation_context.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3aea93518c633aa667d1b21f0ff028ce1f117819 |
--- /dev/null |
+++ b/base/trace_event/memory_profiler_allocation_context.cc |
@@ -0,0 +1,91 @@ |
+// 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/memory_profiler_allocation_context.h" |
+ |
+#include "base/threading/thread_local_storage.h" |
+ |
+namespace base { |
+namespace trace_event { |
+ |
+subtle::Atomic32 AllocationContextTracker::capture_enabled_ = 0; |
+ |
+namespace { |
+ThreadLocalStorage::StaticSlot g_tls_alloc_ctx_tracker = TLS_INITIALIZER; |
+} |
+ |
+AllocationStack::AllocationStack() {} |
+AllocationStack::~AllocationStack() {} |
+ |
+// 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); |
+} |
+ |
+AllocationContextTracker* AllocationContextTracker::GetThreadLocalTracker() { |
+ AllocationContextTracker* tracker; |
+ |
+ if (g_tls_alloc_ctx_tracker.initialized()) { |
Dmitry Skiba
2015/09/29 19:00:16
Hmm, so we are setting g_tls_alloc_ctx_tracker val
Primiano Tucci (use gerrit)
2015/09/30 08:26:31
Ahh I think I see your point. Yes, looks like the
|
+ tracker = |
+ static_cast<AllocationContextTracker*>(g_tls_alloc_ctx_tracker.Get()); |
+ } else { |
+ tracker = new AllocationContextTracker(); |
+ g_tls_alloc_ctx_tracker.Initialize(DestructAllocationContextTracker); |
+ g_tls_alloc_ctx_tracker.Set(tracker); |
+ } |
+ |
+ return tracker; |
+} |
+ |
+AllocationContextTracker::AllocationContextTracker() {} |
+AllocationContextTracker::~AllocationContextTracker() {} |
+ |
+// static |
+void AllocationContextTracker::SetCaptureEnabled(bool enabled) { |
+ // There is no memory barrier here for performance reasons, a little lag is |
+ // not an issue. |
+ subtle::NoBarrier_Store(&capture_enabled_, enabled); |
+} |
+ |
+// static |
+void AllocationContextTracker::PushPseudoStackFrame(StackFrame frame) { |
+ auto tracker = AllocationContextTracker::GetThreadLocalTracker(); |
+ tracker->pseudo_stack_.push(frame); |
+} |
+ |
+// static |
+void AllocationContextTracker::PopPseudoStackFrame(StackFrame frame) { |
+ auto tracker = AllocationContextTracker::GetThreadLocalTracker(); |
+ DCHECK_EQ(frame, *tracker->pseudo_stack_.top()); |
+ tracker->pseudo_stack_.pop(); |
+} |
+ |
+// static |
+void AllocationContextTracker::SetContextField(const char* key, |
+ const char* value) { |
+ auto tracker = AllocationContextTracker::GetThreadLocalTracker(); |
+ tracker->context_[key] = value; |
+} |
+ |
+// static |
+void AllocationContextTracker::UnsetContextField(const char* key) { |
+ auto tracker = AllocationContextTracker::GetThreadLocalTracker(); |
+ tracker->context_.erase(key); |
+} |
+ |
+// static |
+AllocationStack* AllocationContextTracker::GetPseudoStackForTesting() { |
+ auto tracker = AllocationContextTracker::GetThreadLocalTracker(); |
+ return &tracker->pseudo_stack_; |
+} |
+ |
+// static |
+AllocationContext AllocationContextTracker::GetContext() { |
+ // TODO(ruuda): Implement this in a follow-up CL. |
+ return AllocationContext(); |
+} |
+ |
+} // namespace trace_event |
+} // namespace base |