diff --git a/include/hermes/VM/GCPointer-inline.h b/include/hermes/VM/GCPointer-inline.h index 0ceca7ecdf3..ed4a7e9321c 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 inline void GCPointerBase::setImpl( PointerBase &base, diff --git a/include/hermes/VM/GCPointer.h b/include/hermes/VM/GCPointer.h index a127fb0ae5f..80245d0d4d6 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 @@ -97,12 +105,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;