OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
105 gc_post_processing_depth_(0), | 105 gc_post_processing_depth_(0), |
106 ms_count_(0), | 106 ms_count_(0), |
107 gc_count_(0), | 107 gc_count_(0), |
108 unflattened_strings_length_(0), | 108 unflattened_strings_length_(0), |
109 #ifdef DEBUG | 109 #ifdef DEBUG |
110 allocation_allowed_(true), | 110 allocation_allowed_(true), |
111 allocation_timeout_(0), | 111 allocation_timeout_(0), |
112 disallow_allocation_failure_(false), | 112 disallow_allocation_failure_(false), |
113 debug_utils_(NULL), | 113 debug_utils_(NULL), |
114 #endif // DEBUG | 114 #endif // DEBUG |
| 115 new_space_high_promotion_mode_active_(false), |
115 old_gen_promotion_limit_(kMinimumPromotionLimit), | 116 old_gen_promotion_limit_(kMinimumPromotionLimit), |
116 old_gen_allocation_limit_(kMinimumAllocationLimit), | 117 old_gen_allocation_limit_(kMinimumAllocationLimit), |
117 old_gen_limit_factor_(1), | 118 old_gen_limit_factor_(1), |
118 size_of_old_gen_at_last_old_space_gc_(0), | 119 size_of_old_gen_at_last_old_space_gc_(0), |
119 external_allocation_limit_(0), | 120 external_allocation_limit_(0), |
120 amount_of_external_allocated_memory_(0), | 121 amount_of_external_allocated_memory_(0), |
121 amount_of_external_allocated_memory_at_last_global_gc_(0), | 122 amount_of_external_allocated_memory_at_last_global_gc_(0), |
122 old_gen_exhausted_(false), | 123 old_gen_exhausted_(false), |
123 store_buffer_rebuilder_(store_buffer()), | 124 store_buffer_rebuilder_(store_buffer()), |
124 hidden_symbol_(NULL), | 125 hidden_symbol_(NULL), |
(...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 | 729 |
729 if (collector == MARK_COMPACTOR) { | 730 if (collector == MARK_COMPACTOR) { |
730 // Perform mark-sweep with optional compaction. | 731 // Perform mark-sweep with optional compaction. |
731 MarkCompact(tracer); | 732 MarkCompact(tracer); |
732 sweep_generation_++; | 733 sweep_generation_++; |
733 bool high_survival_rate_during_scavenges = IsHighSurvivalRate() && | 734 bool high_survival_rate_during_scavenges = IsHighSurvivalRate() && |
734 IsStableOrIncreasingSurvivalTrend(); | 735 IsStableOrIncreasingSurvivalTrend(); |
735 | 736 |
736 UpdateSurvivalRateTrend(start_new_space_size); | 737 UpdateSurvivalRateTrend(start_new_space_size); |
737 | 738 |
| 739 if (!new_space_high_promotion_mode_active_ && |
| 740 new_space_.Capacity() == new_space_.MaximumCapacity() && |
| 741 IsStableOrIncreasingSurvivalTrend() && |
| 742 IsHighSurvivalRate()) { |
| 743 // Stable high survival rates even though young generation is at |
| 744 // maximum capacity indicates that most objects will be promoted. |
| 745 // To decrease scavenger pauses and final mark-sweep pauses, we |
| 746 // have to limit maximal capacity of the young generation. |
| 747 new_space_high_promotion_mode_active_ = true; |
| 748 if (FLAG_trace_gc) { |
| 749 PrintF("Limited new space size due to high promotion rate: %d MB\n", |
| 750 new_space_.InitialCapacity() / MB); |
| 751 } |
| 752 } else if (new_space_high_promotion_mode_active_ && |
| 753 IsDecreasingSurvivalTrend() && |
| 754 !IsHighSurvivalRate()) { |
| 755 // Decreasing low survival rates might indicate that the above high |
| 756 // promotion mode is over and we should allow the young generation |
| 757 // to grow again. |
| 758 new_space_high_promotion_mode_active_ = false; |
| 759 if (FLAG_trace_gc) { |
| 760 PrintF("Unlimited new space size due to low promotion rate: %d MB\n", |
| 761 new_space_.MaximumCapacity() / MB); |
| 762 } |
| 763 } |
| 764 |
738 size_of_old_gen_at_last_old_space_gc_ = PromotedSpaceSize(); | 765 size_of_old_gen_at_last_old_space_gc_ = PromotedSpaceSize(); |
739 | 766 |
740 if (high_survival_rate_during_scavenges && | 767 if (high_survival_rate_during_scavenges && |
741 IsStableOrIncreasingSurvivalTrend()) { | 768 IsStableOrIncreasingSurvivalTrend()) { |
742 // Stable high survival rates of young objects both during partial and | 769 // Stable high survival rates of young objects both during partial and |
743 // full collection indicate that mutator is either building or modifying | 770 // full collection indicate that mutator is either building or modifying |
744 // a structure with a long lifetime. | 771 // a structure with a long lifetime. |
745 // In this case we aggressively raise old generation memory limits to | 772 // In this case we aggressively raise old generation memory limits to |
746 // postpone subsequent mark-sweep collection and thus trade memory | 773 // postpone subsequent mark-sweep collection and thus trade memory |
747 // space for the mutation speed. | 774 // space for the mutation speed. |
748 old_gen_limit_factor_ = 2; | 775 old_gen_limit_factor_ = 2; |
749 } else { | 776 } else { |
750 old_gen_limit_factor_ = 1; | 777 old_gen_limit_factor_ = 1; |
751 } | 778 } |
752 | 779 |
753 old_gen_promotion_limit_ = | 780 old_gen_promotion_limit_ = |
754 OldGenPromotionLimit(size_of_old_gen_at_last_old_space_gc_); | 781 OldGenPromotionLimit(size_of_old_gen_at_last_old_space_gc_); |
755 old_gen_allocation_limit_ = | 782 old_gen_allocation_limit_ = |
756 OldGenAllocationLimit(size_of_old_gen_at_last_old_space_gc_); | 783 OldGenAllocationLimit(size_of_old_gen_at_last_old_space_gc_); |
757 | 784 |
758 old_gen_exhausted_ = false; | 785 old_gen_exhausted_ = false; |
759 } else { | 786 } else { |
760 tracer_ = tracer; | 787 tracer_ = tracer; |
761 Scavenge(); | 788 Scavenge(); |
762 tracer_ = NULL; | 789 tracer_ = NULL; |
763 | 790 |
764 UpdateSurvivalRateTrend(start_new_space_size); | 791 UpdateSurvivalRateTrend(start_new_space_size); |
765 } | 792 } |
766 | 793 |
| 794 if (new_space_high_promotion_mode_active_ && |
| 795 new_space_.Capacity() > new_space_.InitialCapacity()) { |
| 796 new_space_.Shrink(); |
| 797 } |
| 798 |
767 isolate_->counters()->objs_since_last_young()->Set(0); | 799 isolate_->counters()->objs_since_last_young()->Set(0); |
768 | 800 |
769 gc_post_processing_depth_++; | 801 gc_post_processing_depth_++; |
770 { DisableAssertNoAllocation allow_allocation; | 802 { DisableAssertNoAllocation allow_allocation; |
771 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); | 803 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); |
772 next_gc_likely_to_collect_more = | 804 next_gc_likely_to_collect_more = |
773 isolate_->global_handles()->PostGarbageCollectionProcessing(collector); | 805 isolate_->global_handles()->PostGarbageCollectionProcessing(collector); |
774 } | 806 } |
775 gc_post_processing_depth_--; | 807 gc_post_processing_depth_--; |
776 | 808 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
909 for (HeapObject* object = data_it.Next(); | 941 for (HeapObject* object = data_it.Next(); |
910 object != NULL; object = data_it.Next()) | 942 object != NULL; object = data_it.Next()) |
911 object->Iterate(&v); | 943 object->Iterate(&v); |
912 } | 944 } |
913 } | 945 } |
914 #endif | 946 #endif |
915 | 947 |
916 | 948 |
917 void Heap::CheckNewSpaceExpansionCriteria() { | 949 void Heap::CheckNewSpaceExpansionCriteria() { |
918 if (new_space_.Capacity() < new_space_.MaximumCapacity() && | 950 if (new_space_.Capacity() < new_space_.MaximumCapacity() && |
919 survived_since_last_expansion_ > new_space_.Capacity()) { | 951 survived_since_last_expansion_ > new_space_.Capacity() && |
920 // Grow the size of new space if there is room to grow and enough | 952 !new_space_high_promotion_mode_active_) { |
921 // data has survived scavenge since the last expansion. | 953 // Grow the size of new space if there is room to grow, enough data |
| 954 // has survived scavenge since the last expansion and we are not in |
| 955 // high promotion mode. |
922 new_space_.Grow(); | 956 new_space_.Grow(); |
923 survived_since_last_expansion_ = 0; | 957 survived_since_last_expansion_ = 0; |
924 } | 958 } |
925 } | 959 } |
926 | 960 |
927 | 961 |
928 static bool IsUnscavengedHeapObject(Heap* heap, Object** p) { | 962 static bool IsUnscavengedHeapObject(Heap* heap, Object** p) { |
929 return heap->InNewSpace(*p) && | 963 return heap->InNewSpace(*p) && |
930 !HeapObject::cast(*p)->map_word().IsForwardingAddress(); | 964 !HeapObject::cast(*p)->map_word().IsForwardingAddress(); |
931 } | 965 } |
(...skipping 5517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6449 isolate_->heap()->store_buffer()->Compact(); | 6483 isolate_->heap()->store_buffer()->Compact(); |
6450 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); | 6484 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); |
6451 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { | 6485 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { |
6452 next = chunk->next_chunk(); | 6486 next = chunk->next_chunk(); |
6453 isolate_->memory_allocator()->Free(chunk); | 6487 isolate_->memory_allocator()->Free(chunk); |
6454 } | 6488 } |
6455 chunks_queued_for_free_ = NULL; | 6489 chunks_queued_for_free_ = NULL; |
6456 } | 6490 } |
6457 | 6491 |
6458 } } // namespace v8::internal | 6492 } } // namespace v8::internal |
OLD | NEW |