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