| 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 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 | 182 |
| 183 // It is very important to keep objects that form a heap snapshot | 183 // It is very important to keep objects that form a heap snapshot |
| 184 // as small as possible. | 184 // as small as possible. |
| 185 namespace { // Avoid littering the global namespace. | 185 namespace { // Avoid littering the global namespace. |
| 186 | 186 |
| 187 template <size_t ptr_size> struct SnapshotSizeConstants; | 187 template <size_t ptr_size> struct SnapshotSizeConstants; |
| 188 | 188 |
| 189 template <> struct SnapshotSizeConstants<4> { | 189 template <> struct SnapshotSizeConstants<4> { |
| 190 static const int kExpectedHeapGraphEdgeSize = 12; | 190 static const int kExpectedHeapGraphEdgeSize = 12; |
| 191 static const int kExpectedHeapEntrySize = 24; | 191 static const int kExpectedHeapEntrySize = 24; |
| 192 static const int kExpectedHeapSnapshotsCollectionSize = 100; | |
| 193 static const int kExpectedHeapSnapshotSize = 132; | |
| 194 }; | 192 }; |
| 195 | 193 |
| 196 template <> struct SnapshotSizeConstants<8> { | 194 template <> struct SnapshotSizeConstants<8> { |
| 197 static const int kExpectedHeapGraphEdgeSize = 24; | 195 static const int kExpectedHeapGraphEdgeSize = 24; |
| 198 static const int kExpectedHeapEntrySize = 32; | 196 static const int kExpectedHeapEntrySize = 32; |
| 199 static const int kExpectedHeapSnapshotsCollectionSize = 152; | |
| 200 static const int kExpectedHeapSnapshotSize = 160; | |
| 201 }; | 197 }; |
| 202 | 198 |
| 203 } // namespace | 199 } // namespace |
| 204 | 200 |
| 205 HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection, | 201 HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection, |
| 206 const char* title, | 202 const char* title, |
| 207 unsigned uid) | 203 unsigned uid) |
| 208 : collection_(collection), | 204 : collection_(collection), |
| 209 title_(title), | 205 title_(title), |
| 210 uid_(uid), | 206 uid_(uid), |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 } | 342 } |
| 347 | 343 |
| 348 | 344 |
| 349 template<typename T, class P> | 345 template<typename T, class P> |
| 350 static size_t GetMemoryUsedByList(const List<T, P>& list) { | 346 static size_t GetMemoryUsedByList(const List<T, P>& list) { |
| 351 return list.length() * sizeof(T) + sizeof(list); | 347 return list.length() * sizeof(T) + sizeof(list); |
| 352 } | 348 } |
| 353 | 349 |
| 354 | 350 |
| 355 size_t HeapSnapshot::RawSnapshotSize() const { | 351 size_t HeapSnapshot::RawSnapshotSize() const { |
| 356 STATIC_CHECK(SnapshotSizeConstants<kPointerSize>::kExpectedHeapSnapshotSize == | |
| 357 sizeof(HeapSnapshot)); // NOLINT | |
| 358 return | 352 return |
| 359 sizeof(*this) + | 353 sizeof(*this) + |
| 360 GetMemoryUsedByList(entries_) + | 354 GetMemoryUsedByList(entries_) + |
| 361 GetMemoryUsedByList(edges_) + | 355 GetMemoryUsedByList(edges_) + |
| 362 GetMemoryUsedByList(children_) + | 356 GetMemoryUsedByList(children_) + |
| 363 GetMemoryUsedByList(sorted_entries_); | 357 GetMemoryUsedByList(sorted_entries_); |
| 364 } | 358 } |
| 365 | 359 |
| 366 | 360 |
| 367 // We split IDs on evens for embedder objects (see | 361 // We split IDs on evens for embedder objects (see |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 571 return | 565 return |
| 572 sizeof(*this) + | 566 sizeof(*this) + |
| 573 sizeof(HashMap::Entry) * entries_map_.capacity() + | 567 sizeof(HashMap::Entry) * entries_map_.capacity() + |
| 574 GetMemoryUsedByList(entries_) + | 568 GetMemoryUsedByList(entries_) + |
| 575 GetMemoryUsedByList(time_intervals_); | 569 GetMemoryUsedByList(time_intervals_); |
| 576 } | 570 } |
| 577 | 571 |
| 578 | 572 |
| 579 HeapSnapshotsCollection::HeapSnapshotsCollection(Heap* heap) | 573 HeapSnapshotsCollection::HeapSnapshotsCollection(Heap* heap) |
| 580 : is_tracking_objects_(false), | 574 : is_tracking_objects_(false), |
| 581 snapshots_uids_(HeapSnapshotsMatch), | |
| 582 token_enumerator_(new TokenEnumerator()), | 575 token_enumerator_(new TokenEnumerator()), |
| 583 ids_(heap) { | 576 ids_(heap) { |
| 584 } | 577 } |
| 585 | 578 |
| 586 | 579 |
| 587 static void DeleteHeapSnapshot(HeapSnapshot** snapshot_ptr) { | 580 static void DeleteHeapSnapshot(HeapSnapshot** snapshot_ptr) { |
| 588 delete *snapshot_ptr; | 581 delete *snapshot_ptr; |
| 589 } | 582 } |
| 590 | 583 |
| 591 | 584 |
| 592 HeapSnapshotsCollection::~HeapSnapshotsCollection() { | 585 HeapSnapshotsCollection::~HeapSnapshotsCollection() { |
| 593 delete token_enumerator_; | 586 delete token_enumerator_; |
| 594 snapshots_.Iterate(DeleteHeapSnapshot); | 587 snapshots_.Iterate(DeleteHeapSnapshot); |
| 595 } | 588 } |
| 596 | 589 |
| 597 | 590 |
| 598 HeapSnapshot* HeapSnapshotsCollection::NewSnapshot(const char* name, | 591 HeapSnapshot* HeapSnapshotsCollection::NewSnapshot(const char* name, |
| 599 unsigned uid) { | 592 unsigned uid) { |
| 600 is_tracking_objects_ = true; // Start watching for heap objects moves. | 593 is_tracking_objects_ = true; // Start watching for heap objects moves. |
| 601 return new HeapSnapshot(this, name, uid); | 594 return new HeapSnapshot(this, name, uid); |
| 602 } | 595 } |
| 603 | 596 |
| 604 | 597 |
| 605 void HeapSnapshotsCollection::SnapshotGenerationFinished( | 598 void HeapSnapshotsCollection::SnapshotGenerationFinished( |
| 606 HeapSnapshot* snapshot) { | 599 HeapSnapshot* snapshot) { |
| 607 ids_.SnapshotGenerationFinished(); | 600 ids_.SnapshotGenerationFinished(); |
| 608 if (snapshot != NULL) { | 601 if (snapshot != NULL) { |
| 609 snapshots_.Add(snapshot); | 602 snapshots_.Add(snapshot); |
| 610 HashMap::Entry* entry = | |
| 611 snapshots_uids_.Lookup(reinterpret_cast<void*>(snapshot->uid()), | |
| 612 static_cast<uint32_t>(snapshot->uid()), | |
| 613 true); | |
| 614 ASSERT(entry->value == NULL); | |
| 615 entry->value = snapshot; | |
| 616 } | 603 } |
| 617 } | 604 } |
| 618 | 605 |
| 619 | 606 |
| 620 HeapSnapshot* HeapSnapshotsCollection::GetSnapshot(unsigned uid) { | |
| 621 HashMap::Entry* entry = snapshots_uids_.Lookup(reinterpret_cast<void*>(uid), | |
| 622 static_cast<uint32_t>(uid), | |
| 623 false); | |
| 624 return entry != NULL ? reinterpret_cast<HeapSnapshot*>(entry->value) : NULL; | |
| 625 } | |
| 626 | |
| 627 | |
| 628 void HeapSnapshotsCollection::RemoveSnapshot(HeapSnapshot* snapshot) { | 607 void HeapSnapshotsCollection::RemoveSnapshot(HeapSnapshot* snapshot) { |
| 629 snapshots_.RemoveElement(snapshot); | 608 snapshots_.RemoveElement(snapshot); |
| 630 unsigned uid = snapshot->uid(); | |
| 631 snapshots_uids_.Remove(reinterpret_cast<void*>(uid), | |
| 632 static_cast<uint32_t>(uid)); | |
| 633 } | 609 } |
| 634 | 610 |
| 635 | 611 |
| 636 Handle<HeapObject> HeapSnapshotsCollection::FindHeapObjectById( | 612 Handle<HeapObject> HeapSnapshotsCollection::FindHeapObjectById( |
| 637 SnapshotObjectId id) { | 613 SnapshotObjectId id) { |
| 638 // First perform a full GC in order to avoid dead objects. | 614 // First perform a full GC in order to avoid dead objects. |
| 639 HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask, | 615 HEAP->CollectAllGarbage(Heap::kMakeHeapIterableMask, |
| 640 "HeapSnapshotsCollection::FindHeapObjectById"); | 616 "HeapSnapshotsCollection::FindHeapObjectById"); |
| 641 DisallowHeapAllocation no_allocation; | 617 DisallowHeapAllocation no_allocation; |
| 642 HeapObject* object = NULL; | 618 HeapObject* object = NULL; |
| 643 HeapIterator iterator(heap(), HeapIterator::kFilterUnreachable); | 619 HeapIterator iterator(heap(), HeapIterator::kFilterUnreachable); |
| 644 // Make sure that object with the given id is still reachable. | 620 // Make sure that object with the given id is still reachable. |
| 645 for (HeapObject* obj = iterator.next(); | 621 for (HeapObject* obj = iterator.next(); |
| 646 obj != NULL; | 622 obj != NULL; |
| 647 obj = iterator.next()) { | 623 obj = iterator.next()) { |
| 648 if (ids_.FindEntry(obj->address()) == id) { | 624 if (ids_.FindEntry(obj->address()) == id) { |
| 649 ASSERT(object == NULL); | 625 ASSERT(object == NULL); |
| 650 object = obj; | 626 object = obj; |
| 651 // Can't break -- kFilterUnreachable requires full heap traversal. | 627 // Can't break -- kFilterUnreachable requires full heap traversal. |
| 652 } | 628 } |
| 653 } | 629 } |
| 654 return object != NULL ? Handle<HeapObject>(object) : Handle<HeapObject>(); | 630 return object != NULL ? Handle<HeapObject>(object) : Handle<HeapObject>(); |
| 655 } | 631 } |
| 656 | 632 |
| 657 | 633 |
| 658 size_t HeapSnapshotsCollection::GetUsedMemorySize() const { | 634 size_t HeapSnapshotsCollection::GetUsedMemorySize() const { |
| 659 STATIC_CHECK(SnapshotSizeConstants<kPointerSize>:: | |
| 660 kExpectedHeapSnapshotsCollectionSize == | |
| 661 sizeof(HeapSnapshotsCollection)); // NOLINT | |
| 662 size_t size = sizeof(*this); | 635 size_t size = sizeof(*this); |
| 663 size += names_.GetUsedMemorySize(); | 636 size += names_.GetUsedMemorySize(); |
| 664 size += ids_.GetUsedMemorySize(); | 637 size += ids_.GetUsedMemorySize(); |
| 665 size += sizeof(HashMap::Entry) * snapshots_uids_.capacity(); | |
| 666 size += GetMemoryUsedByList(snapshots_); | 638 size += GetMemoryUsedByList(snapshots_); |
| 667 for (int i = 0; i < snapshots_.length(); ++i) { | 639 for (int i = 0; i < snapshots_.length(); ++i) { |
| 668 size += snapshots_[i]->RawSnapshotSize(); | 640 size += snapshots_[i]->RawSnapshotSize(); |
| 669 } | 641 } |
| 670 return size; | 642 return size; |
| 671 } | 643 } |
| 672 | 644 |
| 673 | 645 |
| 674 HeapEntriesMap::HeapEntriesMap() | 646 HeapEntriesMap::HeapEntriesMap() |
| 675 : entries_(HeapThingsMatch) { | 647 : entries_(HeapThingsMatch) { |
| (...skipping 2018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2694 | 2666 |
| 2695 | 2667 |
| 2696 void HeapSnapshotJSONSerializer::SortHashMap( | 2668 void HeapSnapshotJSONSerializer::SortHashMap( |
| 2697 HashMap* map, List<HashMap::Entry*>* sorted_entries) { | 2669 HashMap* map, List<HashMap::Entry*>* sorted_entries) { |
| 2698 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) | 2670 for (HashMap::Entry* p = map->Start(); p != NULL; p = map->Next(p)) |
| 2699 sorted_entries->Add(p); | 2671 sorted_entries->Add(p); |
| 2700 sorted_entries->Sort(SortUsingEntryValue); | 2672 sorted_entries->Sort(SortUsingEntryValue); |
| 2701 } | 2673 } |
| 2702 | 2674 |
| 2703 } } // namespace v8::internal | 2675 } } // namespace v8::internal |
| OLD | NEW |