Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 555 } | 555 } |
| 556 | 556 |
| 557 | 557 |
| 558 bool MarkCompactCollector::MustBeMarked(Object** p) { | 558 bool MarkCompactCollector::MustBeMarked(Object** p) { |
| 559 // Check whether *p is a HeapObject pointer. | 559 // Check whether *p is a HeapObject pointer. |
| 560 if (!(*p)->IsHeapObject()) return false; | 560 if (!(*p)->IsHeapObject()) return false; |
| 561 return !HeapObject::cast(*p)->IsMarked(); | 561 return !HeapObject::cast(*p)->IsMarked(); |
| 562 } | 562 } |
| 563 | 563 |
| 564 | 564 |
| 565 // Helper class to unmark marked objects in a range of pointers but | |
| 566 // not recursively. | |
| 567 class UnmarkingVisitor : public ObjectVisitor { | |
| 568 public: | |
| 569 void VisitPointers(Object** start, Object** end) { | |
| 570 for (Object** p = start; p < end; p++) { | |
| 571 if ((*p)->IsHeapObject() && HeapObject::cast(*p)->IsMarked()) { | |
| 572 MarkCompactCollector::ClearMark(HeapObject::cast(*p)); | |
| 573 } | |
| 574 } | |
| 575 } | |
| 576 }; | |
| 577 | |
| 578 | |
| 565 void MarkCompactCollector::ProcessRoots(RootMarkingVisitor* visitor) { | 579 void MarkCompactCollector::ProcessRoots(RootMarkingVisitor* visitor) { |
| 566 // Mark the heap roots gray, including global variables, stack variables, | 580 // Handle the symbol table specially. Mark the prefix and the |
| 567 // etc. | 581 // symbol table itself. Do not mark the symbol table entries, but |
| 582 // do explicitly mark all other objects reachable from them. | |
| 583 // | |
| 584 // Objects reachable from symbols are marked as live so as to ensure | |
| 585 // that if the symbol itself remains alive after GC for any reason, | |
| 586 // and if it is a sliced string or a cons string backed by an | |
| 587 // external string (even indirectly), then the external string does | |
| 588 // not receive a weak reference callback. | |
|
iposva
2009/05/04 17:54:47
In retrospect was that not always a problem even w
Kevin Millikin (Chromium)
2009/05/04 18:34:52
I don't think so. The problem was that the weak r
| |
| 589 SymbolTable* symbol_table = SymbolTable::cast(Heap::symbol_table()); | |
| 590 // First mark everything reachable from the symbol table, then | |
| 591 // unmark just the elements themselves. | |
| 592 symbol_table->Iterate(visitor); | |
| 593 // There may be overflowed objects in the heap. Visit them now. | |
| 594 while (marking_stack.overflowed()) { | |
| 595 RefillMarkingStack(); | |
| 596 EmptyMarkingStack(visitor->stack_visitor()); | |
| 597 } | |
| 598 UnmarkingVisitor unmarking_visitor; | |
| 599 symbol_table->IterateElements(&unmarking_visitor); | |
| 600 // Mark the symbol table itself. | |
| 601 SetMark(symbol_table); | |
|
iposva
2009/05/04 17:54:47
The flipping of mark bits to marked and back to un
Kevin Millikin (Chromium)
2009/05/04 18:34:52
This was just the simplest implementation to get a
| |
| 602 | |
| 603 // Mark the heap roots including global variables, stack variables, | |
| 604 // etc., and all objects reachable from them. | |
| 568 Heap::IterateStrongRoots(visitor); | 605 Heap::IterateStrongRoots(visitor); |
| 569 | 606 |
| 570 // Take care of the symbol table specially. | |
| 571 SymbolTable* symbol_table = SymbolTable::cast(Heap::symbol_table()); | |
| 572 // 1. Mark the prefix of the symbol table gray. | |
| 573 symbol_table->IteratePrefix(visitor); | |
| 574 // 2. Mark the symbol table black (ie, do not push it on the marking stack | |
| 575 // or mark it overflowed). | |
| 576 SetMark(symbol_table); | |
| 577 | |
| 578 // There may be overflowed objects in the heap. Visit them now. | 607 // There may be overflowed objects in the heap. Visit them now. |
| 579 while (marking_stack.overflowed()) { | 608 while (marking_stack.overflowed()) { |
| 580 RefillMarkingStack(); | 609 RefillMarkingStack(); |
| 581 EmptyMarkingStack(visitor->stack_visitor()); | 610 EmptyMarkingStack(visitor->stack_visitor()); |
| 582 } | 611 } |
| 583 } | 612 } |
| 584 | 613 |
| 585 | 614 |
| 586 void MarkCompactCollector::MarkObjectGroups() { | 615 void MarkCompactCollector::MarkObjectGroups() { |
| 587 List<ObjectGroup*>* object_groups = GlobalHandles::ObjectGroups(); | 616 List<ObjectGroup*>* object_groups = GlobalHandles::ObjectGroups(); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 755 | 784 |
| 756 | 785 |
| 757 static int CountMarkedCallback(HeapObject* obj) { | 786 static int CountMarkedCallback(HeapObject* obj) { |
| 758 MapWord map_word = obj->map_word(); | 787 MapWord map_word = obj->map_word(); |
| 759 map_word.ClearMark(); | 788 map_word.ClearMark(); |
| 760 return obj->SizeFromMap(map_word.ToMap()); | 789 return obj->SizeFromMap(map_word.ToMap()); |
| 761 } | 790 } |
| 762 | 791 |
| 763 | 792 |
| 764 #ifdef DEBUG | 793 #ifdef DEBUG |
| 765 void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj) { | 794 void MarkCompactCollector::UpdateLiveObjectCount(HeapObject* obj, int scale) { |
| 766 live_bytes_ += obj->Size(); | 795 ASSERT(scale == -1 || scale == 1); |
| 796 live_bytes_ += obj->Size() * scale; | |
| 767 if (Heap::new_space()->Contains(obj)) { | 797 if (Heap::new_space()->Contains(obj)) { |
| 768 live_young_objects_++; | 798 live_young_objects_ += scale; |
| 769 } else if (Heap::map_space()->Contains(obj)) { | 799 } else if (Heap::map_space()->Contains(obj)) { |
| 770 ASSERT(obj->IsMap()); | 800 ASSERT(obj->IsMap()); |
| 771 live_map_objects_++; | 801 live_map_objects_ += scale; |
| 772 } else if (Heap::old_pointer_space()->Contains(obj)) { | 802 } else if (Heap::old_pointer_space()->Contains(obj)) { |
| 773 live_old_pointer_objects_++; | 803 live_old_pointer_objects_ += scale; |
| 774 } else if (Heap::old_data_space()->Contains(obj)) { | 804 } else if (Heap::old_data_space()->Contains(obj)) { |
| 775 live_old_data_objects_++; | 805 live_old_data_objects_ += scale; |
| 776 } else if (Heap::code_space()->Contains(obj)) { | 806 } else if (Heap::code_space()->Contains(obj)) { |
| 777 live_code_objects_++; | 807 live_code_objects_ += scale; |
| 778 } else if (Heap::lo_space()->Contains(obj)) { | 808 } else if (Heap::lo_space()->Contains(obj)) { |
| 779 live_lo_objects_++; | 809 live_lo_objects_ +=scale; |
| 780 } else { | 810 } else { |
| 781 UNREACHABLE(); | 811 UNREACHABLE(); |
| 782 } | 812 } |
| 783 } | 813 } |
| 784 #endif // DEBUG | 814 #endif // DEBUG |
| 785 | 815 |
| 786 | 816 |
| 787 void MarkCompactCollector::SweepLargeObjectSpace() { | 817 void MarkCompactCollector::SweepLargeObjectSpace() { |
| 788 #ifdef DEBUG | 818 #ifdef DEBUG |
| 789 ASSERT(state_ == MARK_LIVE_OBJECTS); | 819 ASSERT(state_ == MARK_LIVE_OBJECTS); |
| (...skipping 966 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1756 | 1786 |
| 1757 void MarkCompactCollector::RebuildRSets() { | 1787 void MarkCompactCollector::RebuildRSets() { |
| 1758 #ifdef DEBUG | 1788 #ifdef DEBUG |
| 1759 ASSERT(state_ == RELOCATE_OBJECTS); | 1789 ASSERT(state_ == RELOCATE_OBJECTS); |
| 1760 state_ = REBUILD_RSETS; | 1790 state_ = REBUILD_RSETS; |
| 1761 #endif | 1791 #endif |
| 1762 Heap::RebuildRSets(); | 1792 Heap::RebuildRSets(); |
| 1763 } | 1793 } |
| 1764 | 1794 |
| 1765 } } // namespace v8::internal | 1795 } } // namespace v8::internal |
| OLD | NEW |