|  | // Copyright 2016 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_HEAP_PROFILER_H | 
|  | #define BASE_TRACE_EVENT_HEAP_PROFILER_H | 
|  |  | 
|  | #include "base/compiler_specific.h" | 
|  | #include "base/trace_event/heap_profiler_allocation_context_tracker.h" | 
|  |  | 
|  | // This header file defines the set of macros that are used to track memory | 
|  | // usage in the heap profiler. This is in addition to the macros defined in | 
|  | // trace_event.h and are specific to heap profiler. This file also defines | 
|  | // implementation details of these macros. | 
|  |  | 
|  | // Implementation detail: heap profiler macros create temporary variables to | 
|  | // keep instrumentation overhead low. These macros give each temporary variable | 
|  | // a unique name based on the line number to prevent name collisions. | 
|  | #define INTERNAL_HEAP_PROFILER_UID3(a, b) heap_profiler_unique_##a##b | 
|  | #define INTERNAL_HEAP_PROFILER_UID2(a, b) INTERNAL_HEAP_PROFILER_UID3(a, b) | 
|  | #define INTERNAL_HEAP_PROFILER_UID(name_prefix) \ | 
|  | INTERNAL_HEAP_PROFILER_UID2(name_prefix, __LINE__) | 
|  |  | 
|  | // Scoped tracker for task execution context in the heap profiler. | 
|  | #define TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION \ | 
|  | trace_event_internal::HeapProfilerScopedTaskExecutionTracker | 
|  |  | 
|  | // Scoped tracker that tracks the given program counter as a native stack frame | 
|  | // in the heap profiler. | 
|  | #define TRACE_HEAP_PROFILER_API_SCOPED_WITH_PROGRAM_COUNTER \ | 
|  | trace_event_internal::HeapProfilerScopedStackFrame | 
|  |  | 
|  | // A scoped ignore event used to tell heap profiler to ignore all the | 
|  | // allocations in the scope. It is useful to exclude allocations made for | 
|  | // tracing from the heap profiler dumps. | 
|  | #define HEAP_PROFILER_SCOPED_IGNORE                                          \ | 
|  | trace_event_internal::HeapProfilerScopedIgnore INTERNAL_HEAP_PROFILER_UID( \ | 
|  | scoped_ignore) | 
|  |  | 
|  | namespace trace_event_internal { | 
|  |  | 
|  | // HeapProfilerScopedTaskExecutionTracker records the current task's context in | 
|  | // the heap profiler. | 
|  | class HeapProfilerScopedTaskExecutionTracker { | 
|  | public: | 
|  | inline explicit HeapProfilerScopedTaskExecutionTracker( | 
|  | const char* task_context) | 
|  | : context_(task_context) { | 
|  | using base::trace_event::AllocationContextTracker; | 
|  | if (UNLIKELY(AllocationContextTracker::capture_mode() != | 
|  | AllocationContextTracker::CaptureMode::DISABLED)) { | 
|  | AllocationContextTracker::GetInstanceForCurrentThread() | 
|  | ->PushCurrentTaskContext(context_); | 
|  | } | 
|  | } | 
|  |  | 
|  | inline ~HeapProfilerScopedTaskExecutionTracker() { | 
|  | using base::trace_event::AllocationContextTracker; | 
|  | if (UNLIKELY(AllocationContextTracker::capture_mode() != | 
|  | AllocationContextTracker::CaptureMode::DISABLED)) { | 
|  | AllocationContextTracker::GetInstanceForCurrentThread() | 
|  | ->PopCurrentTaskContext(context_); | 
|  | } | 
|  | } | 
|  |  | 
|  | private: | 
|  | const char* context_; | 
|  | }; | 
|  |  | 
|  | class HeapProfilerScopedStackFrame { | 
|  | public: | 
|  | inline explicit HeapProfilerScopedStackFrame(const void* program_counter) | 
|  | : program_counter_(program_counter) { | 
|  | using base::trace_event::AllocationContextTracker; | 
|  | if (UNLIKELY(AllocationContextTracker::capture_mode() == | 
|  | AllocationContextTracker::CaptureMode::MIXED_STACK)) { | 
|  | AllocationContextTracker::GetInstanceForCurrentThread() | 
|  | ->PushNativeStackFrame(program_counter_); | 
|  | } | 
|  | } | 
|  |  | 
|  | inline ~HeapProfilerScopedStackFrame() { | 
|  | using base::trace_event::AllocationContextTracker; | 
|  | if (UNLIKELY(AllocationContextTracker::capture_mode() == | 
|  | AllocationContextTracker::CaptureMode::MIXED_STACK)) { | 
|  | AllocationContextTracker::GetInstanceForCurrentThread() | 
|  | ->PopNativeStackFrame(program_counter_); | 
|  | } | 
|  | } | 
|  |  | 
|  | private: | 
|  | const void* const program_counter_; | 
|  | }; | 
|  |  | 
|  | class BASE_EXPORT HeapProfilerScopedIgnore { | 
|  | public: | 
|  | inline HeapProfilerScopedIgnore() { | 
|  | using base::trace_event::AllocationContextTracker; | 
|  | if (UNLIKELY( | 
|  | AllocationContextTracker::capture_mode() != | 
|  | AllocationContextTracker::CaptureMode::DISABLED)) { | 
|  | AllocationContextTracker::GetInstanceForCurrentThread() | 
|  | ->begin_ignore_scope(); | 
|  | } | 
|  | } | 
|  | inline ~HeapProfilerScopedIgnore() { | 
|  | using base::trace_event::AllocationContextTracker; | 
|  | if (UNLIKELY( | 
|  | AllocationContextTracker::capture_mode() != | 
|  | AllocationContextTracker::CaptureMode::DISABLED)) { | 
|  | AllocationContextTracker::GetInstanceForCurrentThread() | 
|  | ->end_ignore_scope(); | 
|  | } | 
|  | } | 
|  | }; | 
|  |  | 
|  | }  // namespace trace_event_internal | 
|  |  | 
|  | #endif  // BASE_TRACE_EVENT_HEAP_PROFILER_H |