Skip to content

Commit 312fcf8

Browse files
lavenzgfacebook-github-bot
authored andcommitted
Collapse write barrier function for HV and SHV (#1501)
Summary: Collapse them to `GCHermesValueBase` since the implementation is exactly the same. This will make future changes to these functions easier. Differential Revision: D62158417
1 parent 510b8d5 commit 312fcf8

File tree

4 files changed

+76
-163
lines changed

4 files changed

+76
-163
lines changed

include/hermes/VM/GCBase.h

+11-15
Original file line numberDiff line numberDiff line change
@@ -1152,29 +1152,25 @@ class GCBase {
11521152

11531153
#ifdef HERMESVM_GC_RUNTIME
11541154
/// Default implementations for read and write barriers: do nothing.
1155-
void writeBarrier(const GCHermesValue *loc, HermesValue value);
1156-
void writeBarrier(const GCSmallHermesValue *loc, SmallHermesValue value);
1155+
template <typename HVType>
1156+
void writeBarrier(const GCHermesValueBase<HVType> *loc, HVType value);
11571157
void writeBarrier(const GCPointerBase *loc, const GCCell *value);
1158-
void constructorWriteBarrier(const GCHermesValue *loc, HermesValue value);
1158+
template <typename HVType>
11591159
void constructorWriteBarrier(
1160-
const GCSmallHermesValue *loc,
1161-
SmallHermesValue value);
1160+
const GCHermesValueBase<HVType> *loc,
1161+
HVType value);
11621162
void constructorWriteBarrier(const GCPointerBase *loc, const GCCell *value);
1163-
void writeBarrierRange(const GCHermesValue *start, uint32_t numHVs);
1164-
void writeBarrierRange(const GCSmallHermesValue *start, uint32_t numHVs);
1165-
void constructorWriteBarrierRange(
1166-
const GCHermesValue *start,
1167-
uint32_t numHVs);
1163+
template <typename HVType>
11681164
void constructorWriteBarrierRange(
1169-
const GCSmallHermesValue *start,
1165+
const GCHermesValueBase<HVType> *start,
11701166
uint32_t numHVs);
1171-
void snapshotWriteBarrier(const GCHermesValue *loc);
1172-
void snapshotWriteBarrier(const GCSmallHermesValue *loc);
1167+
template <typename HVType>
1168+
void snapshotWriteBarrier(const GCHermesValueBase<HVType> *loc);
11731169
void snapshotWriteBarrier(const GCPointerBase *loc);
11741170
void snapshotWriteBarrier(const GCSymbolID *symbol);
1175-
void snapshotWriteBarrierRange(const GCHermesValue *start, uint32_t numHVs);
1171+
template <typename HVType>
11761172
void snapshotWriteBarrierRange(
1177-
const GCSmallHermesValue *start,
1173+
const GCHermesValueBase<HVType> *start,
11781174
uint32_t numHVs);
11791175
void weakRefReadBarrier(HermesValue value);
11801176
void weakRefReadBarrier(GCCell *value);

include/hermes/VM/HadesGC.h

+51-50
Original file line numberDiff line numberDiff line change
@@ -152,25 +152,25 @@ class HadesGC final : public GCBase {
152152
/// be in the heap). If value is a pointer, execute a write barrier.
153153
/// NOTE: The write barrier call must be placed *before* the write to the
154154
/// 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) {
156157
assert(
157158
!calledByBackgroundThread() &&
158159
"Write barrier invoked by background thread.");
159160
// A pointer that lives in YG never needs any write barriers.
160161
if (LLVM_UNLIKELY(!inYoungGen(loc)))
161162
writeBarrierSlow(loc, value);
162163
}
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()));
172173
}
173-
void writeBarrierSlow(const GCSmallHermesValue *loc, SmallHermesValue value);
174174

175175
/// The given pointer value is being written at the given loc (required to
176176
/// be in the heap). The value may be null. Execute a write barrier.
@@ -188,57 +188,60 @@ class HadesGC final : public GCBase {
188188

189189
/// Special versions of \p writeBarrier for when there was no previous value
190190
/// 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>
198192
void constructorWriteBarrier(
199-
const GCSmallHermesValue *loc,
200-
SmallHermesValue value) {
193+
const GCHermesValueBase<HVType> *loc,
194+
HVType value) {
201195
// A pointer that lives in YG never needs any write barriers.
202196
if (LLVM_UNLIKELY(!inYoungGen(loc)))
203197
constructorWriteBarrierSlow(loc, value);
204198
}
199+
template <typename HVType>
205200
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+
}
208210

209211
void constructorWriteBarrier(const GCPointerBase *loc, const GCCell *value) {
210212
// A pointer that lives in YG never needs any write barriers.
211213
if (LLVM_UNLIKELY(!inYoungGen(loc)))
212214
relocationWriteBarrier(loc, value);
213215
}
214216

217+
template <typename HVType>
215218
void constructorWriteBarrierRange(
216-
const GCHermesValue *start,
219+
const GCHermesValueBase<HVType> *start,
217220
uint32_t numHVs) {
218221
// A pointer that lives in YG never needs any write barriers.
219222
if (LLVM_UNLIKELY(!inYoungGen(start)))
220223
constructorWriteBarrierRangeSlow(start, numHVs);
221224
}
225+
template <typename HVType>
222226
void constructorWriteBarrierRangeSlow(
223-
const GCHermesValue *start,
224-
uint32_t numHVs);
225-
226-
void constructorWriteBarrierRange(
227-
const GCSmallHermesValue *start,
227+
const GCHermesValueBase<HVType> *start,
228228
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.");
236232

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);
240241
}
241-
void snapshotWriteBarrier(const GCSmallHermesValue *loc) {
242+
243+
template <typename HVType>
244+
void snapshotWriteBarrier(const GCHermesValueBase<HVType> *loc) {
242245
if (LLVM_UNLIKELY(!inYoungGen(loc) && ogMarkingBarriers_))
243246
snapshotWriteBarrierInternal(*loc);
244247
}
@@ -252,23 +255,21 @@ class HadesGC final : public GCBase {
252255
snapshotWriteBarrierInternal(*loc);
253256
}
254257

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>
263259
void snapshotWriteBarrierRange(
264-
const GCSmallHermesValue *start,
260+
const GCHermesValueBase<HVType> *start,
265261
uint32_t numHVs) {
266262
if (LLVM_UNLIKELY(!inYoungGen(start) && ogMarkingBarriers_))
267263
snapshotWriteBarrierRangeSlow(start, numHVs);
268264
}
265+
template <typename HVType>
269266
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+
}
272273

273274
/// Add read barrier for \p value. This is only used when reading entry
274275
/// value from WeakMap/WeakSet.

include/hermes/VM/MallocGC.h

+14-12
Original file line numberDiff line numberDiff line change
@@ -233,22 +233,24 @@ class MallocGC final : public GCBase {
233233
virtual void creditExternalMemory(GCCell *alloc, uint32_t size) override;
234234
virtual void debitExternalMemory(GCCell *alloc, uint32_t size) override;
235235

236-
void writeBarrier(const GCHermesValue *, HermesValue) {}
237-
void writeBarrier(const GCSmallHermesValue *, SmallHermesValue) {}
236+
template <typename HVType>
237+
void writeBarrier(const GCHermesValueBase<HVType> *, HVType) {}
238238
void writeBarrier(const GCPointerBase *, const GCCell *) {}
239-
void constructorWriteBarrier(const GCHermesValue *, HermesValue) {}
240-
void constructorWriteBarrier(const GCSmallHermesValue *, SmallHermesValue) {}
239+
template <typename HVType>
240+
void constructorWriteBarrier(const GCHermesValueBase<HVType> *, HVType) {}
241241
void constructorWriteBarrier(const GCPointerBase *, const GCCell *) {}
242-
void writeBarrierRange(const GCHermesValue *, uint32_t) {}
243-
void writeBarrierRange(const GCSmallHermesValue *, uint32_t) {}
244-
void constructorWriteBarrierRange(const GCHermesValue *, uint32_t) {}
245-
void constructorWriteBarrierRange(const GCSmallHermesValue *, uint32_t) {}
246-
void snapshotWriteBarrier(const GCHermesValue *) {}
247-
void snapshotWriteBarrier(const GCSmallHermesValue *) {}
242+
template <typename HVType>
243+
void writeBarrierRange(const GCHermesValueBase<HVType> *, uint32_t) {}
244+
template <typename HVType>
245+
void constructorWriteBarrierRange(
246+
const GCHermesValueBase<HVType> *,
247+
uint32_t) {}
248+
template <typename HVType>
249+
void snapshotWriteBarrier(const GCHermesValueBase<HVType> *) {}
248250
void snapshotWriteBarrier(const GCPointerBase *) {}
249251
void snapshotWriteBarrier(const GCSymbolID *) {}
250-
void snapshotWriteBarrierRange(const GCHermesValue *, uint32_t) {}
251-
void snapshotWriteBarrierRange(const GCSmallHermesValue *, uint32_t) {}
252+
template <typename HVType>
253+
void snapshotWriteBarrierRange(const GCHermesValueBase<HVType> *, uint32_t) {}
252254
void weakRefReadBarrier(HermesValue) {}
253255
void weakRefReadBarrier(GCCell *) {}
254256

lib/VM/gcs/HadesGC.cpp

-86
Original file line numberDiff line numberDiff line change
@@ -1899,28 +1899,6 @@ void HadesGC::debitExternalMemory(GCCell *cell, uint32_t sz) {
18991899
}
19001900
}
19011901

1902-
void HadesGC::writeBarrierSlow(const GCHermesValue *loc, HermesValue value) {
1903-
if (ogMarkingBarriers_) {
1904-
snapshotWriteBarrierInternal(*loc);
1905-
}
1906-
if (!value.isPointer()) {
1907-
return;
1908-
}
1909-
relocationWriteBarrier(loc, value.getPointer());
1910-
}
1911-
1912-
void HadesGC::writeBarrierSlow(
1913-
const GCSmallHermesValue *loc,
1914-
SmallHermesValue value) {
1915-
if (ogMarkingBarriers_) {
1916-
snapshotWriteBarrierInternal(*loc);
1917-
}
1918-
if (!value.isPointer()) {
1919-
return;
1920-
}
1921-
relocationWriteBarrier(loc, value.getPointer(getPointerBase()));
1922-
}
1923-
19241902
void HadesGC::writeBarrierSlow(const GCPointerBase *loc, const GCCell *value) {
19251903
if (*loc && ogMarkingBarriers_)
19261904
snapshotWriteBarrierInternal(*loc);
@@ -1929,70 +1907,6 @@ void HadesGC::writeBarrierSlow(const GCPointerBase *loc, const GCCell *value) {
19291907
relocationWriteBarrier(loc, value);
19301908
}
19311909

1932-
void HadesGC::constructorWriteBarrierSlow(
1933-
const GCHermesValue *loc,
1934-
HermesValue value) {
1935-
// A constructor never needs to execute a SATB write barrier, since its
1936-
// previous value was definitely not live.
1937-
if (!value.isPointer()) {
1938-
return;
1939-
}
1940-
relocationWriteBarrier(loc, value.getPointer());
1941-
}
1942-
1943-
void HadesGC::constructorWriteBarrierSlow(
1944-
const GCSmallHermesValue *loc,
1945-
SmallHermesValue value) {
1946-
// A constructor never needs to execute a SATB write barrier, since its
1947-
// previous value was definitely not live.
1948-
if (!value.isPointer()) {
1949-
return;
1950-
}
1951-
relocationWriteBarrier(loc, value.getPointer(getPointerBase()));
1952-
}
1953-
1954-
void HadesGC::constructorWriteBarrierRangeSlow(
1955-
const GCHermesValue *start,
1956-
uint32_t numHVs) {
1957-
assert(
1958-
AlignedHeapSegment::containedInSame(start, start + numHVs) &&
1959-
"Range must start and end within a heap segment.");
1960-
1961-
// Most constructors should be running in the YG, so in the common case, we
1962-
// can avoid doing anything for the whole range. If the range is in the OG,
1963-
// then just dirty all the cards corresponding to it, and we can scan them for
1964-
// pointers later. This is less precise but makes the write barrier faster.
1965-
1966-
AlignedHeapSegment::cardTableCovering(start)->dirtyCardsForAddressRange(
1967-
start, start + numHVs);
1968-
}
1969-
1970-
void HadesGC::constructorWriteBarrierRangeSlow(
1971-
const GCSmallHermesValue *start,
1972-
uint32_t numHVs) {
1973-
assert(
1974-
AlignedHeapSegment::containedInSame(start, start + numHVs) &&
1975-
"Range must start and end within a heap segment.");
1976-
AlignedHeapSegment::cardTableCovering(start)->dirtyCardsForAddressRange(
1977-
start, start + numHVs);
1978-
}
1979-
1980-
void HadesGC::snapshotWriteBarrierRangeSlow(
1981-
const GCHermesValue *start,
1982-
uint32_t numHVs) {
1983-
for (uint32_t i = 0; i < numHVs; ++i) {
1984-
snapshotWriteBarrierInternal(start[i]);
1985-
}
1986-
}
1987-
1988-
void HadesGC::snapshotWriteBarrierRangeSlow(
1989-
const GCSmallHermesValue *start,
1990-
uint32_t numHVs) {
1991-
for (uint32_t i = 0; i < numHVs; ++i) {
1992-
snapshotWriteBarrierInternal(start[i]);
1993-
}
1994-
}
1995-
19961910
void HadesGC::snapshotWriteBarrierInternal(GCCell *oldValue) {
19971911
assert(
19981912
(oldValue->isValid()) &&

0 commit comments

Comments
 (0)