-
Notifications
You must be signed in to change notification settings - Fork 661
/
Copy pathGCConfig.h
231 lines (200 loc) · 10.9 KB
/
GCConfig.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#ifndef HERMES_PUBLIC_GCCONFIG_H
#define HERMES_PUBLIC_GCCONFIG_H
#include "hermes/Public/CtorConfig.h"
#include "hermes/Public/GCTripwireContext.h"
#include <algorithm>
#include <cassert>
#include <chrono>
#include <cstdint>
#include <functional>
#include <limits>
#include <memory>
#include <string>
#include <vector>
namespace hermes {
namespace vm {
/// A type big enough to accomodate the entire allocated address space.
/// Individual allocations are always 'uint32_t', but on a 64-bit machine we
/// might want to accommodate a larger total heap (or not, in which case we keep
/// it 32-bit).
using gcheapsize_t = uint32_t;
/// Represents a value before and after an event.
/// NOTE: Not a std::pair because using the names are more readable than first
/// and second.
struct BeforeAndAfter {
uint64_t before;
uint64_t after;
};
struct GCAnalyticsEvent {
/// The same value as \p Name from GCConfig. Stored here for simplicity of
/// the API since this is passed in callbacks that might not be able to store
/// the name. For a given Runtime, this will be the same value every time.
std::string runtimeDescription;
/// The kind of GC this was. For a given Runtime, this will be the same value
/// every time.
std::string gcKind;
/// The type of collection that ran, typically differentiating a "young"
/// generation GC and an "old" generation GC. When other values say they're
/// "scoped to the collectionType", it means that for a generation GC
/// they're only reporting the numbers for that generation.
std::string collectionType;
/// The cause of this GC. Can be an arbitrary string describing the cause.
/// Typically "natural" is used to mean that the GC decided it was time, and
/// other causes mean it was forced by some other condition.
std::string cause;
/// The wall time a collection took from start to end.
std::chrono::milliseconds duration;
/// The CPU time a collection took from start to end. This time measure will
/// exclude time waiting on disk, mutexes, or time spent not scheduled to run.
std::chrono::milliseconds cpuDuration;
/// The number of bytes allocated in the heap before and after the collection.
/// measurement does not include fragmentation, and is the same as the sum of
/// all sizes in calls to \p GC::makeA into that generation (including any
/// rounding up the GC does).
/// The value is scoped to the \p collectionType.
BeforeAndAfter allocated;
/// The number of bytes in use by the heap before and after the collection.
/// This measurement can include fragmentation if the \p gcKind has that
/// concept.
/// The value is scoped to the \p collectionType.
BeforeAndAfter size;
/// The number of bytes external to the JS heap before and after the
/// collection.
/// The value is scoped to the \p collectionType.
BeforeAndAfter external;
/// The ratio of cells that survived the collection to all cells before
/// the collection. Note that this is in term of sizes of cells, not the
/// numbers of cells. Excludes any cells not in direct use by the JS program,
/// such as FillerCell or FreelistCell.
/// The value is scoped to the \p collectionType.
double survivalRatio;
/// A list of metadata tags to annotate this event with.
std::vector<std::string> tags;
};
/// Parameters to control a tripwire function called when the live set size
/// surpasses a given threshold after collections. Check documentation in
/// README.md
#define GC_TRIPWIRE_FIELDS(F) \
/* If the heap size is above this threshold after a collection, the tripwire \
* is triggered. */ \
F(constexpr, gcheapsize_t, Limit, std::numeric_limits<gcheapsize_t>::max()) \
\
/* The callback to call when the tripwire is considered triggered. */ \
F(HERMES_NON_CONSTEXPR, \
std::function<void(GCTripwireContext &)>, \
Callback, \
nullptr) \
/* GC_TRIPWIRE_FIELDS END */
_HERMES_CTORCONFIG_STRUCT(GCTripwireConfig, GC_TRIPWIRE_FIELDS, {});
#undef HEAP_TRIPWIRE_FIELDS
#define GC_HANDLESAN_FIELDS(F) \
/* The probability with which the GC should keep moving the heap */ \
/* to detect stale GC handles. */ \
F(constexpr, double, SanitizeRate, 0.0) \
/* Random seed to use for basis of decisions whether or not to */ \
/* sanitize. A negative value will mean a seed will be chosen at */ \
/* random. */ \
F(constexpr, int64_t, RandomSeed, -1) \
/* GC_HANDLESAN_FIELDS END */
_HERMES_CTORCONFIG_STRUCT(GCSanitizeConfig, GC_HANDLESAN_FIELDS, {});
#undef GC_HANDLESAN_FIELDS
/// How aggressively to return unused memory to the OS.
enum ReleaseUnused {
kReleaseUnusedNone = 0, /// Don't try to release unused memory.
kReleaseUnusedOld, /// Only old gen, on full collections.
kReleaseUnusedYoungOnFull, /// Also young gen, but only on full collections.
kReleaseUnusedYoungAlways /// Also young gen, also on young gen collections.
};
enum class GCEventKind {
CollectionStart,
CollectionEnd,
};
/// Parameters for GC Initialisation. Check documentation in README.md
/// constexpr indicates that the default value is constexpr.
#define GC_FIELDS(F) \
/* Minimum heap size hint. */ \
F(constexpr, gcheapsize_t, MinHeapSize, 0) \
\
/* Initial heap size hint. */ \
F(constexpr, gcheapsize_t, InitHeapSize, 32 << 20) \
\
/* Maximum heap size hint. */ \
F(constexpr, gcheapsize_t, MaxHeapSize, 512 << 20) \
\
/* Sizing heuristic: fraction of heap to be occupied by live data. */ \
F(constexpr, double, OccupancyTarget, 0.5) \
\
/* Number of consecutive full collections considered to be an OOM. */ \
F(constexpr, \
unsigned, \
EffectiveOOMThreshold, \
std::numeric_limits<unsigned>::max()) \
\
/* Sanitizer configuration for the GC. */ \
F(constexpr, GCSanitizeConfig, SanitizeConfig) \
\
/* Whether the GC should spread allocations across all its "spaces". */ \
F(constexpr, bool, ShouldRandomizeAllocSpace, false) \
\
/* Whether to Keep track of GC Statistics. */ \
F(constexpr, bool, ShouldRecordStats, false) \
\
/* How aggressively to return unused memory to the OS. */ \
F(constexpr, ReleaseUnused, ShouldReleaseUnused, kReleaseUnusedOld) \
\
/* Name for this heap in logs. */ \
F(HERMES_NON_CONSTEXPR, std::string, Name, "") \
\
/* Configuration for the Heap Tripwire. */ \
F(HERMES_NON_CONSTEXPR, GCTripwireConfig, TripwireConfig) \
\
/* Whether to (initially) allocate from the young gen (true) or the */ \
/* old gen (false). */ \
F(constexpr, bool, AllocInYoung, true) \
\
/* Whether to revert, if necessary, to young-gen allocation at TTI. */ \
F(constexpr, bool, RevertToYGAtTTI, false) \
\
/* Whether to use mprotect on GC metadata between GCs. */ \
F(constexpr, bool, ProtectMetadata, false) \
\
/* Callout for an analytics event. */ \
F(HERMES_NON_CONSTEXPR, \
std::function<void(const GCAnalyticsEvent &)>, \
AnalyticsCallback, \
nullptr) \
\
/* Called at GC events (see GCEventKind enum for the list). The */ \
/* second argument contains human-readable details about the event. */ \
/* NOTE: The function MUST NOT invoke any methods on the Runtime. */ \
F(HERMES_NON_CONSTEXPR, \
std::function<void(GCEventKind, const char *)>, \
Callback, \
nullptr) \
/* GC_FIELDS END */
_HERMES_CTORCONFIG_STRUCT(GCConfig, GC_FIELDS, {
if (builder.hasMinHeapSize()) {
if (builder.hasInitHeapSize()) {
// If both are specified, normalize the initial size up to the minimum,
// if necessary.
InitHeapSize_ = std::max(MinHeapSize_, InitHeapSize_);
} else {
// If the minimum is set explicitly, but the initial heap size is not,
// use the minimum as the initial size.
InitHeapSize_ = MinHeapSize_;
}
}
assert(InitHeapSize_ >= MinHeapSize_);
// Make sure the max is at least the Init.
MaxHeapSize_ = std::max(InitHeapSize_, MaxHeapSize_);
});
#undef GC_FIELDS
} // namespace vm
} // namespace hermes
#endif // HERMES_PUBLIC_GCCONFIG_H