| // 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 |