From 4bfe41a94ebf19d77580b6b5c25183ad2c3e0486 Mon Sep 17 00:00:00 2001 From: "Gang Zhao (Hermes)" Date: Fri, 22 Nov 2024 16:04:32 -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 | 18 ++++++++++++++++++ include/hermes/VM/GCPointer.h | 24 +++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/include/hermes/VM/GCPointer-inline.h b/include/hermes/VM/GCPointer-inline.h index 4db995331fe..d40e9842669 100644 --- a/include/hermes/VM/GCPointer-inline.h +++ b/include/hermes/VM/GCPointer-inline.h @@ -32,6 +32,24 @@ 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"); + if constexpr (NeedsBarriers::value) { + gc.constructorWriteBarrierForLargeObj(owningObj, this, ptr); + } else { + assert(!gc.needsWriteBarrier(this, ptr)); + } +} + inline void GCPointerBase::set(PointerBase &base, GCCell *ptr, GC &gc) { assert( (!ptr || gc.validPointer(ptr)) && diff --git a/include/hermes/VM/GCPointer.h b/include/hermes/VM/GCPointer.h index cff5dc5b86e..96b31120fba 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 @@ -81,12 +89,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;