| 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 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 681 context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); | 681 context = Context::cast(context)->get(Context::NEXT_CONTEXT_LINK); |
| 682 } | 682 } |
| 683 } | 683 } |
| 684 | 684 |
| 685 | 685 |
| 686 void Heap::UpdateSurvivalRateTrend(int start_new_space_size) { | 686 void Heap::UpdateSurvivalRateTrend(int start_new_space_size) { |
| 687 double survival_rate = | 687 double survival_rate = |
| 688 (static_cast<double>(young_survivors_after_last_gc_) * 100) / | 688 (static_cast<double>(young_survivors_after_last_gc_) * 100) / |
| 689 start_new_space_size; | 689 start_new_space_size; |
| 690 | 690 |
| 691 if (survival_rate > kYoungSurvivalRateThreshold) { | 691 if (survival_rate > kYoungSurvivalRateHighThreshold) { |
| 692 high_survival_rate_period_length_++; | 692 high_survival_rate_period_length_++; |
| 693 } else { | 693 } else { |
| 694 high_survival_rate_period_length_ = 0; | 694 high_survival_rate_period_length_ = 0; |
| 695 } | 695 } |
| 696 | 696 |
| 697 if (survival_rate < kYoungSurvivalRateLowThreshold) { |
| 698 low_survival_rate_period_length_++; |
| 699 } else { |
| 700 low_survival_rate_period_length_ = 0; |
| 701 } |
| 702 |
| 697 double survival_rate_diff = survival_rate_ - survival_rate; | 703 double survival_rate_diff = survival_rate_ - survival_rate; |
| 698 | 704 |
| 699 if (survival_rate_diff > kYoungSurvivalRateAllowedDeviation) { | 705 if (survival_rate_diff > kYoungSurvivalRateAllowedDeviation) { |
| 700 set_survival_rate_trend(DECREASING); | 706 set_survival_rate_trend(DECREASING); |
| 701 } else if (survival_rate_diff < -kYoungSurvivalRateAllowedDeviation) { | 707 } else if (survival_rate_diff < -kYoungSurvivalRateAllowedDeviation) { |
| 702 set_survival_rate_trend(INCREASING); | 708 set_survival_rate_trend(INCREASING); |
| 703 } else { | 709 } else { |
| 704 set_survival_rate_trend(STABLE); | 710 set_survival_rate_trend(STABLE); |
| 705 } | 711 } |
| 706 | 712 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 746 | 752 |
| 747 if (collector == MARK_COMPACTOR) { | 753 if (collector == MARK_COMPACTOR) { |
| 748 // Perform mark-sweep with optional compaction. | 754 // Perform mark-sweep with optional compaction. |
| 749 MarkCompact(tracer); | 755 MarkCompact(tracer); |
| 750 sweep_generation_++; | 756 sweep_generation_++; |
| 751 bool high_survival_rate_during_scavenges = IsHighSurvivalRate() && | 757 bool high_survival_rate_during_scavenges = IsHighSurvivalRate() && |
| 752 IsStableOrIncreasingSurvivalTrend(); | 758 IsStableOrIncreasingSurvivalTrend(); |
| 753 | 759 |
| 754 UpdateSurvivalRateTrend(start_new_space_size); | 760 UpdateSurvivalRateTrend(start_new_space_size); |
| 755 | 761 |
| 756 if (!new_space_high_promotion_mode_active_ && | |
| 757 new_space_.Capacity() == new_space_.MaximumCapacity() && | |
| 758 IsStableOrIncreasingSurvivalTrend() && | |
| 759 IsHighSurvivalRate()) { | |
| 760 // Stable high survival rates even though young generation is at | |
| 761 // maximum capacity indicates that most objects will be promoted. | |
| 762 // To decrease scavenger pauses and final mark-sweep pauses, we | |
| 763 // have to limit maximal capacity of the young generation. | |
| 764 new_space_high_promotion_mode_active_ = true; | |
| 765 if (FLAG_trace_gc) { | |
| 766 PrintF("Limited new space size due to high promotion rate: %d MB\n", | |
| 767 new_space_.InitialCapacity() / MB); | |
| 768 } | |
| 769 } else if (new_space_high_promotion_mode_active_ && | |
| 770 IsDecreasingSurvivalTrend() && | |
| 771 !IsHighSurvivalRate()) { | |
| 772 // Decreasing low survival rates might indicate that the above high | |
| 773 // promotion mode is over and we should allow the young generation | |
| 774 // to grow again. | |
| 775 new_space_high_promotion_mode_active_ = false; | |
| 776 if (FLAG_trace_gc) { | |
| 777 PrintF("Unlimited new space size due to low promotion rate: %d MB\n", | |
| 778 new_space_.MaximumCapacity() / MB); | |
| 779 } | |
| 780 } | |
| 781 | |
| 782 size_of_old_gen_at_last_old_space_gc_ = PromotedSpaceSize(); | 762 size_of_old_gen_at_last_old_space_gc_ = PromotedSpaceSize(); |
| 783 | 763 |
| 784 if (high_survival_rate_during_scavenges && | 764 if (high_survival_rate_during_scavenges && |
| 785 IsStableOrIncreasingSurvivalTrend()) { | 765 IsStableOrIncreasingSurvivalTrend()) { |
| 786 // Stable high survival rates of young objects both during partial and | 766 // Stable high survival rates of young objects both during partial and |
| 787 // full collection indicate that mutator is either building or modifying | 767 // full collection indicate that mutator is either building or modifying |
| 788 // a structure with a long lifetime. | 768 // a structure with a long lifetime. |
| 789 // In this case we aggressively raise old generation memory limits to | 769 // In this case we aggressively raise old generation memory limits to |
| 790 // postpone subsequent mark-sweep collection and thus trade memory | 770 // postpone subsequent mark-sweep collection and thus trade memory |
| 791 // space for the mutation speed. | 771 // space for the mutation speed. |
| 792 old_gen_limit_factor_ = 2; | 772 old_gen_limit_factor_ = 2; |
| 793 } else { | 773 } else { |
| 794 old_gen_limit_factor_ = 1; | 774 old_gen_limit_factor_ = 1; |
| 795 } | 775 } |
| 796 | 776 |
| 797 old_gen_promotion_limit_ = | 777 old_gen_promotion_limit_ = |
| 798 OldGenPromotionLimit(size_of_old_gen_at_last_old_space_gc_); | 778 OldGenPromotionLimit(size_of_old_gen_at_last_old_space_gc_); |
| 799 old_gen_allocation_limit_ = | 779 old_gen_allocation_limit_ = |
| 800 OldGenAllocationLimit(size_of_old_gen_at_last_old_space_gc_); | 780 OldGenAllocationLimit(size_of_old_gen_at_last_old_space_gc_); |
| 801 | 781 |
| 802 old_gen_exhausted_ = false; | 782 old_gen_exhausted_ = false; |
| 803 } else { | 783 } else { |
| 804 tracer_ = tracer; | 784 tracer_ = tracer; |
| 805 Scavenge(); | 785 Scavenge(); |
| 806 tracer_ = NULL; | 786 tracer_ = NULL; |
| 807 | 787 |
| 808 UpdateSurvivalRateTrend(start_new_space_size); | 788 UpdateSurvivalRateTrend(start_new_space_size); |
| 809 } | 789 } |
| 810 | 790 |
| 791 if (!new_space_high_promotion_mode_active_ && |
| 792 new_space_.Capacity() == new_space_.MaximumCapacity() && |
| 793 IsStableOrIncreasingSurvivalTrend() && |
| 794 IsHighSurvivalRate()) { |
| 795 // Stable high survival rates even though young generation is at |
| 796 // maximum capacity indicates that most objects will be promoted. |
| 797 // To decrease scavenger pauses and final mark-sweep pauses, we |
| 798 // have to limit maximal capacity of the young generation. |
| 799 new_space_high_promotion_mode_active_ = true; |
| 800 if (FLAG_trace_gc) { |
| 801 PrintF("Limited new space size due to high promotion rate: %d MB\n", |
| 802 new_space_.InitialCapacity() / MB); |
| 803 } |
| 804 } else if (new_space_high_promotion_mode_active_ && |
| 805 IsStableOrDecreasingSurvivalTrend() && |
| 806 IsLowSurvivalRate()) { |
| 807 // Decreasing low survival rates might indicate that the above high |
| 808 // promotion mode is over and we should allow the young generation |
| 809 // to grow again. |
| 810 new_space_high_promotion_mode_active_ = false; |
| 811 if (FLAG_trace_gc) { |
| 812 PrintF("Unlimited new space size due to low promotion rate: %d MB\n", |
| 813 new_space_.MaximumCapacity() / MB); |
| 814 } |
| 815 } |
| 816 |
| 811 if (new_space_high_promotion_mode_active_ && | 817 if (new_space_high_promotion_mode_active_ && |
| 812 new_space_.Capacity() > new_space_.InitialCapacity()) { | 818 new_space_.Capacity() > new_space_.InitialCapacity()) { |
| 813 new_space_.Shrink(); | 819 new_space_.Shrink(); |
| 814 } | 820 } |
| 815 | 821 |
| 816 isolate_->counters()->objs_since_last_young()->Set(0); | 822 isolate_->counters()->objs_since_last_young()->Set(0); |
| 817 | 823 |
| 818 gc_post_processing_depth_++; | 824 gc_post_processing_depth_++; |
| 819 { DisableAssertNoAllocation allow_allocation; | 825 { DisableAssertNoAllocation allow_allocation; |
| 820 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); | 826 GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL); |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1083 | 1089 |
| 1084 gc_state_ = SCAVENGE; | 1090 gc_state_ = SCAVENGE; |
| 1085 | 1091 |
| 1086 // Implements Cheney's copying algorithm | 1092 // Implements Cheney's copying algorithm |
| 1087 LOG(isolate_, ResourceEvent("scavenge", "begin")); | 1093 LOG(isolate_, ResourceEvent("scavenge", "begin")); |
| 1088 | 1094 |
| 1089 // Clear descriptor cache. | 1095 // Clear descriptor cache. |
| 1090 isolate_->descriptor_lookup_cache()->Clear(); | 1096 isolate_->descriptor_lookup_cache()->Clear(); |
| 1091 | 1097 |
| 1092 // Used for updating survived_since_last_expansion_ at function end. | 1098 // Used for updating survived_since_last_expansion_ at function end. |
| 1093 intptr_t survived_watermark = PromotedSpaceSize(); | 1099 intptr_t survived_watermark = PromotedSpaceSizeOfObjects(); |
| 1094 | 1100 |
| 1095 CheckNewSpaceExpansionCriteria(); | 1101 CheckNewSpaceExpansionCriteria(); |
| 1096 | 1102 |
| 1097 SelectScavengingVisitorsTable(); | 1103 SelectScavengingVisitorsTable(); |
| 1098 | 1104 |
| 1099 incremental_marking()->PrepareForScavenge(); | 1105 incremental_marking()->PrepareForScavenge(); |
| 1100 | 1106 |
| 1101 AdvanceSweepers(static_cast<int>(new_space_.Size())); | 1107 AdvanceSweepers(static_cast<int>(new_space_.Size())); |
| 1102 | 1108 |
| 1103 // Flip the semispaces. After flipping, to space is empty, from space has | 1109 // Flip the semispaces. After flipping, to space is empty, from space has |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1175 ASSERT(new_space_front == new_space_.top()); | 1181 ASSERT(new_space_front == new_space_.top()); |
| 1176 | 1182 |
| 1177 // Set age mark. | 1183 // Set age mark. |
| 1178 new_space_.set_age_mark(new_space_.top()); | 1184 new_space_.set_age_mark(new_space_.top()); |
| 1179 | 1185 |
| 1180 new_space_.LowerInlineAllocationLimit( | 1186 new_space_.LowerInlineAllocationLimit( |
| 1181 new_space_.inline_allocation_limit_step()); | 1187 new_space_.inline_allocation_limit_step()); |
| 1182 | 1188 |
| 1183 // Update how much has survived scavenge. | 1189 // Update how much has survived scavenge. |
| 1184 IncrementYoungSurvivorsCounter(static_cast<int>( | 1190 IncrementYoungSurvivorsCounter(static_cast<int>( |
| 1185 (PromotedSpaceSize() - survived_watermark) + new_space_.Size())); | 1191 (PromotedSpaceSizeOfObjects() - survived_watermark) + new_space_.Size())); |
| 1186 | 1192 |
| 1187 LOG(isolate_, ResourceEvent("scavenge", "end")); | 1193 LOG(isolate_, ResourceEvent("scavenge", "end")); |
| 1188 | 1194 |
| 1189 gc_state_ = NOT_IN_GC; | 1195 gc_state_ = NOT_IN_GC; |
| 1190 | 1196 |
| 1191 scavenges_since_last_idle_round_++; | 1197 scavenges_since_last_idle_round_++; |
| 1192 } | 1198 } |
| 1193 | 1199 |
| 1194 | 1200 |
| 1195 String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap, | 1201 String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap, |
| (...skipping 4210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5406 intptr_t Heap::PromotedSpaceSize() { | 5412 intptr_t Heap::PromotedSpaceSize() { |
| 5407 return old_pointer_space_->Size() | 5413 return old_pointer_space_->Size() |
| 5408 + old_data_space_->Size() | 5414 + old_data_space_->Size() |
| 5409 + code_space_->Size() | 5415 + code_space_->Size() |
| 5410 + map_space_->Size() | 5416 + map_space_->Size() |
| 5411 + cell_space_->Size() | 5417 + cell_space_->Size() |
| 5412 + lo_space_->Size(); | 5418 + lo_space_->Size(); |
| 5413 } | 5419 } |
| 5414 | 5420 |
| 5415 | 5421 |
| 5422 intptr_t Heap::PromotedSpaceSizeOfObjects() { |
| 5423 return old_pointer_space_->SizeOfObjects() |
| 5424 + old_data_space_->SizeOfObjects() |
| 5425 + code_space_->SizeOfObjects() |
| 5426 + map_space_->SizeOfObjects() |
| 5427 + cell_space_->SizeOfObjects() |
| 5428 + lo_space_->SizeOfObjects(); |
| 5429 } |
| 5430 |
| 5431 |
| 5416 int Heap::PromotedExternalMemorySize() { | 5432 int Heap::PromotedExternalMemorySize() { |
| 5417 if (amount_of_external_allocated_memory_ | 5433 if (amount_of_external_allocated_memory_ |
| 5418 <= amount_of_external_allocated_memory_at_last_global_gc_) return 0; | 5434 <= amount_of_external_allocated_memory_at_last_global_gc_) return 0; |
| 5419 return amount_of_external_allocated_memory_ | 5435 return amount_of_external_allocated_memory_ |
| 5420 - amount_of_external_allocated_memory_at_last_global_gc_; | 5436 - amount_of_external_allocated_memory_at_last_global_gc_; |
| 5421 } | 5437 } |
| 5422 | 5438 |
| 5423 #ifdef DEBUG | 5439 #ifdef DEBUG |
| 5424 | 5440 |
| 5425 // Tags 0, 1, and 3 are used. Use 2 for marking visited HeapObject. | 5441 // Tags 0, 1, and 3 are used. Use 2 for marking visited HeapObject. |
| (...skipping 1228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6654 isolate_->heap()->store_buffer()->Compact(); | 6670 isolate_->heap()->store_buffer()->Compact(); |
| 6655 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); | 6671 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); |
| 6656 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { | 6672 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { |
| 6657 next = chunk->next_chunk(); | 6673 next = chunk->next_chunk(); |
| 6658 isolate_->memory_allocator()->Free(chunk); | 6674 isolate_->memory_allocator()->Free(chunk); |
| 6659 } | 6675 } |
| 6660 chunks_queued_for_free_ = NULL; | 6676 chunks_queued_for_free_ = NULL; |
| 6661 } | 6677 } |
| 6662 | 6678 |
| 6663 } } // namespace v8::internal | 6679 } } // namespace v8::internal |
| OLD | NEW |