OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
11 #include "src/base/utils/random-number-generator.h" | 11 #include "src/base/utils/random-number-generator.h" |
12 #include "src/bootstrapper.h" | 12 #include "src/bootstrapper.h" |
13 #include "src/codegen.h" | 13 #include "src/codegen.h" |
14 #include "src/compilation-cache.h" | 14 #include "src/compilation-cache.h" |
15 #include "src/conversions.h" | 15 #include "src/conversions.h" |
16 #include "src/cpu-profiler.h" | 16 #include "src/cpu-profiler.h" |
17 #include "src/debug.h" | 17 #include "src/debug.h" |
18 #include "src/deoptimizer.h" | 18 #include "src/deoptimizer.h" |
19 #include "src/global-handles.h" | 19 #include "src/global-handles.h" |
20 #include "src/heap/gc-idle-time-handler.h" | 20 #include "src/heap/gc-idle-time-handler.h" |
21 #include "src/heap/incremental-marking.h" | 21 #include "src/heap/incremental-marking.h" |
22 #include "src/heap/mark-compact.h" | 22 #include "src/heap/mark-compact.h" |
23 #include "src/heap/memory-reducer.h" | |
24 #include "src/heap/objects-visiting-inl.h" | 23 #include "src/heap/objects-visiting-inl.h" |
25 #include "src/heap/objects-visiting.h" | 24 #include "src/heap/objects-visiting.h" |
26 #include "src/heap/store-buffer.h" | 25 #include "src/heap/store-buffer.h" |
27 #include "src/heap-profiler.h" | 26 #include "src/heap-profiler.h" |
28 #include "src/runtime-profiler.h" | 27 #include "src/runtime-profiler.h" |
29 #include "src/scopeinfo.h" | 28 #include "src/scopeinfo.h" |
30 #include "src/snapshot/natives.h" | 29 #include "src/snapshot/natives.h" |
31 #include "src/snapshot/serialize.h" | 30 #include "src/snapshot/serialize.h" |
32 #include "src/snapshot/snapshot.h" | 31 #include "src/snapshot/snapshot.h" |
33 #include "src/utils.h" | 32 #include "src/utils.h" |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 raw_allocations_hash_(0), | 100 raw_allocations_hash_(0), |
102 dump_allocations_hash_countdown_(FLAG_dump_allocations_digest_at_alloc), | 101 dump_allocations_hash_countdown_(FLAG_dump_allocations_digest_at_alloc), |
103 ms_count_(0), | 102 ms_count_(0), |
104 gc_count_(0), | 103 gc_count_(0), |
105 remembered_unmapped_pages_index_(0), | 104 remembered_unmapped_pages_index_(0), |
106 unflattened_strings_length_(0), | 105 unflattened_strings_length_(0), |
107 #ifdef DEBUG | 106 #ifdef DEBUG |
108 allocation_timeout_(0), | 107 allocation_timeout_(0), |
109 #endif // DEBUG | 108 #endif // DEBUG |
110 old_generation_allocation_limit_(initial_old_generation_size_), | 109 old_generation_allocation_limit_(initial_old_generation_size_), |
| 110 idle_old_generation_allocation_limit_( |
| 111 kMinimumOldGenerationAllocationLimit), |
111 old_gen_exhausted_(false), | 112 old_gen_exhausted_(false), |
112 inline_allocation_disabled_(false), | 113 inline_allocation_disabled_(false), |
113 store_buffer_rebuilder_(store_buffer()), | 114 store_buffer_rebuilder_(store_buffer()), |
114 hidden_string_(NULL), | 115 hidden_string_(NULL), |
115 gc_safe_size_of_old_object_(NULL), | 116 gc_safe_size_of_old_object_(NULL), |
116 total_regexp_code_generated_(0), | 117 total_regexp_code_generated_(0), |
117 tracer_(this), | 118 tracer_(this), |
118 new_space_high_promotion_mode_active_(false), | 119 new_space_high_promotion_mode_active_(false), |
119 high_survival_rate_period_length_(0), | 120 high_survival_rate_period_length_(0), |
120 promoted_objects_size_(0), | 121 promoted_objects_size_(0), |
(...skipping 14 matching lines...) Expand all Loading... |
135 max_alive_after_gc_(0), | 136 max_alive_after_gc_(0), |
136 min_in_mutator_(kMaxInt), | 137 min_in_mutator_(kMaxInt), |
137 marking_time_(0.0), | 138 marking_time_(0.0), |
138 sweeping_time_(0.0), | 139 sweeping_time_(0.0), |
139 last_idle_notification_time_(0.0), | 140 last_idle_notification_time_(0.0), |
140 last_gc_time_(0.0), | 141 last_gc_time_(0.0), |
141 mark_compact_collector_(this), | 142 mark_compact_collector_(this), |
142 store_buffer_(this), | 143 store_buffer_(this), |
143 marking_(this), | 144 marking_(this), |
144 incremental_marking_(this), | 145 incremental_marking_(this), |
145 memory_reducer_(this), | |
146 full_codegen_bytes_generated_(0), | 146 full_codegen_bytes_generated_(0), |
147 crankshaft_codegen_bytes_generated_(0), | 147 crankshaft_codegen_bytes_generated_(0), |
148 new_space_allocation_counter_(0), | 148 new_space_allocation_counter_(0), |
149 old_generation_allocation_counter_(0), | 149 old_generation_allocation_counter_(0), |
150 old_generation_size_at_last_gc_(0), | 150 old_generation_size_at_last_gc_(0), |
151 gcs_since_last_deopt_(0), | 151 gcs_since_last_deopt_(0), |
152 allocation_sites_scratchpad_length_(0), | 152 allocation_sites_scratchpad_length_(0), |
153 ring_buffer_full_(false), | 153 ring_buffer_full_(false), |
154 ring_buffer_end_(0), | 154 ring_buffer_end_(0), |
155 promotion_queue_(this), | 155 promotion_queue_(this), |
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
919 !mark_compact_collector_.marking_deque_.IsEmpty() && !FLAG_gc_global) { | 919 !mark_compact_collector_.marking_deque_.IsEmpty() && !FLAG_gc_global) { |
920 if (FLAG_trace_incremental_marking) { | 920 if (FLAG_trace_incremental_marking) { |
921 PrintF("[IncrementalMarking] Delaying MarkSweep.\n"); | 921 PrintF("[IncrementalMarking] Delaying MarkSweep.\n"); |
922 } | 922 } |
923 collector = SCAVENGER; | 923 collector = SCAVENGER; |
924 collector_reason = "incremental marking delaying mark-sweep"; | 924 collector_reason = "incremental marking delaying mark-sweep"; |
925 } | 925 } |
926 } | 926 } |
927 | 927 |
928 bool next_gc_likely_to_collect_more = false; | 928 bool next_gc_likely_to_collect_more = false; |
929 intptr_t committed_memory_before; | |
930 | |
931 if (collector == MARK_COMPACTOR) { | |
932 committed_memory_before = CommittedOldGenerationMemory(); | |
933 } | |
934 | 929 |
935 { | 930 { |
936 tracer()->Start(collector, gc_reason, collector_reason); | 931 tracer()->Start(collector, gc_reason, collector_reason); |
937 DCHECK(AllowHeapAllocation::IsAllowed()); | 932 DCHECK(AllowHeapAllocation::IsAllowed()); |
938 DisallowHeapAllocation no_allocation_during_gc; | 933 DisallowHeapAllocation no_allocation_during_gc; |
939 GarbageCollectionPrologue(); | 934 GarbageCollectionPrologue(); |
940 | 935 |
941 { | 936 { |
942 HistogramTimerScope histogram_timer_scope( | 937 HistogramTimerScope histogram_timer_scope( |
943 (collector == SCAVENGER) ? isolate_->counters()->gc_scavenger() | 938 (collector == SCAVENGER) ? isolate_->counters()->gc_scavenger() |
944 : isolate_->counters()->gc_compactor()); | 939 : isolate_->counters()->gc_compactor()); |
945 next_gc_likely_to_collect_more = | 940 next_gc_likely_to_collect_more = |
946 PerformGarbageCollection(collector, gc_callback_flags); | 941 PerformGarbageCollection(collector, gc_callback_flags); |
947 } | 942 } |
948 | 943 |
949 GarbageCollectionEpilogue(); | 944 GarbageCollectionEpilogue(); |
950 if (collector == MARK_COMPACTOR && FLAG_track_detached_contexts) { | 945 if (collector == MARK_COMPACTOR && FLAG_track_detached_contexts) { |
951 isolate()->CheckDetachedContextsAfterGC(); | 946 isolate()->CheckDetachedContextsAfterGC(); |
952 } | 947 } |
953 | 948 |
954 if (collector == MARK_COMPACTOR) { | 949 if (collector == MARK_COMPACTOR) { |
955 intptr_t committed_memory_after = CommittedOldGenerationMemory(); | 950 gc_idle_time_handler_.NotifyMarkCompact(next_gc_likely_to_collect_more); |
956 intptr_t used_memory_after = PromotedSpaceSizeOfObjects(); | 951 } else { |
957 MemoryReducer::Event event; | 952 gc_idle_time_handler_.NotifyScavenge(); |
958 event.type = MemoryReducer::kMarkCompact; | |
959 event.time_ms = MonotonicallyIncreasingTimeInMs(); | |
960 // Trigger one more GC if | |
961 // - this GC decreased committed memory, | |
962 // - there is high fragmentation, | |
963 // - there are live detached contexts. | |
964 event.next_gc_likely_to_collect_more = | |
965 (committed_memory_before - committed_memory_after) > MB || | |
966 HasHighFragmentation(used_memory_after, committed_memory_after) || | |
967 (detached_contexts()->length() > 0); | |
968 memory_reducer_.NotifyMarkCompact(event); | |
969 } | 953 } |
970 | 954 |
971 tracer()->Stop(collector); | 955 tracer()->Stop(collector); |
972 } | 956 } |
973 | 957 |
974 if (collector == MARK_COMPACTOR && | 958 if (collector == MARK_COMPACTOR && |
975 (gc_callback_flags & kGCCallbackFlagForced) != 0) { | 959 (gc_callback_flags & kGCCallbackFlagForced) != 0) { |
976 isolate()->CountUsage(v8::Isolate::kForcedGC); | 960 isolate()->CountUsage(v8::Isolate::kForcedGC); |
977 } | 961 } |
978 | 962 |
(...skipping 14 matching lines...) Expand all Loading... |
993 tracer()->ResetSurvivalEvents(); | 977 tracer()->ResetSurvivalEvents(); |
994 old_generation_size_configured_ = false; | 978 old_generation_size_configured_ = false; |
995 } | 979 } |
996 if (isolate()->concurrent_recompilation_enabled()) { | 980 if (isolate()->concurrent_recompilation_enabled()) { |
997 // Flush the queued recompilation tasks. | 981 // Flush the queued recompilation tasks. |
998 isolate()->optimizing_compile_dispatcher()->Flush(); | 982 isolate()->optimizing_compile_dispatcher()->Flush(); |
999 } | 983 } |
1000 AgeInlineCaches(); | 984 AgeInlineCaches(); |
1001 set_retained_maps(ArrayList::cast(empty_fixed_array())); | 985 set_retained_maps(ArrayList::cast(empty_fixed_array())); |
1002 tracer()->AddContextDisposalTime(base::OS::TimeCurrentMillis()); | 986 tracer()->AddContextDisposalTime(base::OS::TimeCurrentMillis()); |
1003 MemoryReducer::Event event; | |
1004 event.type = MemoryReducer::kContextDisposed; | |
1005 event.time_ms = MonotonicallyIncreasingTimeInMs(); | |
1006 memory_reducer_.NotifyContextDisposed(event); | |
1007 return ++contexts_disposed_; | 987 return ++contexts_disposed_; |
1008 } | 988 } |
1009 | 989 |
1010 | 990 |
1011 void Heap::StartIdleIncrementalMarking() { | |
1012 gc_idle_time_handler_.ResetNoProgressCounter(); | |
1013 incremental_marking()->Start(kReduceMemoryFootprintMask); | |
1014 } | |
1015 | |
1016 | |
1017 void Heap::MoveElements(FixedArray* array, int dst_index, int src_index, | 991 void Heap::MoveElements(FixedArray* array, int dst_index, int src_index, |
1018 int len) { | 992 int len) { |
1019 if (len == 0) return; | 993 if (len == 0) return; |
1020 | 994 |
1021 DCHECK(array->map() != fixed_cow_array_map()); | 995 DCHECK(array->map() != fixed_cow_array_map()); |
1022 Object** dst_objects = array->data_start() + dst_index; | 996 Object** dst_objects = array->data_start() + dst_index; |
1023 MemMove(dst_objects, array->data_start() + src_index, len * kPointerSize); | 997 MemMove(dst_objects, array->data_start() + src_index, len * kPointerSize); |
1024 if (!InNewSpace(array)) { | 998 if (!InNewSpace(array)) { |
1025 for (int i = 0; i < len; i++) { | 999 for (int i = 0; i < len; i++) { |
1026 // TODO(hpayer): check store buffer for entries | 1000 // TODO(hpayer): check store buffer for entries |
(...skipping 3738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4765 return mutator_utilization > high_mutator_utilization; | 4739 return mutator_utilization > high_mutator_utilization; |
4766 } | 4740 } |
4767 | 4741 |
4768 | 4742 |
4769 bool Heap::HasLowAllocationRate() { | 4743 bool Heap::HasLowAllocationRate() { |
4770 return HasLowYoungGenerationAllocationRate() && | 4744 return HasLowYoungGenerationAllocationRate() && |
4771 HasLowOldGenerationAllocationRate(); | 4745 HasLowOldGenerationAllocationRate(); |
4772 } | 4746 } |
4773 | 4747 |
4774 | 4748 |
4775 bool Heap::HasHighFragmentation() { | |
4776 intptr_t used = PromotedSpaceSizeOfObjects(); | |
4777 intptr_t committed = CommittedOldGenerationMemory(); | |
4778 return HasHighFragmentation(used, committed); | |
4779 } | |
4780 | |
4781 | |
4782 bool Heap::HasHighFragmentation(intptr_t used, intptr_t committed) { | |
4783 const intptr_t kSlack = 16 * MB; | |
4784 // Fragmentation is high if committed > 2 * used + kSlack. | |
4785 // Rewrite the exression to avoid overflow. | |
4786 return committed - used > used + kSlack; | |
4787 } | |
4788 | |
4789 | |
4790 void Heap::ReduceNewSpaceSize() { | 4749 void Heap::ReduceNewSpaceSize() { |
4791 if (!FLAG_predictable && HasLowAllocationRate()) { | 4750 if (!FLAG_predictable && HasLowAllocationRate()) { |
4792 new_space_.Shrink(); | 4751 new_space_.Shrink(); |
4793 UncommitFromSpace(); | 4752 UncommitFromSpace(); |
4794 } | 4753 } |
4795 } | 4754 } |
4796 | 4755 |
4797 | 4756 |
4798 bool Heap::TryFinalizeIdleIncrementalMarking( | 4757 bool Heap::TryFinalizeIdleIncrementalMarking( |
4799 double idle_time_in_ms, size_t size_of_objects, | 4758 double idle_time_in_ms, size_t size_of_objects, |
4800 size_t final_incremental_mark_compact_speed_in_bytes_per_ms) { | 4759 size_t final_incremental_mark_compact_speed_in_bytes_per_ms) { |
4801 if (FLAG_overapproximate_weak_closure && | 4760 if (FLAG_overapproximate_weak_closure && |
4802 (incremental_marking()->IsReadyToOverApproximateWeakClosure() || | 4761 (incremental_marking()->IsReadyToOverApproximateWeakClosure() || |
4803 (!incremental_marking()->weak_closure_was_overapproximated() && | 4762 (!incremental_marking()->weak_closure_was_overapproximated() && |
4804 mark_compact_collector_.marking_deque()->IsEmpty() && | 4763 mark_compact_collector_.marking_deque()->IsEmpty() && |
4805 gc_idle_time_handler_.ShouldDoOverApproximateWeakClosure( | 4764 gc_idle_time_handler_.ShouldDoOverApproximateWeakClosure( |
4806 static_cast<size_t>(idle_time_in_ms))))) { | 4765 static_cast<size_t>(idle_time_in_ms))))) { |
4807 OverApproximateWeakClosure( | 4766 OverApproximateWeakClosure( |
4808 "Idle notification: overapproximate weak closure"); | 4767 "Idle notification: overapproximate weak closure"); |
4809 return true; | 4768 return true; |
4810 } else if (incremental_marking()->IsComplete() || | 4769 } else if (incremental_marking()->IsComplete() || |
4811 (mark_compact_collector_.marking_deque()->IsEmpty() && | 4770 (mark_compact_collector_.marking_deque()->IsEmpty() && |
4812 gc_idle_time_handler_.ShouldDoFinalIncrementalMarkCompact( | 4771 gc_idle_time_handler_.ShouldDoFinalIncrementalMarkCompact( |
4813 static_cast<size_t>(idle_time_in_ms), size_of_objects, | 4772 static_cast<size_t>(idle_time_in_ms), size_of_objects, |
4814 final_incremental_mark_compact_speed_in_bytes_per_ms))) { | 4773 final_incremental_mark_compact_speed_in_bytes_per_ms))) { |
4815 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); | 4774 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); |
| 4775 gc_idle_time_handler_.NotifyIdleMarkCompact(); |
4816 return true; | 4776 return true; |
4817 } | 4777 } |
4818 return false; | 4778 return false; |
4819 } | 4779 } |
4820 | 4780 |
4821 | 4781 |
4822 GCIdleTimeHandler::HeapState Heap::ComputeHeapState() { | 4782 GCIdleTimeHandler::HeapState Heap::ComputeHeapState() { |
4823 GCIdleTimeHandler::HeapState heap_state; | 4783 GCIdleTimeHandler::HeapState heap_state; |
4824 heap_state.contexts_disposed = contexts_disposed_; | 4784 heap_state.contexts_disposed = contexts_disposed_; |
4825 heap_state.contexts_disposal_rate = | 4785 heap_state.contexts_disposal_rate = |
(...skipping 10 matching lines...) Expand all Loading... |
4836 tracer()->IncrementalMarkingSpeedInBytesPerMillisecond()); | 4796 tracer()->IncrementalMarkingSpeedInBytesPerMillisecond()); |
4837 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms = | 4797 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms = |
4838 static_cast<size_t>( | 4798 static_cast<size_t>( |
4839 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()); | 4799 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()); |
4840 heap_state.scavenge_speed_in_bytes_per_ms = | 4800 heap_state.scavenge_speed_in_bytes_per_ms = |
4841 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); | 4801 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); |
4842 heap_state.used_new_space_size = new_space_.Size(); | 4802 heap_state.used_new_space_size = new_space_.Size(); |
4843 heap_state.new_space_capacity = new_space_.Capacity(); | 4803 heap_state.new_space_capacity = new_space_.Capacity(); |
4844 heap_state.new_space_allocation_throughput_in_bytes_per_ms = | 4804 heap_state.new_space_allocation_throughput_in_bytes_per_ms = |
4845 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond(); | 4805 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond(); |
| 4806 heap_state.has_low_allocation_rate = HasLowAllocationRate(); |
| 4807 intptr_t limit = old_generation_allocation_limit_; |
| 4808 if (heap_state.has_low_allocation_rate) { |
| 4809 limit = idle_old_generation_allocation_limit_; |
| 4810 } |
| 4811 heap_state.can_start_incremental_marking = |
| 4812 incremental_marking()->CanBeActivated() && |
| 4813 HeapIsFullEnoughToStartIncrementalMarking(limit) && |
| 4814 !mark_compact_collector()->sweeping_in_progress(); |
4846 return heap_state; | 4815 return heap_state; |
4847 } | 4816 } |
4848 | 4817 |
4849 | 4818 |
4850 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, | 4819 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, |
4851 GCIdleTimeHandler::HeapState heap_state, | 4820 GCIdleTimeHandler::HeapState heap_state, |
4852 double deadline_in_ms) { | 4821 double deadline_in_ms) { |
4853 bool result = false; | 4822 bool result = false; |
4854 switch (action.type) { | 4823 switch (action.type) { |
4855 case DONE: | 4824 case DONE: |
4856 result = true; | 4825 result = true; |
4857 break; | 4826 break; |
4858 case DO_INCREMENTAL_MARKING: { | 4827 case DO_INCREMENTAL_MARKING: { |
4859 DCHECK(!incremental_marking()->IsStopped()); | 4828 if (incremental_marking()->IsStopped()) { |
| 4829 incremental_marking()->Start( |
| 4830 action.reduce_memory ? kReduceMemoryFootprintMask : kNoGCFlags); |
| 4831 } |
4860 double remaining_idle_time_in_ms = 0.0; | 4832 double remaining_idle_time_in_ms = 0.0; |
4861 do { | 4833 do { |
4862 incremental_marking()->Step( | 4834 incremental_marking()->Step( |
4863 action.parameter, IncrementalMarking::NO_GC_VIA_STACK_GUARD, | 4835 action.parameter, IncrementalMarking::NO_GC_VIA_STACK_GUARD, |
4864 IncrementalMarking::FORCE_MARKING, | 4836 IncrementalMarking::FORCE_MARKING, |
4865 IncrementalMarking::DO_NOT_FORCE_COMPLETION); | 4837 IncrementalMarking::DO_NOT_FORCE_COMPLETION); |
4866 remaining_idle_time_in_ms = | 4838 remaining_idle_time_in_ms = |
4867 deadline_in_ms - MonotonicallyIncreasingTimeInMs(); | 4839 deadline_in_ms - MonotonicallyIncreasingTimeInMs(); |
4868 } while (remaining_idle_time_in_ms >= | 4840 } while (remaining_idle_time_in_ms >= |
4869 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs && | 4841 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs && |
4870 !incremental_marking()->IsComplete() && | 4842 !incremental_marking()->IsComplete() && |
4871 !mark_compact_collector_.marking_deque()->IsEmpty()); | 4843 !mark_compact_collector_.marking_deque()->IsEmpty()); |
4872 if (remaining_idle_time_in_ms > 0.0) { | 4844 if (remaining_idle_time_in_ms > 0.0) { |
4873 action.additional_work = TryFinalizeIdleIncrementalMarking( | 4845 action.additional_work = TryFinalizeIdleIncrementalMarking( |
4874 remaining_idle_time_in_ms, heap_state.size_of_objects, | 4846 remaining_idle_time_in_ms, heap_state.size_of_objects, |
4875 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms); | 4847 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms); |
4876 } | 4848 } |
4877 break; | 4849 break; |
4878 } | 4850 } |
4879 case DO_FULL_GC: { | 4851 case DO_FULL_GC: { |
4880 DCHECK(contexts_disposed_ > 0); | 4852 if (action.reduce_memory) { |
4881 HistogramTimerScope scope(isolate_->counters()->gc_context()); | 4853 isolate_->compilation_cache()->Clear(); |
4882 CollectAllGarbage(kNoGCFlags, "idle notification: contexts disposed"); | 4854 } |
| 4855 if (contexts_disposed_) { |
| 4856 HistogramTimerScope scope(isolate_->counters()->gc_context()); |
| 4857 CollectAllGarbage(kNoGCFlags, "idle notification: contexts disposed"); |
| 4858 } else { |
| 4859 CollectAllGarbage(kReduceMemoryFootprintMask, |
| 4860 "idle notification: finalize idle round"); |
| 4861 } |
| 4862 gc_idle_time_handler_.NotifyIdleMarkCompact(); |
4883 break; | 4863 break; |
4884 } | 4864 } |
4885 case DO_SCAVENGE: | 4865 case DO_SCAVENGE: |
4886 CollectGarbage(NEW_SPACE, "idle notification: scavenge"); | 4866 CollectGarbage(NEW_SPACE, "idle notification: scavenge"); |
4887 break; | 4867 break; |
4888 case DO_FINALIZE_SWEEPING: | 4868 case DO_FINALIZE_SWEEPING: |
4889 mark_compact_collector()->EnsureSweepingCompleted(); | 4869 mark_compact_collector()->EnsureSweepingCompleted(); |
4890 break; | 4870 break; |
4891 case DO_NOTHING: | 4871 case DO_NOTHING: |
4892 break; | 4872 break; |
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5607 // memory-constrained devices. | 5587 // memory-constrained devices. |
5608 if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) { | 5588 if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) { |
5609 factor = Min(factor, kMaxHeapGrowingFactorMemoryConstrained); | 5589 factor = Min(factor, kMaxHeapGrowingFactorMemoryConstrained); |
5610 } | 5590 } |
5611 | 5591 |
5612 if (FLAG_stress_compaction || | 5592 if (FLAG_stress_compaction || |
5613 mark_compact_collector()->reduce_memory_footprint_) { | 5593 mark_compact_collector()->reduce_memory_footprint_) { |
5614 factor = kMinHeapGrowingFactor; | 5594 factor = kMinHeapGrowingFactor; |
5615 } | 5595 } |
5616 | 5596 |
| 5597 // TODO(hpayer): Investigate if idle_old_generation_allocation_limit_ is still |
| 5598 // needed after taking the allocation rate for the old generation limit into |
| 5599 // account. |
| 5600 double idle_factor = Min(factor, kMaxHeapGrowingFactorIdle); |
| 5601 |
5617 old_generation_allocation_limit_ = | 5602 old_generation_allocation_limit_ = |
5618 CalculateOldGenerationAllocationLimit(factor, old_gen_size); | 5603 CalculateOldGenerationAllocationLimit(factor, old_gen_size); |
| 5604 idle_old_generation_allocation_limit_ = |
| 5605 CalculateOldGenerationAllocationLimit(idle_factor, old_gen_size); |
5619 | 5606 |
5620 if (FLAG_trace_gc_verbose) { | 5607 if (FLAG_trace_gc_verbose) { |
5621 PrintIsolate(isolate_, "Grow: old size: %" V8_PTR_PREFIX | 5608 PrintIsolate( |
5622 "d KB, new limit: %" V8_PTR_PREFIX "d KB (%.1f)\n", | 5609 isolate_, |
5623 old_gen_size / KB, old_generation_allocation_limit_ / KB, | 5610 "Grow: old size: %" V8_PTR_PREFIX "d KB, new limit: %" V8_PTR_PREFIX |
5624 factor); | 5611 "d KB (%.1f), new idle limit: %" V8_PTR_PREFIX "d KB (%.1f)\n", |
| 5612 old_gen_size / KB, old_generation_allocation_limit_ / KB, factor, |
| 5613 idle_old_generation_allocation_limit_ / KB, idle_factor); |
5625 } | 5614 } |
5626 } | 5615 } |
5627 | 5616 |
5628 | 5617 |
5629 void Heap::DampenOldGenerationAllocationLimit(intptr_t old_gen_size, | 5618 void Heap::DampenOldGenerationAllocationLimit(intptr_t old_gen_size, |
5630 double gc_speed, | 5619 double gc_speed, |
5631 double mutator_speed) { | 5620 double mutator_speed) { |
5632 double factor = HeapGrowingFactor(gc_speed, mutator_speed); | 5621 double factor = HeapGrowingFactor(gc_speed, mutator_speed); |
5633 intptr_t limit = CalculateOldGenerationAllocationLimit(factor, old_gen_size); | 5622 intptr_t limit = CalculateOldGenerationAllocationLimit(factor, old_gen_size); |
5634 if (limit < old_generation_allocation_limit_) { | 5623 if (limit < old_generation_allocation_limit_) { |
(...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6857 *object_type = "CODE_TYPE"; \ | 6846 *object_type = "CODE_TYPE"; \ |
6858 *object_sub_type = "CODE_AGE/" #name; \ | 6847 *object_sub_type = "CODE_AGE/" #name; \ |
6859 return true; | 6848 return true; |
6860 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) | 6849 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) |
6861 #undef COMPARE_AND_RETURN_NAME | 6850 #undef COMPARE_AND_RETURN_NAME |
6862 } | 6851 } |
6863 return false; | 6852 return false; |
6864 } | 6853 } |
6865 } // namespace internal | 6854 } // namespace internal |
6866 } // namespace v8 | 6855 } // namespace v8 |
OLD | NEW |