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 |