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 : // If contexts are disposed at a higher rate a full gc is triggered.
111 : static const double kHighContextDisposalRate;
112 :
113 : // Incremental marking step time.
114 : static const size_t kIncrementalMarkingStepTimeInMs = 1;
115 :
116 : static const size_t kMinTimeForOverApproximatingWeakClosureInMs;
117 :
118 : // Number of times we will return a Nothing action in the current mode
119 : // despite having idle time available before we returning a Done action to
120 : // ensure we don't keep scheduling idle tasks and making no progress.
121 : static const int kMaxNoProgressIdleTimes = 10;
122 :
123 60782 : GCIdleTimeHandler() : idle_times_which_made_no_progress_(0) {}
124 :
125 : GCIdleTimeAction Compute(double idle_time_in_ms,
126 : GCIdleTimeHeapState heap_state);
127 :
128 : bool Enabled();
129 :
130 6 : void ResetNoProgressCounter() { idle_times_which_made_no_progress_ = 0; }
131 :
132 : static size_t EstimateMarkingStepSize(double idle_time_in_ms,
133 : double marking_speed_in_bytes_per_ms);
134 :
135 : static double EstimateFinalIncrementalMarkCompactTime(
136 : size_t size_of_objects, double mark_compact_speed_in_bytes_per_ms);
137 :
138 : static bool ShouldDoContextDisposalMarkCompact(int context_disposed,
139 : double contexts_disposal_rate);
140 :
141 : static bool ShouldDoFinalIncrementalMarkCompact(
142 : double idle_time_in_ms, size_t size_of_objects,
143 : double final_incremental_mark_compact_speed_in_bytes_per_ms);
144 :
145 : static bool ShouldDoOverApproximateWeakClosure(double idle_time_in_ms);
146 :
147 : private:
148 : GCIdleTimeAction NothingOrDone(double idle_time_in_ms);
149 :
150 : // Idle notifications with no progress.
151 : int idle_times_which_made_no_progress_;
152 :
153 : DISALLOW_COPY_AND_ASSIGN(GCIdleTimeHandler);
154 : };
155 :
156 : } // namespace internal
157 : } // namespace v8
158 :
159 : #endif // V8_HEAP_GC_IDLE_TIME_HANDLER_H_
|