Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(325)

Side by Side Diff: src/heap/memory-reducer.cc

Issue 1218863002: Replace reduce-memory mode in idle notification with delayed clean-up GC. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: fix int -> double Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 the V8 project authors. All rights reserved.
Hannes Payer (out of office) 2015/07/02 13:19:06 2015
ulan 2015/07/02 13:30:16 Done.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/heap/memory-reducer.h"
6
7 #include "src/flags.h"
8 #include "src/heap/heap.h"
9 #include "src/utils.h"
10 #include "src/v8.h"
11
12 namespace v8 {
13 namespace internal {
14
15 const int MemoryReducer::kLongDelayMs = 5000;
16 const int MemoryReducer::kShortDelayMs = 500;
17 const int MemoryReducer::kMaxNumberOfGCs = 3;
18
19
20 void MemoryReducer::TimerTask::Run() {
21 Heap* heap = memory_reducer_->heap();
22 Event event;
23 event.type = kTimer;
24 event.time_ms = heap->MonotonicallyIncreasingTimeInMs();
25 event.high_fragmentation = heap->HasHighFragmentation();
26 event.low_allocation_rate = heap->HasLowAllocationRate();
27 event.incremental_gc_in_progress = !heap->incremental_marking()->IsStopped();
28 memory_reducer_->NotifyTimer(event);
29 }
30
31
32 void MemoryReducer::NotifyTimer(const Event& event) {
33 DCHECK_EQ(kTimer, event.type);
34 DCHECK_EQ(kWait, state_.action);
35 state_ = Step(state_, event);
36 if (state_.action == kRun) {
37 DCHECK(heap()->incremental_marking()->IsStopped());
38 DCHECK(FLAG_incremental_marking);
39 heap()->StartIdleIncrementalMarking();
40 if (FLAG_trace_gc_verbose) {
41 PrintIsolate(heap()->isolate(), "Clean-up GC: started #%d\n",
Hannes Payer (out of office) 2015/07/02 13:19:06 Please don't use the term Cleanup-gc, also below.
ulan 2015/07/02 13:30:16 Done.
42 state_.started_gcs);
43 }
44 } else if (state_.action == kWait) {
45 // Re-schedule the timer.
46 ScheduleTimer(state_.next_gc_start_ms - event.time_ms);
47 if (FLAG_trace_gc_verbose) {
48 PrintIsolate(heap()->isolate(), "Clean-up GC: wait for %.f ms",
49 state_.next_gc_start_ms - event.time_ms);
50 }
51 }
52 }
53
54
55 void MemoryReducer::NotifyMarkCompact(const Event& event) {
56 DCHECK_EQ(kMarkCompact, event.type);
57 Action old_action = state_.action;
58 state_ = Step(state_, event);
59 if (old_action != kWait && state_.action == kWait) {
60 // If we are transitioning to the WAIT state, start the timer.
61 ScheduleTimer(state_.next_gc_start_ms - event.time_ms);
62 }
63 if (old_action == kRun) {
64 if (FLAG_trace_gc_verbose) {
65 PrintIsolate(heap()->isolate(), "Clean-up GC: finished #%d (%s)\n",
66 state_.started_gcs,
67 state_.action == kWait ? "will do more" : "done");
68 }
69 }
70 }
71
72
73 void MemoryReducer::NotifyScavenge(const Event& event) {
74 DCHECK_EQ(kScavenge, event.type);
75 state_ = Step(state_, event);
76 }
77
78
79 void MemoryReducer::NotifyContextDisposed(const Event& event) {
80 DCHECK_EQ(kContextDisposed, event.type);
81 Action old_action = state_.action;
82 state_ = Step(state_, event);
83 if (old_action != kWait && state_.action == kWait) {
84 // If we are transitioning to the WAIT state, start the timer.
85 ScheduleTimer(state_.next_gc_start_ms - event.time_ms);
86 }
87 }
88
89
90 // For specification of this function see the comment for MemoryReducer class.
91 MemoryReducer::State MemoryReducer::Step(const State& state,
92 const Event& event) {
93 if (!FLAG_incremental_marking) {
94 return State(kDone, 0, 0);
95 }
96 switch (state.action) {
97 case kDone:
98 if (event.type == kScavenge || event.type == kTimer) {
99 return state;
100 } else {
101 DCHECK(event.type == kContextDisposed || event.type == kMarkCompact);
102 return State(kWait, 0, event.time_ms + kLongDelayMs);
103 }
104 case kWait:
105 if (event.type == kContextDisposed) {
106 return state;
107 } else if (event.type == kTimer && !event.incremental_gc_in_progress &&
108 (event.low_allocation_rate || event.high_fragmentation)) {
109 if (state.next_gc_start_ms <= event.time_ms) {
110 return State(kRun, state.started_gcs + 1, 0.0);
111 } else {
112 return state;
113 }
114 } else {
115 return State(kWait, state.started_gcs, event.time_ms + kLongDelayMs);
116 }
117 case kRun:
118 if (event.type != kMarkCompact) {
119 return state;
120 } else {
121 if (state.started_gcs < kMaxNumberOfGCs &&
122 (event.next_gc_likely_to_collect_more || state.started_gcs == 1)) {
123 return State(kWait, state.started_gcs, event.time_ms + kShortDelayMs);
124 } else {
125 return State(kDone, 0, 0.0);
126 }
127 }
128 }
129 UNREACHABLE();
130 return State(kDone, 0, 0); // Make the compiler happy.
131 }
132
133
134 void MemoryReducer::ScheduleTimer(double delay_ms) {
135 DCHECK(delay_ms > 0);
136 // Leave some room for precision error in task scheduler.
137 const double kSlackMs = 100;
138 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(heap()->isolate());
139 V8::GetCurrentPlatform()->CallDelayedOnForegroundThread(
140 isolate, new MemoryReducer::TimerTask(this),
141 (delay_ms + kSlackMs) / 1000.0);
142 }
143
144 } // internal
145 } // v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698