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