diff --git a/packages/react-native/ReactCommon/jsc/JSCRuntime.cpp b/packages/react-native/ReactCommon/jsc/JSCRuntime.cpp index 40633656596873..c42d4f3008e4a6 100644 --- a/packages/react-native/ReactCommon/jsc/JSCRuntime.cpp +++ b/packages/react-native/ReactCommon/jsc/JSCRuntime.cpp @@ -233,6 +233,7 @@ class JSCRuntime : public jsi::Runtime { bool strictEquals(const jsi::String& a, const jsi::String& b) const override; bool strictEquals(const jsi::Object& a, const jsi::Object& b) const override; bool instanceOf(const jsi::Object& o, const jsi::Function& f) override; + void setExternalMemoryPressure(const jsi::Object&, size_t) override; private: // Basically convenience casts @@ -1392,6 +1393,8 @@ bool JSCRuntime::instanceOf(const jsi::Object& o, const jsi::Function& f) { return res; } +void JSCRuntime::setExternalMemoryPressure(const jsi::Object&, size_t) {} + jsi::Runtime::PointerValue* JSCRuntime::makeSymbolValue( JSValueRef symbolRef) const { #ifndef NDEBUG diff --git a/packages/react-native/ReactCommon/jsi/jsi/decorator.h b/packages/react-native/ReactCommon/jsi/jsi/decorator.h index baece80fe71d0f..7bddd1fad80a52 100644 --- a/packages/react-native/ReactCommon/jsi/jsi/decorator.h +++ b/packages/react-native/ReactCommon/jsi/jsi/decorator.h @@ -252,6 +252,10 @@ class RuntimeDecorator : public Base, private jsi::Instrumentation { plain_.setNativeState(o, state); } + void setExternalMemoryPressure(const Object& obj, size_t amt) override { + plain_.setExternalMemoryPressure(obj, amt); + } + Value getProperty(const Object& o, const PropNameID& name) override { return plain_.getProperty(o, name); }; diff --git a/packages/react-native/ReactCommon/jsi/jsi/jsi-inl.h b/packages/react-native/ReactCommon/jsi/jsi/jsi-inl.h index 4ce00adb883c59..f3955815e41f06 100644 --- a/packages/react-native/ReactCommon/jsi/jsi/jsi-inl.h +++ b/packages/react-native/ReactCommon/jsi/jsi/jsi-inl.h @@ -227,6 +227,11 @@ inline void Object::setNativeState( runtime.setNativeState(*this, state); } +inline void Object::setExternalMemoryPressure(Runtime& runtime, size_t amt) + const { + runtime.setExternalMemoryPressure(*this, amt); +} + inline Array Object::getPropertyNames(Runtime& runtime) const { return runtime.getPropertyNames(*this); } diff --git a/packages/react-native/ReactCommon/jsi/jsi/jsi.h b/packages/react-native/ReactCommon/jsi/jsi/jsi.h index e5112b753b69d1..962dae93609423 100644 --- a/packages/react-native/ReactCommon/jsi/jsi/jsi.h +++ b/packages/react-native/ReactCommon/jsi/jsi/jsi.h @@ -387,6 +387,11 @@ class JSI_EXPORT Runtime { virtual bool instanceOf(const Object& o, const Function& f) = 0; + /// See Object::setExternalMemoryPressure. + virtual void setExternalMemoryPressure( + const jsi::Object& obj, + size_t amount) = 0; + // These exist so derived classes can access the private parts of // Value, Symbol, String, and Object, which are all friends of Runtime. template @@ -834,6 +839,16 @@ class JSI_EXPORT Object : public Pointer { /// works. I only need it in one place.) Array getPropertyNames(Runtime& runtime) const; + /// Inform the runtime that there is additional memory associated with a given + /// JavaScript object that is not visible to the GC. This can be used if an + /// object is known to retain some native memory, and may be used to guide + /// decisions about when to run garbage collection. + /// This method may be invoked multiple times on an object, and subsequent + /// calls will overwrite any previously set value. Once the object is garbage + /// collected, the associated external memory will be considered freed and may + /// no longer factor into GC decisions. + void setExternalMemoryPressure(Runtime& runtime, size_t amt) const; + protected: void setPropertyValue( Runtime& runtime,