1 // Copyright 2016 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_TRACE_EVENT_HEAP_PROFILER_H 6 #define BASE_TRACE_EVENT_HEAP_PROFILER_H 7 8 #include "base/compiler_specific.h" 9 #include "base/trace_event/heap_profiler_allocation_context_tracker.h" 10 11 // This header file defines the set of macros that are used to track memory 12 // usage in the heap profiler. This is in addition to the macros defined in 13 // trace_event.h and are specific to heap profiler. This file also defines 14 // implementation details of these macros. 15 16 // Implementation detail: heap profiler macros create temporary variables to 17 // keep instrumentation overhead low. These macros give each temporary variable 18 // a unique name based on the line number to prevent name collisions. 19 #define INTERNAL_HEAP_PROFILER_UID3(a, b) heap_profiler_unique_##a##b 20 #define INTERNAL_HEAP_PROFILER_UID2(a, b) INTERNAL_HEAP_PROFILER_UID3(a, b) 21 #define INTERNAL_HEAP_PROFILER_UID(name_prefix) \ 22 INTERNAL_HEAP_PROFILER_UID2(name_prefix, __LINE__) 23 24 // Scoped tracker for task execution context in the heap profiler. 25 #define TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION \ 26 trace_event_internal::HeapProfilerScopedTaskExecutionTracker 27 28 // A scoped ignore event used to tell heap profiler to ignore all the 29 // allocations in the scope. It is useful to exclude allocations made for 30 // tracing from the heap profiler dumps. 31 #define HEAP_PROFILER_SCOPED_IGNORE \ 32 trace_event_internal::HeapProfilerScopedIgnore INTERNAL_HEAP_PROFILER_UID( \ 33 scoped_ignore) 34 35 namespace trace_event_internal { 36 37 // HeapProfilerScopedTaskExecutionTracker records the current task's context in 38 // the heap profiler. 39 class HeapProfilerScopedTaskExecutionTracker { 40 public: HeapProfilerScopedTaskExecutionTracker(const char * task_context)41 inline explicit HeapProfilerScopedTaskExecutionTracker( 42 const char* task_context) 43 : context_(task_context) { 44 using base::trace_event::AllocationContextTracker; 45 if (UNLIKELY(AllocationContextTracker::capture_mode() != 46 AllocationContextTracker::CaptureMode::DISABLED)) { 47 AllocationContextTracker::GetInstanceForCurrentThread() 48 ->PushCurrentTaskContext(context_); 49 } 50 } 51 ~HeapProfilerScopedTaskExecutionTracker()52 inline ~HeapProfilerScopedTaskExecutionTracker() { 53 using base::trace_event::AllocationContextTracker; 54 if (UNLIKELY(AllocationContextTracker::capture_mode() != 55 AllocationContextTracker::CaptureMode::DISABLED)) { 56 AllocationContextTracker::GetInstanceForCurrentThread() 57 ->PopCurrentTaskContext(context_); 58 } 59 } 60 61 private: 62 const char* context_; 63 }; 64 65 class BASE_EXPORT HeapProfilerScopedIgnore { 66 public: HeapProfilerScopedIgnore()67 inline HeapProfilerScopedIgnore() { 68 using base::trace_event::AllocationContextTracker; 69 if (UNLIKELY( 70 AllocationContextTracker::capture_mode() != 71 AllocationContextTracker::CaptureMode::DISABLED)) { 72 AllocationContextTracker::GetInstanceForCurrentThread() 73 ->begin_ignore_scope(); 74 } 75 } ~HeapProfilerScopedIgnore()76 inline ~HeapProfilerScopedIgnore() { 77 using base::trace_event::AllocationContextTracker; 78 if (UNLIKELY( 79 AllocationContextTracker::capture_mode() != 80 AllocationContextTracker::CaptureMode::DISABLED)) { 81 AllocationContextTracker::GetInstanceForCurrentThread() 82 ->end_ignore_scope(); 83 } 84 } 85 }; 86 87 } // namespace trace_event_internal 88 89 #endif // BASE_TRACE_EVENT_HEAP_PROFILER_H 90