From e45542b91d3f5237a0520270d5000d72c5d91ca5 Mon Sep 17 00:00:00 2001 From: houjiahui1 Date: Sat, 21 Jun 2025 17:24:39 +0800 Subject: [PATCH] App warm startup support SmartGC Signed-off-by: QiangShaowei --- frameworks/native/appkit/app/main_thread.cpp | 7 ++++++- frameworks/native/runtime/js_runtime.cpp | 2 ++ .../include/appmgr/app_launch_data.h | 15 +++++++++++++++ .../include/appmgr/running_process_info.h | 1 + .../app_manager/src/appmgr/app_launch_data.cpp | 18 +++++++++++++++++- .../src/appmgr/running_process_info.cpp | 2 ++ interfaces/inner_api/runtime/include/runtime.h | 1 + .../abilitymgr/src/ability_connect_manager.cpp | 2 +- .../abilitymgr/src/ability_manager_service.cpp | 14 ++++++++++---- services/appmgr/src/app_mgr_service_inner.cpp | 1 + services/appmgr/src/app_running_record.cpp | 1 + services/common/include/res_sched_util.h | 2 +- services/common/src/res_sched_util.cpp | 4 ++-- .../app_launch_data_test.cpp | 16 ++++++++++++++++ .../res_sched_util_test.cpp | 2 +- 15 files changed, 77 insertions(+), 11 deletions(-) diff --git a/frameworks/native/appkit/app/main_thread.cpp b/frameworks/native/appkit/app/main_thread.cpp index cb0cb60d00..091515d8bd 100644 --- a/frameworks/native/appkit/app/main_thread.cpp +++ b/frameworks/native/appkit/app/main_thread.cpp @@ -1711,6 +1711,11 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con static_cast(hapModuleInfo.aotCompileStatus); } } + options.enableWarmStartupSmartGC = + (appLaunchData.GetAppPreloadMode() == AppExecFwk::PreloadMode::PRE_MAKE || + appLaunchData.GetAppPreloadMode() == AppExecFwk::PreloadMode::PRELOAD_MODULE); + TAG_LOGI(AAFwkTag::APPKIT, "SmartGC: process is start. enable warm startup SmartGC: %{public}d", + static_cast(options.enableWarmStartupSmartGC)); auto runtime = AbilityRuntime::Runtime::Create(options); if (!runtime) { TAG_LOGE(AAFwkTag::APPKIT, "null runtime"); @@ -1938,7 +1943,7 @@ void MainThread::HandleLaunchApplication(const AppLaunchData &appLaunchData, con HandleNWebPreload(); } #endif - if (appLaunchData.IsNeedPreloadModule()) { + if (appLaunchData.GetAppPreloadMode() == AppExecFwk::PreloadMode::PRELOAD_MODULE) { PreloadModule(entryHapModuleInfo, application_->GetRuntime()); } } diff --git a/frameworks/native/runtime/js_runtime.cpp b/frameworks/native/runtime/js_runtime.cpp index 3e27628ca4..4e5eb21356 100644 --- a/frameworks/native/runtime/js_runtime.cpp +++ b/frameworks/native/runtime/js_runtime.cpp @@ -637,6 +637,8 @@ void JsRuntime::PostPreload(const Options& options) TAG_LOGD(AAFwkTag::JSRUNTIME, "ASMM JIT Verify PostFork, jitEnabled: %{public}d", options.jitEnabled); postOption.SetEnableJIT(options.jitEnabled); postOption.SetAOTCompileStatusMap(options.aotCompileStatusMap); + TAG_LOGD(AAFwkTag::JSRUNTIME, "SmartGC: set options enableWarmStartupSmartGC to RuntimeOption"); + postOption.SetEnableWarmStartupSmartGC(options.enableWarmStartupSmartGC); { HITRACE_METER_NAME(HITRACE_TAG_APP, "panda::JSNApi::PostFork"); panda::JSNApi::PostFork(vm, postOption); diff --git a/interfaces/inner_api/app_manager/include/appmgr/app_launch_data.h b/interfaces/inner_api/app_manager/include/appmgr/app_launch_data.h index 67e753601d..ee2c7a633c 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/app_launch_data.h +++ b/interfaces/inner_api/app_manager/include/appmgr/app_launch_data.h @@ -309,6 +309,20 @@ public: */ bool IsNeedPreloadModule() const; + /** + * @brief Setting preload mode. + * + * @param preloadMode PreloadMode enum + */ + void SetAppPreloadMode(PreloadMode preloadMode); + + /** + * @brief Obtains preload mode. + * + * @return Returns preloadMode enum + */ + PreloadMode GetAppPreloadMode() const; + /** * @brief Setting if allow nweb preload. * @@ -342,6 +356,7 @@ private: bool isMultiThread_ = false; bool isErrorInfoEnhance_ = false; bool isNeedPreloadModule_ = false; + PreloadMode appPreloadMode_ = PreloadMode::PRELOAD_NONE; bool isAllowedNWebPreload_ = false; int32_t recordId_ = 0; int32_t uId_ = 0; diff --git a/interfaces/inner_api/app_manager/include/appmgr/running_process_info.h b/interfaces/inner_api/app_manager/include/appmgr/running_process_info.h index 1873da6497..b14a60f077 100644 --- a/interfaces/inner_api/app_manager/include/appmgr/running_process_info.h +++ b/interfaces/inner_api/app_manager/include/appmgr/running_process_info.h @@ -79,6 +79,7 @@ struct RunningProcessInfo : public Parcelable { static RunningProcessInfo *Unmarshalling(Parcel &parcel); ProcessType processType_ = ProcessType::NORMAL; ExtensionAbilityType extensionType_ = ExtensionAbilityType::UNSPECIFIED; + bool isCached = false; }; } // namespace AppExecFwk } // namespace OHOS diff --git a/interfaces/inner_api/app_manager/src/appmgr/app_launch_data.cpp b/interfaces/inner_api/app_manager/src/appmgr/app_launch_data.cpp index bb68a64e40..67411eaff3 100644 --- a/interfaces/inner_api/app_manager/src/appmgr/app_launch_data.cpp +++ b/interfaces/inner_api/app_manager/src/appmgr/app_launch_data.cpp @@ -117,7 +117,12 @@ bool AppLaunchData::MarshallingExtend(Parcel &parcel) const } if (!parcel.WriteBool(isNeedPreloadModule_)) { - TAG_LOGE(AAFwkTag::APPMGR, "Marshalling, Failed to write instance key."); + TAG_LOGE(AAFwkTag::APPMGR, "Marshalling, Failed to write is need preload module."); + return false; + } + + if (!parcel.WriteInt32(static_cast(appPreloadMode_))) { + TAG_LOGE(AAFwkTag::APPMGR, "Marshalling, Failed to write app preload mode"); return false; } @@ -190,6 +195,7 @@ bool AppLaunchData::ReadFromParcel(Parcel &parcel) isErrorInfoEnhance_ = parcel.ReadBool(); instanceKey_ = parcel.ReadString(); isNeedPreloadModule_ = parcel.ReadBool(); + appPreloadMode_ = static_cast(parcel.ReadInt32()); isAllowedNWebPreload_ = parcel.ReadBool(); preloadModuleName_ = parcel.ReadString(); isDebugFromLocal_ = parcel.ReadBool(); @@ -311,6 +317,16 @@ bool AppLaunchData::IsNeedPreloadModule() const return isNeedPreloadModule_; } +void AppLaunchData::SetAppPreloadMode(PreloadMode preloadMode) +{ + appPreloadMode_ = preloadMode; +} + +PreloadMode AppLaunchData::GetAppPreloadMode() const +{ + return appPreloadMode_; +} + void AppLaunchData::SetNWebPreload(const bool isAllowedNWebPreload) { isAllowedNWebPreload_ = isAllowedNWebPreload; diff --git a/interfaces/inner_api/app_manager/src/appmgr/running_process_info.cpp b/interfaces/inner_api/app_manager/src/appmgr/running_process_info.cpp index e30da61ef5..b4d1eda553 100644 --- a/interfaces/inner_api/app_manager/src/appmgr/running_process_info.cpp +++ b/interfaces/inner_api/app_manager/src/appmgr/running_process_info.cpp @@ -71,6 +71,7 @@ bool RunningProcessInfo::ReadFromParcel(Parcel &parcel) int32_t pssData; READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, pssData); pssValue = static_cast(pssData); + isCached = parcel.ReadBool(); return true; } @@ -111,6 +112,7 @@ bool RunningProcessInfo::Marshalling(Parcel &parcel) const WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast(appMode)); WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast(rssValue)); WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast(pssValue)); + WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isCached); return true; } } // namespace AppExecFwk diff --git a/interfaces/inner_api/runtime/include/runtime.h b/interfaces/inner_api/runtime/include/runtime.h index 9352326216..457106ae90 100644 --- a/interfaces/inner_api/runtime/include/runtime.h +++ b/interfaces/inner_api/runtime/include/runtime.h @@ -75,6 +75,7 @@ public: std::map packageNameList; std::map aotCompileStatusMap; uint32_t versionCode = 0; + bool enableWarmStartupSmartGC = false; }; struct DebugOption { diff --git a/services/abilitymgr/src/ability_connect_manager.cpp b/services/abilitymgr/src/ability_connect_manager.cpp index c3afff7354..c8942fd7db 100644 --- a/services/abilitymgr/src/ability_connect_manager.cpp +++ b/services/abilitymgr/src/ability_connect_manager.cpp @@ -3718,7 +3718,7 @@ int32_t AbilityConnectManager::ReportAbilityStartInfoToRSS(const AppExecFwk::Abi } } TAG_LOGI(AAFwkTag::SERVICE_EXT, "ReportAbilityStartInfoToRSS, abilityName:%{public}s", abilityInfo.name.c_str()); - ResSchedUtil::GetInstance().ReportAbilityStartInfoToRSS(abilityInfo, pid, isColdStart, -1); // -1代表与预加载无关 + ResSchedUtil::GetInstance().ReportAbilityStartInfoToRSS(abilityInfo, pid, isColdStart, false); return ERR_OK; } diff --git a/services/abilitymgr/src/ability_manager_service.cpp b/services/abilitymgr/src/ability_manager_service.cpp index dd43f19553..4714a0ef95 100644 --- a/services/abilitymgr/src/ability_manager_service.cpp +++ b/services/abilitymgr/src/ability_manager_service.cpp @@ -2944,19 +2944,25 @@ void AbilityManagerService::ReportAbilityStartInfoToRSS(const AppExecFwk::Abilit } bool isColdStart = true; int32_t pid = 0; - int32_t warmStartType = -1; + bool supportWarmSmartGC = false; for (auto const &info : runningProcessInfos) { if (info.uid_ == abilityInfo.applicationInfo.uid && info.processType_ == AppExecFwk::ProcessType::NORMAL && - std::find(info.bundleNames.begin(), info.bundleNames.end(), + std::find(info.bundleNames.begin(), info.bundleNames.end(), abilityInfo.applicationInfo.bundleName) != info.bundleNames.end()) { isColdStart = info.isExiting ? true : info.preloadMode_ == AppExecFwk::PreloadMode::PRESS_DOWN; pid = info.isExiting ? 0 : info.pid_; - warmStartType = static_cast(info.preloadMode_); + AppExecFwk::PreloadMode mode = info.preloadMode_; + bool isSuggestCache = info.isCached; + bool supportWarmSmartGC = (isSuggestCache || + mode == AppExecFwk::PreloadMode::PRE_MAKE || + mode == AppExecFwk::PreloadMode::PRELOAD_MODULE); + TAG_LOGI(AAFwkTag::ABILITYMGR, "SmartGC: Process %{public}d report to RSS, start type: %{public}d, isCached: %{public}d, supportWarmGC: %{public}d", + pid, static_cast(mode), static_cast(isSuggestCache), static_cast(supportWarmSmartGC)); break; } } - ResSchedUtil::GetInstance().ReportAbilityStartInfoToRSS(abilityInfo, pid, isColdStart, warmStartType); + ResSchedUtil::GetInstance().ReportAbilityStartInfoToRSS(abilityInfo, pid, isColdStart, supportWarmSmartGC); } } diff --git a/services/appmgr/src/app_mgr_service_inner.cpp b/services/appmgr/src/app_mgr_service_inner.cpp index 94d8a07e2a..341b1217aa 100644 --- a/services/appmgr/src/app_mgr_service_inner.cpp +++ b/services/appmgr/src/app_mgr_service_inner.cpp @@ -2717,6 +2717,7 @@ void AppMgrServiceInner::GetRunningProcess(const std::shared_ptrIsDebug(); info.isExiting = appRecord->IsTerminating() || appRecord->IsKilling() || appRecord->GetRestartAppFlag() || appRecord->IsUserRequestCleaning(); + info.isCached = DelayedSingleton::GetInstance()->IsCachedProcess(appRecord); if (appRecord->GetUserTestInfo() != nullptr && system::GetBoolParameter(DEVELOPER_MODE_STATE, false)) { info.isTestMode = true; } diff --git a/services/appmgr/src/app_running_record.cpp b/services/appmgr/src/app_running_record.cpp index 1915f7764b..8480d30d5e 100644 --- a/services/appmgr/src/app_running_record.cpp +++ b/services/appmgr/src/app_running_record.cpp @@ -355,6 +355,7 @@ void AppRunningRecord::LaunchApplication(const Configuration &config) launchData.SetNativeStart(isNativeStart_); launchData.SetAppRunningUniqueId(std::to_string(startTimeMillis_)); launchData.SetIsNeedPreloadModule(isNeedPreloadModule_); + launchData.SetAppPreloadMode(preloadMode_); launchData.SetNWebPreload(isAllowedNWebPreload_); launchData.SetPreloadModuleName(preloadModuleName_); launchData.SetDebugFromLocal(isDebugFromLocal_); diff --git a/services/common/include/res_sched_util.h b/services/common/include/res_sched_util.h index 63d6527539..f7cb27e478 100644 --- a/services/common/include/res_sched_util.h +++ b/services/common/include/res_sched_util.h @@ -49,7 +49,7 @@ class ResSchedUtil final { public: static ResSchedUtil &GetInstance(); void ReportAbilityStartInfoToRSS(const AbilityInfo &abilityInfo, int32_t pid, bool isColdStart, - int32_t warmStartType); + bool supportWarmSmartGC); void ReportPreloadApplicationToRSS(const std::shared_ptr& abilityInfo, int32_t preloadMode); void ReportAbilityAssociatedStartInfoToRSS( const AbilityInfo &abilityInfo, int64_t resSchedType, int32_t callerUid, int32_t callerPid); diff --git a/services/common/src/res_sched_util.cpp b/services/common/src/res_sched_util.cpp index 649e251030..5b2df1149b 100644 --- a/services/common/src/res_sched_util.cpp +++ b/services/common/src/res_sched_util.cpp @@ -63,7 +63,7 @@ void ResSchedUtil::ReportSubHealtyPerfInfoToRSS() } void ResSchedUtil::ReportAbilityStartInfoToRSS(const AbilityInfo &abilityInfo, int32_t pid, bool isColdStart, - int32_t warmStartType) + bool supportWarmSmartGC) { #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE uint32_t resType = ResourceSchedule::ResType::RES_TYPE_APP_ABILITY_START; @@ -73,7 +73,7 @@ void ResSchedUtil::ReportAbilityStartInfoToRSS(const AbilityInfo &abilityInfo, i { "bundleName", abilityInfo.applicationInfo.bundleName }, { "abilityName", abilityInfo.name }, { "pid", std::to_string(pid) }, - { "warmStartType", std::to_string(warmStartType) } + { "supportWarmSmartGC", supportWarmSmartGC ? "1": "0" } }; TAG_LOGD(AAFwkTag::DEFAULT, "call"); ResourceSchedule::ResSchedClient::GetInstance().ReportData(resType, isColdStart ? 1 : 0, eventParams); diff --git a/test/unittest/app_launch_data_test/app_launch_data_test.cpp b/test/unittest/app_launch_data_test/app_launch_data_test.cpp index 0997fb1cfe..01f10d4d63 100644 --- a/test/unittest/app_launch_data_test/app_launch_data_test.cpp +++ b/test/unittest/app_launch_data_test/app_launch_data_test.cpp @@ -147,5 +147,21 @@ HWTEST_F(AppLaunchDataTest, ReadFromParcel_0100, TestSize.Level1) EXPECT_EQ(launchData_->appIndex_, appIndex); EXPECT_EQ(launchData_->debugApp_, isDebug); } + +/** + * @tc.name: GetAppPreloadMode_0100 + * @tc.desc: AppLaunchData SetAppPreloadMode, verify if AppLaunchData startup successfully. + * @tc.type: FUNC + */ +HWTEST_F(AppLaunchDataTest, GetAppPreloadMode_0100, TestSize.Level1) +{ + EXPECT_NE(launchData_, nullptr); + PreloadMode premakeMode = PreloadMode::PRE_MAKE; + launchData_->SetAppPreloadMode(premakeMode); + EXPECT_EQ(premakeMode, launchData_->GetAppPreloadMode()); + + launchData_->SetAppPreloadMode(PreloadMode::PRELOAD_MODULE); + EXPECT_NE(premakeMode, launchData_->GetAppPreloadMode()); +} } // namespace AppExecFwk } // namespace OHOS diff --git a/test/unittest/res_sched_util_test/res_sched_util_test.cpp b/test/unittest/res_sched_util_test/res_sched_util_test.cpp index ef5945009c..43309c1b55 100644 --- a/test/unittest/res_sched_util_test/res_sched_util_test.cpp +++ b/test/unittest/res_sched_util_test/res_sched_util_test.cpp @@ -58,7 +58,7 @@ HWTEST_F(ResSchedUtilTest, ResSchedUtilTest_0100, TestSize.Level2) TAG_LOGI(AAFwkTag::TEST, "ResSchedUtilTest_0100 called."); AbilityInfo abilityInfo; int64_t resSchedType = -1; - AAFwk::ResSchedUtil::GetInstance().ReportAbilityStartInfoToRSS(abilityInfo, -1, false, -1); + AAFwk::ResSchedUtil::GetInstance().ReportAbilityStartInfoToRSS(abilityInfo, -1, false, false); AAFwk::ResSchedUtil::GetInstance().ReportAbilityAssociatedStartInfoToRSS(abilityInfo, resSchedType, 0, 0); int64_t ret = AAFwk::ResSchedUtil::GetInstance().convertType(resSchedType); EXPECT_EQ(resSchedType, ret);