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 909 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
920 unsigned trace_node_id = 0; | 920 unsigned trace_node_id = 0; |
921 if (AllocationTracker* allocation_tracker = | 921 if (AllocationTracker* allocation_tracker = |
922 snapshot_->profiler()->allocation_tracker()) { | 922 snapshot_->profiler()->allocation_tracker()) { |
923 trace_node_id = | 923 trace_node_id = |
924 allocation_tracker->address_to_trace()->GetTraceNodeId(address); | 924 allocation_tracker->address_to_trace()->GetTraceNodeId(address); |
925 } | 925 } |
926 return snapshot_->AddEntry(type, name, object_id, size, trace_node_id); | 926 return snapshot_->AddEntry(type, name, object_id, size, trace_node_id); |
927 } | 927 } |
928 | 928 |
929 | 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 |
930 class GcSubrootsEnumerator : public ObjectVisitor { | 988 class GcSubrootsEnumerator : public ObjectVisitor { |
931 public: | 989 public: |
932 GcSubrootsEnumerator( | 990 GcSubrootsEnumerator( |
933 SnapshotFillerInterface* filler, V8HeapExplorer* explorer) | 991 SnapshotFiller* filler, V8HeapExplorer* explorer) |
934 : filler_(filler), | 992 : filler_(filler), |
935 explorer_(explorer), | 993 explorer_(explorer), |
936 previous_object_count_(0), | 994 previous_object_count_(0), |
937 object_count_(0) { | 995 object_count_(0) { |
938 } | 996 } |
939 void VisitPointers(Object** start, Object** end) { | 997 void VisitPointers(Object** start, Object** end) { |
940 object_count_ += end - start; | 998 object_count_ += end - start; |
941 } | 999 } |
942 void Synchronize(VisitorSynchronization::SyncTag tag) { | 1000 void Synchronize(VisitorSynchronization::SyncTag tag) { |
943 // Skip empty subroots. | 1001 // Skip empty subroots. |
944 if (previous_object_count_ != object_count_) { | 1002 if (previous_object_count_ != object_count_) { |
945 previous_object_count_ = object_count_; | 1003 previous_object_count_ = object_count_; |
946 filler_->AddEntry(V8HeapExplorer::GetNthGcSubrootObject(tag), explorer_); | 1004 filler_->AddEntry(V8HeapExplorer::GetNthGcSubrootObject(tag), explorer_); |
947 } | 1005 } |
948 } | 1006 } |
949 private: | 1007 private: |
950 SnapshotFillerInterface* filler_; | 1008 SnapshotFiller* filler_; |
951 V8HeapExplorer* explorer_; | 1009 V8HeapExplorer* explorer_; |
952 intptr_t previous_object_count_; | 1010 intptr_t previous_object_count_; |
953 intptr_t object_count_; | 1011 intptr_t object_count_; |
954 }; | 1012 }; |
955 | 1013 |
956 | 1014 |
957 void V8HeapExplorer::AddRootEntries(SnapshotFillerInterface* filler) { | 1015 void V8HeapExplorer::AddRootEntries(SnapshotFiller* filler) { |
958 filler->AddEntry(kInternalRootObject, this); | 1016 filler->AddEntry(kInternalRootObject, this); |
959 filler->AddEntry(kGcRootsObject, this); | 1017 filler->AddEntry(kGcRootsObject, this); |
960 GcSubrootsEnumerator enumerator(filler, this); | 1018 GcSubrootsEnumerator enumerator(filler, this); |
961 heap_->IterateRoots(&enumerator, VISIT_ALL); | 1019 heap_->IterateRoots(&enumerator, VISIT_ALL); |
962 } | 1020 } |
963 | 1021 |
964 | 1022 |
965 const char* V8HeapExplorer::GetSystemEntryName(HeapObject* object) { | 1023 const char* V8HeapExplorer::GetSystemEntryName(HeapObject* object) { |
966 switch (object->map()->instance_type()) { | 1024 switch (object->map()->instance_type()) { |
967 case MAP_TYPE: | 1025 case MAP_TYPE: |
(...skipping 789 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1757 bool collecting_all_references_; | 1815 bool collecting_all_references_; |
1758 List<Object*> strong_references_; | 1816 List<Object*> strong_references_; |
1759 List<Object*> all_references_; | 1817 List<Object*> all_references_; |
1760 int previous_reference_count_; | 1818 int previous_reference_count_; |
1761 List<IndexTag> reference_tags_; | 1819 List<IndexTag> reference_tags_; |
1762 Heap* heap_; | 1820 Heap* heap_; |
1763 }; | 1821 }; |
1764 | 1822 |
1765 | 1823 |
1766 bool V8HeapExplorer::IterateAndExtractReferences( | 1824 bool V8HeapExplorer::IterateAndExtractReferences( |
1767 SnapshotFillerInterface* filler) { | 1825 SnapshotFiller* filler) { |
1768 filler_ = filler; | 1826 filler_ = filler; |
1769 | 1827 |
1770 // Make sure builtin code objects get their builtin tags | 1828 // Make sure builtin code objects get their builtin tags |
1771 // first. Otherwise a particular JSFunction object could set | 1829 // first. Otherwise a particular JSFunction object could set |
1772 // its custom name to a generic builtin. | 1830 // its custom name to a generic builtin. |
1773 SetRootGcRootsReference(); | 1831 SetRootGcRootsReference(); |
1774 RootsReferencesExtractor extractor(heap_); | 1832 RootsReferencesExtractor extractor(heap_); |
1775 heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG); | 1833 heap_->IterateRoots(&extractor, VISIT_ONLY_STRONG); |
1776 extractor.SetCollectingAllReferences(); | 1834 extractor.SetCollectingAllReferences(); |
1777 heap_->IterateRoots(&extractor, VISIT_ALL); | 1835 heap_->IterateRoots(&extractor, VISIT_ALL); |
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2268 if (entry->value != NULL) { | 2326 if (entry->value != NULL) { |
2269 info->Dispose(); | 2327 info->Dispose(); |
2270 } else { | 2328 } else { |
2271 entry->value = new List<HeapObject*>(4); | 2329 entry->value = new List<HeapObject*>(4); |
2272 } | 2330 } |
2273 return reinterpret_cast<List<HeapObject*>* >(entry->value); | 2331 return reinterpret_cast<List<HeapObject*>* >(entry->value); |
2274 } | 2332 } |
2275 | 2333 |
2276 | 2334 |
2277 bool NativeObjectsExplorer::IterateAndExtractReferences( | 2335 bool NativeObjectsExplorer::IterateAndExtractReferences( |
2278 SnapshotFillerInterface* filler) { | 2336 SnapshotFiller* filler) { |
2279 filler_ = filler; | 2337 filler_ = filler; |
2280 FillRetainedObjects(); | 2338 FillRetainedObjects(); |
2281 FillImplicitReferences(); | 2339 FillImplicitReferences(); |
2282 if (EstimateObjectsCount() > 0) { | 2340 if (EstimateObjectsCount() > 0) { |
2283 for (HashMap::Entry* p = objects_by_info_.Start(); | 2341 for (HashMap::Entry* p = objects_by_info_.Start(); |
2284 p != NULL; | 2342 p != NULL; |
2285 p = objects_by_info_.Next(p)) { | 2343 p = objects_by_info_.Next(p)) { |
2286 v8::RetainedObjectInfo* info = | 2344 v8::RetainedObjectInfo* info = |
2287 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); | 2345 reinterpret_cast<v8::RetainedObjectInfo*>(p->key); |
2288 SetNativeRootReference(info); | 2346 SetNativeRootReference(info); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2395 void NativeObjectsExplorer::VisitSubtreeWrapper(Object** p, uint16_t class_id) { | 2453 void NativeObjectsExplorer::VisitSubtreeWrapper(Object** p, uint16_t class_id) { |
2396 if (in_groups_.Contains(*p)) return; | 2454 if (in_groups_.Contains(*p)) return; |
2397 Isolate* isolate = isolate_; | 2455 Isolate* isolate = isolate_; |
2398 v8::RetainedObjectInfo* info = | 2456 v8::RetainedObjectInfo* info = |
2399 isolate->heap_profiler()->ExecuteWrapperClassCallback(class_id, p); | 2457 isolate->heap_profiler()->ExecuteWrapperClassCallback(class_id, p); |
2400 if (info == NULL) return; | 2458 if (info == NULL) return; |
2401 GetListMaybeDisposeInfo(info)->Add(HeapObject::cast(*p)); | 2459 GetListMaybeDisposeInfo(info)->Add(HeapObject::cast(*p)); |
2402 } | 2460 } |
2403 | 2461 |
2404 | 2462 |
2405 class SnapshotFiller : public SnapshotFillerInterface { | |
2406 public: | |
2407 explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries) | |
2408 : snapshot_(snapshot), | |
2409 names_(snapshot->profiler()->names()), | |
2410 entries_(entries) { } | |
2411 HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) { | |
2412 HeapEntry* entry = allocator->AllocateEntry(ptr); | |
2413 entries_->Pair(ptr, entry->index()); | |
2414 return entry; | |
2415 } | |
2416 HeapEntry* FindEntry(HeapThing ptr) { | |
2417 int index = entries_->Map(ptr); | |
2418 return index != HeapEntry::kNoEntry ? &snapshot_->entries()[index] : NULL; | |
2419 } | |
2420 HeapEntry* FindOrAddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) { | |
2421 HeapEntry* entry = FindEntry(ptr); | |
2422 return entry != NULL ? entry : AddEntry(ptr, allocator); | |
2423 } | |
2424 void SetIndexedReference(HeapGraphEdge::Type type, | |
2425 int parent, | |
2426 int index, | |
2427 HeapEntry* child_entry) { | |
2428 HeapEntry* parent_entry = &snapshot_->entries()[parent]; | |
2429 parent_entry->SetIndexedReference(type, index, child_entry); | |
2430 } | |
2431 void SetIndexedAutoIndexReference(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->SetIndexedReference(type, index, child_entry); | |
2437 } | |
2438 void SetNamedReference(HeapGraphEdge::Type type, | |
2439 int parent, | |
2440 const char* reference_name, | |
2441 HeapEntry* child_entry) { | |
2442 HeapEntry* parent_entry = &snapshot_->entries()[parent]; | |
2443 parent_entry->SetNamedReference(type, reference_name, child_entry); | |
2444 } | |
2445 void SetNamedAutoIndexReference(HeapGraphEdge::Type type, | |
2446 int parent, | |
2447 HeapEntry* child_entry) { | |
2448 HeapEntry* parent_entry = &snapshot_->entries()[parent]; | |
2449 int index = parent_entry->children_count() + 1; | |
2450 parent_entry->SetNamedReference( | |
2451 type, | |
2452 names_->GetName(index), | |
2453 child_entry); | |
2454 } | |
2455 | |
2456 private: | |
2457 HeapSnapshot* snapshot_; | |
2458 StringsStorage* names_; | |
2459 HeapEntriesMap* entries_; | |
2460 }; | |
2461 | |
2462 | |
2463 HeapSnapshotGenerator::HeapSnapshotGenerator( | 2463 HeapSnapshotGenerator::HeapSnapshotGenerator( |
2464 HeapSnapshot* snapshot, | 2464 HeapSnapshot* snapshot, |
2465 v8::ActivityControl* control, | 2465 v8::ActivityControl* control, |
2466 v8::HeapProfiler::ObjectNameResolver* resolver, | 2466 v8::HeapProfiler::ObjectNameResolver* resolver, |
2467 Heap* heap) | 2467 Heap* heap) |
2468 : snapshot_(snapshot), | 2468 : snapshot_(snapshot), |
2469 control_(control), | 2469 control_(control), |
2470 v8_heap_explorer_(snapshot_, this, resolver), | 2470 v8_heap_explorer_(snapshot_, this, resolver), |
2471 dom_explorer_(snapshot_, this), | 2471 dom_explorer_(snapshot_, this), |
2472 heap_(heap) { | 2472 heap_(heap) { |
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3078 writer_->AddString("\"<dummy>\""); | 3078 writer_->AddString("\"<dummy>\""); |
3079 for (int i = 1; i < sorted_strings.length(); ++i) { | 3079 for (int i = 1; i < sorted_strings.length(); ++i) { |
3080 writer_->AddCharacter(','); | 3080 writer_->AddCharacter(','); |
3081 SerializeString(sorted_strings[i]); | 3081 SerializeString(sorted_strings[i]); |
3082 if (writer_->aborted()) return; | 3082 if (writer_->aborted()) return; |
3083 } | 3083 } |
3084 } | 3084 } |
3085 | 3085 |
3086 | 3086 |
3087 } } // namespace v8::internal | 3087 } } // namespace v8::internal |
OLD | NEW |