From 9795500ded56338ea39e36724d56d04dabf5220d Mon Sep 17 00:00:00 2001 From: "Gang Zhao (Hermes)" Date: Fri, 22 Nov 2024 15:58:09 -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 | 16 ++++++++++++++++ include/hermes/VM/HermesValue.h | 12 ++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/include/hermes/VM/HermesValue-inline.h b/include/hermes/VM/HermesValue-inline.h index 7fb255f7965..4b827951166 100644 --- a/include/hermes/VM/HermesValue-inline.h +++ b/include/hermes/VM/HermesValue-inline.h @@ -61,6 +61,22 @@ inline void GCHermesValueBase::set(HVType hv, GC &gc) { HVType::setNoBarrier(hv); } +template +template +inline void +GCHermesValueBase::set(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 5b99dfd9258..88cae4512ed 100644 --- a/include/hermes/VM/HermesValue.h +++ b/include/hermes/VM/HermesValue.h @@ -530,11 +530,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 set(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.