Index: base/trace_event/memory_profiler_allocation_context.h |
diff --git a/base/trace_event/memory_profiler_allocation_context.h b/base/trace_event/memory_profiler_allocation_context.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..11ecc881baffb7b359089259626844ea4200d189 |
--- /dev/null |
+++ b/base/trace_event/memory_profiler_allocation_context.h |
@@ -0,0 +1,119 @@ |
+// 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. |
+ |
+#ifndef BASE_TRACE_EVENT_MEMORY_PROFILER_ALLOCATION_CONTEXT_H_ |
+#define BASE_TRACE_EVENT_MEMORY_PROFILER_ALLOCATION_CONTEXT_H_ |
+ |
+#include <vector> |
+ |
+#include "base/atomicops.h" |
+#include "base/base_export.h" |
+#include "base/containers/small_map.h" |
+ |
+namespace base { |
+namespace trace_event { |
+ |
+// When heap profiling is enabled, tracing keeps track of the allocation |
+// context for each allocation intercepted. It is generated by the |
+// |AllocationContextTracker| which keeps stacks of context in TLS. |
+// The tracker is initialized lazily. |
+ |
+using StackFrame = const char*; |
+ |
+// A simple stack of |StackFrame| that unlike |std::stack| allows iterating |
+// the stack and guards for underflow. |
+class BASE_EXPORT AllocationStack { |
+ public: |
+ // Incrementing the iterator iterates down the stack. |
+ using ConstIterator = std::vector<StackFrame>::const_reverse_iterator; |
+ |
+ AllocationStack(); |
+ ~AllocationStack(); |
+ |
+ inline ConstIterator top() const { return stack_.rbegin(); } |
+ inline ConstIterator bottom() const { return stack_.rend(); } |
+ |
+ inline void push(StackFrame frame) { |
+ // 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(stack_.size(), 128u); |
+ stack_.push_back(frame); |
+ } |
+ |
+ inline void pop() { |
+ if (!stack_.empty()) |
+ stack_.pop_back(); |
+ } |
+ |
+ private: |
+ std::vector<StackFrame> stack_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AllocationStack); |
+}; |
+ |
+class BASE_EXPORT AllocationContext { |
+ // TODO(ruuda): Fill this in a follow-up CL. |
+}; |
+ |
+// The allocation context tracker keeps track of thread-local context for heap |
+// profiling. It includes a pseudo stack of trace events, and it might contain |
+// arbitrary (key, value) context. On every allocation the tracker provides a |
+// snapshot of its context in the form of an |AllocationContext| that is to be |
+// stored together with the allocation details. |
+class BASE_EXPORT AllocationContextTracker { |
+ public: |
+ // Globally enables capturing allocation context. |
+ // TODO(ruuda): Should this be replaced by |EnableCapturing| in the future? |
+ // Or at least have something that guards agains enable -> disable -> enable? |
+ static void SetCaptureEnabled(bool enabled); |
+ |
+ // Returns whether capturing allocation context is enabled globally. |
+ inline static bool capture_enabled() { |
+ // A little lag after heap profiling is enabled or disabled is fine, it is |
+ // more important that the check is as cheap as possible when capturing is |
+ // not enabled, so do not issue a memory barrier. |
+ return subtle::NoBarrier_Load(&capture_enabled_) != 0; |
+ } |
+ |
+ // Pushes a frame onto the thread-local pseudo stack. |
+ static void PushPseudoStackFrame(StackFrame frame); |
+ |
+ // Pops a frame from the thread-local pseudo stack. |
+ static void PopPseudoStackFrame(StackFrame frame); |
+ |
+ // Sets a thread-local (key, value) pair. |
+ static void SetContextField(const char* key, const char* value); |
+ |
+ // Removes the (key, value) pair with the specified key from the thread-local |
+ // context. |
+ static void UnsetContextField(const char* key); |
+ |
+ // Returns a snapshot of the current thread-local context. |
+ static AllocationContext GetContext(); |
+ |
+ // TODO(ruuda): Remove in a follow-up CL, this is only used for testing now. |
+ static AllocationStack* GetPseudoStackForTesting(); |
+ |
+ ~AllocationContextTracker(); |
+ |
+ private: |
+ AllocationContextTracker(); |
+ |
+ static AllocationContextTracker* GetThreadLocalTracker(); |
+ |
+ static subtle::Atomic32 capture_enabled_; |
+ |
+ // The pseudo stack where frames are |TRACE_EVENT| names. |
+ AllocationStack pseudo_stack_; |
+ |
+ // A dictionary of arbitrary context. |
+ SmallMap<std::map<const char*, const char*>> context_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AllocationContextTracker); |
+}; |
+ |
+} // namespace trace_event |
+} // namespace base |
+ |
+#endif // BASE_TRACE_EVENT_MEMORY_PROFILER_ALLOCATION_CONTEXT_H_ |