Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2944)

Unified Diff: base/trace_event/memory_profiler_allocation_context.h

Issue 1368993002: Reland of "Add thread-local allocation context for tracing" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address primiano comment Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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_

Powered by Google App Engine
This is Rietveld 408576698