From 1d2a5bed03f21610c96b3e117d7bc9e1e8dcc798 Mon Sep 17 00:00:00 2001 From: "Gang Zhao (Hermes)" Date: Thu, 14 Nov 2024 13:12:50 -0800 Subject: [PATCH] Pass the pointer of owning object in ctor of GCPointer (#1503) Summary: Pull Request resolved: https://github.com/facebook/hermes/pull/1503 Differential Revision: D62227037 --- include/hermes/VM/GCPointer-inline.h | 19 +++++++++++++++++++ include/hermes/VM/GCPointer.h | 24 +++++++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/include/hermes/VM/GCPointer-inline.h b/include/hermes/VM/GCPointer-inline.h index 250fc0c3581..06f14031e31 100644 --- a/include/hermes/VM/GCPointer-inline.h +++ b/include/hermes/VM/GCPointer-inline.h @@ -32,6 +32,25 @@ GCPointerBase::GCPointerBase( } } +template +GCPointerBase::GCPointerBase( + PointerBase &base, + GCCell *ptr, + GC &gc, + const GCCell *owningObj, + NeedsBarriers) + : CompressedPointer(CompressedPointer::encode(ptr, base)) { + assert( + (!ptr || gc.validPointer(ptr)) && + "Cannot construct a GCPointer from an invalid pointer"); + (void)owningObj; + if constexpr (NeedsBarriers::value) { + gc.constructorWriteBarrier(this, ptr); + } else { + assert(!gc.needsWriteBarrier(this, ptr)); + } +} + template < GCPointerBase::MaybeLargeObj maybeLargeObj, GCPointerBase::NonNull nonNull> diff --git a/include/hermes/VM/GCPointer.h b/include/hermes/VM/GCPointer.h index eb51e29631d..589f755aa31 100644 --- a/include/hermes/VM/GCPointer.h +++ b/include/hermes/VM/GCPointer.h @@ -27,6 +27,14 @@ class GCPointerBase : public CompressedPointer { template inline GCPointerBase(PointerBase &base, GCCell *ptr, GC &gc, NeedsBarriers); + template + inline GCPointerBase( + PointerBase &base, + GCCell *ptr, + GC &gc, + const GCCell *owningObj, + NeedsBarriers); + public: // These classes are used as arguments to GCPointer constructors, to // indicate whether write barriers are necessary in initializing the @@ -99,12 +107,26 @@ class GCPointer : public GCPointerBase { template GCPointer(PointerBase &base, T *ptr, GC &gc, NeedsBarriers needsBarriers) : GCPointerBase(base, ptr, gc, needsBarriers) {} + /// Pass the owning object pointer to perform barriers when the object + /// supports large allocation. + template + GCPointer( + PointerBase &base, + T *ptr, + GC &gc, + const GCCell *owningObj, + NeedsBarriers needsBarriers) + : GCPointerBase(base, ptr, gc, owningObj, needsBarriers) {} /// Same as the constructor above, with the default for /// NeedsBarriers as "YesBarriers". (We can't use default template /// arguments with the idiom used above.) - inline GCPointer(PointerBase &base, T *ptr, GC &gc) + GCPointer(PointerBase &base, T *ptr, GC &gc) : GCPointer(base, ptr, gc, YesBarriers()) {} + /// Pass the owning object pointer to perform barriers when the object + /// supports large allocation. + GCPointer(PointerBase &base, T *ptr, GC &gc, const GCCell *owningObj) + : GCPointer(base, ptr, gc, owningObj, YesBarriers()) {} /// We are not allowed to copy-construct or assign GCPointers. GCPointer(const GCPointerBase &) = delete;