1 // Copyright 2013 the V8 project 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 V8_PROFILER_ALLOCATION_TRACKER_H_ 6 #define V8_PROFILER_ALLOCATION_TRACKER_H_ 7 8 #include <map> 9 #include <vector> 10 11 #include "include/v8-persistent-handle.h" 12 #include "include/v8-profiler.h" 13 #include "include/v8-unwinder.h" 14 #include "src/base/hashmap.h" 15 #include "src/base/vector.h" 16 #include "src/handles/handles.h" 17 18 namespace v8 { 19 namespace internal { 20 21 // Forward declarations. 22 class AllocationTraceTree; 23 class AllocationTracker; 24 class HeapObjectsMap; 25 class SharedFunctionInfo; 26 class StringsStorage; 27 28 class AllocationTraceNode { 29 public: 30 AllocationTraceNode(AllocationTraceTree* tree, 31 unsigned function_info_index); 32 ~AllocationTraceNode(); 33 AllocationTraceNode(const AllocationTraceNode&) = delete; 34 AllocationTraceNode& operator=(const AllocationTraceNode&) = delete; 35 AllocationTraceNode* FindChild(unsigned function_info_index); 36 AllocationTraceNode* FindOrAddChild(unsigned function_info_index); 37 void AddAllocation(unsigned size); 38 function_info_index()39 unsigned function_info_index() const { return function_info_index_; } allocation_size()40 unsigned allocation_size() const { return total_size_; } allocation_count()41 unsigned allocation_count() const { return allocation_count_; } id()42 unsigned id() const { return id_; } children()43 const std::vector<AllocationTraceNode*>& children() const { 44 return children_; 45 } 46 47 void Print(int indent, AllocationTracker* tracker); 48 49 private: 50 AllocationTraceTree* tree_; 51 unsigned function_info_index_; 52 unsigned total_size_; 53 unsigned allocation_count_; 54 unsigned id_; 55 std::vector<AllocationTraceNode*> children_; 56 }; 57 58 59 class AllocationTraceTree { 60 public: 61 AllocationTraceTree(); 62 ~AllocationTraceTree() = default; 63 AllocationTraceTree(const AllocationTraceTree&) = delete; 64 AllocationTraceTree& operator=(const AllocationTraceTree&) = delete; 65 AllocationTraceNode* AddPathFromEnd(const base::Vector<unsigned>& path); root()66 AllocationTraceNode* root() { return &root_; } next_node_id()67 unsigned next_node_id() { return next_node_id_++; } 68 V8_EXPORT_PRIVATE void Print(AllocationTracker* tracker); 69 70 private: 71 unsigned next_node_id_; 72 AllocationTraceNode root_; 73 }; 74 75 class V8_EXPORT_PRIVATE AddressToTraceMap { 76 public: 77 void AddRange(Address addr, int size, unsigned node_id); 78 unsigned GetTraceNodeId(Address addr); 79 void MoveObject(Address from, Address to, int size); 80 void Clear(); size()81 size_t size() { return ranges_.size(); } 82 void Print(); 83 84 private: 85 struct RangeStack { RangeStackRangeStack86 RangeStack(Address start, unsigned node_id) 87 : start(start), trace_node_id(node_id) {} 88 Address start; 89 unsigned trace_node_id; 90 }; 91 // [start, end) -> trace 92 using RangeMap = std::map<Address, RangeStack>; 93 94 void RemoveRange(Address start, Address end); 95 96 RangeMap ranges_; 97 }; 98 99 class AllocationTracker { 100 public: 101 struct FunctionInfo { 102 FunctionInfo(); 103 const char* name; 104 SnapshotObjectId function_id; 105 const char* script_name; 106 int script_id; 107 int line; 108 int column; 109 }; 110 111 AllocationTracker(HeapObjectsMap* ids, StringsStorage* names); 112 ~AllocationTracker(); 113 AllocationTracker(const AllocationTracker&) = delete; 114 AllocationTracker& operator=(const AllocationTracker&) = delete; 115 116 V8_EXPORT_PRIVATE void PrepareForSerialization(); 117 void AllocationEvent(Address addr, int size); 118 trace_tree()119 AllocationTraceTree* trace_tree() { return &trace_tree_; } function_info_list()120 const std::vector<FunctionInfo*>& function_info_list() const { 121 return function_info_list_; 122 } address_to_trace()123 AddressToTraceMap* address_to_trace() { return &address_to_trace_; } 124 125 private: 126 unsigned AddFunctionInfo(SharedFunctionInfo info, SnapshotObjectId id); 127 unsigned functionInfoIndexForVMState(StateTag state); 128 129 class UnresolvedLocation { 130 public: 131 UnresolvedLocation(Script script, int start, FunctionInfo* info); 132 ~UnresolvedLocation(); 133 void Resolve(); 134 135 private: 136 static void HandleWeakScript(const v8::WeakCallbackInfo<void>& data); 137 138 Handle<Script> script_; 139 int start_position_; 140 FunctionInfo* info_; 141 }; 142 143 static const int kMaxAllocationTraceLength = 64; 144 HeapObjectsMap* ids_; 145 StringsStorage* names_; 146 AllocationTraceTree trace_tree_; 147 unsigned allocation_trace_buffer_[kMaxAllocationTraceLength]; 148 std::vector<FunctionInfo*> function_info_list_; 149 base::HashMap id_to_function_info_index_; 150 std::vector<UnresolvedLocation*> unresolved_locations_; 151 unsigned info_index_for_other_state_; 152 AddressToTraceMap address_to_trace_; 153 }; 154 155 } // namespace internal 156 } // namespace v8 157 158 #endif // V8_PROFILER_ALLOCATION_TRACKER_H_ 159