From f948662013bb96017b13cb4ae8bc480b2751f2ed Mon Sep 17 00:00:00 2001 From: Charles Dick Date: Thu, 26 May 2016 11:07:41 -0700 Subject: [PATCH] Drop JSC code on background Reviewed By: lexs Differential Revision: D3311037 fbshipit-source-id: e46559108c51f1cd163ed5c557d23c21f696ef88 --- .../facebook/react/MemoryPressureRouter.java | 10 +++++++++- .../facebook/react/bridge/MemoryPressure.java | 1 + .../com/facebook/react/bridge/ReactBridge.java | 4 ++++ .../react/cxxbridge/CatalystInstanceImpl.java | 18 ++++++++++++++++++ ReactAndroid/src/main/jni/react/Bridge.cpp | 6 ++++++ ReactAndroid/src/main/jni/react/Bridge.h | 1 + ReactAndroid/src/main/jni/react/Executor.h | 1 + .../src/main/jni/react/JSCExecutor.cpp | 6 ++++++ ReactAndroid/src/main/jni/react/JSCExecutor.h | 1 + ReactAndroid/src/main/jni/react/jni/OnLoad.cpp | 7 +++++++ .../jni/xreact/jni/CatalystInstanceImpl.cpp | 15 +++++++++++++++ .../main/jni/xreact/jni/CatalystInstanceImpl.h | 3 +++ ReactCommon/bridge/Executor.h | 1 + ReactCommon/bridge/Instance.cpp | 12 ++++++++++++ ReactCommon/bridge/Instance.h | 3 +++ ReactCommon/bridge/JSCExecutor.cpp | 6 ++++++ ReactCommon/bridge/JSCExecutor.h | 1 + ReactCommon/bridge/NativeToJsBridge.cpp | 6 ++++++ ReactCommon/bridge/NativeToJsBridge.h | 1 + 19 files changed, 102 insertions(+), 1 deletion(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/MemoryPressureRouter.java b/ReactAndroid/src/main/java/com/facebook/react/MemoryPressureRouter.java index e9fd75748..7a17830a8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/MemoryPressureRouter.java +++ b/ReactAndroid/src/main/java/com/facebook/react/MemoryPressureRouter.java @@ -20,6 +20,7 @@ import static android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; import static android.content.ComponentCallbacks2.TRIM_MEMORY_COMPLETE; import static android.content.ComponentCallbacks2.TRIM_MEMORY_MODERATE; import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; +import static android.content.ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; /** * Translates and routes memory pressure events to the current catalyst instance. @@ -27,6 +28,8 @@ import static android.content.ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; public class MemoryPressureRouter { // Trigger this by sending an intent to your activity with adb shell: // am broadcast -a com.facebook.catalyst.ACTION_TRIM_MEMORY_MODERATE + private static final String ACTION_TRIM_MEMORY_UI_HIDDEN = + "com.facebook.rnfeed.ACTION_TRIM_MEMORY_UI_HIDDEN"; private static final String ACTION_TRIM_MEMORY_MODERATE = "com.facebook.rnfeed.ACTION_TRIM_MEMORY_MODERATE"; private static final String ACTION_TRIM_MEMORY_CRITICAL = @@ -52,6 +55,9 @@ public class MemoryPressureRouter { @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public static boolean handleDebugIntent(Application application, String action) { switch (action) { + case ACTION_TRIM_MEMORY_UI_HIDDEN: + simulateTrimMemory(application, ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); + break; case ACTION_TRIM_MEMORY_MODERATE: simulateTrimMemory(application, TRIM_MEMORY_MODERATE); break; @@ -87,10 +93,12 @@ public class MemoryPressureRouter { } private void trimMemory(int level) { - if (level >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) { + if (level >= TRIM_MEMORY_COMPLETE) { dispatchMemoryPressure(MemoryPressure.CRITICAL); } else if (level >= TRIM_MEMORY_BACKGROUND || level == TRIM_MEMORY_RUNNING_CRITICAL) { dispatchMemoryPressure(MemoryPressure.MODERATE); + } else if (level == TRIM_MEMORY_UI_HIDDEN) { + dispatchMemoryPressure(MemoryPressure.UI_HIDDEN); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/MemoryPressure.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/MemoryPressure.java index c947782ef..7412204e6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/MemoryPressure.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/MemoryPressure.java @@ -3,6 +3,7 @@ package com.facebook.react.bridge; public enum MemoryPressure { + UI_HIDDEN, MODERATE, CRITICAL } diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactBridge.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactBridge.java index cbdebb4f3..e4d43f90b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactBridge.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactBridge.java @@ -58,6 +58,9 @@ public class ReactBridge extends Countable { public void handleMemoryPressure(MemoryPressure level) { switch (level) { + case UI_HIDDEN: + handleMemoryPressureUiHidden(); + break; case MODERATE: handleMemoryPressureModerate(); break; @@ -86,6 +89,7 @@ public class ReactBridge extends Countable { public native void startProfiler(String title); public native void stopProfiler(String title, String filename); public native ExecutorToken getMainExecutorToken(); + private native void handleMemoryPressureUiHidden(); private native void handleMemoryPressureModerate(); private native void handleMemoryPressureCritical(); public native void destroy(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/cxxbridge/CatalystInstanceImpl.java b/ReactAndroid/src/main/java/com/facebook/react/cxxbridge/CatalystInstanceImpl.java index 3a5de280d..753ef65a6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/cxxbridge/CatalystInstanceImpl.java +++ b/ReactAndroid/src/main/java/com/facebook/react/cxxbridge/CatalystInstanceImpl.java @@ -289,8 +289,26 @@ public class CatalystInstanceImpl implements CatalystInstance { return mJavaRegistry.getAllModules(); } + private native void handleMemoryPressureUiHidden(); + private native void handleMemoryPressureModerate(); + private native void handleMemoryPressureCritical(); + @Override public void handleMemoryPressure(MemoryPressure level) { + if (mDestroyed) { + return; + } + switch(level) { + case UI_HIDDEN: + handleMemoryPressureUiHidden(); + break; + case MODERATE: + handleMemoryPressureModerate(); + break; + case CRITICAL: + handleMemoryPressureCritical(); + break; + } } /** diff --git a/ReactAndroid/src/main/jni/react/Bridge.cpp b/ReactAndroid/src/main/jni/react/Bridge.cpp index cf5dd566b..ee5bcb16c 100644 --- a/ReactAndroid/src/main/jni/react/Bridge.cpp +++ b/ReactAndroid/src/main/jni/react/Bridge.cpp @@ -127,6 +127,12 @@ void Bridge::stopProfiler(const std::string& title, const std::string& filename) }); } +void Bridge::handleMemoryPressureUiHidden() { + runOnExecutorQueue(*m_mainExecutorToken, [=] (JSExecutor* executor) { + executor->handleMemoryPressureUiHidden(); + }); +} + void Bridge::handleMemoryPressureModerate() { runOnExecutorQueue(*m_mainExecutorToken, [=] (JSExecutor* executor) { executor->handleMemoryPressureModerate(); diff --git a/ReactAndroid/src/main/jni/react/Bridge.h b/ReactAndroid/src/main/jni/react/Bridge.h index 9fa3413ec..b2c004a58 100644 --- a/ReactAndroid/src/main/jni/react/Bridge.h +++ b/ReactAndroid/src/main/jni/react/Bridge.h @@ -96,6 +96,7 @@ public: bool supportsProfiling(); void startProfiler(const std::string& title); void stopProfiler(const std::string& title, const std::string& filename); + void handleMemoryPressureUiHidden(); void handleMemoryPressureModerate(); void handleMemoryPressureCritical(); diff --git a/ReactAndroid/src/main/jni/react/Executor.h b/ReactAndroid/src/main/jni/react/Executor.h index 07aea900a..c161547b1 100644 --- a/ReactAndroid/src/main/jni/react/Executor.h +++ b/ReactAndroid/src/main/jni/react/Executor.h @@ -68,6 +68,7 @@ public: }; virtual void startProfiler(const std::string &titleString) {}; virtual void stopProfiler(const std::string &titleString, const std::string &filename) {}; + virtual void handleMemoryPressureUiHidden() {}; virtual void handleMemoryPressureModerate() {}; virtual void handleMemoryPressureCritical() { handleMemoryPressureModerate(); diff --git a/ReactAndroid/src/main/jni/react/JSCExecutor.cpp b/ReactAndroid/src/main/jni/react/JSCExecutor.cpp index e8027a064..a26a79742 100644 --- a/ReactAndroid/src/main/jni/react/JSCExecutor.cpp +++ b/ReactAndroid/src/main/jni/react/JSCExecutor.cpp @@ -363,6 +363,12 @@ void JSCExecutor::stopProfiler(const std::string &titleString, const std::string #endif } +void JSCExecutor::handleMemoryPressureUiHidden() { + #ifdef WITH_JSC_MEMORY_PRESSURE + JSHandleMemoryPressure(this, m_context, JSMemoryPressure::UI_HIDDEN); + #endif +} + void JSCExecutor::handleMemoryPressureModerate() { #ifdef WITH_JSC_MEMORY_PRESSURE JSHandleMemoryPressure(this, m_context, JSMemoryPressure::MODERATE); diff --git a/ReactAndroid/src/main/jni/react/JSCExecutor.h b/ReactAndroid/src/main/jni/react/JSCExecutor.h index 3de1c088e..acd6d14cc 100644 --- a/ReactAndroid/src/main/jni/react/JSCExecutor.h +++ b/ReactAndroid/src/main/jni/react/JSCExecutor.h @@ -71,6 +71,7 @@ public: virtual bool supportsProfiling() override; virtual void startProfiler(const std::string &titleString) override; virtual void stopProfiler(const std::string &titleString, const std::string &filename) override; + virtual void handleMemoryPressureUiHidden() override; virtual void handleMemoryPressureModerate() override; virtual void handleMemoryPressureCritical() override; virtual void destroy() override; diff --git a/ReactAndroid/src/main/jni/react/jni/OnLoad.cpp b/ReactAndroid/src/main/jni/react/jni/OnLoad.cpp index 76a24fbb1..001c7237e 100644 --- a/ReactAndroid/src/main/jni/react/jni/OnLoad.cpp +++ b/ReactAndroid/src/main/jni/react/jni/OnLoad.cpp @@ -839,6 +839,12 @@ static void stopProfiler(JNIEnv* env, jobject obj, jstring title, jstring filena bridge->stopProfiler(fromJString(env, title), fromJString(env, filename)); } +static void handleMemoryPressureUiHidden(JNIEnv* env, jobject obj) { + LOG(WARNING) << "handleMemoryPressureUiHidden"; + auto bridge = extractRefPtr(env, obj); + bridge->handleMemoryPressureUiHidden(); +} + static void handleMemoryPressureModerate(JNIEnv* env, jobject obj) { auto bridge = extractRefPtr(env, obj); bridge->handleMemoryPressureModerate(); @@ -1029,6 +1035,7 @@ extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) { makeNativeMethod("supportsProfiling", bridge::supportsProfiling), makeNativeMethod("startProfiler", bridge::startProfiler), makeNativeMethod("stopProfiler", bridge::stopProfiler), + makeNativeMethod("handleMemoryPressureUiHidden", bridge::handleMemoryPressureUiHidden), makeNativeMethod("handleMemoryPressureModerate", bridge::handleMemoryPressureModerate), makeNativeMethod("handleMemoryPressureCritical", bridge::handleMemoryPressureCritical), makeNativeMethod("getJavaScriptContextNativePtrExperimental", bridge::getJavaScriptContext), diff --git a/ReactAndroid/src/main/jni/xreact/jni/CatalystInstanceImpl.cpp b/ReactAndroid/src/main/jni/xreact/jni/CatalystInstanceImpl.cpp index 6bdeae504..c4c6faa74 100644 --- a/ReactAndroid/src/main/jni/xreact/jni/CatalystInstanceImpl.cpp +++ b/ReactAndroid/src/main/jni/xreact/jni/CatalystInstanceImpl.cpp @@ -106,6 +106,9 @@ void CatalystInstanceImpl::registerNatives() { makeNativeMethod("callJSCallback", CatalystInstanceImpl::callJSCallback), makeNativeMethod("getMainExecutorToken", CatalystInstanceImpl::getMainExecutorToken), makeNativeMethod("setGlobalVariable", CatalystInstanceImpl::setGlobalVariable), + makeNativeMethod("handleMemoryPressureUiHidden", CatalystInstanceImpl::handleMemoryPressureUiHidden), + makeNativeMethod("handleMemoryPressureModerate", CatalystInstanceImpl::handleMemoryPressureModerate), + makeNativeMethod("handleMemoryPressureCritical", CatalystInstanceImpl::handleMemoryPressureCritical), makeNativeMethod("supportsProfiling", CatalystInstanceImpl::supportsProfiling), makeNativeMethod("startProfiler", CatalystInstanceImpl::startProfiler), makeNativeMethod("stopProfiler", CatalystInstanceImpl::stopProfiler), @@ -204,6 +207,18 @@ void CatalystInstanceImpl::setGlobalVariable(std::string propName, folly::make_unique(std::move(jsonValue))); } +void CatalystInstanceImpl::handleMemoryPressureUiHidden() { + instance_->handleMemoryPressureUiHidden(); +} + +void CatalystInstanceImpl::handleMemoryPressureModerate() { + instance_->handleMemoryPressureModerate(); +} + +void CatalystInstanceImpl::handleMemoryPressureCritical() { + instance_->handleMemoryPressureCritical(); +} + jboolean CatalystInstanceImpl::supportsProfiling() { if (!instance_) { return false; diff --git a/ReactAndroid/src/main/jni/xreact/jni/CatalystInstanceImpl.h b/ReactAndroid/src/main/jni/xreact/jni/CatalystInstanceImpl.h index 0bb6302fc..cddc4e03c 100644 --- a/ReactAndroid/src/main/jni/xreact/jni/CatalystInstanceImpl.h +++ b/ReactAndroid/src/main/jni/xreact/jni/CatalystInstanceImpl.h @@ -55,6 +55,9 @@ class CatalystInstanceImpl : public jni::HybridClass { local_ref getMainExecutorToken(); void setGlobalVariable(std::string propName, std::string&& jsonValue); + void handleMemoryPressureUiHidden(); + void handleMemoryPressureModerate(); + void handleMemoryPressureCritical(); jboolean supportsProfiling(); void startProfiler(const std::string& title); void stopProfiler(const std::string& title, const std::string& filename); diff --git a/ReactCommon/bridge/Executor.h b/ReactCommon/bridge/Executor.h index 08af931d5..a27bf844f 100644 --- a/ReactCommon/bridge/Executor.h +++ b/ReactCommon/bridge/Executor.h @@ -168,6 +168,7 @@ public: } virtual void startProfiler(const std::string &titleString) {} virtual void stopProfiler(const std::string &titleString, const std::string &filename) {} + virtual void handleMemoryPressureUiHidden() {} virtual void handleMemoryPressureModerate() {} virtual void handleMemoryPressureCritical() { handleMemoryPressureModerate(); diff --git a/ReactCommon/bridge/Instance.cpp b/ReactCommon/bridge/Instance.cpp index fa70b02ab..a179fa14f 100644 --- a/ReactCommon/bridge/Instance.cpp +++ b/ReactCommon/bridge/Instance.cpp @@ -118,5 +118,17 @@ ExecutorToken Instance::getMainExecutorToken() { return nativeToJsBridge_->getMainExecutorToken(); } +void Instance::handleMemoryPressureUiHidden() { + nativeToJsBridge_->handleMemoryPressureUiHidden(); +} + +void Instance::handleMemoryPressureModerate() { + nativeToJsBridge_->handleMemoryPressureModerate(); +} + +void Instance::handleMemoryPressureCritical() { + nativeToJsBridge_->handleMemoryPressureCritical(); +} + } // namespace react } // namespace facebook diff --git a/ReactCommon/bridge/Instance.h b/ReactCommon/bridge/Instance.h index 9aee9d238..d5a3507eb 100644 --- a/ReactCommon/bridge/Instance.h +++ b/ReactCommon/bridge/Instance.h @@ -50,6 +50,9 @@ class Instance { MethodCallResult callSerializableNativeHook(ExecutorToken token, unsigned int moduleId, unsigned int methodId, folly::dynamic&& args); ExecutorToken getMainExecutorToken(); + void handleMemoryPressureUiHidden(); + void handleMemoryPressureModerate(); + void handleMemoryPressureCritical(); private: void callNativeModules(ExecutorToken token, const std::string& calls, bool isEndOfBatch); diff --git a/ReactCommon/bridge/JSCExecutor.cpp b/ReactCommon/bridge/JSCExecutor.cpp index 4bc0d99a0..cde2a7715 100644 --- a/ReactCommon/bridge/JSCExecutor.cpp +++ b/ReactCommon/bridge/JSCExecutor.cpp @@ -371,6 +371,12 @@ void JSCExecutor::stopProfiler(const std::string &titleString, const std::string #endif } +void JSCExecutor::handleMemoryPressureUiHidden() { + #ifdef WITH_JSC_MEMORY_PRESSURE + JSHandleMemoryPressure(this, m_context, JSMemoryPressure::UI_HIDDEN); + #endif +} + void JSCExecutor::handleMemoryPressureModerate() { #ifdef WITH_JSC_MEMORY_PRESSURE JSHandleMemoryPressure(this, m_context, JSMemoryPressure::MODERATE); diff --git a/ReactCommon/bridge/JSCExecutor.h b/ReactCommon/bridge/JSCExecutor.h index e869946d7..735e1c45e 100644 --- a/ReactCommon/bridge/JSCExecutor.h +++ b/ReactCommon/bridge/JSCExecutor.h @@ -74,6 +74,7 @@ public: virtual bool supportsProfiling() override; virtual void startProfiler(const std::string &titleString) override; virtual void stopProfiler(const std::string &titleString, const std::string &filename) override; + virtual void handleMemoryPressureUiHidden() override; virtual void handleMemoryPressureModerate() override; virtual void handleMemoryPressureCritical() override; virtual void destroy() override; diff --git a/ReactCommon/bridge/NativeToJsBridge.cpp b/ReactCommon/bridge/NativeToJsBridge.cpp index eaa50d38f..8a90f7a0e 100644 --- a/ReactCommon/bridge/NativeToJsBridge.cpp +++ b/ReactCommon/bridge/NativeToJsBridge.cpp @@ -226,6 +226,12 @@ void NativeToJsBridge::stopProfiler(const std::string& title, const std::string& }); } +void NativeToJsBridge::handleMemoryPressureUiHidden() { + runOnExecutorQueue(m_mainExecutorToken, [=] (JSExecutor* executor) { + executor->handleMemoryPressureUiHidden(); + }); +} + void NativeToJsBridge::handleMemoryPressureModerate() { runOnExecutorQueue(m_mainExecutorToken, [=] (JSExecutor* executor) { executor->handleMemoryPressureModerate(); diff --git a/ReactCommon/bridge/NativeToJsBridge.h b/ReactCommon/bridge/NativeToJsBridge.h index 3f3230a6c..942ee17c9 100644 --- a/ReactCommon/bridge/NativeToJsBridge.h +++ b/ReactCommon/bridge/NativeToJsBridge.h @@ -101,6 +101,7 @@ public: bool supportsProfiling(); void startProfiler(const std::string& title); void stopProfiler(const std::string& title, const std::string& filename); + void handleMemoryPressureUiHidden(); void handleMemoryPressureModerate(); void handleMemoryPressureCritical();