The C and C++ Include Header Files
/usr/include/nodejs/src/memory_tracker-inl.h
$ cat -n /usr/include/nodejs/src/memory_tracker-inl.h 1 #ifndef SRC_MEMORY_TRACKER_INL_H_ 2 #define SRC_MEMORY_TRACKER_INL_H_ 3 4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 5 6 #include "memory_tracker.h" 7 #include "util-inl.h" 8 9 namespace node { 10 11 // Fallback edge_name if node_name is not available, or "" if edge_name 12 // is not available either. 13 inline const char* GetNodeName(const char* node_name, const char* edge_name) { 14 if (node_name != nullptr) { 15 return node_name; 16 } 17 if (edge_name != nullptr) { 18 return edge_name; 19 } 20 return ""; 21 } 22 23 class MemoryRetainerNode : public v8::EmbedderGraph::Node { 24 public: 25 inline MemoryRetainerNode(MemoryTracker* tracker, 26 const MemoryRetainer* retainer) 27 : retainer_(retainer) { 28 CHECK_NOT_NULL(retainer_); 29 v8::HandleScope handle_scope(tracker->isolate()); 30 v8::Local
obj = retainer_->WrappedObject(); 31 if (!obj.IsEmpty()) wrapper_node_ = tracker->graph()->V8Node(obj); 32 33 name_ = retainer_->MemoryInfoName(); 34 size_ = retainer_->SelfSize(); 35 detachedness_ = retainer_->GetDetachedness(); 36 } 37 38 inline MemoryRetainerNode(MemoryTracker* tracker, 39 const char* name, 40 size_t size, 41 bool is_root_node = false) 42 : retainer_(nullptr) { 43 name_ = name; 44 size_ = size; 45 is_root_node_ = is_root_node; 46 } 47 48 const char* Name() override { return name_; } 49 const char* NamePrefix() override { return "Node /"; } 50 size_t SizeInBytes() override { return size_; } 51 // TODO(addaleax): Merging this with the "official" WrapperNode() method 52 // seems to lose accuracy, e.g. SizeInBytes() is disregarded. 53 // Figure out whether to do anything about that. 54 Node* JSWrapperNode() { return wrapper_node_; } 55 56 bool IsRootNode() override { 57 if (retainer_ != nullptr) { 58 return retainer_->IsRootNode(); 59 } 60 return is_root_node_; 61 } 62 v8::EmbedderGraph::Node::Detachedness GetDetachedness() override { 63 return detachedness_; 64 } 65 66 private: 67 friend class MemoryTracker; 68 69 // If retainer_ is not nullptr, then it must have a wrapper_node_, 70 // and we have 71 // name_ == retainer_->MemoryInfoName() 72 // size_ == retainer_->SelfSize() 73 // is_root_node_ == retainer_->IsRootNode() 74 const MemoryRetainer* retainer_; 75 Node* wrapper_node_ = nullptr; 76 77 // Otherwise (retainer == nullptr), we set these fields in an ad-hoc way 78 bool is_root_node_ = false; 79 const char* name_; 80 size_t size_ = 0; 81 v8::EmbedderGraph::Node::Detachedness detachedness_ = 82 v8::EmbedderGraph::Node::Detachedness::kUnknown; 83 }; 84 85 void MemoryTracker::TrackFieldWithSize(const char* edge_name, 86 size_t size, 87 const char* node_name) { 88 if (size > 0) AddNode(GetNodeName(node_name, edge_name), size, edge_name); 89 } 90 91 void MemoryTracker::TrackInlineFieldWithSize(const char* edge_name, 92 size_t size, 93 const char* node_name) { 94 if (size > 0) AddNode(GetNodeName(node_name, edge_name), size, edge_name); 95 CHECK(CurrentNode()); 96 CurrentNode()->size_ -= size; 97 } 98 99 void MemoryTracker::TrackField(const char* edge_name, 100 const MemoryRetainer& value, 101 const char* node_name) { 102 TrackField(edge_name, &value); 103 } 104 105 void MemoryTracker::TrackField(const char* edge_name, 106 const MemoryRetainer* value, 107 const char* node_name) { 108 if (value == nullptr) return; 109 auto it = seen_.find(value); 110 if (it != seen_.end()) { 111 graph_->AddEdge(CurrentNode(), it->second, edge_name); 112 } else { 113 Track(value, edge_name); 114 } 115 } 116 117 template
118 void MemoryTracker::TrackField(const char* edge_name, 119 const std::unique_ptr
& value, 120 const char* node_name) { 121 if (value.get() == nullptr) { 122 return; 123 } 124 TrackField(edge_name, value.get(), node_name); 125 } 126 127 template
128 void MemoryTracker::TrackField(const char* edge_name, 129 const std::shared_ptr
& value, 130 const char* node_name) { 131 if (value.get() == nullptr) { 132 return; 133 } 134 TrackField(edge_name, value.get(), node_name); 135 } 136 137 template
138 void MemoryTracker::TrackField(const char* edge_name, 139 const BaseObjectPtrImpl
& value, 140 const char* node_name) { 141 if (value.get() == nullptr || kIsWeak) return; 142 TrackField(edge_name, value.get(), node_name); 143 } 144 145 template
146 void MemoryTracker::TrackField(const char* edge_name, 147 const T& value, 148 const char* node_name, 149 const char* element_name, 150 bool subtract_from_self) { 151 // If the container is empty, the size has been accounted into the parent's 152 // self size 153 if (value.begin() == value.end()) return; 154 // Fall back to edge name if node names are not provided 155 if (CurrentNode() != nullptr && subtract_from_self) { 156 // Shift the self size of this container out to a separate node 157 CurrentNode()->size_ -= sizeof(T); 158 } 159 PushNode(GetNodeName(node_name, edge_name), sizeof(T), edge_name); 160 for (Iterator it = value.begin(); it != value.end(); ++it) { 161 // Use nullptr as edge names so the elements appear as indexed properties 162 TrackField(nullptr, *it, element_name); 163 } 164 PopNode(); 165 } 166 167 template
168 void MemoryTracker::TrackField(const char* edge_name, 169 const std::queue
& value, 170 const char* node_name, 171 const char* element_name) { 172 struct ContainerGetter : public std::queue
{ 173 static const typename std::queue
::container_type& Get( 174 const std::queue
& value) { 175 return value.*&ContainerGetter::c; 176 } 177 }; 178 179 const auto& container = ContainerGetter::Get(value); 180 TrackField(edge_name, container, node_name, element_name); 181 } 182 183 template
184 void MemoryTracker::TrackField(const char* edge_name, 185 const T& value, 186 const char* node_name) { 187 // For numbers, creating new nodes is not worth the overhead. 188 CurrentNode()->size_ += sizeof(T); 189 } 190 191 template
192 void MemoryTracker::TrackField(const char* edge_name, 193 const std::pair
& value, 194 const char* node_name) { 195 PushNode(node_name == nullptr ? "pair" : node_name, 196 sizeof(const std::pair
), 197 edge_name); 198 // TODO(joyeecheung): special case if one of these is a number type 199 // that meets the test_for_number trait so that their sizes don't get 200 // merged into the pair node 201 TrackField("first", value.first); 202 TrackField("second", value.second); 203 PopNode(); 204 } 205 206 template
207 void MemoryTracker::TrackField(const char* edge_name, 208 const std::basic_string
& value, 209 const char* node_name) { 210 TrackFieldWithSize(edge_name, value.size() * sizeof(T), "std::basic_string"); 211 } 212 213 template
214 void MemoryTracker::TrackField(const char* edge_name, 215 const v8::Eternal
& value, 216 const char* node_name) { 217 TrackField(edge_name, value.Get(isolate_)); 218 } 219 220 template
221 void MemoryTracker::TrackField(const char* edge_name, 222 const v8::PersistentBase
& value, 223 const char* node_name) { 224 if (value.IsWeak()) return; 225 TrackField(edge_name, value.Get(isolate_)); 226 } 227 228 template
229 void MemoryTracker::TrackField(const char* edge_name, 230 const v8::Local
& value, 231 const char* node_name) { 232 if (!value.IsEmpty()) 233 graph_->AddEdge(CurrentNode(), graph_->V8Node(value), edge_name); 234 } 235 236 template
237 void MemoryTracker::TrackField(const char* edge_name, 238 const MallocedBuffer
& value, 239 const char* node_name) { 240 TrackFieldWithSize(edge_name, value.size, "MallocedBuffer"); 241 } 242 243 void MemoryTracker::TrackField(const char* edge_name, 244 const v8::BackingStore* value, 245 const char* node_name) { 246 TrackFieldWithSize(edge_name, value->ByteLength(), "BackingStore"); 247 } 248 249 void MemoryTracker::TrackField(const char* name, 250 const uv_buf_t& value, 251 const char* node_name) { 252 TrackFieldWithSize(name, value.len, "uv_buf_t"); 253 } 254 255 void MemoryTracker::TrackField(const char* name, 256 const uv_timer_t& value, 257 const char* node_name) { 258 TrackFieldWithSize(name, sizeof(value), "uv_timer_t"); 259 } 260 261 void MemoryTracker::TrackField(const char* name, 262 const uv_async_t& value, 263 const char* node_name) { 264 TrackFieldWithSize(name, sizeof(value), "uv_async_t"); 265 } 266 267 void MemoryTracker::TrackInlineField(const char* name, 268 const uv_async_t& value, 269 const char* node_name) { 270 TrackInlineFieldWithSize(name, sizeof(value), "uv_async_t"); 271 } 272 273 void MemoryTracker::Track(const MemoryRetainer* retainer, 274 const char* edge_name) { 275 v8::HandleScope handle_scope(isolate_); 276 auto it = seen_.find(retainer); 277 if (it != seen_.end()) { 278 if (CurrentNode() != nullptr) { 279 graph_->AddEdge(CurrentNode(), it->second, edge_name); 280 } 281 return; // It has already been tracked, no need to call MemoryInfo again 282 } 283 MemoryRetainerNode* n = PushNode(retainer, edge_name); 284 retainer->MemoryInfo(this); 285 CHECK_EQ(CurrentNode(), n); 286 CHECK_NE(n->size_, 0); 287 PopNode(); 288 } 289 290 void MemoryTracker::TrackInlineField(const MemoryRetainer* retainer, 291 const char* edge_name) { 292 Track(retainer, edge_name); 293 CHECK(CurrentNode()); 294 CurrentNode()->size_ -= retainer->SelfSize(); 295 } 296 297 MemoryRetainerNode* MemoryTracker::CurrentNode() const { 298 if (node_stack_.empty()) return nullptr; 299 return node_stack_.top(); 300 } 301 302 MemoryRetainerNode* MemoryTracker::AddNode(const MemoryRetainer* retainer, 303 const char* edge_name) { 304 auto it = seen_.find(retainer); 305 if (it != seen_.end()) { 306 return it->second; 307 } 308 309 MemoryRetainerNode* n = new MemoryRetainerNode(this, retainer); 310 graph_->AddNode(std::unique_ptr
(n)); 311 seen_[retainer] = n; 312 if (CurrentNode() != nullptr) graph_->AddEdge(CurrentNode(), n, edge_name); 313 314 if (n->JSWrapperNode() != nullptr) { 315 graph_->AddEdge(n, n->JSWrapperNode(), "native_to_javascript"); 316 graph_->AddEdge(n->JSWrapperNode(), n, "javascript_to_native"); 317 } 318 319 return n; 320 } 321 322 MemoryRetainerNode* MemoryTracker::AddNode(const char* node_name, 323 size_t size, 324 const char* edge_name) { 325 MemoryRetainerNode* n = new MemoryRetainerNode(this, node_name, size); 326 graph_->AddNode(std::unique_ptr
(n)); 327 328 if (CurrentNode() != nullptr) graph_->AddEdge(CurrentNode(), n, edge_name); 329 330 return n; 331 } 332 333 MemoryRetainerNode* MemoryTracker::PushNode(const MemoryRetainer* retainer, 334 const char* edge_name) { 335 MemoryRetainerNode* n = AddNode(retainer, edge_name); 336 node_stack_.push(n); 337 return n; 338 } 339 340 MemoryRetainerNode* MemoryTracker::PushNode(const char* node_name, 341 size_t size, 342 const char* edge_name) { 343 MemoryRetainerNode* n = AddNode(node_name, size, edge_name); 344 node_stack_.push(n); 345 return n; 346 } 347 348 void MemoryTracker::PopNode() { 349 node_stack_.pop(); 350 } 351 352 } // namespace node 353 354 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 355 356 #endif // SRC_MEMORY_TRACKER_INL_H_
Contact us
|
About us
|
Term of use
|
Copyright © 2000-2024 MyWebUniversity.com ™