Chromium Code Reviews| 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 |