@@ -152,25 +152,25 @@ class HadesGC final : public GCBase {
152
152
// / be in the heap). If value is a pointer, execute a write barrier.
153
153
// / NOTE: The write barrier call must be placed *before* the write to the
154
154
// / pointer, so that the current value can be fetched.
155
- void writeBarrier (const GCHermesValue *loc, HermesValue value) {
155
+ template <typename HVType>
156
+ void writeBarrier (const GCHermesValueBase<HVType> *loc, HVType value) {
156
157
assert (
157
158
!calledByBackgroundThread () &&
158
159
" Write barrier invoked by background thread." );
159
160
// A pointer that lives in YG never needs any write barriers.
160
161
if (LLVM_UNLIKELY (!inYoungGen (loc)))
161
162
writeBarrierSlow (loc, value);
162
163
}
163
- void writeBarrierSlow ( const GCHermesValue *loc, HermesValue value);
164
-
165
- void writeBarrier ( const GCSmallHermesValue *loc, SmallHermesValue value ) {
166
- assert (
167
- ! calledByBackgroundThread () &&
168
- " Write barrier invoked by background thread. " );
169
- // A pointer that lives in YG never needs any write barriers.
170
- if ( LLVM_UNLIKELY (! inYoungGen (loc)))
171
- writeBarrierSlow (loc, value);
164
+ template < typename HVType>
165
+ void writeBarrierSlow ( const GCHermesValueBase<HVType> *loc, HVType value) {
166
+ if (ogMarkingBarriers_ ) {
167
+ snapshotWriteBarrierInternal (*loc);
168
+ }
169
+ if (!value. isPointer ()) {
170
+ return ;
171
+ }
172
+ relocationWriteBarrier (loc, value. getPointer ( getPointerBase ()) );
172
173
}
173
- void writeBarrierSlow (const GCSmallHermesValue *loc, SmallHermesValue value);
174
174
175
175
// / The given pointer value is being written at the given loc (required to
176
176
// / be in the heap). The value may be null. Execute a write barrier.
@@ -188,57 +188,60 @@ class HadesGC final : public GCBase {
188
188
189
189
// / Special versions of \p writeBarrier for when there was no previous value
190
190
// / initialized into the space.
191
- void constructorWriteBarrier (const GCHermesValue *loc, HermesValue value) {
192
- // A pointer that lives in YG never needs any write barriers.
193
- if (LLVM_UNLIKELY (!inYoungGen (loc)))
194
- constructorWriteBarrierSlow (loc, value);
195
- }
196
- void constructorWriteBarrierSlow (const GCHermesValue *loc, HermesValue value);
197
-
191
+ template <typename HVType>
198
192
void constructorWriteBarrier (
199
- const GCSmallHermesValue *loc,
200
- SmallHermesValue value) {
193
+ const GCHermesValueBase<HVType> *loc,
194
+ HVType value) {
201
195
// A pointer that lives in YG never needs any write barriers.
202
196
if (LLVM_UNLIKELY (!inYoungGen (loc)))
203
197
constructorWriteBarrierSlow (loc, value);
204
198
}
199
+ template <typename HVType>
205
200
void constructorWriteBarrierSlow (
206
- const GCSmallHermesValue *loc,
207
- SmallHermesValue value);
201
+ const GCHermesValueBase<HVType> *loc,
202
+ HVType value) {
203
+ // A constructor never needs to execute a SATB write barrier, since its
204
+ // previous value was definitely not live.
205
+ if (!value.isPointer ()) {
206
+ return ;
207
+ }
208
+ relocationWriteBarrier (loc, value.getPointer (getPointerBase ()));
209
+ }
208
210
209
211
void constructorWriteBarrier (const GCPointerBase *loc, const GCCell *value) {
210
212
// A pointer that lives in YG never needs any write barriers.
211
213
if (LLVM_UNLIKELY (!inYoungGen (loc)))
212
214
relocationWriteBarrier (loc, value);
213
215
}
214
216
217
+ template <typename HVType>
215
218
void constructorWriteBarrierRange (
216
- const GCHermesValue *start,
219
+ const GCHermesValueBase<HVType> *start,
217
220
uint32_t numHVs) {
218
221
// A pointer that lives in YG never needs any write barriers.
219
222
if (LLVM_UNLIKELY (!inYoungGen (start)))
220
223
constructorWriteBarrierRangeSlow (start, numHVs);
221
224
}
225
+ template <typename HVType>
222
226
void constructorWriteBarrierRangeSlow (
223
- const GCHermesValue *start,
224
- uint32_t numHVs);
225
-
226
- void constructorWriteBarrierRange (
227
- const GCSmallHermesValue *start,
227
+ const GCHermesValueBase<HVType> *start,
228
228
uint32_t numHVs) {
229
- // A pointer that lives in YG never needs any write barriers.
230
- if (LLVM_UNLIKELY (!inYoungGen (start)))
231
- constructorWriteBarrierRangeSlow (start, numHVs);
232
- }
233
- void constructorWriteBarrierRangeSlow (
234
- const GCSmallHermesValue *start,
235
- uint32_t numHVs);
229
+ assert (
230
+ AlignedHeapSegment::containedInSame (start, start + numHVs) &&
231
+ " Range must start and end within a heap segment." );
236
232
237
- void snapshotWriteBarrier (const GCHermesValue *loc) {
238
- if (LLVM_UNLIKELY (!inYoungGen (loc) && ogMarkingBarriers_))
239
- snapshotWriteBarrierInternal (*loc);
233
+ // Most constructors should be running in the YG, so in the common case, we
234
+ // can avoid doing anything for the whole range. If the range is in the OG,
235
+ // then just dirty all the cards corresponding to it, and we can scan them
236
+ // for pointers later. This is less precise but makes the write barrier
237
+ // faster.
238
+
239
+ AlignedHeapSegment::cardTableCovering (start)->dirtyCardsForAddressRange (
240
+ start, start + numHVs);
240
241
}
241
- void snapshotWriteBarrier (const GCSmallHermesValue *loc) {
242
+
243
+ template <typename HVType>
244
+ void snapshotWriteBarrier (const GCHermesValueBase<HVType> *loc) {
242
245
if (LLVM_UNLIKELY (!inYoungGen (loc) && ogMarkingBarriers_))
243
246
snapshotWriteBarrierInternal (*loc);
244
247
}
@@ -252,23 +255,21 @@ class HadesGC final : public GCBase {
252
255
snapshotWriteBarrierInternal (*loc);
253
256
}
254
257
255
- void snapshotWriteBarrierRange (const GCHermesValue *start, uint32_t numHVs) {
256
- if (LLVM_UNLIKELY (!inYoungGen (start) && ogMarkingBarriers_))
257
- snapshotWriteBarrierRangeSlow (start, numHVs);
258
- }
259
- void snapshotWriteBarrierRangeSlow (
260
- const GCHermesValue *start,
261
- uint32_t numHVs);
262
-
258
+ template <typename HVType>
263
259
void snapshotWriteBarrierRange (
264
- const GCSmallHermesValue *start,
260
+ const GCHermesValueBase<HVType> *start,
265
261
uint32_t numHVs) {
266
262
if (LLVM_UNLIKELY (!inYoungGen (start) && ogMarkingBarriers_))
267
263
snapshotWriteBarrierRangeSlow (start, numHVs);
268
264
}
265
+ template <typename HVType>
269
266
void snapshotWriteBarrierRangeSlow (
270
- const GCSmallHermesValue *start,
271
- uint32_t numHVs);
267
+ const GCHermesValueBase<HVType> *start,
268
+ uint32_t numHVs) {
269
+ for (uint32_t i = 0 ; i < numHVs; ++i) {
270
+ snapshotWriteBarrierInternal (start[i]);
271
+ }
272
+ }
272
273
273
274
// / Add read barrier for \p value. This is only used when reading entry
274
275
// / value from WeakMap/WeakSet.
0 commit comments