From 2d810682c878d6017b088e23e3ca5384e7da998d Mon Sep 17 00:00:00 2001 From: "Gang Zhao (Hermes)" Date: Fri, 22 Nov 2024 16:06:36 -0800 Subject: [PATCH] Pass the pointer of owning object in GCPointer::set() part I (#1502) Summary: Pull Request resolved: https://github.com/facebook/hermes/pull/1502 Differential Revision: D62222257 --- include/hermes/VM/GCPointer-inline.h | 25 ++++++++++++++++++++++++ include/hermes/VM/GCPointer.h | 29 ++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/include/hermes/VM/GCPointer-inline.h b/include/hermes/VM/GCPointer-inline.h index fa5f7633ed5..0cfbbb0fc01 100644 --- a/include/hermes/VM/GCPointer-inline.h +++ b/include/hermes/VM/GCPointer-inline.h @@ -59,6 +59,31 @@ GCPointerBase::set(PointerBase &base, CompressedPointer ptr, GC &gc) { setNoBarrier(ptr); } +inline void GCPointerBase::set( + PointerBase &base, + GCCell *ptr, + GC &gc, + const GCCell *owningObj) { + assert( + (!ptr || gc.validPointer(ptr)) && + "Cannot set a GCPointer to an invalid pointer"); + // Write barrier must happen before the write. + gc.writeBarrierForLargeObj(owningObj, this, ptr); + setNoBarrier(CompressedPointer::encode(ptr, base)); +} + +inline void GCPointerBase::setNonNull( + PointerBase &base, + GCCell *ptr, + GC &gc, + const GCCell *owningObj) { + assert( + gc.validPointer(ptr) && "Cannot set a GCPointer to an invalid pointer"); + // Write barrier must happen before the write. + gc.writeBarrierForLargeObj(owningObj, this, ptr); + setNoBarrier(CompressedPointer::encodeNonNull(ptr, base)); +} + inline void GCPointerBase::setNull(GC &gc) { gc.snapshotWriteBarrier(this); setNoBarrier(CompressedPointer(nullptr)); diff --git a/include/hermes/VM/GCPointer.h b/include/hermes/VM/GCPointer.h index 09db5f06d87..1336c7c5a30 100644 --- a/include/hermes/VM/GCPointer.h +++ b/include/hermes/VM/GCPointer.h @@ -34,7 +34,8 @@ class GCPointerBase : public CompressedPointer { class NoBarriers : public std::false_type {}; class YesBarriers : public std::true_type {}; - /// This must be used to assign a new value to this GCPointer. + /// This must be used to assign a new value to this GCPointer. This must not + /// be used if it lives in an object that supports large allocation. /// \param ptr The memory being pointed to. /// \param base The base of ptr. /// \param gc Used for write barriers. @@ -42,6 +43,17 @@ class GCPointerBase : public CompressedPointer { inline void set(PointerBase &base, CompressedPointer ptr, GC &gc); inline void setNonNull(PointerBase &base, GCCell *ptr, GC &gc); + /// This must be used to assign a new value to this GCPointer. + /// \param ptr The memory being pointed to. + /// \param base The base of ptr. + /// \param gc Used for write barriers. + /// \param owningObj The object that contains this GCPointer, used by the + /// writer barriers. + inline void + set(PointerBase &base, GCCell *ptr, GC &gc, const GCCell *owningObj); + inline void + setNonNull(PointerBase &base, GCCell *ptr, GC &gc, const GCCell *owningObj); + /// Set this pointer to null. This needs a write barrier in some types of /// garbage collectors. inline void setNull(GC &gc); @@ -86,7 +98,8 @@ class GCPointer : public GCPointerBase { return vmcast(GCPointerBase::getNonNull(base)); } - /// Assign a new value to this GCPointer. + /// Assign a new value to this GCPointer. This must not be used if it lives in + /// an object that supports large allocation. /// \param base The base of ptr. /// \param ptr The memory being pointed to. /// \param gc Used for write barriers. @@ -97,6 +110,18 @@ class GCPointer : public GCPointerBase { GCPointerBase::setNonNull(base, ptr, gc); } + /// Assign a new value to this GCPointer. + /// \param ptr The memory being pointed to. + /// \param gc Used for write barriers. + /// \param owningObj The object that contains this GCPointer, used by the + /// writer barriers. + void set(PointerBase &base, T *ptr, GC &gc, const GCCell *owningObj) { + GCPointerBase::set(base, ptr, gc, owningObj); + } + void setNonNull(PointerBase &base, T *ptr, GC &gc, const GCCell *owningObj) { + GCPointerBase::setNonNull(base, ptr, gc, owningObj); + } + /// Convenience overload of GCPointer::set for other GCPointers. void set(PointerBase &base, const GCPointer &ptr, GC &gc) { GCPointerBase::set(base, ptr, gc);