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

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

Issue 1262363002: Ensure the memory reduces makes progress. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 4 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
« no previous file with comments | « no previous file | src/heap/memory-reducer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 #ifndef V8_HEAP_memory_reducer_H 5 #ifndef V8_HEAP_memory_reducer_H
6 #define V8_HEAP_memory_reducer_H 6 #define V8_HEAP_memory_reducer_H
7 7
8 #include "include/v8-platform.h" 8 #include "include/v8-platform.h"
9 #include "src/base/macros.h" 9 #include "src/base/macros.h"
10 #include "src/cancelable-task.h" 10 #include "src/cancelable-task.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 14
15 class Heap; 15 class Heap;
16 16
17 17
18 // The goal of the MemoryReducer class is to detect transition of the mutator 18 // The goal of the MemoryReducer class is to detect transition of the mutator
19 // from high allocation phase to low allocation phase and to collect potential 19 // from high allocation phase to low allocation phase and to collect potential
20 // garbage created in the high allocation phase. 20 // garbage created in the high allocation phase.
21 // 21 //
22 // The class implements an automaton with the following states and transitions. 22 // The class implements an automaton with the following states and transitions.
23 // 23 //
24 // States: 24 // States:
25 // - DONE 25 // - DONE <last_gc_time_ms>
26 // - WAIT <started_gcs> <next_gc_start_ms> 26 // - WAIT <started_gcs> <next_gc_start_ms> <last_gc_time_ms>
27 // - RUN <started_gcs> 27 // - RUN <started_gcs> <last_gc_time_ms>
28 // The <started_gcs> is an integer in range from 0..kMaxNumberOfGCs that stores 28 // The <started_gcs> is an integer in range from 0..kMaxNumberOfGCs that stores
29 // the number of GCs initiated by the MemoryReducer since it left the DONE 29 // the number of GCs initiated by the MemoryReducer since it left the DONE
30 // state. 30 // state.
31 // The <next_gc_start_ms> is a double that stores the earliest time the next GC 31 // The <next_gc_start_ms> is a double that stores the earliest time the next GC
32 // can be initiated by the MemoryReducer. 32 // can be initiated by the MemoryReducer.
33 // The <last_gc_start_ms> is a double that stores the time of the last full GC.
33 // The DONE state means that the MemoryReducer is not active. 34 // The DONE state means that the MemoryReducer is not active.
34 // The WAIT state means that the MemoryReducer is waiting for mutator allocation 35 // The WAIT state means that the MemoryReducer is waiting for mutator allocation
35 // rate to drop. The check for the allocation rate happens in the timer task 36 // rate to drop. The check for the allocation rate happens in the timer task
36 // callback. 37 // callback. If the allocation rate does not drop in watchdog_delay_ms since
38 // the last GC then transition to the RUN state is forced.
37 // The RUN state means that the MemoryReducer started incremental marking and is 39 // The RUN state means that the MemoryReducer started incremental marking and is
38 // waiting for it to finish. Incremental marking steps are performed as usual 40 // waiting for it to finish. Incremental marking steps are performed as usual
39 // in the idle notification and in the mutator. 41 // in the idle notification and in the mutator.
40 // 42 //
41 // Transitions: 43 // Transitions:
42 // DONE -> WAIT 0 (now_ms + long_delay_ms) happens: 44 // DONE t -> WAIT 0 (now_ms + long_delay_ms) t' happens:
43 // - on context disposal, 45 // - on context disposal.
44 // - at the end of mark-compact GC initiated by the mutator. 46 // - at the end of mark-compact GC initiated by the mutator.
45 // This signals that there is potential garbage to be collected. 47 // This signals that there is potential garbage to be collected.
46 // 48 //
47 // WAIT n x -> WAIT n (now_ms + long_delay_ms) happens: 49 // WAIT n x t -> WAIT n (now_ms + long_delay_ms) t' happens:
48 // - on mark-compact GC initiated by the mutator, 50 // - on mark-compact GC initiated by the mutator,
49 // - in the timer callback if the mutator allocation rate is high or 51 // - in the timer callback if the mutator allocation rate is high or
50 // incremental GC is in progress. 52 // incremental GC is in progress or (now_ms - t < watchdog_delay_ms)
51 // 53 //
52 // WAIT n x -> WAIT (n+1) happens: 54 // WAIT n x t -> WAIT (n+1) t happens:
53 // - on background idle notification, which signals that we can start 55 // - on background idle notification, which signals that we can start
54 // incremental marking even if the allocation rate is high. 56 // incremental marking even if the allocation rate is high.
55 // The MemoryReducer starts incremental marking on this transition but still 57 // The MemoryReducer starts incremental marking on this transition but still
56 // has a pending timer task. 58 // has a pending timer task.
57 // 59 //
58 // WAIT n x -> DONE happens: 60 // WAIT n x t -> DONE t happens:
59 // - in the timer callback if n >= kMaxNumberOfGCs. 61 // - in the timer callback if n >= kMaxNumberOfGCs.
60 // 62 //
61 // WAIT n x -> RUN (n+1) happens: 63 // WAIT n x t -> RUN (n+1) t happens:
62 // - in the timer callback if the mutator allocation rate is low 64 // - in the timer callback if the mutator allocation rate is low
63 // and now_ms >= x and there is no incremental GC in progress. 65 // and now_ms >= x and there is no incremental GC in progress.
66 // - in the timer callback if (now_ms - t > watchdog_delay_ms) and
67 // and now_ms >= x and there is no incremental GC in progress.
64 // The MemoryReducer starts incremental marking on this transition. 68 // The MemoryReducer starts incremental marking on this transition.
65 // 69 //
66 // RUN n -> DONE happens: 70 // RUN n t -> DONE now_ms happens:
67 // - at end of the incremental GC initiated by the MemoryReducer if 71 // - at end of the incremental GC initiated by the MemoryReducer if
68 // (n > 1 and there is no more garbage to be collected) or 72 // (n > 1 and there is no more garbage to be collected) or
69 // n == kMaxNumberOfGCs. 73 // n == kMaxNumberOfGCs.
70 // RUN n -> WAIT n (now_ms + short_delay_ms) happens: 74 // RUN n t -> WAIT n (now_ms + short_delay_ms) now_ms happens:
71 // - at end of the incremental GC initiated by the MemoryReducer if 75 // - at end of the incremental GC initiated by the MemoryReducer if
72 // (n == 1 or there is more garbage to be collected) and 76 // (n == 1 or there is more garbage to be collected) and
73 // n < kMaxNumberOfGCs. 77 // n < kMaxNumberOfGCs.
74 // 78 //
75 // now_ms is the current time, long_delay_ms and short_delay_ms are constants. 79 // now_ms is the current time,
80 // t' is t if the current event is not a GC event and is now_ms otherwise,
81 // long_delay_ms, short_delay_ms, and watchdog_delay_ms are constants.
76 class MemoryReducer { 82 class MemoryReducer {
77 public: 83 public:
78 enum Action { kDone, kWait, kRun }; 84 enum Action { kDone, kWait, kRun };
79 85
80 struct State { 86 struct State {
81 State(Action action, int started_gcs, double next_gc_start_ms) 87 State(Action action, int started_gcs, double next_gc_start_ms,
88 double last_gc_time_ms)
82 : action(action), 89 : action(action),
83 started_gcs(started_gcs), 90 started_gcs(started_gcs),
84 next_gc_start_ms(next_gc_start_ms) {} 91 next_gc_start_ms(next_gc_start_ms),
92 last_gc_time_ms(last_gc_time_ms) {}
85 Action action; 93 Action action;
86 int started_gcs; 94 int started_gcs;
87 double next_gc_start_ms; 95 double next_gc_start_ms;
96 double last_gc_time_ms;
88 }; 97 };
89 98
90 enum EventType { 99 enum EventType {
91 kTimer, 100 kTimer,
92 kMarkCompact, 101 kMarkCompact,
93 kContextDisposed, 102 kContextDisposed,
94 kBackgroundIdleNotification 103 kBackgroundIdleNotification
95 }; 104 };
96 105
97 struct Event { 106 struct Event {
98 EventType type; 107 EventType type;
99 double time_ms; 108 double time_ms;
100 bool low_allocation_rate; 109 bool low_allocation_rate;
101 bool next_gc_likely_to_collect_more; 110 bool next_gc_likely_to_collect_more;
102 bool can_start_incremental_gc; 111 bool can_start_incremental_gc;
103 }; 112 };
104 113
105 explicit MemoryReducer(Heap* heap) : heap_(heap), state_(kDone, 0, 0.0) {} 114 explicit MemoryReducer(Heap* heap)
115 : heap_(heap), state_(kDone, 0, 0.0, 0.0) {}
106 // Callbacks. 116 // Callbacks.
107 void NotifyMarkCompact(const Event& event); 117 void NotifyMarkCompact(const Event& event);
108 void NotifyContextDisposed(const Event& event); 118 void NotifyContextDisposed(const Event& event);
109 void NotifyBackgroundIdleNotification(const Event& event); 119 void NotifyBackgroundIdleNotification(const Event& event);
110 // The step function that computes the next state from the current state and 120 // The step function that computes the next state from the current state and
111 // the incoming event. 121 // the incoming event.
112 static State Step(const State& state, const Event& event); 122 static State Step(const State& state, const Event& event);
113 // Posts a timer task that will call NotifyTimer after the given delay. 123 // Posts a timer task that will call NotifyTimer after the given delay.
114 void ScheduleTimer(double delay_ms); 124 void ScheduleTimer(double delay_ms);
115 void TearDown(); 125 void TearDown();
116 static const int kLongDelayMs; 126 static const int kLongDelayMs;
117 static const int kShortDelayMs; 127 static const int kShortDelayMs;
128 static const int kWatchdogDelayMs;
118 static const int kMaxNumberOfGCs; 129 static const int kMaxNumberOfGCs;
119 130
120 Heap* heap() { return heap_; } 131 Heap* heap() { return heap_; }
121 132
122 private: 133 private:
123 class TimerTask : public v8::internal::CancelableTask { 134 class TimerTask : public v8::internal::CancelableTask {
124 public: 135 public:
125 explicit TimerTask(MemoryReducer* memory_reducer); 136 explicit TimerTask(MemoryReducer* memory_reducer);
126 137
127 private: 138 private:
128 // v8::internal::CancelableTask overrides. 139 // v8::internal::CancelableTask overrides.
129 void RunInternal() override; 140 void RunInternal() override;
130 MemoryReducer* memory_reducer_; 141 MemoryReducer* memory_reducer_;
131 DISALLOW_COPY_AND_ASSIGN(TimerTask); 142 DISALLOW_COPY_AND_ASSIGN(TimerTask);
132 }; 143 };
133 144
134 void NotifyTimer(const Event& event); 145 void NotifyTimer(const Event& event);
135 146
147 static bool WatchdogGC(const State& state, const Event& event);
148
136 Heap* heap_; 149 Heap* heap_;
137 State state_; 150 State state_;
138
139 DISALLOW_COPY_AND_ASSIGN(MemoryReducer); 151 DISALLOW_COPY_AND_ASSIGN(MemoryReducer);
140 }; 152 };
141 153
142 } // namespace internal 154 } // namespace internal
143 } // namespace v8 155 } // namespace v8
144 156
145 #endif // V8_HEAP_memory_reducer_H 157 #endif // V8_HEAP_memory_reducer_H
OLDNEW
« no previous file with comments | « no previous file | src/heap/memory-reducer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698