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(); |
| 956 intptr_t used_memory_after = PromotedSpaceSizeOfObjects(); |
| 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); |
951 } else { | 969 } else { |
952 gc_idle_time_handler_.NotifyScavenge(); | 970 MemoryReducer::Event event; |
| 971 event.type = MemoryReducer::kScavenge; |
| 972 event.time_ms = MonotonicallyIncreasingTimeInMs(); |
| 973 memory_reducer_.NotifyScavenge(event); |
953 } | 974 } |
954 | 975 |
955 tracer()->Stop(collector); | 976 tracer()->Stop(collector); |
956 } | 977 } |
957 | 978 |
958 if (collector == MARK_COMPACTOR && | 979 if (collector == MARK_COMPACTOR && |
959 (gc_callback_flags & kGCCallbackFlagForced) != 0) { | 980 (gc_callback_flags & kGCCallbackFlagForced) != 0) { |
960 isolate()->CountUsage(v8::Isolate::kForcedGC); | 981 isolate()->CountUsage(v8::Isolate::kForcedGC); |
961 } | 982 } |
962 | 983 |
(...skipping 14 matching lines...) Expand all Loading... |
977 tracer()->ResetSurvivalEvents(); | 998 tracer()->ResetSurvivalEvents(); |
978 old_generation_size_configured_ = false; | 999 old_generation_size_configured_ = false; |
979 } | 1000 } |
980 if (isolate()->concurrent_recompilation_enabled()) { | 1001 if (isolate()->concurrent_recompilation_enabled()) { |
981 // Flush the queued recompilation tasks. | 1002 // Flush the queued recompilation tasks. |
982 isolate()->optimizing_compile_dispatcher()->Flush(); | 1003 isolate()->optimizing_compile_dispatcher()->Flush(); |
983 } | 1004 } |
984 AgeInlineCaches(); | 1005 AgeInlineCaches(); |
985 set_retained_maps(ArrayList::cast(empty_fixed_array())); | 1006 set_retained_maps(ArrayList::cast(empty_fixed_array())); |
986 tracer()->AddContextDisposalTime(base::OS::TimeCurrentMillis()); | 1007 tracer()->AddContextDisposalTime(base::OS::TimeCurrentMillis()); |
| 1008 MemoryReducer::Event event; |
| 1009 event.type = MemoryReducer::kContextDisposed; |
| 1010 event.time_ms = MonotonicallyIncreasingTimeInMs(); |
| 1011 memory_reducer_.NotifyContextDisposed(event); |
987 return ++contexts_disposed_; | 1012 return ++contexts_disposed_; |
988 } | 1013 } |
989 | 1014 |
990 | 1015 |
| 1016 void Heap::StartIdleIncrementalMarking() { |
| 1017 gc_idle_time_handler_.ResetNoProgressCounter(); |
| 1018 incremental_marking()->Start(kReduceMemoryFootprintMask); |
| 1019 } |
| 1020 |
| 1021 |
991 void Heap::MoveElements(FixedArray* array, int dst_index, int src_index, | 1022 void Heap::MoveElements(FixedArray* array, int dst_index, int src_index, |
992 int len) { | 1023 int len) { |
993 if (len == 0) return; | 1024 if (len == 0) return; |
994 | 1025 |
995 DCHECK(array->map() != fixed_cow_array_map()); | 1026 DCHECK(array->map() != fixed_cow_array_map()); |
996 Object** dst_objects = array->data_start() + dst_index; | 1027 Object** dst_objects = array->data_start() + dst_index; |
997 MemMove(dst_objects, array->data_start() + src_index, len * kPointerSize); | 1028 MemMove(dst_objects, array->data_start() + src_index, len * kPointerSize); |
998 if (!InNewSpace(array)) { | 1029 if (!InNewSpace(array)) { |
999 for (int i = 0; i < len; i++) { | 1030 for (int i = 0; i < len; i++) { |
1000 // TODO(hpayer): check store buffer for entries | 1031 // 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; | 4770 return mutator_utilization > high_mutator_utilization; |
4740 } | 4771 } |
4741 | 4772 |
4742 | 4773 |
4743 bool Heap::HasLowAllocationRate() { | 4774 bool Heap::HasLowAllocationRate() { |
4744 return HasLowYoungGenerationAllocationRate() && | 4775 return HasLowYoungGenerationAllocationRate() && |
4745 HasLowOldGenerationAllocationRate(); | 4776 HasLowOldGenerationAllocationRate(); |
4746 } | 4777 } |
4747 | 4778 |
4748 | 4779 |
| 4780 bool Heap::HasHighFragmentation() { |
| 4781 intptr_t used = PromotedSpaceSizeOfObjects(); |
| 4782 intptr_t committed = CommittedOldGenerationMemory(); |
| 4783 return HasHighFragmentation(used, committed); |
| 4784 } |
| 4785 |
| 4786 |
| 4787 bool Heap::HasHighFragmentation(intptr_t used, intptr_t committed) { |
| 4788 const intptr_t kSlack = 16 * MB; |
| 4789 // Fragmentation is high if committed > 2 * used + kSlack. |
| 4790 // Rewrite the exression to avoid overflow. |
| 4791 return committed - used > used + kSlack; |
| 4792 } |
| 4793 |
| 4794 |
4749 void Heap::ReduceNewSpaceSize() { | 4795 void Heap::ReduceNewSpaceSize() { |
4750 if (!FLAG_predictable && HasLowAllocationRate()) { | 4796 if (!FLAG_predictable && HasLowAllocationRate()) { |
4751 new_space_.Shrink(); | 4797 new_space_.Shrink(); |
4752 UncommitFromSpace(); | 4798 UncommitFromSpace(); |
4753 } | 4799 } |
4754 } | 4800 } |
4755 | 4801 |
4756 | 4802 |
4757 bool Heap::TryFinalizeIdleIncrementalMarking( | 4803 bool Heap::TryFinalizeIdleIncrementalMarking( |
4758 double idle_time_in_ms, size_t size_of_objects, | 4804 double idle_time_in_ms, size_t size_of_objects, |
4759 size_t final_incremental_mark_compact_speed_in_bytes_per_ms) { | 4805 size_t final_incremental_mark_compact_speed_in_bytes_per_ms) { |
4760 if (FLAG_overapproximate_weak_closure && | 4806 if (FLAG_overapproximate_weak_closure && |
4761 (incremental_marking()->IsReadyToOverApproximateWeakClosure() || | 4807 (incremental_marking()->IsReadyToOverApproximateWeakClosure() || |
4762 (!incremental_marking()->weak_closure_was_overapproximated() && | 4808 (!incremental_marking()->weak_closure_was_overapproximated() && |
4763 mark_compact_collector_.marking_deque()->IsEmpty() && | 4809 mark_compact_collector_.marking_deque()->IsEmpty() && |
4764 gc_idle_time_handler_.ShouldDoOverApproximateWeakClosure( | 4810 gc_idle_time_handler_.ShouldDoOverApproximateWeakClosure( |
4765 static_cast<size_t>(idle_time_in_ms))))) { | 4811 static_cast<size_t>(idle_time_in_ms))))) { |
4766 OverApproximateWeakClosure( | 4812 OverApproximateWeakClosure( |
4767 "Idle notification: overapproximate weak closure"); | 4813 "Idle notification: overapproximate weak closure"); |
4768 return true; | 4814 return true; |
4769 } else if (incremental_marking()->IsComplete() || | 4815 } else if (incremental_marking()->IsComplete() || |
4770 (mark_compact_collector_.marking_deque()->IsEmpty() && | 4816 (mark_compact_collector_.marking_deque()->IsEmpty() && |
4771 gc_idle_time_handler_.ShouldDoFinalIncrementalMarkCompact( | 4817 gc_idle_time_handler_.ShouldDoFinalIncrementalMarkCompact( |
4772 static_cast<size_t>(idle_time_in_ms), size_of_objects, | 4818 static_cast<size_t>(idle_time_in_ms), size_of_objects, |
4773 final_incremental_mark_compact_speed_in_bytes_per_ms))) { | 4819 final_incremental_mark_compact_speed_in_bytes_per_ms))) { |
4774 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); | 4820 CollectAllGarbage(kNoGCFlags, "idle notification: finalize incremental"); |
4775 gc_idle_time_handler_.NotifyIdleMarkCompact(); | |
4776 return true; | 4821 return true; |
4777 } | 4822 } |
4778 return false; | 4823 return false; |
4779 } | 4824 } |
4780 | 4825 |
4781 | 4826 |
4782 GCIdleTimeHandler::HeapState Heap::ComputeHeapState() { | 4827 GCIdleTimeHandler::HeapState Heap::ComputeHeapState() { |
4783 GCIdleTimeHandler::HeapState heap_state; | 4828 GCIdleTimeHandler::HeapState heap_state; |
4784 heap_state.contexts_disposed = contexts_disposed_; | 4829 heap_state.contexts_disposed = contexts_disposed_; |
4785 heap_state.contexts_disposal_rate = | 4830 heap_state.contexts_disposal_rate = |
(...skipping 10 matching lines...) Expand all Loading... |
4796 tracer()->IncrementalMarkingSpeedInBytesPerMillisecond()); | 4841 tracer()->IncrementalMarkingSpeedInBytesPerMillisecond()); |
4797 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms = | 4842 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms = |
4798 static_cast<size_t>( | 4843 static_cast<size_t>( |
4799 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()); | 4844 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()); |
4800 heap_state.scavenge_speed_in_bytes_per_ms = | 4845 heap_state.scavenge_speed_in_bytes_per_ms = |
4801 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); | 4846 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); |
4802 heap_state.used_new_space_size = new_space_.Size(); | 4847 heap_state.used_new_space_size = new_space_.Size(); |
4803 heap_state.new_space_capacity = new_space_.Capacity(); | 4848 heap_state.new_space_capacity = new_space_.Capacity(); |
4804 heap_state.new_space_allocation_throughput_in_bytes_per_ms = | 4849 heap_state.new_space_allocation_throughput_in_bytes_per_ms = |
4805 tracer()->NewSpaceAllocationThroughputInBytesPerMillisecond(); | 4850 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; | 4851 return heap_state; |
4816 } | 4852 } |
4817 | 4853 |
4818 | 4854 |
4819 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, | 4855 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, |
4820 GCIdleTimeHandler::HeapState heap_state, | 4856 GCIdleTimeHandler::HeapState heap_state, |
4821 double deadline_in_ms) { | 4857 double deadline_in_ms) { |
4822 bool result = false; | 4858 bool result = false; |
4823 switch (action.type) { | 4859 switch (action.type) { |
4824 case DONE: | 4860 case DONE: |
4825 result = true; | 4861 result = true; |
4826 break; | 4862 break; |
4827 case DO_INCREMENTAL_MARKING: { | 4863 case DO_INCREMENTAL_MARKING: { |
4828 if (incremental_marking()->IsStopped()) { | 4864 DCHECK(!incremental_marking()->IsStopped()); |
4829 incremental_marking()->Start( | |
4830 action.reduce_memory ? kReduceMemoryFootprintMask : kNoGCFlags); | |
4831 } | |
4832 double remaining_idle_time_in_ms = 0.0; | 4865 double remaining_idle_time_in_ms = 0.0; |
4833 do { | 4866 do { |
4834 incremental_marking()->Step( | 4867 incremental_marking()->Step( |
4835 action.parameter, IncrementalMarking::NO_GC_VIA_STACK_GUARD, | 4868 action.parameter, IncrementalMarking::NO_GC_VIA_STACK_GUARD, |
4836 IncrementalMarking::FORCE_MARKING, | 4869 IncrementalMarking::FORCE_MARKING, |
4837 IncrementalMarking::DO_NOT_FORCE_COMPLETION); | 4870 IncrementalMarking::DO_NOT_FORCE_COMPLETION); |
4838 remaining_idle_time_in_ms = | 4871 remaining_idle_time_in_ms = |
4839 deadline_in_ms - MonotonicallyIncreasingTimeInMs(); | 4872 deadline_in_ms - MonotonicallyIncreasingTimeInMs(); |
4840 } while (remaining_idle_time_in_ms >= | 4873 } while (remaining_idle_time_in_ms >= |
4841 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs && | 4874 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs && |
4842 !incremental_marking()->IsComplete() && | 4875 !incremental_marking()->IsComplete() && |
4843 !mark_compact_collector_.marking_deque()->IsEmpty()); | 4876 !mark_compact_collector_.marking_deque()->IsEmpty()); |
4844 if (remaining_idle_time_in_ms > 0.0) { | 4877 if (remaining_idle_time_in_ms > 0.0) { |
4845 action.additional_work = TryFinalizeIdleIncrementalMarking( | 4878 action.additional_work = TryFinalizeIdleIncrementalMarking( |
4846 remaining_idle_time_in_ms, heap_state.size_of_objects, | 4879 remaining_idle_time_in_ms, heap_state.size_of_objects, |
4847 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms); | 4880 heap_state.final_incremental_mark_compact_speed_in_bytes_per_ms); |
4848 } | 4881 } |
4849 break; | 4882 break; |
4850 } | 4883 } |
4851 case DO_FULL_GC: { | 4884 case DO_FULL_GC: { |
4852 if (action.reduce_memory) { | 4885 DCHECK(contexts_disposed_ > 0); |
4853 isolate_->compilation_cache()->Clear(); | 4886 HistogramTimerScope scope(isolate_->counters()->gc_context()); |
4854 } | 4887 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; | 4888 break; |
4864 } | 4889 } |
4865 case DO_SCAVENGE: | 4890 case DO_SCAVENGE: |
4866 CollectGarbage(NEW_SPACE, "idle notification: scavenge"); | 4891 CollectGarbage(NEW_SPACE, "idle notification: scavenge"); |
4867 break; | 4892 break; |
4868 case DO_FINALIZE_SWEEPING: | 4893 case DO_FINALIZE_SWEEPING: |
4869 mark_compact_collector()->EnsureSweepingCompleted(); | 4894 mark_compact_collector()->EnsureSweepingCompleted(); |
4870 break; | 4895 break; |
4871 case DO_NOTHING: | 4896 case DO_NOTHING: |
4872 break; | 4897 break; |
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5587 // memory-constrained devices. | 5612 // memory-constrained devices. |
5588 if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) { | 5613 if (max_old_generation_size_ <= kMaxOldSpaceSizeMediumMemoryDevice) { |
5589 factor = Min(factor, kMaxHeapGrowingFactorMemoryConstrained); | 5614 factor = Min(factor, kMaxHeapGrowingFactorMemoryConstrained); |
5590 } | 5615 } |
5591 | 5616 |
5592 if (FLAG_stress_compaction || | 5617 if (FLAG_stress_compaction || |
5593 mark_compact_collector()->reduce_memory_footprint_) { | 5618 mark_compact_collector()->reduce_memory_footprint_) { |
5594 factor = kMinHeapGrowingFactor; | 5619 factor = kMinHeapGrowingFactor; |
5595 } | 5620 } |
5596 | 5621 |
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_ = | 5622 old_generation_allocation_limit_ = |
5603 CalculateOldGenerationAllocationLimit(factor, old_gen_size); | 5623 CalculateOldGenerationAllocationLimit(factor, old_gen_size); |
5604 idle_old_generation_allocation_limit_ = | |
5605 CalculateOldGenerationAllocationLimit(idle_factor, old_gen_size); | |
5606 | 5624 |
5607 if (FLAG_trace_gc_verbose) { | 5625 if (FLAG_trace_gc_verbose) { |
5608 PrintIsolate( | 5626 PrintIsolate(isolate_, "Grow: old size: %" V8_PTR_PREFIX |
5609 isolate_, | 5627 "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 | 5628 old_gen_size / KB, old_generation_allocation_limit_ / KB, |
5611 "d KB (%.1f), new idle limit: %" V8_PTR_PREFIX "d KB (%.1f)\n", | 5629 factor); |
5612 old_gen_size / KB, old_generation_allocation_limit_ / KB, factor, | |
5613 idle_old_generation_allocation_limit_ / KB, idle_factor); | |
5614 } | 5630 } |
5615 } | 5631 } |
5616 | 5632 |
5617 | 5633 |
5618 void Heap::DampenOldGenerationAllocationLimit(intptr_t old_gen_size, | 5634 void Heap::DampenOldGenerationAllocationLimit(intptr_t old_gen_size, |
5619 double gc_speed, | 5635 double gc_speed, |
5620 double mutator_speed) { | 5636 double mutator_speed) { |
5621 double factor = HeapGrowingFactor(gc_speed, mutator_speed); | 5637 double factor = HeapGrowingFactor(gc_speed, mutator_speed); |
5622 intptr_t limit = CalculateOldGenerationAllocationLimit(factor, old_gen_size); | 5638 intptr_t limit = CalculateOldGenerationAllocationLimit(factor, old_gen_size); |
5623 if (limit < old_generation_allocation_limit_) { | 5639 if (limit < old_generation_allocation_limit_) { |
(...skipping 1222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6846 *object_type = "CODE_TYPE"; \ | 6862 *object_type = "CODE_TYPE"; \ |
6847 *object_sub_type = "CODE_AGE/" #name; \ | 6863 *object_sub_type = "CODE_AGE/" #name; \ |
6848 return true; | 6864 return true; |
6849 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) | 6865 CODE_AGE_LIST_COMPLETE(COMPARE_AND_RETURN_NAME) |
6850 #undef COMPARE_AND_RETURN_NAME | 6866 #undef COMPARE_AND_RETURN_NAME |
6851 } | 6867 } |
6852 return false; | 6868 return false; |
6853 } | 6869 } |
6854 } // namespace internal | 6870 } // namespace internal |
6855 } // namespace v8 | 6871 } // namespace v8 |
OLD | NEW |