From d81ba7d3fdcb9198b86d1cd000feb91724d8771f Mon Sep 17 00:00:00 2001 From: Gang Zhao Date: Wed, 25 Dec 2024 23:01:09 -0800 Subject: [PATCH] Add needsWriteBarriers for constructors and large objects Differential Revision: D67556001 --- include/hermes/VM/GCBase.h | 12 ++++++++++ include/hermes/VM/HadesGC.h | 10 ++++++++ include/hermes/VM/MallocGC.h | 10 ++++++++ lib/VM/gcs/HadesGC.cpp | 46 ++++++++++++++++++++++++++++++++++++ lib/VM/gcs/MallocGC.cpp | 20 ++++++++++++++++ 5 files changed, 98 insertions(+) diff --git a/include/hermes/VM/GCBase.h b/include/hermes/VM/GCBase.h index f3fe1ae71e3..cc22ef06c3d 100644 --- a/include/hermes/VM/GCBase.h +++ b/include/hermes/VM/GCBase.h @@ -1084,6 +1084,18 @@ class GCBase { SmallHermesValue value) const = 0; virtual bool needsWriteBarrier(const GCPointerBase *loc, GCCell *value) const = 0; + virtual bool needsWriteBarrierInCtor( + const GCHermesValue *loc, + HermesValue value) const = 0; + virtual bool needsWriteBarrierInCtor( + const GCSmallHermesValue *loc, + SmallHermesValue value) const = 0; + virtual bool needsWriteBarrierForLargeObj( + const GCHermesValue *loc, + HermesValue value) const = 0; + virtual bool needsWriteBarrierForLargeObj( + const GCSmallHermesValue *loc, + SmallHermesValue value) const = 0; /// \} #endif diff --git a/include/hermes/VM/HadesGC.h b/include/hermes/VM/HadesGC.h index 3c4de3a6ac3..1483d44c3e7 100644 --- a/include/hermes/VM/HadesGC.h +++ b/include/hermes/VM/HadesGC.h @@ -489,6 +489,16 @@ class HadesGC final : public GCBase { const override; bool needsWriteBarrier(const GCPointerBase *loc, GCCell *value) const override; + bool needsWriteBarrierInCtor(const GCHermesValue *loc, HermesValue value) + const override; + bool needsWriteBarrierInCtor( + const GCSmallHermesValue *loc, + SmallHermesValue value) const override; + bool needsWriteBarrierForLargeObj(const GCHermesValue *loc, HermesValue value) + const override; + bool needsWriteBarrierForLargeObj( + const GCSmallHermesValue *loc, + SmallHermesValue value) const override; /// \} #endif diff --git a/include/hermes/VM/MallocGC.h b/include/hermes/VM/MallocGC.h index ea0f2d9970b..8381fb1abc0 100644 --- a/include/hermes/VM/MallocGC.h +++ b/include/hermes/VM/MallocGC.h @@ -222,6 +222,16 @@ class MallocGC final : public GCBase { const override; bool needsWriteBarrier(const GCPointerBase *loc, GCCell *value) const override; + bool needsWriteBarrierInCtor(const GCHermesValue *loc, HermesValue value) + const override; + bool needsWriteBarrierInCtor( + const GCSmallHermesValue *loc, + SmallHermesValue value) const override; + bool needsWriteBarrierForLargeObj(const GCHermesValue *loc, HermesValue value) + const override; + bool needsWriteBarrierForLargeObj( + const GCSmallHermesValue *loc, + SmallHermesValue value) const override; #endif #ifdef HERMES_MEMORY_INSTRUMENTATION diff --git a/lib/VM/gcs/HadesGC.cpp b/lib/VM/gcs/HadesGC.cpp index ff44fe33dd2..5d4d3aff415 100644 --- a/lib/VM/gcs/HadesGC.cpp +++ b/lib/VM/gcs/HadesGC.cpp @@ -2289,6 +2289,17 @@ bool HadesGC::needsWriteBarrier(const GCHermesValue *loc, HermesValue value) return true; return false; } +bool HadesGC::needsWriteBarrierInCtor( + const GCHermesValue *loc, + HermesValue value) const { + // Values in the YG never need a barrier. + if (inYoungGen(loc)) + return false; + // If the new value is a pointer, a relocation barrier is needed. + if (value.isPointer()) + return true; + return false; +} bool HadesGC::needsWriteBarrier( const GCSmallHermesValue *loc, SmallHermesValue value) const { @@ -2303,6 +2314,41 @@ bool HadesGC::needsWriteBarrier( return true; return false; } +bool HadesGC::needsWriteBarrierInCtor( + const GCSmallHermesValue *loc, + SmallHermesValue value) const { + // Values in the YG never need a barrier. + if (inYoungGen(loc)) + return false; + // If the new value is a pointer, a relocation barrier is needed. + if (value.isPointer()) + return true; + return false; +} +bool HadesGC::needsWriteBarrierForLargeObj( + const GCHermesValue *loc, + HermesValue value) const { + // For large allocation, we don't allow skipping barriers if the pointer lives + // in YG. We may revisit this if there is a case that we really want to skip + // barriers (by ensuring that the owning object always lives in YG). + if (loc->isPointer() || loc->isSymbol()) + return true; + if (value.isPointer()) + return true; + return false; +} +bool HadesGC::needsWriteBarrierForLargeObj( + const GCSmallHermesValue *loc, + SmallHermesValue value) const { + // For large allocation, we don't allow skipping barriers if the pointer lives + // in YG. We may revisit this if there is a case that we really want to skip + // barriers (by ensuring that the owning object always lives in YG). + if (loc->isPointer() || loc->isSymbol()) + return true; + if (value.isPointer()) + return true; + return false; +} bool HadesGC::needsWriteBarrier(const GCPointerBase *loc, GCCell *value) const { return !inYoungGen(loc); } diff --git a/lib/VM/gcs/MallocGC.cpp b/lib/VM/gcs/MallocGC.cpp index 141c51c0277..dd778bf4d0f 100644 --- a/lib/VM/gcs/MallocGC.cpp +++ b/lib/VM/gcs/MallocGC.cpp @@ -515,15 +515,35 @@ bool MallocGC::needsWriteBarrier(const GCHermesValue *loc, HermesValue value) const { return false; } +bool MallocGC::needsWriteBarrierInCtor( + const GCHermesValue *loc, + HermesValue value) const { + return false; +} bool MallocGC::needsWriteBarrier( const GCSmallHermesValue *loc, SmallHermesValue value) const { return false; } +bool MallocGC::needsWriteBarrierInCtor( + const GCSmallHermesValue *loc, + SmallHermesValue value) const { + return false; +} bool MallocGC::needsWriteBarrier(const GCPointerBase *loc, GCCell *value) const { return false; } +bool MallocGC::needsWriteBarrierForLargeObj( + const GCHermesValue *loc, + HermesValue value) const { + return false; +} +bool MallocGC::needsWriteBarrierForLargeObj( + const GCSmallHermesValue *loc, + SmallHermesValue value) const { + return false; +} #endif #ifdef HERMES_MEMORY_INSTRUMENTATION