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

Side by Side Diff: src/heap.cc

Issue 9196003: Fix responsiveness of high promotion mode heuristics. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comment by Vyacheslav Egorov and fixed regression. Created 8 years, 11 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') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/heap.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698