Chromium Code Reviews| 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 4575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5396 obj = iterator.next()) { | 5402 obj = iterator.next()) { |
| 5397 InstanceType type = obj->map()->instance_type(); | 5403 InstanceType type = obj->map()->instance_type(); |
| 5398 ASSERT(0 <= type && type <= LAST_TYPE); | 5404 ASSERT(0 <= type && type <= LAST_TYPE); |
| 5399 stats->objects_per_type[type]++; | 5405 stats->objects_per_type[type]++; |
| 5400 stats->size_per_type[type] += obj->Size(); | 5406 stats->size_per_type[type] += obj->Size(); |
| 5401 } | 5407 } |
| 5402 } | 5408 } |
| 5403 } | 5409 } |
| 5404 | 5410 |
| 5405 | 5411 |
| 5406 intptr_t Heap::PromotedSpaceSize() { | 5412 intptr_t Heap::PromotedSpaceSize() { |
|
Vyacheslav Egorov (Chromium)
2012/01/16 12:36:11
Size->SizeOfObjects for consistency.
Michael Starzinger
2012/01/17 11:56:26
Done. Other NewGC heuristics are tuned for the ori
| |
| 5407 return old_pointer_space_->Size() | 5413 return old_pointer_space_->SizeOfObjects() |
| 5408 + old_data_space_->Size() | 5414 + old_data_space_->SizeOfObjects() |
| 5409 + code_space_->Size() | 5415 + code_space_->SizeOfObjects() |
| 5410 + map_space_->Size() | 5416 + map_space_->SizeOfObjects() |
| 5411 + cell_space_->Size() | 5417 + cell_space_->SizeOfObjects() |
| 5412 + lo_space_->Size(); | 5418 + lo_space_->SizeOfObjects(); |
| 5413 } | 5419 } |
| 5414 | 5420 |
| 5415 | 5421 |
| 5416 int Heap::PromotedExternalMemorySize() { | 5422 int Heap::PromotedExternalMemorySize() { |
| 5417 if (amount_of_external_allocated_memory_ | 5423 if (amount_of_external_allocated_memory_ |
| 5418 <= amount_of_external_allocated_memory_at_last_global_gc_) return 0; | 5424 <= amount_of_external_allocated_memory_at_last_global_gc_) return 0; |
| 5419 return amount_of_external_allocated_memory_ | 5425 return amount_of_external_allocated_memory_ |
| 5420 - amount_of_external_allocated_memory_at_last_global_gc_; | 5426 - amount_of_external_allocated_memory_at_last_global_gc_; |
| 5421 } | 5427 } |
| 5422 | 5428 |
| (...skipping 1231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6654 isolate_->heap()->store_buffer()->Compact(); | 6660 isolate_->heap()->store_buffer()->Compact(); |
| 6655 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); | 6661 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); |
| 6656 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { | 6662 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { |
| 6657 next = chunk->next_chunk(); | 6663 next = chunk->next_chunk(); |
| 6658 isolate_->memory_allocator()->Free(chunk); | 6664 isolate_->memory_allocator()->Free(chunk); |
| 6659 } | 6665 } |
| 6660 chunks_queued_for_free_ = NULL; | 6666 chunks_queued_for_free_ = NULL; |
| 6661 } | 6667 } |
| 6662 | 6668 |
| 6663 } } // namespace v8::internal | 6669 } } // namespace v8::internal |
| OLD | NEW |