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/heap/heap.h" | 5 #include "src/heap/heap.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" |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 max_alive_after_gc_(0), | 118 max_alive_after_gc_(0), |
119 min_in_mutator_(kMaxInt), | 119 min_in_mutator_(kMaxInt), |
120 marking_time_(0.0), | 120 marking_time_(0.0), |
121 sweeping_time_(0.0), | 121 sweeping_time_(0.0), |
122 last_idle_notification_time_(0.0), | 122 last_idle_notification_time_(0.0), |
123 last_gc_time_(0.0), | 123 last_gc_time_(0.0), |
124 scavenge_collector_(nullptr), | 124 scavenge_collector_(nullptr), |
125 mark_compact_collector_(this), | 125 mark_compact_collector_(this), |
126 store_buffer_(this), | 126 store_buffer_(this), |
127 incremental_marking_(this), | 127 incremental_marking_(this), |
| 128 gc_idle_time_handler_(nullptr), |
128 memory_reducer_(nullptr), | 129 memory_reducer_(nullptr), |
129 object_stats_(nullptr), | 130 object_stats_(nullptr), |
130 full_codegen_bytes_generated_(0), | 131 full_codegen_bytes_generated_(0), |
131 crankshaft_codegen_bytes_generated_(0), | 132 crankshaft_codegen_bytes_generated_(0), |
132 new_space_allocation_counter_(0), | 133 new_space_allocation_counter_(0), |
133 old_generation_allocation_counter_(0), | 134 old_generation_allocation_counter_(0), |
134 old_generation_size_at_last_gc_(0), | 135 old_generation_size_at_last_gc_(0), |
135 gcs_since_last_deopt_(0), | 136 gcs_since_last_deopt_(0), |
136 allocation_sites_scratchpad_length_(0), | 137 allocation_sites_scratchpad_length_(0), |
137 ring_buffer_full_(false), | 138 ring_buffer_full_(false), |
(...skipping 867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1005 const GCCallbackFlags gc_callback_flags, | 1006 const GCCallbackFlags gc_callback_flags, |
1006 const char* reason) { | 1007 const char* reason) { |
1007 DCHECK(incremental_marking()->IsStopped()); | 1008 DCHECK(incremental_marking()->IsStopped()); |
1008 set_current_gc_flags(gc_flags); | 1009 set_current_gc_flags(gc_flags); |
1009 current_gc_callback_flags_ = gc_callback_flags; | 1010 current_gc_callback_flags_ = gc_callback_flags; |
1010 incremental_marking()->Start(reason); | 1011 incremental_marking()->Start(reason); |
1011 } | 1012 } |
1012 | 1013 |
1013 | 1014 |
1014 void Heap::StartIdleIncrementalMarking() { | 1015 void Heap::StartIdleIncrementalMarking() { |
1015 gc_idle_time_handler_.ResetNoProgressCounter(); | 1016 gc_idle_time_handler_->ResetNoProgressCounter(); |
1016 StartIncrementalMarking(kReduceMemoryFootprintMask, kNoGCCallbackFlags, | 1017 StartIncrementalMarking(kReduceMemoryFootprintMask, kNoGCCallbackFlags, |
1017 "idle"); | 1018 "idle"); |
1018 } | 1019 } |
1019 | 1020 |
1020 | 1021 |
1021 void Heap::MoveElements(FixedArray* array, int dst_index, int src_index, | 1022 void Heap::MoveElements(FixedArray* array, int dst_index, int src_index, |
1022 int len) { | 1023 int len) { |
1023 if (len == 0) return; | 1024 if (len == 0) return; |
1024 | 1025 |
1025 DCHECK(array->map() != fixed_cow_array_map()); | 1026 DCHECK(array->map() != fixed_cow_array_map()); |
(...skipping 3041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4067 | 4068 |
4068 bool Heap::TryFinalizeIdleIncrementalMarking(double idle_time_in_ms) { | 4069 bool Heap::TryFinalizeIdleIncrementalMarking(double idle_time_in_ms) { |
4069 size_t size_of_objects = static_cast<size_t>(SizeOfObjects()); | 4070 size_t size_of_objects = static_cast<size_t>(SizeOfObjects()); |
4070 size_t final_incremental_mark_compact_speed_in_bytes_per_ms = | 4071 size_t final_incremental_mark_compact_speed_in_bytes_per_ms = |
4071 static_cast<size_t>( | 4072 static_cast<size_t>( |
4072 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()); | 4073 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond()); |
4073 if (FLAG_overapproximate_weak_closure && | 4074 if (FLAG_overapproximate_weak_closure && |
4074 (incremental_marking()->IsReadyToOverApproximateWeakClosure() || | 4075 (incremental_marking()->IsReadyToOverApproximateWeakClosure() || |
4075 (!incremental_marking()->weak_closure_was_overapproximated() && | 4076 (!incremental_marking()->weak_closure_was_overapproximated() && |
4076 mark_compact_collector_.marking_deque()->IsEmpty() && | 4077 mark_compact_collector_.marking_deque()->IsEmpty() && |
4077 gc_idle_time_handler_.ShouldDoOverApproximateWeakClosure( | 4078 gc_idle_time_handler_->ShouldDoOverApproximateWeakClosure( |
4078 static_cast<size_t>(idle_time_in_ms))))) { | 4079 static_cast<size_t>(idle_time_in_ms))))) { |
4079 OverApproximateWeakClosure( | 4080 OverApproximateWeakClosure( |
4080 "Idle notification: overapproximate weak closure"); | 4081 "Idle notification: overapproximate weak closure"); |
4081 return true; | 4082 return true; |
4082 } else if (incremental_marking()->IsComplete() || | 4083 } else if (incremental_marking()->IsComplete() || |
4083 (mark_compact_collector_.marking_deque()->IsEmpty() && | 4084 (mark_compact_collector_.marking_deque()->IsEmpty() && |
4084 gc_idle_time_handler_.ShouldDoFinalIncrementalMarkCompact( | 4085 gc_idle_time_handler_->ShouldDoFinalIncrementalMarkCompact( |
4085 static_cast<size_t>(idle_time_in_ms), size_of_objects, | 4086 static_cast<size_t>(idle_time_in_ms), size_of_objects, |
4086 final_incremental_mark_compact_speed_in_bytes_per_ms))) { | 4087 final_incremental_mark_compact_speed_in_bytes_per_ms))) { |
4087 CollectAllGarbage(current_gc_flags_, | 4088 CollectAllGarbage(current_gc_flags_, |
4088 "idle notification: finalize incremental"); | 4089 "idle notification: finalize incremental"); |
4089 return true; | 4090 return true; |
4090 } | 4091 } |
4091 return false; | 4092 return false; |
4092 } | 4093 } |
4093 | 4094 |
4094 | 4095 |
4095 GCIdleTimeHandler::HeapState Heap::ComputeHeapState() { | 4096 GCIdleTimeHeapState Heap::ComputeHeapState() { |
4096 GCIdleTimeHandler::HeapState heap_state; | 4097 GCIdleTimeHeapState heap_state; |
4097 heap_state.contexts_disposed = contexts_disposed_; | 4098 heap_state.contexts_disposed = contexts_disposed_; |
4098 heap_state.contexts_disposal_rate = | 4099 heap_state.contexts_disposal_rate = |
4099 tracer()->ContextDisposalRateInMilliseconds(); | 4100 tracer()->ContextDisposalRateInMilliseconds(); |
4100 heap_state.incremental_marking_stopped = incremental_marking()->IsStopped(); | 4101 heap_state.incremental_marking_stopped = incremental_marking()->IsStopped(); |
4101 heap_state.mark_compact_speed_in_bytes_per_ms = | 4102 heap_state.mark_compact_speed_in_bytes_per_ms = |
4102 static_cast<size_t>(tracer()->MarkCompactSpeedInBytesPerMillisecond()); | 4103 static_cast<size_t>(tracer()->MarkCompactSpeedInBytesPerMillisecond()); |
4103 heap_state.scavenge_speed_in_bytes_per_ms = | 4104 heap_state.scavenge_speed_in_bytes_per_ms = |
4104 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); | 4105 static_cast<size_t>(tracer()->ScavengeSpeedInBytesPerMillisecond()); |
4105 heap_state.used_new_space_size = new_space_.Size(); | 4106 heap_state.used_new_space_size = new_space_.Size(); |
4106 heap_state.new_space_capacity = new_space_.Capacity(); | 4107 heap_state.new_space_capacity = new_space_.Capacity(); |
(...skipping 23 matching lines...) Expand all Loading... |
4130 remaining_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs(); | 4131 remaining_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs(); |
4131 } while (remaining_time_in_ms >= | 4132 } while (remaining_time_in_ms >= |
4132 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs && | 4133 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs && |
4133 !incremental_marking()->IsComplete() && | 4134 !incremental_marking()->IsComplete() && |
4134 !mark_compact_collector_.marking_deque()->IsEmpty()); | 4135 !mark_compact_collector_.marking_deque()->IsEmpty()); |
4135 return remaining_time_in_ms; | 4136 return remaining_time_in_ms; |
4136 } | 4137 } |
4137 | 4138 |
4138 | 4139 |
4139 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, | 4140 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, |
4140 GCIdleTimeHandler::HeapState heap_state, | 4141 GCIdleTimeHeapState heap_state, |
4141 double deadline_in_ms) { | 4142 double deadline_in_ms) { |
4142 bool result = false; | 4143 bool result = false; |
4143 switch (action.type) { | 4144 switch (action.type) { |
4144 case DONE: | 4145 case DONE: |
4145 result = true; | 4146 result = true; |
4146 break; | 4147 break; |
4147 case DO_INCREMENTAL_STEP: { | 4148 case DO_INCREMENTAL_STEP: { |
4148 if (incremental_marking()->incremental_marking_job()->IdleTaskPending()) { | 4149 if (incremental_marking()->incremental_marking_job()->IdleTaskPending()) { |
4149 result = true; | 4150 result = true; |
4150 } else { | 4151 } else { |
(...skipping 16 matching lines...) Expand all Loading... |
4167 break; | 4168 break; |
4168 case DO_NOTHING: | 4169 case DO_NOTHING: |
4169 break; | 4170 break; |
4170 } | 4171 } |
4171 | 4172 |
4172 return result; | 4173 return result; |
4173 } | 4174 } |
4174 | 4175 |
4175 | 4176 |
4176 void Heap::IdleNotificationEpilogue(GCIdleTimeAction action, | 4177 void Heap::IdleNotificationEpilogue(GCIdleTimeAction action, |
4177 GCIdleTimeHandler::HeapState heap_state, | 4178 GCIdleTimeHeapState heap_state, |
4178 double start_ms, double deadline_in_ms) { | 4179 double start_ms, double deadline_in_ms) { |
4179 double idle_time_in_ms = deadline_in_ms - start_ms; | 4180 double idle_time_in_ms = deadline_in_ms - start_ms; |
4180 double current_time = MonotonicallyIncreasingTimeInMs(); | 4181 double current_time = MonotonicallyIncreasingTimeInMs(); |
4181 last_idle_notification_time_ = current_time; | 4182 last_idle_notification_time_ = current_time; |
4182 double deadline_difference = deadline_in_ms - current_time; | 4183 double deadline_difference = deadline_in_ms - current_time; |
4183 | 4184 |
4184 contexts_disposed_ = 0; | 4185 contexts_disposed_ = 0; |
4185 | 4186 |
4186 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample( | 4187 isolate()->counters()->gc_idle_time_allotted_in_ms()->AddSample( |
4187 static_cast<int>(idle_time_in_ms)); | 4188 static_cast<int>(idle_time_in_ms)); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4264 HistogramTimerScope idle_notification_scope( | 4265 HistogramTimerScope idle_notification_scope( |
4265 isolate_->counters()->gc_idle_notification()); | 4266 isolate_->counters()->gc_idle_notification()); |
4266 double start_ms = MonotonicallyIncreasingTimeInMs(); | 4267 double start_ms = MonotonicallyIncreasingTimeInMs(); |
4267 double idle_time_in_ms = deadline_in_ms - start_ms; | 4268 double idle_time_in_ms = deadline_in_ms - start_ms; |
4268 | 4269 |
4269 CheckAndNotifyBackgroundIdleNotification(idle_time_in_ms, start_ms); | 4270 CheckAndNotifyBackgroundIdleNotification(idle_time_in_ms, start_ms); |
4270 | 4271 |
4271 tracer()->SampleAllocation(start_ms, NewSpaceAllocationCounter(), | 4272 tracer()->SampleAllocation(start_ms, NewSpaceAllocationCounter(), |
4272 OldGenerationAllocationCounter()); | 4273 OldGenerationAllocationCounter()); |
4273 | 4274 |
4274 GCIdleTimeHandler::HeapState heap_state = ComputeHeapState(); | 4275 GCIdleTimeHeapState heap_state = ComputeHeapState(); |
4275 | 4276 |
4276 GCIdleTimeAction action = | 4277 GCIdleTimeAction action = |
4277 gc_idle_time_handler_.Compute(idle_time_in_ms, heap_state); | 4278 gc_idle_time_handler_->Compute(idle_time_in_ms, heap_state); |
4278 | 4279 |
4279 bool result = PerformIdleTimeAction(action, heap_state, deadline_in_ms); | 4280 bool result = PerformIdleTimeAction(action, heap_state, deadline_in_ms); |
4280 | 4281 |
4281 IdleNotificationEpilogue(action, heap_state, start_ms, deadline_in_ms); | 4282 IdleNotificationEpilogue(action, heap_state, start_ms, deadline_in_ms); |
4282 return result; | 4283 return result; |
4283 } | 4284 } |
4284 | 4285 |
4285 | 4286 |
4286 bool Heap::RecentIdleNotificationHappened() { | 4287 bool Heap::RecentIdleNotificationHappened() { |
4287 return (last_idle_notification_time_ + | 4288 return (last_idle_notification_time_ + |
(...skipping 781 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5069 | 5070 |
5070 for (int i = 0; i < static_cast<int>(v8::Isolate::kUseCounterFeatureCount); | 5071 for (int i = 0; i < static_cast<int>(v8::Isolate::kUseCounterFeatureCount); |
5071 i++) { | 5072 i++) { |
5072 deferred_counters_[i] = 0; | 5073 deferred_counters_[i] = 0; |
5073 } | 5074 } |
5074 | 5075 |
5075 tracer_ = new GCTracer(this); | 5076 tracer_ = new GCTracer(this); |
5076 | 5077 |
5077 scavenge_collector_ = new Scavenger(this); | 5078 scavenge_collector_ = new Scavenger(this); |
5078 | 5079 |
| 5080 gc_idle_time_handler_ = new GCIdleTimeHandler(); |
| 5081 |
5079 memory_reducer_ = new MemoryReducer(this); | 5082 memory_reducer_ = new MemoryReducer(this); |
5080 | 5083 |
5081 object_stats_ = new ObjectStats(this); | 5084 object_stats_ = new ObjectStats(this); |
5082 object_stats_->ClearObjectStats(true); | 5085 object_stats_->ClearObjectStats(true); |
5083 | 5086 |
5084 array_buffer_tracker_ = new ArrayBufferTracker(this); | 5087 array_buffer_tracker_ = new ArrayBufferTracker(this); |
5085 | 5088 |
5086 LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity())); | 5089 LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity())); |
5087 LOG(isolate_, IntPtrTEvent("heap-available", Available())); | 5090 LOG(isolate_, IntPtrTEvent("heap-available", Available())); |
5088 | 5091 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5183 PrintF("\n\n"); | 5186 PrintF("\n\n"); |
5184 } | 5187 } |
5185 | 5188 |
5186 if (FLAG_verify_predictable) { | 5189 if (FLAG_verify_predictable) { |
5187 PrintAlloctionsHash(); | 5190 PrintAlloctionsHash(); |
5188 } | 5191 } |
5189 | 5192 |
5190 delete scavenge_collector_; | 5193 delete scavenge_collector_; |
5191 scavenge_collector_ = nullptr; | 5194 scavenge_collector_ = nullptr; |
5192 | 5195 |
| 5196 delete gc_idle_time_handler_; |
| 5197 gc_idle_time_handler_ = nullptr; |
| 5198 |
5193 if (memory_reducer_ != nullptr) { | 5199 if (memory_reducer_ != nullptr) { |
5194 memory_reducer_->TearDown(); | 5200 memory_reducer_->TearDown(); |
5195 delete memory_reducer_; | 5201 delete memory_reducer_; |
5196 memory_reducer_ = nullptr; | 5202 memory_reducer_ = nullptr; |
5197 } | 5203 } |
5198 | 5204 |
5199 delete object_stats_; | 5205 delete object_stats_; |
5200 object_stats_ = nullptr; | 5206 object_stats_ = nullptr; |
5201 | 5207 |
5202 WaitUntilUnmappingOfFreeChunksCompleted(); | 5208 WaitUntilUnmappingOfFreeChunksCompleted(); |
(...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6105 } | 6111 } |
6106 | 6112 |
6107 | 6113 |
6108 // static | 6114 // static |
6109 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6115 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6110 return StaticVisitorBase::GetVisitorId(map); | 6116 return StaticVisitorBase::GetVisitorId(map); |
6111 } | 6117 } |
6112 | 6118 |
6113 } // namespace internal | 6119 } // namespace internal |
6114 } // namespace v8 | 6120 } // namespace v8 |
OLD | NEW |