• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The Chromium Authors
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_ALLOCATION_CONTEXT_H_
6 #define BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_CONTEXT_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <functional>
12 
13 #include "base/base_export.h"
14 #include "base/memory/raw_ptr.h"
15 
16 namespace base {
17 namespace trace_event {
18 
19 // When heap profiling is enabled, tracing keeps track of the allocation
20 // context for each allocation intercepted. It is generated by the
21 // |AllocationContextTracker| which keeps stacks of context in TLS.
22 // The tracker is initialized lazily.
23 
24 // The backtrace in the allocation context is a snapshot of the native call
25 // stack.
26 
27 // Represents a stack frame. Used in Backtrace class below.
28 //
29 // Conceptually stack frame is identified by its value, and type is used
30 // mostly to properly format the value. Value is expected to be a valid
31 // pointer from process' address space.
32 struct BASE_EXPORT StackFrame {
33   enum class Type {
34     THREAD_NAME,        // const char* thread name
35     PROGRAM_COUNTER,    // as returned by stack tracing (e.g. by StackTrace)
36   };
37 
FromThreadNameStackFrame38   static StackFrame FromThreadName(const char* name) {
39     return {Type::THREAD_NAME, name};
40   }
FromProgramCounterStackFrame41   static StackFrame FromProgramCounter(const void* pc) {
42     return {Type::PROGRAM_COUNTER, pc};
43   }
44 
45   Type type;
46   raw_ptr<const void> value;
47 };
48 
49 bool BASE_EXPORT operator < (const StackFrame& lhs, const StackFrame& rhs);
50 bool BASE_EXPORT operator == (const StackFrame& lhs, const StackFrame& rhs);
51 bool BASE_EXPORT operator != (const StackFrame& lhs, const StackFrame& rhs);
52 
53 struct BASE_EXPORT Backtrace {
54   Backtrace();
55 
56   // If the stack is higher than what can be stored here, the top frames
57   // (the ones further from main()) are stored. Depth of 12 is enough for most
58   // pseudo traces (see above), but not for native traces, where we need more.
59   enum { kMaxFrameCount = 48 };
60   StackFrame frames[kMaxFrameCount];
61   size_t frame_count = 0;
62 };
63 
64 bool BASE_EXPORT operator==(const Backtrace& lhs, const Backtrace& rhs);
65 bool BASE_EXPORT operator!=(const Backtrace& lhs, const Backtrace& rhs);
66 
67 // The |AllocationContext| is context metadata that is kept for every allocation
68 // when heap profiling is enabled. To simplify memory management for book-
69 // keeping, this struct has a fixed size.
70 struct BASE_EXPORT AllocationContext {
71   AllocationContext();
72   AllocationContext(const Backtrace& backtrace, const char* type_name);
73 
74   Backtrace backtrace;
75 
76   // Type name of the type stored in the allocated memory. A null pointer
77   // indicates "unknown type". Grouping is done by comparing pointers, not by
78   // deep string comparison. In a component build, where a type name can have a
79   // string literal in several dynamic libraries, this may distort grouping.
80   const char* type_name;
81 };
82 
83 bool BASE_EXPORT operator==(const AllocationContext& lhs,
84                             const AllocationContext& rhs);
85 bool BASE_EXPORT operator!=(const AllocationContext& lhs,
86                             const AllocationContext& rhs);
87 
88 // Struct to store the size and count of the allocations.
89 struct AllocationMetrics {
90   size_t size;
91   size_t count;
92 };
93 
94 }  // namespace trace_event
95 }  // namespace base
96 
97 namespace std {
98 
99 template <>
100 struct BASE_EXPORT hash<base::trace_event::StackFrame> {
101   size_t operator()(const base::trace_event::StackFrame& frame) const;
102 };
103 
104 template <>
105 struct BASE_EXPORT hash<base::trace_event::Backtrace> {
106   size_t operator()(const base::trace_event::Backtrace& backtrace) const;
107 };
108 
109 template <>
110 struct BASE_EXPORT hash<base::trace_event::AllocationContext> {
111   size_t operator()(const base::trace_event::AllocationContext& context) const;
112 };
113 
114 }  // namespace std
115 
116 #endif  // BASE_TRACE_EVENT_HEAP_PROFILER_ALLOCATION_CONTEXT_H_
117