forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
/
heap_profiler.h
134 lines (115 loc) · 5.15 KB
/
heap_profiler.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// 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
// Returns the current task context (c-string) tracked by heap profiler. This is
// useful along with TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION if a async
// system needs to track client's allocation context across post tasks. Use this
// macro to get the current context and use
// TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION in the posted task which
// allocates memory for a client.
#define TRACE_HEAP_PROFILER_API_GET_CURRENT_TASK_CONTEXT \
trace_event_internal::HeapProfilerCurrentTaskContext
// 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_;
};
inline const char* HeapProfilerCurrentTaskContext() {
return base::trace_event::AllocationContextTracker::
GetInstanceForCurrentThread()
->TaskContext();
}
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