From d18b763359b3d624f93bb4280aeaa1908396bad7 Mon Sep 17 00:00:00 2001 From: "Gang Zhao (Hermes)" Date: Tue, 10 Dec 2024 15:57:10 -0800 Subject: [PATCH] Pass the pointer of owning object in GCHermesValueBase::set() (#1512) Summary: Pull Request resolved: https://github.com/facebook/hermes/pull/1512 This variant will be used by write barriers that support large allocation in following diffs. Differential Revision: D62196480 --- include/hermes/VM/HermesValue-inline.h | 30 ++++++++++++++++++++++++++ include/hermes/VM/HermesValue.h | 20 ++++++++++++++--- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/include/hermes/VM/HermesValue-inline.h b/include/hermes/VM/HermesValue-inline.h index e60dfb6219e..5e4af784832 100644 --- a/include/hermes/VM/HermesValue-inline.h +++ b/include/hermes/VM/HermesValue-inline.h @@ -37,6 +37,18 @@ GCHermesValueBase::GCHermesValueBase(HVType hv, GC &gc) : HVType{hv} { gc.constructorWriteBarrier(this, hv); } +template +template +GCHermesValueBase::GCHermesValueBase( + HVType hv, + GC &gc, + const GCCell *owningObj) + : HVType{hv} { + assert(!hv.isPointer() || hv.getPointer()); + if (NeedsBarriers::value) + gc.constructorWriteBarrierForLargeObj(owningObj, this, hv); +} + template template GCHermesValueBase::GCHermesValueBase(HVType hv, GC &gc, std::nullptr_t) @@ -61,6 +73,24 @@ inline void GCHermesValueBase::set(HVType hv, GC &gc) { HVType::setNoBarrier(hv); } +template +template +inline void GCHermesValueBase::setInLarge( + HVType hv, + GC &gc, + const GCCell *owningObj) { + if (hv.isPointer()) { + HERMES_SLOW_ASSERT( + gc.validPointer(hv.getPointer(gc.getPointerBase())) && + "Setting an invalid pointer into a GCHermesValue"); + } + assert(NeedsBarriers::value || !gc.needsWriteBarrier(this, hv)); + if constexpr (NeedsBarriers::value) { + gc.writeBarrierForLargeObj(owningObj, this, hv); + } + HVType::setNoBarrier(hv); +} + template void GCHermesValueBase::setNonPtr(HVType hv, GC &gc) { assert(!hv.isPointer()); diff --git a/include/hermes/VM/HermesValue.h b/include/hermes/VM/HermesValue.h index 1dbd01effe5..45c37f61bdf 100644 --- a/include/hermes/VM/HermesValue.h +++ b/include/hermes/VM/HermesValue.h @@ -520,9 +520,15 @@ template class GCHermesValueBase final : public HVType { public: GCHermesValueBase() : HVType(HVType::encodeUndefinedValue()) {} - /// Initialize a GCHermesValue from another HV. Performs a write barrier. + /// Initialize a GCHermesValue from another HV. Performs a write barrier. This + /// must not be used if it lives in an object that supports large allocation. template GCHermesValueBase(HVType hv, GC &gc); + /// Initialize a GCHermesValue from another HV. Performs a write barrier using + /// \p owningObj, which owns this GCHermesValue and may support large + /// allocation. + template + GCHermesValueBase(HVType hv, GC &gc, const GCCell *owningObj); /// Initialize a GCHermesValue from a non-pointer HV. Might perform a write /// barrier, depending on the GC. /// NOTE: The last parameter is unused, but acts as an overload selector. @@ -530,11 +536,19 @@ class GCHermesValueBase final : public HVType { GCHermesValueBase(HVType hv, GC &gc, std::nullptr_t); GCHermesValueBase(const HVType &) = delete; - /// The HermesValue \p hv may be an object pointer. Assign the - /// value, and perform any necessary write barriers. + /// The HermesValue \p hv may be an object pointer. Assign the value, and + /// perform any necessary write barriers. This must not be used if it lives in + /// an object that supports large allocation. template inline void set(HVType hv, GC &gc); + /// The HermesValue \p hv may be an object pointer. Assign the value, and + /// perform any necessary write barriers. \p owningObj is the object that + /// contains this GCHermesValueBase, and it may support large allocation. + /// for which the object pointer is needed by writer barriers. + template + inline void setInLarge(HVType hv, GC &gc, const GCCell *owningObj); + /// The HermesValue \p hv must not be an object pointer. Assign the /// value. /// Some GCs still need to do a write barrier though, so pass a GC parameter.