From 199892662e7765d26df484574fa9b64d3b1cbc43 Mon Sep 17 00:00:00 2001
From: "Gang Zhao (Hermes)" <zhaogang@meta.com>
Date: Thu, 7 Nov 2024 17:15:57 -0800
Subject: [PATCH] Pass the pointer of owning object in ctor of
 GCHermesValueBase (#1508)

Summary: Pull Request resolved: https://github.com/facebook/hermes/pull/1508

Differential Revision: D62222238
---
 include/hermes/VM/HermesValue-inline.h | 13 +++++++++++++
 include/hermes/VM/HermesValue.h        |  8 +++++++-
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/include/hermes/VM/HermesValue-inline.h b/include/hermes/VM/HermesValue-inline.h
index a31321785df..4e9334d4a1e 100644
--- a/include/hermes/VM/HermesValue-inline.h
+++ b/include/hermes/VM/HermesValue-inline.h
@@ -37,6 +37,19 @@ GCHermesValueBase<HVType>::GCHermesValueBase(HVType hv, GC &gc) : HVType{hv} {
     gc.constructorWriteBarrier(this, hv);
 }
 
+template <typename HVType>
+template <typename NeedsBarriers>
+GCHermesValueBase<HVType>::GCHermesValueBase(
+    HVType hv,
+    GC &gc,
+    const GCCell *owningObj)
+    : HVType{hv} {
+  assert(!hv.isPointer() || hv.getPointer());
+  (void)owningObj;
+  if (NeedsBarriers::value)
+    gc.constructorWriteBarrier(this, hv);
+}
+
 template <typename HVType>
 template <typename NeedsBarriers>
 GCHermesValueBase<HVType>::GCHermesValueBase(HVType hv, GC &gc, std::nullptr_t)
diff --git a/include/hermes/VM/HermesValue.h b/include/hermes/VM/HermesValue.h
index 88cae4512ed..2400e7a3f59 100644
--- a/include/hermes/VM/HermesValue.h
+++ b/include/hermes/VM/HermesValue.h
@@ -520,9 +520,15 @@ template <typename HVType>
 class GCHermesValueBase final : public HVType {
  public:
   GCHermesValueBase() : HVType(HVType::encodeUndefinedValue()) {}
-  /// Initialize a GCHermesValue from another HV. Performs a write barrier.
+  /// Initialize a GCHermesValue from another HV. Performs a write barrier. This
+  /// must not be used if it lives in an object that supports large allocation.
   template <typename NeedsBarriers = std::true_type>
   GCHermesValueBase(HVType hv, GC &gc);
+  /// Initialize a GCHermesValue from another HV. Performs a write barrier using
+  /// \p owningObj, which owns this GCHermesValue and may support large
+  /// allocation.
+  template <typename NeedsBarriers = std::true_type>
+  GCHermesValueBase(HVType hv, GC &gc, const GCCell *owningObj);
   /// Initialize a GCHermesValue from a non-pointer HV. Might perform a write
   /// barrier, depending on the GC.
   /// NOTE: The last parameter is unused, but acts as an overload selector.