heap_profiler.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. #ifndef BASE_TRACE_EVENT_HEAP_PROFILER_H
  5. #define BASE_TRACE_EVENT_HEAP_PROFILER_H
  6. #include "base/compiler_specific.h"
  7. #include "base/trace_event/heap_profiler_allocation_context_tracker.h"
  8. // This header file defines the set of macros that are used to track memory
  9. // usage in the heap profiler. This is in addition to the macros defined in
  10. // trace_event.h and are specific to heap profiler. This file also defines
  11. // implementation details of these macros.
  12. // Implementation detail: heap profiler macros create temporary variables to
  13. // keep instrumentation overhead low. These macros give each temporary variable
  14. // a unique name based on the line number to prevent name collisions.
  15. #define INTERNAL_HEAP_PROFILER_UID3(a, b) heap_profiler_unique_##a##b
  16. #define INTERNAL_HEAP_PROFILER_UID2(a, b) INTERNAL_HEAP_PROFILER_UID3(a, b)
  17. #define INTERNAL_HEAP_PROFILER_UID(name_prefix) \
  18. INTERNAL_HEAP_PROFILER_UID2(name_prefix, __LINE__)
  19. // Scoped tracker for task execution context in the heap profiler.
  20. #define TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION \
  21. trace_event_internal::HeapProfilerScopedTaskExecutionTracker
  22. // Scoped tracker that tracks the given program counter as a native stack frame
  23. // in the heap profiler.
  24. #define TRACE_HEAP_PROFILER_API_SCOPED_WITH_PROGRAM_COUNTER \
  25. trace_event_internal::HeapProfilerScopedStackFrame
  26. // Returns the current task context (c-string) tracked by heap profiler. This is
  27. // useful along with TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION if a async
  28. // system needs to track client's allocation context across post tasks. Use this
  29. // macro to get the current context and use
  30. // TRACE_HEAP_PROFILER_API_SCOPED_TASK_EXECUTION in the posted task which
  31. // allocates memory for a client.
  32. #define TRACE_HEAP_PROFILER_API_GET_CURRENT_TASK_CONTEXT \
  33. trace_event_internal::HeapProfilerCurrentTaskContext
  34. // A scoped ignore event used to tell heap profiler to ignore all the
  35. // allocations in the scope. It is useful to exclude allocations made for
  36. // tracing from the heap profiler dumps.
  37. #define HEAP_PROFILER_SCOPED_IGNORE \
  38. trace_event_internal::HeapProfilerScopedIgnore INTERNAL_HEAP_PROFILER_UID( \
  39. scoped_ignore)
  40. namespace trace_event_internal {
  41. // HeapProfilerScopedTaskExecutionTracker records the current task's context in
  42. // the heap profiler.
  43. class HeapProfilerScopedTaskExecutionTracker {
  44. public:
  45. inline explicit HeapProfilerScopedTaskExecutionTracker(
  46. const char* task_context)
  47. : context_(task_context) {
  48. using base::trace_event::AllocationContextTracker;
  49. if (UNLIKELY(AllocationContextTracker::capture_mode() !=
  50. AllocationContextTracker::CaptureMode::DISABLED)) {
  51. AllocationContextTracker::GetInstanceForCurrentThread()
  52. ->PushCurrentTaskContext(context_);
  53. }
  54. }
  55. inline ~HeapProfilerScopedTaskExecutionTracker() {
  56. using base::trace_event::AllocationContextTracker;
  57. if (UNLIKELY(AllocationContextTracker::capture_mode() !=
  58. AllocationContextTracker::CaptureMode::DISABLED)) {
  59. AllocationContextTracker::GetInstanceForCurrentThread()
  60. ->PopCurrentTaskContext(context_);
  61. }
  62. }
  63. private:
  64. const char* context_;
  65. };
  66. class HeapProfilerScopedStackFrame {
  67. public:
  68. inline explicit HeapProfilerScopedStackFrame(const void* program_counter)
  69. : program_counter_(program_counter) {
  70. using base::trace_event::AllocationContextTracker;
  71. if (UNLIKELY(AllocationContextTracker::capture_mode() ==
  72. AllocationContextTracker::CaptureMode::MIXED_STACK)) {
  73. AllocationContextTracker::GetInstanceForCurrentThread()
  74. ->PushNativeStackFrame(program_counter_);
  75. }
  76. }
  77. inline ~HeapProfilerScopedStackFrame() {
  78. using base::trace_event::AllocationContextTracker;
  79. if (UNLIKELY(AllocationContextTracker::capture_mode() ==
  80. AllocationContextTracker::CaptureMode::MIXED_STACK)) {
  81. AllocationContextTracker::GetInstanceForCurrentThread()
  82. ->PopNativeStackFrame(program_counter_);
  83. }
  84. }
  85. private:
  86. const void* const program_counter_;
  87. };
  88. inline const char* HeapProfilerCurrentTaskContext() {
  89. return base::trace_event::AllocationContextTracker::
  90. GetInstanceForCurrentThread()
  91. ->TaskContext();
  92. }
  93. class BASE_EXPORT HeapProfilerScopedIgnore {
  94. public:
  95. inline HeapProfilerScopedIgnore() {
  96. using base::trace_event::AllocationContextTracker;
  97. if (UNLIKELY(
  98. AllocationContextTracker::capture_mode() !=
  99. AllocationContextTracker::CaptureMode::DISABLED)) {
  100. AllocationContextTracker::GetInstanceForCurrentThread()
  101. ->begin_ignore_scope();
  102. }
  103. }
  104. inline ~HeapProfilerScopedIgnore() {
  105. using base::trace_event::AllocationContextTracker;
  106. if (UNLIKELY(
  107. AllocationContextTracker::capture_mode() !=
  108. AllocationContextTracker::CaptureMode::DISABLED)) {
  109. AllocationContextTracker::GetInstanceForCurrentThread()
  110. ->end_ignore_scope();
  111. }
  112. }
  113. };
  114. } // namespace trace_event_internal
  115. #endif // BASE_TRACE_EVENT_HEAP_PROFILER_H