| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/memory-reducer.h" | 5 #include "src/heap/memory-reducer.h" |
| 6 | 6 |
| 7 #include "src/flags.h" | 7 #include "src/flags.h" |
| 8 #include "src/heap/heap.h" | 8 #include "src/heap/heap.h" |
| 9 #include "src/utils.h" | 9 #include "src/utils.h" |
| 10 #include "src/v8.h" | 10 #include "src/v8.h" |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 75 DCHECK_EQ(kContextDisposed, event.type); | 75 DCHECK_EQ(kContextDisposed, event.type); |
| 76 Action old_action = state_.action; | 76 Action old_action = state_.action; |
| 77 state_ = Step(state_, event); | 77 state_ = Step(state_, event); |
| 78 if (old_action != kWait && state_.action == kWait) { | 78 if (old_action != kWait && state_.action == kWait) { |
| 79 // If we are transitioning to the WAIT state, start the timer. | 79 // If we are transitioning to the WAIT state, start the timer. |
| 80 ScheduleTimer(state_.next_gc_start_ms - event.time_ms); | 80 ScheduleTimer(state_.next_gc_start_ms - event.time_ms); |
| 81 } | 81 } |
| 82 } | 82 } |
| 83 | 83 |
| 84 | 84 |
| 85 void MemoryReducer::NotifyBackgroundIdleNotification(const Event& event) { |
| 86 DCHECK_EQ(kBackgroundIdleNotification, event.type); |
| 87 Action old_action = state_.action; |
| 88 int old_started_gcs = state_.started_gcs; |
| 89 state_ = Step(state_, event); |
| 90 if (old_action == kWait && state_.action == kWait && |
| 91 old_started_gcs + 1 == state_.started_gcs) { |
| 92 DCHECK(heap()->incremental_marking()->IsStopped()); |
| 93 DCHECK(FLAG_incremental_marking); |
| 94 heap()->StartIdleIncrementalMarking(); |
| 95 if (FLAG_trace_gc_verbose) { |
| 96 PrintIsolate(heap()->isolate(), |
| 97 "Memory reducer: started GC #%d" |
| 98 " (background idle)\n", |
| 99 state_.started_gcs); |
| 100 } |
| 101 } |
| 102 } |
| 103 |
| 104 |
| 85 // For specification of this function see the comment for MemoryReducer class. | 105 // For specification of this function see the comment for MemoryReducer class. |
| 86 MemoryReducer::State MemoryReducer::Step(const State& state, | 106 MemoryReducer::State MemoryReducer::Step(const State& state, |
| 87 const Event& event) { | 107 const Event& event) { |
| 88 if (!FLAG_incremental_marking) { | 108 if (!FLAG_incremental_marking) { |
| 89 return State(kDone, 0, 0); | 109 return State(kDone, 0, 0); |
| 90 } | 110 } |
| 91 switch (state.action) { | 111 switch (state.action) { |
| 92 case kDone: | 112 case kDone: |
| 93 if (event.type == kTimer) { | 113 if (event.type == kTimer || event.type == kBackgroundIdleNotification) { |
| 94 return state; | 114 return state; |
| 95 } else { | 115 } else { |
| 96 DCHECK(event.type == kContextDisposed || event.type == kMarkCompact); | 116 DCHECK(event.type == kContextDisposed || event.type == kMarkCompact); |
| 97 return State(kWait, 0, event.time_ms + kLongDelayMs); | 117 return State(kWait, 0, event.time_ms + kLongDelayMs); |
| 98 } | 118 } |
| 99 case kWait: | 119 case kWait: |
| 100 if (event.type == kContextDisposed) { | 120 switch (event.type) { |
| 101 return state; | 121 case kContextDisposed: |
| 102 } else if (event.type == kTimer && event.can_start_incremental_gc && | |
| 103 event.low_allocation_rate) { | |
| 104 if (state.next_gc_start_ms <= event.time_ms) { | |
| 105 return State(kRun, state.started_gcs + 1, 0.0); | |
| 106 } else { | |
| 107 return state; | 122 return state; |
| 108 } | 123 case kTimer: |
| 109 } else { | 124 if (state.started_gcs >= kMaxNumberOfGCs) { |
| 110 return State(kWait, state.started_gcs, event.time_ms + kLongDelayMs); | 125 return State(kDone, 0, 0.0); |
| 126 } else if (event.can_start_incremental_gc && |
| 127 event.low_allocation_rate) { |
| 128 if (state.next_gc_start_ms <= event.time_ms) { |
| 129 return State(kRun, state.started_gcs + 1, 0.0); |
| 130 } else { |
| 131 return state; |
| 132 } |
| 133 } else { |
| 134 return State(kWait, state.started_gcs, |
| 135 event.time_ms + kLongDelayMs); |
| 136 } |
| 137 case kBackgroundIdleNotification: |
| 138 if (event.can_start_incremental_gc && |
| 139 state.started_gcs < kMaxNumberOfGCs) { |
| 140 return State(kWait, state.started_gcs + 1, |
| 141 event.time_ms + kLongDelayMs); |
| 142 } else { |
| 143 return state; |
| 144 } |
| 145 case kMarkCompact: |
| 146 return State(kWait, state.started_gcs, event.time_ms + kLongDelayMs); |
| 111 } | 147 } |
| 112 case kRun: | 148 case kRun: |
| 113 if (event.type != kMarkCompact) { | 149 if (event.type != kMarkCompact) { |
| 114 return state; | 150 return state; |
| 115 } else { | 151 } else { |
| 116 if (state.started_gcs < kMaxNumberOfGCs && | 152 if (state.started_gcs < kMaxNumberOfGCs && |
| 117 (event.next_gc_likely_to_collect_more || state.started_gcs == 1)) { | 153 (event.next_gc_likely_to_collect_more || state.started_gcs == 1)) { |
| 118 return State(kWait, state.started_gcs, event.time_ms + kShortDelayMs); | 154 return State(kWait, state.started_gcs, event.time_ms + kShortDelayMs); |
| 119 } else { | 155 } else { |
| 120 return State(kDone, 0, 0.0); | 156 return State(kDone, 0, 0.0); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 131 // Leave some room for precision error in task scheduler. | 167 // Leave some room for precision error in task scheduler. |
| 132 const double kSlackMs = 100; | 168 const double kSlackMs = 100; |
| 133 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap()->isolate()); | 169 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap()->isolate()); |
| 134 V8::GetCurrentPlatform()->CallDelayedOnForegroundThread( | 170 V8::GetCurrentPlatform()->CallDelayedOnForegroundThread( |
| 135 isolate, new MemoryReducer::TimerTask(this), | 171 isolate, new MemoryReducer::TimerTask(this), |
| 136 (delay_ms + kSlackMs) / 1000.0); | 172 (delay_ms + kSlackMs) / 1000.0); |
| 137 } | 173 } |
| 138 | 174 |
| 139 } // internal | 175 } // internal |
| 140 } // v8 | 176 } // v8 |
| OLD | NEW |