From e821749ed2d2ff8275a25c840f47cb294567695e Mon Sep 17 00:00:00 2001 From: "Gang Zhao (Hermes)" Date: Thu, 7 Nov 2024 17:15:48 -0800 Subject: [PATCH] Pass the pointer of owning object in GCPointer::set() part II (#1509) Summary: Pull Request resolved: https://github.com/facebook/hermes/pull/1509 Differential Revision: D62227030 --- include/hermes/VM/GCPointer-inline.h | 14 ++++++++++++++ include/hermes/VM/GCPointer.h | 18 +++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/include/hermes/VM/GCPointer-inline.h b/include/hermes/VM/GCPointer-inline.h index 0eef539cfc4..0ceca7ecdf3 100644 --- a/include/hermes/VM/GCPointer-inline.h +++ b/include/hermes/VM/GCPointer-inline.h @@ -69,6 +69,20 @@ GCPointerBase::set(PointerBase &base, CompressedPointer ptr, GC &gc) { setNoBarrier(ptr); } +inline void GCPointerBase::set( + PointerBase &base, + CompressedPointer ptr, + GC &gc, + const GCCell *owningObj) { + assert( + (!ptr || gc.validPointer(ptr.get(base))) && + "Cannot set a GCPointer to an invalid pointer"); + // Write barrier must happen before the write. + (void)owningObj; + gc.writeBarrier(this, ptr.get(base)); + setNoBarrier(ptr); +} + 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 7af0bb258ac..a127fb0ae5f 100644 --- a/include/hermes/VM/GCPointer.h +++ b/include/hermes/VM/GCPointer.h @@ -57,6 +57,11 @@ class GCPointerBase : public CompressedPointer { set(PointerBase &base, GCCell *ptr, GC &gc, const GCCell *owningObj) { setImpl(base, ptr, gc, owningObj); } + inline void set( + PointerBase &base, + CompressedPointer ptr, + GC &gc, + const GCCell *owningObj); inline void setNonNull(PointerBase &base, GCCell *ptr, GC &gc, const GCCell *owningObj) { setImpl(base, ptr, gc, owningObj); @@ -138,10 +143,21 @@ class GCPointer : public GCPointerBase { GCPointerBase::setNonNull(base, ptr, gc, owningObj); } - /// Convenience overload of GCPointer::set for other GCPointers. + /// Convenience overload of GCPointer::set for other GCPointers. This must not + /// be used if it lives in an object that supports large allocation. void set(PointerBase &base, const GCPointer &ptr, GC &gc) { GCPointerBase::set(base, ptr, gc); } + + /// Convenience overload of GCPointer::set for other GCPointers. \p owningObj + /// is used by the writer barriers. + void set( + PointerBase &base, + const GCPointer &ptr, + GC &gc, + const GCCell *owningObj) { + GCPointerBase::set(base, ptr, gc, owningObj); + } }; } // namespace vm