Skip to content

Commit 0e60c69

Browse files
lavenzgfacebook-github-bot
authored andcommitted
Collapse write barrier function for HV and SHV (#1501)
Summary: Pull Request resolved: #1501 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 a18b1b5 commit 0e60c69

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+
FixedSizeHeapSegment::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+
FixedSizeHeapSegment::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
@@ -1922,28 +1922,6 @@ void HadesGC::debitExternalMemory(GCCell *cell, uint32_t sz) {
19221922
}
19231923
}
19241924

1925-
void HadesGC::writeBarrierSlow(const GCHermesValue *loc, HermesValue value) {
1926-
if (ogMarkingBarriers_) {
1927-
snapshotWriteBarrierInternal(*loc);
1928-
}
1929-
if (!value.isPointer()) {
1930-
return;
1931-
}
1932-
relocationWriteBarrier(loc, value.getPointer());
1933-
}
1934-
1935-
void HadesGC::writeBarrierSlow(
1936-
const GCSmallHermesValue *loc,
1937-
SmallHermesValue value) {
1938-
if (ogMarkingBarriers_) {
1939-
snapshotWriteBarrierInternal(*loc);
1940-
}
1941-
if (!value.isPointer()) {
1942-
return;
1943-
}
1944-
relocationWriteBarrier(loc, value.getPointer(getPointerBase()));
1945-
}
1946-
19471925
void HadesGC::writeBarrierSlow(const GCPointerBase *loc, const GCCell *value) {
19481926
if (*loc && ogMarkingBarriers_)
19491927
snapshotWriteBarrierInternal(*loc);
@@ -1952,70 +1930,6 @@ void HadesGC::writeBarrierSlow(const GCPointerBase *loc, const GCCell *value) {
19521930
relocationWriteBarrier(loc, value);
19531931
}
19541932

1955-
void HadesGC::constructorWriteBarrierSlow(
1956-
const GCHermesValue *loc,
1957-
HermesValue value) {
1958-
// A constructor never needs to execute a SATB write barrier, since its
1959-
// previous value was definitely not live.
1960-
if (!value.isPointer()) {
1961-
return;
1962-
}
1963-
relocationWriteBarrier(loc, value.getPointer());
1964-
}
1965-
1966-
void HadesGC::constructorWriteBarrierSlow(
1967-
const GCSmallHermesValue *loc,
1968-
SmallHermesValue value) {
1969-
// A constructor never needs to execute a SATB write barrier, since its
1970-
// previous value was definitely not live.
1971-
if (!value.isPointer()) {
1972-
return;
1973-
}
1974-
relocationWriteBarrier(loc, value.getPointer(getPointerBase()));
1975-
}
1976-
1977-
void HadesGC::constructorWriteBarrierRangeSlow(
1978-
const GCHermesValue *start,
1979-
uint32_t numHVs) {
1980-
assert(
1981-
FixedSizeHeapSegment::containedInSame(start, start + numHVs) &&
1982-
"Range must start and end within a heap segment.");
1983-
1984-
// Most constructors should be running in the YG, so in the common case, we
1985-
// can avoid doing anything for the whole range. If the range is in the OG,
1986-
// then just dirty all the cards corresponding to it, and we can scan them for
1987-
// pointers later. This is less precise but makes the write barrier faster.
1988-
1989-
FixedSizeHeapSegment::cardTableCovering(start)->dirtyCardsForAddressRange(
1990-
start, start + numHVs);
1991-
}
1992-
1993-
void HadesGC::constructorWriteBarrierRangeSlow(
1994-
const GCSmallHermesValue *start,
1995-
uint32_t numHVs) {
1996-
assert(
1997-
FixedSizeHeapSegment::containedInSame(start, start + numHVs) &&
1998-
"Range must start and end within a heap segment.");
1999-
FixedSizeHeapSegment::cardTableCovering(start)->dirtyCardsForAddressRange(
2000-
start, start + numHVs);
2001-
}
2002-
2003-
void HadesGC::snapshotWriteBarrierRangeSlow(
2004-
const GCHermesValue *start,
2005-
uint32_t numHVs) {
2006-
for (uint32_t i = 0; i < numHVs; ++i) {
2007-
snapshotWriteBarrierInternal(start[i]);
2008-
}
2009-
}
2010-
2011-
void HadesGC::snapshotWriteBarrierRangeSlow(
2012-
const GCSmallHermesValue *start,
2013-
uint32_t numHVs) {
2014-
for (uint32_t i = 0; i < numHVs; ++i) {
2015-
snapshotWriteBarrierInternal(start[i]);
2016-
}
2017-
}
2018-
20191933
void HadesGC::snapshotWriteBarrierInternal(GCCell *oldValue) {
20201934
assert(
20211935
(oldValue->isValid()) &&

0 commit comments

Comments
 (0)