Line data Source code
1 : // Copyright 2014 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_HEAP_GC_IDLE_TIME_HANDLER_H_
6 : #define V8_HEAP_GC_IDLE_TIME_HANDLER_H_
7 :
8 : #include "src/globals.h"
9 :
10 : namespace v8 {
11 : namespace internal {
12 :
13 : enum GCIdleTimeActionType {
14 : DONE,
15 : DO_NOTHING,
16 : DO_INCREMENTAL_STEP,
17 : DO_FULL_GC,
18 : };
19 :
20 :
21 : class GCIdleTimeAction {
22 : public:
23 : static GCIdleTimeAction Done() {
24 : GCIdleTimeAction result;
25 : result.type = DONE;
26 : result.additional_work = false;
27 : return result;
28 : }
29 :
30 : static GCIdleTimeAction Nothing() {
31 : GCIdleTimeAction result;
32 : result.type = DO_NOTHING;
33 : result.additional_work = false;
34 : return result;
35 : }
36 :
37 : static GCIdleTimeAction IncrementalStep() {
38 : GCIdleTimeAction result;
39 : result.type = DO_INCREMENTAL_STEP;
40 : result.additional_work = false;
41 : return result;
42 : }
43 :
44 : static GCIdleTimeAction FullGC() {
45 : GCIdleTimeAction result;
46 : result.type = DO_FULL_GC;
47 : result.additional_work = false;
48 : return result;
49 : }
50 :
51 : void Print();
52 :
53 : GCIdleTimeActionType type;
54 : bool additional_work;
55 : };
56 :
57 :
58 : class GCIdleTimeHeapState {
59 : public:
60 : void Print();
61 :
62 : int contexts_disposed;
63 : double contexts_disposal_rate;
64 : size_t size_of_objects;
65 : bool incremental_marking_stopped;
66 : };
67 :
68 :
69 : // The idle time handler makes decisions about which garbage collection
70 : // operations are executing during IdleNotification.
71 : class V8_EXPORT_PRIVATE GCIdleTimeHandler {
72 : public:
73 : // If we haven't recorded any incremental marking events yet, we carefully
74 : // mark with a conservative lower bound for the marking speed.
75 : static const size_t kInitialConservativeMarkingSpeed = 100 * KB;
76 :
77 : // Maximum marking step size returned by EstimateMarkingStepSize.
78 : static const size_t kMaximumMarkingStepSize = 700 * MB;
79 :
80 : // We have to make sure that we finish the IdleNotification before
81 : // idle_time_in_ms. Hence, we conservatively prune our workload estimate.
82 : static const double kConservativeTimeRatio;
83 :
84 : // If we haven't recorded any mark-compact events yet, we use
85 : // conservative lower bound for the mark-compact speed.
86 : static const size_t kInitialConservativeMarkCompactSpeed = 2 * MB;
87 :
88 : // If we haven't recorded any final incremental mark-compact events yet, we
89 : // use conservative lower bound for the mark-compact speed.
90 : static const size_t kInitialConservativeFinalIncrementalMarkCompactSpeed =
91 : 2 * MB;
92 :
93 : // Maximum final incremental mark-compact time returned by
94 : // EstimateFinalIncrementalMarkCompactTime.
95 : static const size_t kMaxFinalIncrementalMarkCompactTimeInMs;
96 :
97 : // This is the maximum scheduled idle time. Note that it can be more than
98 : // 16.66 ms when there is currently no rendering going on.
99 : static const size_t kMaxScheduledIdleTime = 50;
100 :
101 : // The maximum idle time when frames are rendered is 16.66ms.
102 : static const size_t kMaxFrameRenderingIdleTime = 17;
103 :
104 : static const int kMinBackgroundIdleTime = 900;
105 :
106 : // An allocation throughput below kLowAllocationThroughput bytes/ms is
107 : // considered low
108 : static const size_t kLowAllocationThroughput = 1000;
109 :
110 : static const size_t kMaxHeapSizeForContextDisposalMarkCompact = 100 * MB;
111 :
112 : // If contexts are disposed at a higher rate a full gc is triggered.
113 : static const double kHighContextDisposalRate;
114 :
115 : // Incremental marking step time.
116 : static const size_t kIncrementalMarkingStepTimeInMs = 1;
117 :
118 : static const size_t kMinTimeForOverApproximatingWeakClosureInMs;
119 :
120 : // Number of times we will return a Nothing action in the current mode
121 : // despite having idle time available before we returning a Done action to
122 : // ensure we don't keep scheduling idle tasks and making no progress.
123 : static const int kMaxNoProgressIdleTimes = 10;
124 :
125 62898 : GCIdleTimeHandler() : idle_times_which_made_no_progress_(0) {}
126 :
127 : GCIdleTimeAction Compute(double idle_time_in_ms,
128 : GCIdleTimeHeapState heap_state);
129 :
130 : bool Enabled();
131 :
132 10 : void ResetNoProgressCounter() { idle_times_which_made_no_progress_ = 0; }
133 :
134 : static size_t EstimateMarkingStepSize(double idle_time_in_ms,
135 : double marking_speed_in_bytes_per_ms);
136 :
137 : static double EstimateFinalIncrementalMarkCompactTime(
138 : size_t size_of_objects, double mark_compact_speed_in_bytes_per_ms);
139 :
140 : static bool ShouldDoContextDisposalMarkCompact(int context_disposed,
141 : double contexts_disposal_rate,
142 : size_t size_of_objects);
143 :
144 : static bool ShouldDoFinalIncrementalMarkCompact(
145 : double idle_time_in_ms, size_t size_of_objects,
146 : double final_incremental_mark_compact_speed_in_bytes_per_ms);
147 :
148 : static bool ShouldDoOverApproximateWeakClosure(double idle_time_in_ms);
149 :
150 : private:
151 : GCIdleTimeAction NothingOrDone(double idle_time_in_ms);
152 :
153 : // Idle notifications with no progress.
154 : int idle_times_which_made_no_progress_;
155 :
156 : DISALLOW_COPY_AND_ASSIGN(GCIdleTimeHandler);
157 : };
158 :
159 : } // namespace internal
160 : } // namespace v8
161 :
162 : #endif // V8_HEAP_GC_IDLE_TIME_HANDLER_H_
|