• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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