Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/heap.cc

Issue 1217011: Merging scavenge into sweeping phase of mark-sweep(-compact) collector. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/heap.h ('k') | src/heap-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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
555 collector == MARK_COMPACTOR ? kGCTypeMarkSweepCompact : kGCTypeScavenge; 555 collector == MARK_COMPACTOR ? kGCTypeMarkSweepCompact : kGCTypeScavenge;
556 556
557 for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) { 557 for (int i = 0; i < gc_prologue_callbacks_.length(); ++i) {
558 if (gc_type & gc_prologue_callbacks_[i].gc_type) { 558 if (gc_type & gc_prologue_callbacks_[i].gc_type) {
559 gc_prologue_callbacks_[i].callback(gc_type, kNoGCCallbackFlags); 559 gc_prologue_callbacks_[i].callback(gc_type, kNoGCCallbackFlags);
560 } 560 }
561 } 561 }
562 562
563 EnsureFromSpaceIsCommitted(); 563 EnsureFromSpaceIsCommitted();
564 564
565 // Perform mark-sweep with optional compaction.
566 if (collector == MARK_COMPACTOR) { 565 if (collector == MARK_COMPACTOR) {
566 // Perform mark-sweep with optional compaction.
567 MarkCompact(tracer); 567 MarkCompact(tracer);
568 }
569 568
570 // Always perform a scavenge to make room in new space.
571 Scavenge();
572
573 // Update the old space promotion limits after the scavenge due to
574 // promotions during scavenge.
575 if (collector == MARK_COMPACTOR) {
576 int old_gen_size = PromotedSpaceSize(); 569 int old_gen_size = PromotedSpaceSize();
577 old_gen_promotion_limit_ = 570 old_gen_promotion_limit_ =
578 old_gen_size + Max(kMinimumPromotionLimit, old_gen_size / 3); 571 old_gen_size + Max(kMinimumPromotionLimit, old_gen_size / 3);
579 old_gen_allocation_limit_ = 572 old_gen_allocation_limit_ =
580 old_gen_size + Max(kMinimumAllocationLimit, old_gen_size / 2); 573 old_gen_size + Max(kMinimumAllocationLimit, old_gen_size / 2);
581 old_gen_exhausted_ = false; 574 old_gen_exhausted_ = false;
575 } else {
576 Scavenge();
582 } 577 }
583 578
584 Counters::objs_since_last_young.Set(0); 579 Counters::objs_since_last_young.Set(0);
585 580
586 if (collector == MARK_COMPACTOR) { 581 if (collector == MARK_COMPACTOR) {
587 DisableAssertNoAllocation allow_allocation; 582 DisableAssertNoAllocation allow_allocation;
588 GCTracer::ExternalScope scope(tracer); 583 GCTracer::ExternalScope scope(tracer);
589 GlobalHandles::PostGarbageCollectionProcessing(); 584 GlobalHandles::PostGarbageCollectionProcessing();
590 } 585 }
591 586
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 object->Iterate(&v); 752 object->Iterate(&v);
758 753
759 HeapObjectIterator data_it(Heap::old_data_space()); 754 HeapObjectIterator data_it(Heap::old_data_space());
760 for (HeapObject* object = data_it.next(); 755 for (HeapObject* object = data_it.next();
761 object != NULL; object = data_it.next()) 756 object != NULL; object = data_it.next())
762 object->Iterate(&v); 757 object->Iterate(&v);
763 } 758 }
764 #endif 759 #endif
765 760
766 761
762 void Heap::CheckNewSpaceExpansionCriteria() {
763 if (new_space_.Capacity() < new_space_.MaximumCapacity() &&
764 survived_since_last_expansion_ > new_space_.Capacity()) {
765 // Grow the size of new space if there is room to grow and enough
766 // data has survived scavenge since the last expansion.
767 new_space_.Grow();
768 survived_since_last_expansion_ = 0;
769 }
770 }
771
772
767 void Heap::Scavenge() { 773 void Heap::Scavenge() {
768 #ifdef DEBUG 774 #ifdef DEBUG
769 if (FLAG_enable_slow_asserts) VerifyNonPointerSpacePointers(); 775 if (FLAG_enable_slow_asserts) VerifyNonPointerSpacePointers();
770 #endif 776 #endif
771 777
772 gc_state_ = SCAVENGE; 778 gc_state_ = SCAVENGE;
773 779
774 // Implements Cheney's copying algorithm 780 // Implements Cheney's copying algorithm
775 LOG(ResourceEvent("scavenge", "begin")); 781 LOG(ResourceEvent("scavenge", "begin"));
776 782
777 // Clear descriptor cache. 783 // Clear descriptor cache.
778 DescriptorLookupCache::Clear(); 784 DescriptorLookupCache::Clear();
779 785
780 // Used for updating survived_since_last_expansion_ at function end. 786 // Used for updating survived_since_last_expansion_ at function end.
781 int survived_watermark = PromotedSpaceSize(); 787 int survived_watermark = PromotedSpaceSize();
782 788
783 if (new_space_.Capacity() < new_space_.MaximumCapacity() && 789 CheckNewSpaceExpansionCriteria();
784 survived_since_last_expansion_ > new_space_.Capacity()) {
785 // Grow the size of new space if there is room to grow and enough
786 // data has survived scavenge since the last expansion.
787 new_space_.Grow();
788 survived_since_last_expansion_ = 0;
789 }
790 790
791 // Flip the semispaces. After flipping, to space is empty, from space has 791 // Flip the semispaces. After flipping, to space is empty, from space has
792 // live objects. 792 // live objects.
793 new_space_.Flip(); 793 new_space_.Flip();
794 new_space_.ResetAllocationInfo(); 794 new_space_.ResetAllocationInfo();
795 795
796 // We need to sweep newly copied objects which can be either in the 796 // We need to sweep newly copied objects which can be either in the
797 // to space or promoted to the old generation. For to-space 797 // to space or promoted to the old generation. For to-space
798 // objects, we treat the bottom of the to space as a queue. Newly 798 // objects, we treat the bottom of the to space as a queue. Newly
799 // copied and unswept objects lie between a 'front' mark and the 799 // copied and unswept objects lie between a 'front' mark and the
(...skipping 30 matching lines...) Expand all
830 if (cell->IsJSGlobalPropertyCell()) { 830 if (cell->IsJSGlobalPropertyCell()) {
831 Address value_address = 831 Address value_address =
832 reinterpret_cast<Address>(cell) + 832 reinterpret_cast<Address>(cell) +
833 (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag); 833 (JSGlobalPropertyCell::kValueOffset - kHeapObjectTag);
834 scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address)); 834 scavenge_visitor.VisitPointer(reinterpret_cast<Object**>(value_address));
835 } 835 }
836 } 836 }
837 837
838 new_space_front = DoScavenge(&scavenge_visitor, new_space_front); 838 new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
839 839
840 ScavengeExternalStringTable(); 840 UpdateNewSpaceReferencesInExternalStringTable(
841 &UpdateNewSpaceReferenceInExternalStringTableEntry);
842
841 ASSERT(new_space_front == new_space_.top()); 843 ASSERT(new_space_front == new_space_.top());
842 844
843 // Set age mark. 845 // Set age mark.
844 new_space_.set_age_mark(new_space_.top()); 846 new_space_.set_age_mark(new_space_.top());
845 847
846 // Update how much has survived scavenge. 848 // Update how much has survived scavenge.
847 survived_since_last_expansion_ += 849 IncrementYoungSurvivorsCounter(
848 (PromotedSpaceSize() - survived_watermark) + new_space_.Size(); 850 (PromotedSpaceSize() - survived_watermark) + new_space_.Size());
849 851
850 LOG(ResourceEvent("scavenge", "end")); 852 LOG(ResourceEvent("scavenge", "end"));
851 853
852 gc_state_ = NOT_IN_GC; 854 gc_state_ = NOT_IN_GC;
853 } 855 }
854 856
855 857
856 void Heap::ScavengeExternalStringTable() { 858 String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Object** p) {
859 MapWord first_word = HeapObject::cast(*p)->map_word();
860
861 if (!first_word.IsForwardingAddress()) {
862 // Unreachable external string can be finalized.
863 FinalizeExternalString(String::cast(*p));
864 return NULL;
865 }
866
867 // String is still reachable.
868 return String::cast(first_word.ToForwardingAddress());
869 }
870
871
872 void Heap::UpdateNewSpaceReferencesInExternalStringTable(
873 ExternalStringTableUpdaterCallback updater_func) {
857 ExternalStringTable::Verify(); 874 ExternalStringTable::Verify();
858 875
859 if (ExternalStringTable::new_space_strings_.is_empty()) return; 876 if (ExternalStringTable::new_space_strings_.is_empty()) return;
860 877
861 Object** start = &ExternalStringTable::new_space_strings_[0]; 878 Object** start = &ExternalStringTable::new_space_strings_[0];
862 Object** end = start + ExternalStringTable::new_space_strings_.length(); 879 Object** end = start + ExternalStringTable::new_space_strings_.length();
863 Object** last = start; 880 Object** last = start;
864 881
865 for (Object** p = start; p < end; ++p) { 882 for (Object** p = start; p < end; ++p) {
866 ASSERT(Heap::InFromSpace(*p)); 883 ASSERT(Heap::InFromSpace(*p));
867 MapWord first_word = HeapObject::cast(*p)->map_word(); 884 String* target = updater_func(p);
868 885
869 if (!first_word.IsForwardingAddress()) { 886 if (target == NULL) continue;
870 // Unreachable external string can be finalized.
871 FinalizeExternalString(String::cast(*p));
872 continue;
873 }
874 887
875 // String is still reachable.
876 String* target = String::cast(first_word.ToForwardingAddress());
877 ASSERT(target->IsExternalString()); 888 ASSERT(target->IsExternalString());
878 889
879 if (Heap::InNewSpace(target)) { 890 if (Heap::InNewSpace(target)) {
880 // String is still in new space. Update the table entry. 891 // String is still in new space. Update the table entry.
881 *last = target; 892 *last = target;
882 ++last; 893 ++last;
883 } else { 894 } else {
884 // String got promoted. Move it to the old string list. 895 // String got promoted. Move it to the old string list.
885 ExternalStringTable::AddOldString(target); 896 ExternalStringTable::AddOldString(target);
886 } 897 }
(...skipping 3479 matching lines...) Expand 10 before | Expand all | Expand 10 after
4366 void ExternalStringTable::TearDown() { 4377 void ExternalStringTable::TearDown() {
4367 new_space_strings_.Free(); 4378 new_space_strings_.Free();
4368 old_space_strings_.Free(); 4379 old_space_strings_.Free();
4369 } 4380 }
4370 4381
4371 4382
4372 List<Object*> ExternalStringTable::new_space_strings_; 4383 List<Object*> ExternalStringTable::new_space_strings_;
4373 List<Object*> ExternalStringTable::old_space_strings_; 4384 List<Object*> ExternalStringTable::old_space_strings_;
4374 4385
4375 } } // namespace v8::internal 4386 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap.h ('k') | src/heap-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698