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 |