| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 to_entry_ = &snapshot->entries()[to_index_]; | 66 to_entry_ = &snapshot->entries()[to_index_]; |
| 67 } | 67 } |
| 68 | 68 |
| 69 | 69 |
| 70 const int HeapEntry::kNoEntry = -1; | 70 const int HeapEntry::kNoEntry = -1; |
| 71 | 71 |
| 72 HeapEntry::HeapEntry(HeapSnapshot* snapshot, | 72 HeapEntry::HeapEntry(HeapSnapshot* snapshot, |
| 73 Type type, | 73 Type type, |
| 74 const char* name, | 74 const char* name, |
| 75 SnapshotObjectId id, | 75 SnapshotObjectId id, |
| 76 size_t self_size) | 76 size_t self_size, |
| 77 unsigned trace_node_id) |
| 77 : type_(type), | 78 : type_(type), |
| 78 children_count_(0), | 79 children_count_(0), |
| 79 children_index_(-1), | 80 children_index_(-1), |
| 80 self_size_(self_size), | 81 self_size_(self_size), |
| 82 snapshot_(snapshot), |
| 83 name_(name), |
| 81 id_(id), | 84 id_(id), |
| 82 snapshot_(snapshot), | 85 trace_node_id_(trace_node_id) { } |
| 83 name_(name) { } | |
| 84 | 86 |
| 85 | 87 |
| 86 void HeapEntry::SetNamedReference(HeapGraphEdge::Type type, | 88 void HeapEntry::SetNamedReference(HeapGraphEdge::Type type, |
| 87 const char* name, | 89 const char* name, |
| 88 HeapEntry* entry) { | 90 HeapEntry* entry) { |
| 89 HeapGraphEdge edge(type, name, this->index(), entry->index()); | 91 HeapGraphEdge edge(type, name, this->index(), entry->index()); |
| 90 snapshot_->edges().Add(edge); | 92 snapshot_->edges().Add(edge); |
| 91 ++children_count_; | 93 ++children_count_; |
| 92 } | 94 } |
| 93 | 95 |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 | 184 |
| 183 | 185 |
| 184 // It is very important to keep objects that form a heap snapshot | 186 // It is very important to keep objects that form a heap snapshot |
| 185 // as small as possible. | 187 // as small as possible. |
| 186 namespace { // Avoid littering the global namespace. | 188 namespace { // Avoid littering the global namespace. |
| 187 | 189 |
| 188 template <size_t ptr_size> struct SnapshotSizeConstants; | 190 template <size_t ptr_size> struct SnapshotSizeConstants; |
| 189 | 191 |
| 190 template <> struct SnapshotSizeConstants<4> { | 192 template <> struct SnapshotSizeConstants<4> { |
| 191 static const int kExpectedHeapGraphEdgeSize = 12; | 193 static const int kExpectedHeapGraphEdgeSize = 12; |
| 192 static const int kExpectedHeapEntrySize = 24; | 194 static const int kExpectedHeapEntrySize = 28; |
| 193 }; | 195 }; |
| 194 | 196 |
| 195 template <> struct SnapshotSizeConstants<8> { | 197 template <> struct SnapshotSizeConstants<8> { |
| 196 static const int kExpectedHeapGraphEdgeSize = 24; | 198 static const int kExpectedHeapGraphEdgeSize = 24; |
| 197 static const int kExpectedHeapEntrySize = 40; | 199 static const int kExpectedHeapEntrySize = 40; |
| 198 }; | 200 }; |
| 199 | 201 |
| 200 } // namespace | 202 } // namespace |
| 201 | 203 |
| 202 | 204 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 max_snapshot_js_object_id_ = profiler_->heap_object_map()->last_assigned_id(); | 238 max_snapshot_js_object_id_ = profiler_->heap_object_map()->last_assigned_id(); |
| 237 } | 239 } |
| 238 | 240 |
| 239 | 241 |
| 240 HeapEntry* HeapSnapshot::AddRootEntry() { | 242 HeapEntry* HeapSnapshot::AddRootEntry() { |
| 241 ASSERT(root_index_ == HeapEntry::kNoEntry); | 243 ASSERT(root_index_ == HeapEntry::kNoEntry); |
| 242 ASSERT(entries_.is_empty()); // Root entry must be the first one. | 244 ASSERT(entries_.is_empty()); // Root entry must be the first one. |
| 243 HeapEntry* entry = AddEntry(HeapEntry::kSynthetic, | 245 HeapEntry* entry = AddEntry(HeapEntry::kSynthetic, |
| 244 "", | 246 "", |
| 245 HeapObjectsMap::kInternalRootObjectId, | 247 HeapObjectsMap::kInternalRootObjectId, |
| 248 0, |
| 246 0); | 249 0); |
| 247 root_index_ = entry->index(); | 250 root_index_ = entry->index(); |
| 248 ASSERT(root_index_ == 0); | 251 ASSERT(root_index_ == 0); |
| 249 return entry; | 252 return entry; |
| 250 } | 253 } |
| 251 | 254 |
| 252 | 255 |
| 253 HeapEntry* HeapSnapshot::AddGcRootsEntry() { | 256 HeapEntry* HeapSnapshot::AddGcRootsEntry() { |
| 254 ASSERT(gc_roots_index_ == HeapEntry::kNoEntry); | 257 ASSERT(gc_roots_index_ == HeapEntry::kNoEntry); |
| 255 HeapEntry* entry = AddEntry(HeapEntry::kSynthetic, | 258 HeapEntry* entry = AddEntry(HeapEntry::kSynthetic, |
| 256 "(GC roots)", | 259 "(GC roots)", |
| 257 HeapObjectsMap::kGcRootsObjectId, | 260 HeapObjectsMap::kGcRootsObjectId, |
| 261 0, |
| 258 0); | 262 0); |
| 259 gc_roots_index_ = entry->index(); | 263 gc_roots_index_ = entry->index(); |
| 260 return entry; | 264 return entry; |
| 261 } | 265 } |
| 262 | 266 |
| 263 | 267 |
| 264 HeapEntry* HeapSnapshot::AddGcSubrootEntry(int tag) { | 268 HeapEntry* HeapSnapshot::AddGcSubrootEntry(int tag) { |
| 265 ASSERT(gc_subroot_indexes_[tag] == HeapEntry::kNoEntry); | 269 ASSERT(gc_subroot_indexes_[tag] == HeapEntry::kNoEntry); |
| 266 ASSERT(0 <= tag && tag < VisitorSynchronization::kNumberOfSyncTags); | 270 ASSERT(0 <= tag && tag < VisitorSynchronization::kNumberOfSyncTags); |
| 267 HeapEntry* entry = AddEntry( | 271 HeapEntry* entry = AddEntry( |
| 268 HeapEntry::kSynthetic, | 272 HeapEntry::kSynthetic, |
| 269 VisitorSynchronization::kTagNames[tag], | 273 VisitorSynchronization::kTagNames[tag], |
| 270 HeapObjectsMap::GetNthGcSubrootId(tag), | 274 HeapObjectsMap::GetNthGcSubrootId(tag), |
| 275 0, |
| 271 0); | 276 0); |
| 272 gc_subroot_indexes_[tag] = entry->index(); | 277 gc_subroot_indexes_[tag] = entry->index(); |
| 273 return entry; | 278 return entry; |
| 274 } | 279 } |
| 275 | 280 |
| 276 | 281 |
| 277 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type, | 282 HeapEntry* HeapSnapshot::AddEntry(HeapEntry::Type type, |
| 278 const char* name, | 283 const char* name, |
| 279 SnapshotObjectId id, | 284 SnapshotObjectId id, |
| 280 size_t size) { | 285 size_t size, |
| 281 HeapEntry entry(this, type, name, id, size); | 286 unsigned trace_node_id) { |
| 287 HeapEntry entry(this, type, name, id, size, trace_node_id); |
| 282 entries_.Add(entry); | 288 entries_.Add(entry); |
| 283 return &entries_.last(); | 289 return &entries_.last(); |
| 284 } | 290 } |
| 285 | 291 |
| 286 | 292 |
| 287 void HeapSnapshot::FillChildren() { | 293 void HeapSnapshot::FillChildren() { |
| 288 ASSERT(children().is_empty()); | 294 ASSERT(children().is_empty()); |
| 289 children().Allocate(edges().length()); | 295 children().Allocate(edges().length()); |
| 290 int children_index = 0; | 296 int children_index = 0; |
| 291 for (int i = 0; i < entries().length(); ++i) { | 297 for (int i = 0; i < entries().length(); ++i) { |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 // When we do lookup in HashMap we see no difference between two cases: | 389 // When we do lookup in HashMap we see no difference between two cases: |
| 384 // it has an entry with NULL as the value or it has created | 390 // it has an entry with NULL as the value or it has created |
| 385 // a new entry on the fly with NULL as the default value. | 391 // a new entry on the fly with NULL as the default value. |
| 386 // With such dummy element we have a guaranty that all entries_map_ entries | 392 // With such dummy element we have a guaranty that all entries_map_ entries |
| 387 // will have the value field grater than 0. | 393 // will have the value field grater than 0. |
| 388 // This fact is using in MoveObject method. | 394 // This fact is using in MoveObject method. |
| 389 entries_.Add(EntryInfo(0, NULL, 0)); | 395 entries_.Add(EntryInfo(0, NULL, 0)); |
| 390 } | 396 } |
| 391 | 397 |
| 392 | 398 |
| 393 void HeapObjectsMap::MoveObject(Address from, Address to, int object_size) { | 399 bool HeapObjectsMap::MoveObject(Address from, Address to, int object_size) { |
| 394 ASSERT(to != NULL); | 400 ASSERT(to != NULL); |
| 395 ASSERT(from != NULL); | 401 ASSERT(from != NULL); |
| 396 if (from == to) return; | 402 if (from == to) return false; |
| 397 void* from_value = entries_map_.Remove(from, ComputePointerHash(from)); | 403 void* from_value = entries_map_.Remove(from, ComputePointerHash(from)); |
| 398 if (from_value == NULL) { | 404 if (from_value == NULL) { |
| 399 // It may occur that some untracked object moves to an address X and there | 405 // It may occur that some untracked object moves to an address X and there |
| 400 // is a tracked object at that address. In this case we should remove the | 406 // is a tracked object at that address. In this case we should remove the |
| 401 // entry as we know that the object has died. | 407 // entry as we know that the object has died. |
| 402 void* to_value = entries_map_.Remove(to, ComputePointerHash(to)); | 408 void* to_value = entries_map_.Remove(to, ComputePointerHash(to)); |
| 403 if (to_value != NULL) { | 409 if (to_value != NULL) { |
| 404 int to_entry_info_index = | 410 int to_entry_info_index = |
| 405 static_cast<int>(reinterpret_cast<intptr_t>(to_value)); | 411 static_cast<int>(reinterpret_cast<intptr_t>(to_value)); |
| 406 entries_.at(to_entry_info_index).addr = NULL; | 412 entries_.at(to_entry_info_index).addr = NULL; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 427 if (FLAG_heap_profiler_trace_objects) { | 433 if (FLAG_heap_profiler_trace_objects) { |
| 428 PrintF("Move object from %p to %p old size %6d new size %6d\n", | 434 PrintF("Move object from %p to %p old size %6d new size %6d\n", |
| 429 from, | 435 from, |
| 430 to, | 436 to, |
| 431 entries_.at(from_entry_info_index).size, | 437 entries_.at(from_entry_info_index).size, |
| 432 object_size); | 438 object_size); |
| 433 } | 439 } |
| 434 entries_.at(from_entry_info_index).size = object_size; | 440 entries_.at(from_entry_info_index).size = object_size; |
| 435 to_entry->value = from_value; | 441 to_entry->value = from_value; |
| 436 } | 442 } |
| 443 return from_value != NULL; |
| 437 } | 444 } |
| 438 | 445 |
| 439 | 446 |
| 440 void HeapObjectsMap::UpdateObjectSize(Address addr, int size) { | 447 void HeapObjectsMap::UpdateObjectSize(Address addr, int size) { |
| 441 FindOrAddEntry(addr, size, false); | 448 FindOrAddEntry(addr, size, false); |
| 442 } | 449 } |
| 443 | 450 |
| 444 | 451 |
| 445 SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { | 452 SnapshotObjectId HeapObjectsMap::FindEntry(Address addr) { |
| 446 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), | 453 HashMap::Entry* entry = entries_map_.Lookup(addr, ComputePointerHash(addr), |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 return AddEntry(object->address(), type, name, object->Size()); | 910 return AddEntry(object->address(), type, name, object->Size()); |
| 904 } | 911 } |
| 905 | 912 |
| 906 | 913 |
| 907 HeapEntry* V8HeapExplorer::AddEntry(Address address, | 914 HeapEntry* V8HeapExplorer::AddEntry(Address address, |
| 908 HeapEntry::Type type, | 915 HeapEntry::Type type, |
| 909 const char* name, | 916 const char* name, |
| 910 size_t size) { | 917 size_t size) { |
| 911 SnapshotObjectId object_id = heap_object_map_->FindOrAddEntry( | 918 SnapshotObjectId object_id = heap_object_map_->FindOrAddEntry( |
| 912 address, static_cast<unsigned int>(size)); | 919 address, static_cast<unsigned int>(size)); |
| 913 return snapshot_->AddEntry(type, name, object_id, size); | 920 unsigned trace_node_id = 0; |
| 921 if (AllocationTracker* allocation_tracker = |
| 922 snapshot_->profiler()->allocation_tracker()) { |
| 923 trace_node_id = |
| 924 allocation_tracker->address_to_trace()->GetTraceNodeId(address); |
| 925 } |
| 926 return snapshot_->AddEntry(type, name, object_id, size, trace_node_id); |
| 914 } | 927 } |
| 915 | 928 |
| 916 | 929 |
| 930 class SnapshotFiller { |
| 931 public: |
| 932 explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries) |
| 933 : snapshot_(snapshot), |
| 934 names_(snapshot->profiler()->names()), |
| 935 entries_(entries) { } |
| 936 HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) { |
| 937 HeapEntry* entry = allocator->AllocateEntry(ptr); |
| 938 entries_->Pair(ptr, entry->index()); |
| 939 return entry; |
| 940 } |
| 941 HeapEntry* FindEntry(HeapThing ptr) { |
| 942 int index = entries_->Map(ptr); |
| 943 return index != HeapEntry::kNoEntry ? &snapshot_->entries()[index] : NULL; |
| 944 } |
| 945 HeapEntry* FindOrAddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) { |
| 946 HeapEntry* entry = FindEntry(ptr); |
| 947 return entry != NULL ? entry : AddEntry(ptr, allocator); |
| 948 } |
| 949 void SetIndexedReference(HeapGraphEdge::Type type, |
| 950 int parent, |
| 951 int index, |
| 952 HeapEntry* child_entry) { |
| 953 HeapEntry* parent_entry = &snapshot_->entries()[parent]; |
| 954 parent_entry->SetIndexedReference(type, index, child_entry); |
| 955 } |
| 956 void SetIndexedAutoIndexReference(HeapGraphEdge::Type type, |
| 957 int parent, |
| 958 HeapEntry* child_entry) { |
| 959 HeapEntry* parent_entry = &snapshot_->entries()[parent]; |
| 960 int index = parent_entry->children_count() + 1; |
| 961 parent_entry->SetIndexedReference(type, index, child_entry); |
| 962 } |
| 963 void SetNamedReference(HeapGraphEdge::Type type, |
| 964 int parent, |
| 965 const char* reference_name, |
| 966 HeapEntry* child_entry) { |
| 967 HeapEntry* parent_entry = &snapshot_->entries()[parent]; |
| 968 parent_entry->SetNamedReference(type, reference_name, child_entry); |
| 969 } |
| 970 void SetNamedAutoIndexReference(HeapGraphEdge::Type type, |
| 971 int parent, |
| 972 HeapEntry* child_entry) { |
| 973 HeapEntry* parent_entry = &snapshot_->entries()[parent]; |
| 974 int index = parent_entry->children_count() + 1; |
| 975 parent_entry->SetNamedReference( |
| 976 type, |
| 977 names_->GetName(index), |
| 978 child_entry); |
| 979 } |
| 980 |
| 981 private: |
| 982 HeapSnapshot* snapshot_; |
| 983 StringsStorage* names_; |
| 984 HeapEntriesMap* entries_; |
| 985 }; |
| 986 |
| 987 |
| 917 class GcSubrootsEnumerator : public ObjectVisitor { | 988 class GcSubrootsEnumerator : public ObjectVisitor { |
| 918 public: | 989 public: |
| 919 GcSubrootsEnumerator( | 990 GcSubrootsEnumerator( |
| 920 SnapshotFillerInterface* filler, V8HeapExplorer* explorer) | 991 SnapshotFiller* filler, V8HeapExplorer* explorer) |
| 921 : filler_(filler), | 992 : filler_(filler), |
| 922 explorer_(explorer), | 993 explorer_(explorer), |
| 923 previous_object_count_(0), | 994 previous_object_count_(0), |
| 924 object_count_(0) { | 995 object_count_(0) { |
| 925 } | 996 } |
| 926 void VisitPointers(Object** start, Object** end) { | 997 void VisitPointers(Object** start, Object** end) { |
| 927 object_count_ += end - start; | 998 object_count_ += end - start; |
| 928 } | 999 } |
| 929 void Synchronize(VisitorSynchronization::SyncTag tag) { | 1000 void Synchronize(VisitorSynchronization::SyncTag tag) { |
| 930 // Skip empty subroots. | 1001 // Skip empty subroots. |
| 931 if (previous_object_count_ != object_count_) { | 1002 if (previous_object_count_ != object_count_) { |
| 932 previous_object_count_ = object_count_; | 1003 previous_object_count_ = object_count_; |
| 933 filler_->AddEntry(V8HeapExplorer::GetNthGcSubrootObject(tag), explorer_); | 1004 filler_->AddEntry(V8HeapExplorer::GetNthGcSubrootObject(tag), explorer_); |
| 934 } | 1005 } |
| 935 } | 1006 } |
| 936 private: | 1007 private: |
| 937 SnapshotFillerInterface* filler_; | 1008 SnapshotFiller* filler_; |
| 938 V8HeapExplorer* explorer_; | 1009 V8HeapExplorer* explorer_; |
| 939 intptr_t previous_object_count_; | 1010 intptr_t previous_object_count_; |
| 940 intptr_t object_count_; | 1011 intptr_t object_count_; |
| 941 }; | 1012 }; |
| 942 | 1013 |
| 943 | 1014 |
| 944 void V8HeapExplorer::AddRootEntries(SnapshotFillerInterface* filler) { | 1015 void V8HeapExplorer::AddRootEntries(SnapshotFiller* filler) { |
| 945 filler->AddEntry(kInternalRootObject, this); | 1016 filler->AddEntry(kInternalRootObject, this); |
| 946 filler->AddEntry(kGcRootsObject, this); | 1017 filler->AddEntry(kGcRootsObject, this); |
| 947 GcSubrootsEnumerator enumerator(filler, this); | 1018 GcSubrootsEnumerator enumerator(filler, this); |
| 948 heap_->IterateRoots(&enumerator, VISIT_ALL); | 1019 heap_->IterateRoots(&enumerator, VISIT_ALL); |
| 949 } | 1020 } |
| 950 | 1021 |
| 951 | 1022 |
| 952 const char* V8HeapExplorer::GetSystemEntryName(HeapObject* object) { | 1023 const char* V8HeapExplorer::GetSystemEntryName(HeapObject* object) { |
| 953 switch (object->map()->instance_type()) { | 1024 switch (object->map()->instance_type()) { |
| 954 case MAP_TYPE: | 1025 case MAP_TYPE: |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1320 SharedFunctionInfo::kFunctionDataOffset); | 1391 SharedFunctionInfo::kFunctionDataOffset); |
| 1321 SetInternalReference(obj, entry, | 1392 SetInternalReference(obj, entry, |
| 1322 "debug_info", shared->debug_info(), | 1393 "debug_info", shared->debug_info(), |
| 1323 SharedFunctionInfo::kDebugInfoOffset); | 1394 SharedFunctionInfo::kDebugInfoOffset); |
| 1324 SetInternalReference(obj, entry, | 1395 SetInternalReference(obj, entry, |
| 1325 "inferred_name", shared->inferred_name(), | 1396 "inferred_name", shared->inferred_name(), |
| 1326 SharedFunctionInfo::kInferredNameOffset); | 1397 SharedFunctionInfo::kInferredNameOffset); |
| 1327 SetInternalReference(obj, entry, | 1398 SetInternalReference(obj, entry, |
| 1328 "optimized_code_map", shared->optimized_code_map(), | 1399 "optimized_code_map", shared->optimized_code_map(), |
| 1329 SharedFunctionInfo::kOptimizedCodeMapOffset); | 1400 SharedFunctionInfo::kOptimizedCodeMapOffset); |
| 1401 SetInternalReference(obj, entry, |
| 1402 "feedback_vector", shared->feedback_vector(), |
| 1403 SharedFunctionInfo::kFeedbackVectorOffset); |
| 1330 SetWeakReference(obj, entry, | 1404 SetWeakReference(obj, entry, |
| 1331 "initial_map", shared->initial_map(), | 1405 "initial_map", shared->initial_map(), |
| 1332 SharedFunctionInfo::kInitialMapOffset); | 1406 SharedFunctionInfo::kInitialMapOffset); |
| 1333 } | 1407 } |
| 1334 | 1408 |
| 1335 | 1409 |
| 1336 void V8HeapExplorer::ExtractScriptReferences(int entry, Script* script) { | 1410 void V8HeapExplorer::ExtractScriptReferences(int entry, Script* script) { |
| 1337 HeapObject* obj = script; | 1411 HeapObject* obj = script; |
| 1338 SetInternalReference(obj, entry, | 1412 SetInternalReference(obj, entry, |
| 1339 "source", script->source(), | 1413 "source", script->source(), |
| 1340 Script::kSourceOffset); | 1414 Script::kSourceOffset); |
| 1341 SetInternalReference(obj, entry, | 1415 SetInternalReference(obj, entry, |
| 1342 "name", script->name(), | 1416 "name", script->name(), |
| 1343 Script::kNameOffset); | 1417 Script::kNameOffset); |
| 1344 SetInternalReference(obj, entry, | 1418 SetInternalReference(obj, entry, |
| 1345 "data", script->data(), | |
| 1346 Script::kDataOffset); | |
| 1347 SetInternalReference(obj, entry, | |
| 1348 "context_data", script->context_data(), | 1419 "context_data", script->context_data(), |
| 1349 Script::kContextOffset); | 1420 Script::kContextOffset); |
| 1350 TagObject(script->line_ends(), "(script line ends)"); | 1421 TagObject(script->line_ends(), "(script line ends)"); |
| 1351 SetInternalReference(obj, entry, | 1422 SetInternalReference(obj, entry, |
| 1352 "line_ends", script->line_ends(), | 1423 "line_ends", script->line_ends(), |
| 1353 Script::kLineEndsOffset); | 1424 Script::kLineEndsOffset); |
| 1354 } | 1425 } |
| 1355 | 1426 |
| 1356 | 1427 |
| 1357 void V8HeapExplorer::ExtractAccessorPairReferences( | 1428 void V8HeapExplorer::ExtractAccessorPairReferences( |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1744 bool collecting_all_references_; | 1815 bool collecting_all_references_; |
| 1745 List<Object*> strong_references_; | 1816 List<Object*> strong_references_; |
| 1746 List<Object*> all_references_; | 1817 List<Object*> all_references_; |
| 1747 int previous_reference_count_; | 1818 int previous_reference_count_; |
| 1748 List<IndexTag> reference_tags_; | 1819 List<IndexTag> reference_tags_; |
| 1749 Heap* heap_; | 1820 Heap* heap_; |
| 1750 }; | 1821 }; |
| 1751 | 1822 |
| 1752 | 1823 |
| 1753 bool V8HeapExplorer::IterateAndExtractReferences( | 1824 bool V8HeapExplorer::IterateAndExtractReferences( |
| 1754 SnapshotFillerInterface* filler) { | 1825 SnapshotFiller* filler) { |
| 1755 filler_ = filler; | 1826 filler_ = filler; |
| 1756 | 1827 |
| 1757 // Make sure builtin code objects get their builtin tags | 1828 // Make sure builtin code objects get their builtin tags |
| 1758 // first. Otherwise a particular JSFunction object could set | 1829 // first. Otherwise a particular JSFunction object could set |
| 1759 // its custom name to a generic builtin. | 1830 // its custom name to a generic builtin. |
| 1760 SetRootGcRootsReference(); | 1831 SetRootGcRootsReference(); |
| 1761 RootsReferencesExtractor extractor(heap_); | 1832 RootsReferencesExtractor extractor(heap_); |
| 1762 heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG); | 1833 heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG); |
| 1763 extractor.SetCollectingAllReferences(); | 1834 extractor.SetCollectingAllReferences(); |
| 1764 heap_->IterateRoots(&extractor, VISIT_ALL); | 1835 heap_->IterateRoots(&extractor, VISIT_ALL); |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2136 intptr_t elements = info->GetElementCount(); | 2207 intptr_t elements = info->GetElementCount(); |
| 2137 intptr_t size = info->GetSizeInBytes(); | 2208 intptr_t size = info->GetSizeInBytes(); |
| 2138 const char* name = elements != -1 | 2209 const char* name = elements != -1 |
| 2139 ? names_->GetFormatted( | 2210 ? names_->GetFormatted( |
| 2140 "%s / %" V8_PTR_PREFIX "d entries", info->GetLabel(), elements) | 2211 "%s / %" V8_PTR_PREFIX "d entries", info->GetLabel(), elements) |
| 2141 : names_->GetCopy(info->GetLabel()); | 2212 : names_->GetCopy(info->GetLabel()); |
| 2142 return snapshot_->AddEntry( | 2213 return snapshot_->AddEntry( |
| 2143 entries_type_, | 2214 entries_type_, |
| 2144 name, | 2215 name, |
| 2145 heap_object_map_->GenerateId(info), | 2216 heap_object_map_->GenerateId(info), |
| 2146 size != -1 ? static_cast<int>(size) : 0); | 2217 size != -1 ? static_cast<int>(size) : 0, |
| 2218 0); |
| 2147 } | 2219 } |
| 2148 | 2220 |
| 2149 | 2221 |
| 2150 NativeObjectsExplorer::NativeObjectsExplorer( | 2222 NativeObjectsExplorer::NativeObjectsExplorer( |
| 2151 HeapSnapshot* snapshot, | 2223 HeapSnapshot* snapshot, |
| 2152 SnapshottingProgressReportingInterface* progress) | 2224 SnapshottingProgressReportingInterface* progress) |
| 2153 : isolate_(snapshot->profiler()->heap_object_map()->heap()->isolate()), | 2225 : isolate_(snapshot->profiler()->heap_object_map()->heap()->isolate()), |
| 2154 snapshot_(snapshot), | 2226 snapshot_(snapshot), |
| 2155 names_(snapshot_->profiler()->names()), | 2227 names_(snapshot_->profiler()->names()), |
| 2156 progress_(progress), | 2228 progress_(progress), |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2254 if (entry->value != NULL) { | 2326 if (entry->value != NULL) { |
| 2255 info->Dispose(); | 2327 info->Dispose(); |
| 2256 } else { | 2328 } else { |
| 2257 entry->value = new List<HeapObject*>(4); | 2329 entry->value = new List<HeapObject*>(4); |
| 2258 } | 2330 } |
| 2259 return reinterpret_cast<List<HeapObject*>* >(entry->value); | 2331 return reinterpret_cast<List<HeapObject*>* >(entry->value); |
| 2260 } | 2332 } |
| 2261 | 2333 |
| 2262 | 2334 |
| 2263 bool NativeObjectsExplorer::IterateAndExtractReferences( | 2335 bool NativeObjectsExplorer::IterateAndExtractReferences( |
| 2264 SnapshotFillerInterface* filler) { | 2336 SnapshotFiller* filler) { |
| 2265 filler_ = filler; | 2337 filler_ = filler; |
| 2266 FillRetainedObjects(); | 2338 FillRetainedObjects(); |
| 2267 FillImplicitReferences(); | 2339 FillImplicitReferences(); |
| 2268 if (EstimateObjectsCount() > 0) { | 2340 if (EstimateObjectsCount() > 0) { |
| 2269 for (HashMap::Entry* p = objects_by_info_.Start(); | 2341 for (HashMap::Entry* p = objects_by_info_.Start(); |
| 2270 p != NULL; | 2342 p != NULL; |
| 2271 p = objects_by_info_.Next(p)) { | 2343 p = objects_by_info_.Next(p)) { |
| 2272 v8::RetainedObjectInfo* info = | 2344 v8::RetainedObjectInfo* info = |
| 2273 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); | 2345 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); |
| 2274 SetNativeRootReference(info); | 2346 SetNativeRootReference(info); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2381 void NativeObjectsExplorer::VisitSubtreeWrapper(Object** p, uint16_t class_id) { | 2453 void NativeObjectsExplorer::VisitSubtreeWrapper(Object** p, uint16_t class_id) { |
| 2382 if (in_groups_.Contains(*p)) return; | 2454 if (in_groups_.Contains(*p)) return; |
| 2383 Isolate* isolate = isolate_; | 2455 Isolate* isolate = isolate_; |
| 2384 v8::RetainedObjectInfo* info = | 2456 v8::RetainedObjectInfo* info = |
| 2385 isolate->heap_profiler()->ExecuteWrapperClassCallback(class_id, p); | 2457 isolate->heap_profiler()->ExecuteWrapperClassCallback(class_id, p); |
| 2386 if (info == NULL) return; | 2458 if (info == NULL) return; |
| 2387 GetListMaybeDisposeInfo(info)->Add(HeapObject::cast(*p)); | 2459 GetListMaybeDisposeInfo(info)->Add(HeapObject::cast(*p)); |
| 2388 } | 2460 } |
| 2389 | 2461 |
| 2390 | 2462 |
| 2391 class SnapshotFiller : public SnapshotFillerInterface { | |
| 2392 public: | |
| 2393 explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries) | |
| 2394 : snapshot_(snapshot), | |
| 2395 names_(snapshot->profiler()->names()), | |
| 2396 entries_(entries) { } | |
| 2397 HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) { | |
| 2398 HeapEntry* entry = allocator->AllocateEntry(ptr); | |
| 2399 entries_->Pair(ptr, entry->index()); | |
| 2400 return entry; | |
| 2401 } | |
| 2402 HeapEntry* FindEntry(HeapThing ptr) { | |
| 2403 int index = entries_->Map(ptr); | |
| 2404 return index != HeapEntry::kNoEntry ? &snapshot_->entries()[index] : NULL; | |
| 2405 } | |
| 2406 HeapEntry* FindOrAddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) { | |
| 2407 HeapEntry* entry = FindEntry(ptr); | |
| 2408 return entry != NULL ? entry : AddEntry(ptr, allocator); | |
| 2409 } | |
| 2410 void SetIndexedReference(HeapGraphEdge::Type type, | |
| 2411 int parent, | |
| 2412 int index, | |
| 2413 HeapEntry* child_entry) { | |
| 2414 HeapEntry* parent_entry = &snapshot_->entries()[parent]; | |
| 2415 parent_entry->SetIndexedReference(type, index, child_entry); | |
| 2416 } | |
| 2417 void SetIndexedAutoIndexReference(HeapGraphEdge::Type type, | |
| 2418 int parent, | |
| 2419 HeapEntry* child_entry) { | |
| 2420 HeapEntry* parent_entry = &snapshot_->entries()[parent]; | |
| 2421 int index = parent_entry->children_count() + 1; | |
| 2422 parent_entry->SetIndexedReference(type, index, child_entry); | |
| 2423 } | |
| 2424 void SetNamedReference(HeapGraphEdge::Type type, | |
| 2425 int parent, | |
| 2426 const char* reference_name, | |
| 2427 HeapEntry* child_entry) { | |
| 2428 HeapEntry* parent_entry = &snapshot_->entries()[parent]; | |
| 2429 parent_entry->SetNamedReference(type, reference_name, child_entry); | |
| 2430 } | |
| 2431 void SetNamedAutoIndexReference(HeapGraphEdge::Type type, | |
| 2432 int parent, | |
| 2433 HeapEntry* child_entry) { | |
| 2434 HeapEntry* parent_entry = &snapshot_->entries()[parent]; | |
| 2435 int index = parent_entry->children_count() + 1; | |
| 2436 parent_entry->SetNamedReference( | |
| 2437 type, | |
| 2438 names_->GetName(index), | |
| 2439 child_entry); | |
| 2440 } | |
| 2441 | |
| 2442 private: | |
| 2443 HeapSnapshot* snapshot_; | |
| 2444 StringsStorage* names_; | |
| 2445 HeapEntriesMap* entries_; | |
| 2446 }; | |
| 2447 | |
| 2448 | |
| 2449 HeapSnapshotGenerator::HeapSnapshotGenerator( | 2463 HeapSnapshotGenerator::HeapSnapshotGenerator( |
| 2450 HeapSnapshot* snapshot, | 2464 HeapSnapshot* snapshot, |
| 2451 v8::ActivityControl* control, | 2465 v8::ActivityControl* control, |
| 2452 v8::HeapProfiler::ObjectNameResolver* resolver, | 2466 v8::HeapProfiler::ObjectNameResolver* resolver, |
| 2453 Heap* heap) | 2467 Heap* heap) |
| 2454 : snapshot_(snapshot), | 2468 : snapshot_(snapshot), |
| 2455 control_(control), | 2469 control_(control), |
| 2456 v8_heap_explorer_(snapshot_, this, resolver), | 2470 v8_heap_explorer_(snapshot_, this, resolver), |
| 2457 dom_explorer_(snapshot_, this), | 2471 dom_explorer_(snapshot_, this), |
| 2458 heap_(heap) { | 2472 heap_(heap) { |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2635 v8::OutputStream* stream_; | 2649 v8::OutputStream* stream_; |
| 2636 int chunk_size_; | 2650 int chunk_size_; |
| 2637 ScopedVector<char> chunk_; | 2651 ScopedVector<char> chunk_; |
| 2638 int chunk_pos_; | 2652 int chunk_pos_; |
| 2639 bool aborted_; | 2653 bool aborted_; |
| 2640 }; | 2654 }; |
| 2641 | 2655 |
| 2642 | 2656 |
| 2643 // type, name|index, to_node. | 2657 // type, name|index, to_node. |
| 2644 const int HeapSnapshotJSONSerializer::kEdgeFieldsCount = 3; | 2658 const int HeapSnapshotJSONSerializer::kEdgeFieldsCount = 3; |
| 2645 // type, name, id, self_size, children_index. | 2659 // type, name, id, self_size, edge_count, trace_node_id. |
| 2646 const int HeapSnapshotJSONSerializer::kNodeFieldsCount = 5; | 2660 const int HeapSnapshotJSONSerializer::kNodeFieldsCount = 6; |
| 2647 | 2661 |
| 2648 void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) { | 2662 void HeapSnapshotJSONSerializer::Serialize(v8::OutputStream* stream) { |
| 2649 if (AllocationTracker* allocation_tracker = | 2663 if (AllocationTracker* allocation_tracker = |
| 2650 snapshot_->profiler()->allocation_tracker()) { | 2664 snapshot_->profiler()->allocation_tracker()) { |
| 2651 allocation_tracker->PrepareForSerialization(); | 2665 allocation_tracker->PrepareForSerialization(); |
| 2652 } | 2666 } |
| 2653 ASSERT(writer_ == NULL); | 2667 ASSERT(writer_ == NULL); |
| 2654 writer_ = new OutputStreamWriter(stream); | 2668 writer_ = new OutputStreamWriter(stream); |
| 2655 SerializeImpl(); | 2669 SerializeImpl(); |
| 2656 delete writer_; | 2670 delete writer_; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2776 edges[i - 1]->from()->index() <= edges[i]->from()->index()); | 2790 edges[i - 1]->from()->index() <= edges[i]->from()->index()); |
| 2777 SerializeEdge(edges[i], i == 0); | 2791 SerializeEdge(edges[i], i == 0); |
| 2778 if (writer_->aborted()) return; | 2792 if (writer_->aborted()) return; |
| 2779 } | 2793 } |
| 2780 } | 2794 } |
| 2781 | 2795 |
| 2782 | 2796 |
| 2783 void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry) { | 2797 void HeapSnapshotJSONSerializer::SerializeNode(HeapEntry* entry) { |
| 2784 // The buffer needs space for 4 unsigned ints, 1 size_t, 5 commas, \n and \0 | 2798 // The buffer needs space for 4 unsigned ints, 1 size_t, 5 commas, \n and \0 |
| 2785 static const int kBufferSize = | 2799 static const int kBufferSize = |
| 2786 4 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT | 2800 5 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT |
| 2787 + MaxDecimalDigitsIn<sizeof(size_t)>::kUnsigned // NOLINT | 2801 + MaxDecimalDigitsIn<sizeof(size_t)>::kUnsigned // NOLINT |
| 2788 + 5 + 1 + 1; | 2802 + 6 + 1 + 1; |
| 2789 EmbeddedVector<char, kBufferSize> buffer; | 2803 EmbeddedVector<char, kBufferSize> buffer; |
| 2790 int buffer_pos = 0; | 2804 int buffer_pos = 0; |
| 2791 if (entry_index(entry) != 0) { | 2805 if (entry_index(entry) != 0) { |
| 2792 buffer[buffer_pos++] = ','; | 2806 buffer[buffer_pos++] = ','; |
| 2793 } | 2807 } |
| 2794 buffer_pos = utoa(entry->type(), buffer, buffer_pos); | 2808 buffer_pos = utoa(entry->type(), buffer, buffer_pos); |
| 2795 buffer[buffer_pos++] = ','; | 2809 buffer[buffer_pos++] = ','; |
| 2796 buffer_pos = utoa(GetStringId(entry->name()), buffer, buffer_pos); | 2810 buffer_pos = utoa(GetStringId(entry->name()), buffer, buffer_pos); |
| 2797 buffer[buffer_pos++] = ','; | 2811 buffer[buffer_pos++] = ','; |
| 2798 buffer_pos = utoa(entry->id(), buffer, buffer_pos); | 2812 buffer_pos = utoa(entry->id(), buffer, buffer_pos); |
| 2799 buffer[buffer_pos++] = ','; | 2813 buffer[buffer_pos++] = ','; |
| 2800 buffer_pos = utoa(entry->self_size(), buffer, buffer_pos); | 2814 buffer_pos = utoa(entry->self_size(), buffer, buffer_pos); |
| 2801 buffer[buffer_pos++] = ','; | 2815 buffer[buffer_pos++] = ','; |
| 2802 buffer_pos = utoa(entry->children_count(), buffer, buffer_pos); | 2816 buffer_pos = utoa(entry->children_count(), buffer, buffer_pos); |
| 2817 buffer[buffer_pos++] = ','; |
| 2818 buffer_pos = utoa(entry->trace_node_id(), buffer, buffer_pos); |
| 2803 buffer[buffer_pos++] = '\n'; | 2819 buffer[buffer_pos++] = '\n'; |
| 2804 buffer[buffer_pos++] = '\0'; | 2820 buffer[buffer_pos++] = '\0'; |
| 2805 writer_->AddString(buffer.start()); | 2821 writer_->AddString(buffer.start()); |
| 2806 } | 2822 } |
| 2807 | 2823 |
| 2808 | 2824 |
| 2809 void HeapSnapshotJSONSerializer::SerializeNodes() { | 2825 void HeapSnapshotJSONSerializer::SerializeNodes() { |
| 2810 List<HeapEntry>& entries = snapshot_->entries(); | 2826 List<HeapEntry>& entries = snapshot_->entries(); |
| 2811 for (int i = 0; i < entries.length(); ++i) { | 2827 for (int i = 0; i < entries.length(); ++i) { |
| 2812 SerializeNode(&entries[i]); | 2828 SerializeNode(&entries[i]); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2826 // We use a set of macros to improve readability. | 2842 // We use a set of macros to improve readability. |
| 2827 #define JSON_A(s) "[" s "]" | 2843 #define JSON_A(s) "[" s "]" |
| 2828 #define JSON_O(s) "{" s "}" | 2844 #define JSON_O(s) "{" s "}" |
| 2829 #define JSON_S(s) "\"" s "\"" | 2845 #define JSON_S(s) "\"" s "\"" |
| 2830 writer_->AddString(JSON_O( | 2846 writer_->AddString(JSON_O( |
| 2831 JSON_S("node_fields") ":" JSON_A( | 2847 JSON_S("node_fields") ":" JSON_A( |
| 2832 JSON_S("type") "," | 2848 JSON_S("type") "," |
| 2833 JSON_S("name") "," | 2849 JSON_S("name") "," |
| 2834 JSON_S("id") "," | 2850 JSON_S("id") "," |
| 2835 JSON_S("self_size") "," | 2851 JSON_S("self_size") "," |
| 2836 JSON_S("edge_count")) "," | 2852 JSON_S("edge_count") "," |
| 2853 JSON_S("trace_node_id")) "," |
| 2837 JSON_S("node_types") ":" JSON_A( | 2854 JSON_S("node_types") ":" JSON_A( |
| 2838 JSON_A( | 2855 JSON_A( |
| 2839 JSON_S("hidden") "," | 2856 JSON_S("hidden") "," |
| 2840 JSON_S("array") "," | 2857 JSON_S("array") "," |
| 2841 JSON_S("string") "," | 2858 JSON_S("string") "," |
| 2842 JSON_S("object") "," | 2859 JSON_S("object") "," |
| 2843 JSON_S("code") "," | 2860 JSON_S("code") "," |
| 2844 JSON_S("closure") "," | 2861 JSON_S("closure") "," |
| 2845 JSON_S("regexp") "," | 2862 JSON_S("regexp") "," |
| 2846 JSON_S("number") "," | 2863 JSON_S("number") "," |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2871 JSON_S("node")) "," | 2888 JSON_S("node")) "," |
| 2872 JSON_S("trace_function_info_fields") ":" JSON_A( | 2889 JSON_S("trace_function_info_fields") ":" JSON_A( |
| 2873 JSON_S("function_id") "," | 2890 JSON_S("function_id") "," |
| 2874 JSON_S("name") "," | 2891 JSON_S("name") "," |
| 2875 JSON_S("script_name") "," | 2892 JSON_S("script_name") "," |
| 2876 JSON_S("script_id") "," | 2893 JSON_S("script_id") "," |
| 2877 JSON_S("line") "," | 2894 JSON_S("line") "," |
| 2878 JSON_S("column")) "," | 2895 JSON_S("column")) "," |
| 2879 JSON_S("trace_node_fields") ":" JSON_A( | 2896 JSON_S("trace_node_fields") ":" JSON_A( |
| 2880 JSON_S("id") "," | 2897 JSON_S("id") "," |
| 2881 JSON_S("function_id") "," | 2898 JSON_S("function_info_index") "," |
| 2882 JSON_S("count") "," | 2899 JSON_S("count") "," |
| 2883 JSON_S("size") "," | 2900 JSON_S("size") "," |
| 2884 JSON_S("children")))); | 2901 JSON_S("children")))); |
| 2885 #undef JSON_S | 2902 #undef JSON_S |
| 2886 #undef JSON_O | 2903 #undef JSON_O |
| 2887 #undef JSON_A | 2904 #undef JSON_A |
| 2888 writer_->AddString(",\"node_count\":"); | 2905 writer_->AddString(",\"node_count\":"); |
| 2889 writer_->AddNumber(snapshot_->entries().length()); | 2906 writer_->AddNumber(snapshot_->entries().length()); |
| 2890 writer_->AddString(",\"edge_count\":"); | 2907 writer_->AddString(",\"edge_count\":"); |
| 2891 writer_->AddNumber(snapshot_->edges().length()); | 2908 writer_->AddNumber(snapshot_->edges().length()); |
| 2892 writer_->AddString(",\"trace_function_count\":"); | 2909 writer_->AddString(",\"trace_function_count\":"); |
| 2893 uint32_t count = 0; | 2910 uint32_t count = 0; |
| 2894 AllocationTracker* tracker = snapshot_->profiler()->allocation_tracker(); | 2911 AllocationTracker* tracker = snapshot_->profiler()->allocation_tracker(); |
| 2895 if (tracker) { | 2912 if (tracker) { |
| 2896 count = tracker->id_to_function_info()->occupancy(); | 2913 count = tracker->function_info_list().length(); |
| 2897 } | 2914 } |
| 2898 writer_->AddNumber(count); | 2915 writer_->AddNumber(count); |
| 2899 } | 2916 } |
| 2900 | 2917 |
| 2901 | 2918 |
| 2902 static void WriteUChar(OutputStreamWriter* w, unibrow::uchar u) { | 2919 static void WriteUChar(OutputStreamWriter* w, unibrow::uchar u) { |
| 2903 static const char hex_chars[] = "0123456789ABCDEF"; | 2920 static const char hex_chars[] = "0123456789ABCDEF"; |
| 2904 w->AddString("\\u"); | 2921 w->AddString("\\u"); |
| 2905 w->AddCharacter(hex_chars[(u >> 12) & 0xf]); | 2922 w->AddCharacter(hex_chars[(u >> 12) & 0xf]); |
| 2906 w->AddCharacter(hex_chars[(u >> 8) & 0xf]); | 2923 w->AddCharacter(hex_chars[(u >> 8) & 0xf]); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2919 | 2936 |
| 2920 void HeapSnapshotJSONSerializer::SerializeTraceNode(AllocationTraceNode* node) { | 2937 void HeapSnapshotJSONSerializer::SerializeTraceNode(AllocationTraceNode* node) { |
| 2921 // The buffer needs space for 4 unsigned ints, 4 commas, [ and \0 | 2938 // The buffer needs space for 4 unsigned ints, 4 commas, [ and \0 |
| 2922 const int kBufferSize = | 2939 const int kBufferSize = |
| 2923 4 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT | 2940 4 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT |
| 2924 + 4 + 1 + 1; | 2941 + 4 + 1 + 1; |
| 2925 EmbeddedVector<char, kBufferSize> buffer; | 2942 EmbeddedVector<char, kBufferSize> buffer; |
| 2926 int buffer_pos = 0; | 2943 int buffer_pos = 0; |
| 2927 buffer_pos = utoa(node->id(), buffer, buffer_pos); | 2944 buffer_pos = utoa(node->id(), buffer, buffer_pos); |
| 2928 buffer[buffer_pos++] = ','; | 2945 buffer[buffer_pos++] = ','; |
| 2929 buffer_pos = utoa(node->function_id(), buffer, buffer_pos); | 2946 buffer_pos = utoa(node->function_info_index(), buffer, buffer_pos); |
| 2930 buffer[buffer_pos++] = ','; | 2947 buffer[buffer_pos++] = ','; |
| 2931 buffer_pos = utoa(node->allocation_count(), buffer, buffer_pos); | 2948 buffer_pos = utoa(node->allocation_count(), buffer, buffer_pos); |
| 2932 buffer[buffer_pos++] = ','; | 2949 buffer[buffer_pos++] = ','; |
| 2933 buffer_pos = utoa(node->allocation_size(), buffer, buffer_pos); | 2950 buffer_pos = utoa(node->allocation_size(), buffer, buffer_pos); |
| 2934 buffer[buffer_pos++] = ','; | 2951 buffer[buffer_pos++] = ','; |
| 2935 buffer[buffer_pos++] = '['; | 2952 buffer[buffer_pos++] = '['; |
| 2936 buffer[buffer_pos++] = '\0'; | 2953 buffer[buffer_pos++] = '\0'; |
| 2937 writer_->AddString(buffer.start()); | 2954 writer_->AddString(buffer.start()); |
| 2938 | 2955 |
| 2939 Vector<AllocationTraceNode*> children = node->children(); | 2956 Vector<AllocationTraceNode*> children = node->children(); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2961 | 2978 |
| 2962 | 2979 |
| 2963 void HeapSnapshotJSONSerializer::SerializeTraceNodeInfos() { | 2980 void HeapSnapshotJSONSerializer::SerializeTraceNodeInfos() { |
| 2964 AllocationTracker* tracker = snapshot_->profiler()->allocation_tracker(); | 2981 AllocationTracker* tracker = snapshot_->profiler()->allocation_tracker(); |
| 2965 if (!tracker) return; | 2982 if (!tracker) return; |
| 2966 // The buffer needs space for 6 unsigned ints, 6 commas, \n and \0 | 2983 // The buffer needs space for 6 unsigned ints, 6 commas, \n and \0 |
| 2967 const int kBufferSize = | 2984 const int kBufferSize = |
| 2968 6 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT | 2985 6 * MaxDecimalDigitsIn<sizeof(unsigned)>::kUnsigned // NOLINT |
| 2969 + 6 + 1 + 1; | 2986 + 6 + 1 + 1; |
| 2970 EmbeddedVector<char, kBufferSize> buffer; | 2987 EmbeddedVector<char, kBufferSize> buffer; |
| 2971 HashMap* id_to_function_info = tracker->id_to_function_info(); | 2988 const List<AllocationTracker::FunctionInfo*>& list = |
| 2989 tracker->function_info_list(); |
| 2972 bool first_entry = true; | 2990 bool first_entry = true; |
| 2973 for (HashMap::Entry* p = id_to_function_info->Start(); | 2991 for (int i = 0; i < list.length(); i++) { |
| 2974 p != NULL; | 2992 AllocationTracker::FunctionInfo* info = list[i]; |
| 2975 p = id_to_function_info->Next(p)) { | |
| 2976 SnapshotObjectId id = | |
| 2977 static_cast<SnapshotObjectId>(reinterpret_cast<intptr_t>(p->key)); | |
| 2978 AllocationTracker::FunctionInfo* info = | |
| 2979 reinterpret_cast<AllocationTracker::FunctionInfo* >(p->value); | |
| 2980 int buffer_pos = 0; | 2993 int buffer_pos = 0; |
| 2981 if (first_entry) { | 2994 if (first_entry) { |
| 2982 first_entry = false; | 2995 first_entry = false; |
| 2983 } else { | 2996 } else { |
| 2984 buffer[buffer_pos++] = ','; | 2997 buffer[buffer_pos++] = ','; |
| 2985 } | 2998 } |
| 2986 buffer_pos = utoa(id, buffer, buffer_pos); | 2999 buffer_pos = utoa(info->function_id, buffer, buffer_pos); |
| 2987 buffer[buffer_pos++] = ','; | 3000 buffer[buffer_pos++] = ','; |
| 2988 buffer_pos = utoa(GetStringId(info->name), buffer, buffer_pos); | 3001 buffer_pos = utoa(GetStringId(info->name), buffer, buffer_pos); |
| 2989 buffer[buffer_pos++] = ','; | 3002 buffer[buffer_pos++] = ','; |
| 2990 buffer_pos = utoa(GetStringId(info->script_name), buffer, buffer_pos); | 3003 buffer_pos = utoa(GetStringId(info->script_name), buffer, buffer_pos); |
| 2991 buffer[buffer_pos++] = ','; | 3004 buffer[buffer_pos++] = ','; |
| 2992 // The cast is safe because script id is a non-negative Smi. | 3005 // The cast is safe because script id is a non-negative Smi. |
| 2993 buffer_pos = utoa(static_cast<unsigned>(info->script_id), buffer, | 3006 buffer_pos = utoa(static_cast<unsigned>(info->script_id), buffer, |
| 2994 buffer_pos); | 3007 buffer_pos); |
| 2995 buffer[buffer_pos++] = ','; | 3008 buffer[buffer_pos++] = ','; |
| 2996 buffer_pos = SerializePosition(info->line, buffer, buffer_pos); | 3009 buffer_pos = SerializePosition(info->line, buffer, buffer_pos); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3065 writer_->AddString("\"<dummy>\""); | 3078 writer_->AddString("\"<dummy>\""); |
| 3066 for (int i = 1; i < sorted_strings.length(); ++i) { | 3079 for (int i = 1; i < sorted_strings.length(); ++i) { |
| 3067 writer_->AddCharacter(','); | 3080 writer_->AddCharacter(','); |
| 3068 SerializeString(sorted_strings[i]); | 3081 SerializeString(sorted_strings[i]); |
| 3069 if (writer_->aborted()) return; | 3082 if (writer_->aborted()) return; |
| 3070 } | 3083 } |
| 3071 } | 3084 } |
| 3072 | 3085 |
| 3073 | 3086 |
| 3074 } } // namespace v8::internal | 3087 } } // namespace v8::internal |
| OLD | NEW |