| 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 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 total_gc_time_ms_(0.0), | 117 total_gc_time_ms_(0.0), |
| 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_(nullptr), | 125 mark_compact_collector_(nullptr), |
| 126 store_buffer_(this), | 126 store_buffer_(this), |
| 127 incremental_marking_(this), | 127 incremental_marking_(nullptr), |
| 128 gc_idle_time_handler_(nullptr), | 128 gc_idle_time_handler_(nullptr), |
| 129 memory_reducer_(nullptr), | 129 memory_reducer_(nullptr), |
| 130 object_stats_(nullptr), | 130 object_stats_(nullptr), |
| 131 scavenge_job_(nullptr), | 131 scavenge_job_(nullptr), |
| 132 full_codegen_bytes_generated_(0), | 132 full_codegen_bytes_generated_(0), |
| 133 crankshaft_codegen_bytes_generated_(0), | 133 crankshaft_codegen_bytes_generated_(0), |
| 134 new_space_allocation_counter_(0), | 134 new_space_allocation_counter_(0), |
| 135 old_generation_allocation_counter_(0), | 135 old_generation_allocation_counter_(0), |
| 136 old_generation_size_at_last_gc_(0), | 136 old_generation_size_at_last_gc_(0), |
| 137 gcs_since_last_deopt_(0), | 137 gcs_since_last_deopt_(0), |
| (...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 858 attempt + 1 >= kMinNumberOfAttempts) { | 858 attempt + 1 >= kMinNumberOfAttempts) { |
| 859 break; | 859 break; |
| 860 } | 860 } |
| 861 } | 861 } |
| 862 set_current_gc_flags(kNoGCFlags); | 862 set_current_gc_flags(kNoGCFlags); |
| 863 new_space_.Shrink(); | 863 new_space_.Shrink(); |
| 864 UncommitFromSpace(); | 864 UncommitFromSpace(); |
| 865 } | 865 } |
| 866 | 866 |
| 867 | 867 |
| 868 void Heap::ReportExternalMemoryPressure(const char* gc_reason) { |
| 869 if (incremental_marking()->IsStopped()) { |
| 870 if (incremental_marking()->CanBeActivated()) { |
| 871 StartIncrementalMarking( |
| 872 i::Heap::kNoGCFlags, |
| 873 kGCCallbackFlagSynchronousPhantomCallbackProcessing, gc_reason); |
| 874 } else { |
| 875 CollectAllGarbage(i::Heap::kNoGCFlags, gc_reason, |
| 876 kGCCallbackFlagSynchronousPhantomCallbackProcessing); |
| 877 } |
| 878 } else { |
| 879 // Incremental marking is turned on an has already been started. |
| 880 |
| 881 // TODO(mlippautz): Compute the time slice for incremental marking based on |
| 882 // memory pressure. |
| 883 double deadline = MonotonicallyIncreasingTimeInMs() + |
| 884 FLAG_external_allocation_limit_incremental_time; |
| 885 incremental_marking()->AdvanceIncrementalMarking( |
| 886 0, deadline, |
| 887 IncrementalMarking::StepActions(IncrementalMarking::GC_VIA_STACK_GUARD, |
| 888 IncrementalMarking::FORCE_MARKING, |
| 889 IncrementalMarking::FORCE_COMPLETION)); |
| 890 } |
| 891 } |
| 892 |
| 893 |
| 868 void Heap::EnsureFillerObjectAtTop() { | 894 void Heap::EnsureFillerObjectAtTop() { |
| 869 // There may be an allocation memento behind every object in new space. | 895 // There may be an allocation memento behind every object in new space. |
| 870 // If we evacuate a not full new space or if we are on the last page of | 896 // If we evacuate a not full new space or if we are on the last page of |
| 871 // the new space, then there may be uninitialized memory behind the top | 897 // the new space, then there may be uninitialized memory behind the top |
| 872 // pointer of the new space page. We store a filler object there to | 898 // pointer of the new space page. We store a filler object there to |
| 873 // identify the unused space. | 899 // identify the unused space. |
| 874 Address from_top = new_space_.top(); | 900 Address from_top = new_space_.top(); |
| 875 // Check that from_top is inside its page (i.e., not at the end). | 901 // Check that from_top is inside its page (i.e., not at the end). |
| 876 Address space_end = new_space_.ToSpaceEnd(); | 902 Address space_end = new_space_.ToSpaceEnd(); |
| 877 if (from_top < space_end) { | 903 if (from_top < space_end) { |
| (...skipping 3226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4104 heap_state.contexts_disposed = contexts_disposed_; | 4130 heap_state.contexts_disposed = contexts_disposed_; |
| 4105 heap_state.contexts_disposal_rate = | 4131 heap_state.contexts_disposal_rate = |
| 4106 tracer()->ContextDisposalRateInMilliseconds(); | 4132 tracer()->ContextDisposalRateInMilliseconds(); |
| 4107 heap_state.incremental_marking_stopped = incremental_marking()->IsStopped(); | 4133 heap_state.incremental_marking_stopped = incremental_marking()->IsStopped(); |
| 4108 heap_state.mark_compact_speed_in_bytes_per_ms = | 4134 heap_state.mark_compact_speed_in_bytes_per_ms = |
| 4109 static_cast<size_t>(tracer()->MarkCompactSpeedInBytesPerMillisecond()); | 4135 static_cast<size_t>(tracer()->MarkCompactSpeedInBytesPerMillisecond()); |
| 4110 return heap_state; | 4136 return heap_state; |
| 4111 } | 4137 } |
| 4112 | 4138 |
| 4113 | 4139 |
| 4114 double Heap::AdvanceIncrementalMarking( | |
| 4115 intptr_t step_size_in_bytes, double deadline_in_ms, | |
| 4116 IncrementalMarking::StepActions step_actions) { | |
| 4117 DCHECK(!incremental_marking()->IsStopped()); | |
| 4118 | |
| 4119 if (step_size_in_bytes == 0) { | |
| 4120 step_size_in_bytes = GCIdleTimeHandler::EstimateMarkingStepSize( | |
| 4121 static_cast<size_t>(GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs), | |
| 4122 static_cast<size_t>( | |
| 4123 tracer()->FinalIncrementalMarkCompactSpeedInBytesPerMillisecond())); | |
| 4124 } | |
| 4125 | |
| 4126 double remaining_time_in_ms = 0.0; | |
| 4127 do { | |
| 4128 incremental_marking()->Step( | |
| 4129 step_size_in_bytes, step_actions.completion_action, | |
| 4130 step_actions.force_marking, step_actions.force_completion); | |
| 4131 remaining_time_in_ms = deadline_in_ms - MonotonicallyIncreasingTimeInMs(); | |
| 4132 } while (remaining_time_in_ms >= | |
| 4133 2.0 * GCIdleTimeHandler::kIncrementalMarkingStepTimeInMs && | |
| 4134 !incremental_marking()->IsComplete() && | |
| 4135 !mark_compact_collector()->marking_deque()->IsEmpty()); | |
| 4136 return remaining_time_in_ms; | |
| 4137 } | |
| 4138 | |
| 4139 | |
| 4140 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, | 4140 bool Heap::PerformIdleTimeAction(GCIdleTimeAction action, |
| 4141 GCIdleTimeHeapState heap_state, | 4141 GCIdleTimeHeapState heap_state, |
| 4142 double deadline_in_ms) { | 4142 double deadline_in_ms) { |
| 4143 bool result = false; | 4143 bool result = false; |
| 4144 switch (action.type) { | 4144 switch (action.type) { |
| 4145 case DONE: | 4145 case DONE: |
| 4146 result = true; | 4146 result = true; |
| 4147 break; | 4147 break; |
| 4148 case DO_INCREMENTAL_STEP: { | 4148 case DO_INCREMENTAL_STEP: { |
| 4149 if (incremental_marking()->incremental_marking_job()->IdleTaskPending()) { | 4149 if (incremental_marking()->incremental_marking_job()->IdleTaskPending()) { |
| (...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5027 } | 5027 } |
| 5028 | 5028 |
| 5029 concurrent_sweeping_enabled_ = FLAG_concurrent_sweeping; | 5029 concurrent_sweeping_enabled_ = FLAG_concurrent_sweeping; |
| 5030 | 5030 |
| 5031 base::CallOnce(&initialize_gc_once, &InitializeGCOnce); | 5031 base::CallOnce(&initialize_gc_once, &InitializeGCOnce); |
| 5032 | 5032 |
| 5033 // Set up memory allocator. | 5033 // Set up memory allocator. |
| 5034 if (!isolate_->memory_allocator()->SetUp(MaxReserved(), MaxExecutableSize())) | 5034 if (!isolate_->memory_allocator()->SetUp(MaxReserved(), MaxExecutableSize())) |
| 5035 return false; | 5035 return false; |
| 5036 | 5036 |
| 5037 // Initialize incremental marking. |
| 5038 incremental_marking_ = new IncrementalMarking(this); |
| 5039 |
| 5037 // Set up new space. | 5040 // Set up new space. |
| 5038 if (!new_space_.SetUp(reserved_semispace_size_, max_semi_space_size_)) { | 5041 if (!new_space_.SetUp(reserved_semispace_size_, max_semi_space_size_)) { |
| 5039 return false; | 5042 return false; |
| 5040 } | 5043 } |
| 5041 new_space_top_after_last_gc_ = new_space()->top(); | 5044 new_space_top_after_last_gc_ = new_space()->top(); |
| 5042 | 5045 |
| 5043 // Initialize old space. | 5046 // Initialize old space. |
| 5044 old_space_ = new OldSpace(this, OLD_SPACE, NOT_EXECUTABLE); | 5047 old_space_ = new OldSpace(this, OLD_SPACE, NOT_EXECUTABLE); |
| 5045 if (old_space_ == NULL) return false; | 5048 if (old_space_ == NULL) return false; |
| 5046 if (!old_space_->SetUp()) return false; | 5049 if (!old_space_->SetUp()) return false; |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5206 | 5209 |
| 5207 delete scavenge_collector_; | 5210 delete scavenge_collector_; |
| 5208 scavenge_collector_ = nullptr; | 5211 scavenge_collector_ = nullptr; |
| 5209 | 5212 |
| 5210 if (mark_compact_collector_ != nullptr) { | 5213 if (mark_compact_collector_ != nullptr) { |
| 5211 mark_compact_collector_->TearDown(); | 5214 mark_compact_collector_->TearDown(); |
| 5212 delete mark_compact_collector_; | 5215 delete mark_compact_collector_; |
| 5213 mark_compact_collector_ = nullptr; | 5216 mark_compact_collector_ = nullptr; |
| 5214 } | 5217 } |
| 5215 | 5218 |
| 5219 delete incremental_marking_; |
| 5220 incremental_marking_ = nullptr; |
| 5221 |
| 5216 delete gc_idle_time_handler_; | 5222 delete gc_idle_time_handler_; |
| 5217 gc_idle_time_handler_ = nullptr; | 5223 gc_idle_time_handler_ = nullptr; |
| 5218 | 5224 |
| 5219 if (memory_reducer_ != nullptr) { | 5225 if (memory_reducer_ != nullptr) { |
| 5220 memory_reducer_->TearDown(); | 5226 memory_reducer_->TearDown(); |
| 5221 delete memory_reducer_; | 5227 delete memory_reducer_; |
| 5222 memory_reducer_ = nullptr; | 5228 memory_reducer_ = nullptr; |
| 5223 } | 5229 } |
| 5224 | 5230 |
| 5225 delete object_stats_; | 5231 delete object_stats_; |
| (...skipping 906 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6132 } | 6138 } |
| 6133 | 6139 |
| 6134 | 6140 |
| 6135 // static | 6141 // static |
| 6136 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6142 int Heap::GetStaticVisitorIdForMap(Map* map) { |
| 6137 return StaticVisitorBase::GetVisitorId(map); | 6143 return StaticVisitorBase::GetVisitorId(map); |
| 6138 } | 6144 } |
| 6139 | 6145 |
| 6140 } // namespace internal | 6146 } // namespace internal |
| 6141 } // namespace v8 | 6147 } // namespace v8 |
| OLD | NEW |