From b17ad39ee2811940bdc200b2a3ce0d45d7d1b9f6 Mon Sep 17 00:00:00 2001 From: yaochaonan Date: Wed, 9 Jul 2025 08:52:40 +0800 Subject: [PATCH 1/6] Signed-off-by: yaochaonan Change-Id: I13c8fe2264f3f2c5927137a3f70b51418c14e75d --- .../compiler/aot_compiler_preprocessor.cpp | 1 - ecmascript/compiler/call_signature.cpp | 14 ++++ ecmascript/compiler/call_signature.h | 3 +- ecmascript/compiler/stub_builder-inl.h | 13 ++++ ecmascript/compiler/stub_builder.cpp | 16 +++-- ecmascript/compiler/stub_builder.h | 2 + ecmascript/module/js_module_manager.cpp | 20 ------ ecmascript/module/js_module_manager.h | 8 +-- ecmascript/module/js_module_namespace.cpp | 7 ++ ecmascript/module/js_module_source_text.cpp | 22 ++++-- .../module/js_shared_module_manager.cpp | 40 ++++++----- ecmascript/module/js_shared_module_manager.h | 21 +++--- ecmascript/module/module_resolver.cpp | 7 +- ecmascript/module/module_snapshot.cpp | 14 ++-- ecmascript/module/module_value_accessor.cpp | 10 ++- ecmascript/module/tests/ecma_module_test.cpp | 70 ++++++++++++++++--- ecmascript/stubs/runtime_stub_list.h | 3 +- ecmascript/stubs/runtime_stubs.cpp | 13 ++++ 18 files changed, 199 insertions(+), 85 deletions(-) diff --git a/ecmascript/compiler/aot_compiler_preprocessor.cpp b/ecmascript/compiler/aot_compiler_preprocessor.cpp index d4f383beca..f9b9411d6c 100644 --- a/ecmascript/compiler/aot_compiler_preprocessor.cpp +++ b/ecmascript/compiler/aot_compiler_preprocessor.cpp @@ -332,7 +332,6 @@ void AotCompilerPreprocessor::ResolveModule(const JSPandaFile *jsPandaFile, cons ModuleResolver::HostResolveImportedModule( thread, fileName.c_str(), CString(recordName.data(), recordName.size())); RETURN_IF_ABRUPT_COMPLETION(thread); - SharedModuleManager::GetInstance()->TransferSModule(thread); } } } diff --git a/ecmascript/compiler/call_signature.cpp b/ecmascript/compiler/call_signature.cpp index b76f88af48..c8eb5c744f 100644 --- a/ecmascript/compiler/call_signature.cpp +++ b/ecmascript/compiler/call_signature.cpp @@ -3886,6 +3886,20 @@ DEF_CALL_SIGNATURE(FindPatchModule) callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC); } +DEF_CALL_SIGNATURE(UpdateSharedModule) +{ + // 2 : 2 input parameters + CallSignature updateSharedModule("UpdateSharedModule", 0, 2, ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY()); + *callSign = updateSharedModule; + std::array params = { // 2 : 2 input parameters + VariableType::NATIVE_POINTER(), + VariableType::JS_ANY(), + }; + callSign->SetParameters(params.data()); + callSign->SetGCLeafFunction(true); + callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC); +} + DEF_CALL_SIGNATURE(FatalPrintMisstakenResolvedBinding) { // 3 : 3 input parameters diff --git a/ecmascript/compiler/call_signature.h b/ecmascript/compiler/call_signature.h index 15f0ea8197..92370ccdfa 100644 --- a/ecmascript/compiler/call_signature.h +++ b/ecmascript/compiler/call_signature.h @@ -712,7 +712,8 @@ private: V(MarkRSetCardTable) \ V(MarkInBuffer) \ V(BatchMarkInBuffer) \ - V(CMCSetValueWithBarrier) + V(CMCSetValueWithBarrier) \ + V(UpdateSharedModule) #define DECL_CALL_SIGNATURE(name) \ class name##CallSignature final { \ diff --git a/ecmascript/compiler/stub_builder-inl.h b/ecmascript/compiler/stub_builder-inl.h index b226427c0b..0febd622ff 100644 --- a/ecmascript/compiler/stub_builder-inl.h +++ b/ecmascript/compiler/stub_builder-inl.h @@ -4582,6 +4582,19 @@ inline GateRef StubBuilder::IsCjsModule(GateRef module) return Int32Equal(moduleType, Int32(static_cast(ModuleTypes::CJS_MODULE))); } +inline GateRef StubBuilder::GetSharedType(GateRef module) +{ + GateRef bitfield = GetBitFieldFromSourceTextModule(module); + return Int32And(Int32LSR(bitfield, Int32(SourceTextModule::REGISTER_COUNTS)), + Int32((1LU << SourceTextModule::IS_SHARED_TYPE_BITS) - 1)); +} + +inline GateRef StubBuilder::IsSharedModule(GateRef module) +{ + GateRef sharedType = GetSharedType(module); + return Int32Equal(sharedType, Int32(static_cast(SharedTypes::SHARED_MODULE))); +} + inline GateRef StubBuilder::GetCjsModuleFunction(GateRef glue) { GateRef globalEnv = GetCurrentGlobalEnv(); diff --git a/ecmascript/compiler/stub_builder.cpp b/ecmascript/compiler/stub_builder.cpp index 2f92b62539..3d61554776 100644 --- a/ecmascript/compiler/stub_builder.cpp +++ b/ecmascript/compiler/stub_builder.cpp @@ -12230,18 +12230,26 @@ GateRef StubBuilder::LoadExternalmodulevar(GateRef glue, GateRef index, GateRef Label isLdEndExecPatchMain(env); Label notLdEndExecPatchMain(env); Label notHole(env); - GateRef resolvedModule = GetResolveModuleFromResolvedIndexBinding(glue, resolvedBinding); - ResolvedModuleMustBeSourceTextModule(glue, resolvedModule); + DEFVARIABLE(resolvedModule, VariableType::JS_ANY(), Hole()); + resolvedModule = GetResolveModuleFromResolvedIndexBinding(glue, resolvedBinding); + ResolvedModuleMustBeSourceTextModule(glue, *resolvedModule); GateRef idxOfResolvedBinding = GetIdxOfResolvedIndexBinding(resolvedBinding); BRANCH(IsLdEndExecPatchMain(glue), &isLdEndExecPatchMain, ¬LdEndExecPatchMain); Bind(&isLdEndExecPatchMain); GateRef resolvedModuleOfHotReload = CallNGCRuntime(glue, RTSTUB_ID(FindPatchModule), - {glue, resolvedModule}); + {glue, *resolvedModule}); BRANCH(TaggedIsHole(resolvedModuleOfHotReload), ¬LdEndExecPatchMain, ¬Hole); Bind(¬LdEndExecPatchMain); - result = GetModuleValue(glue, resolvedModule, idxOfResolvedBinding); + Label isSharedModule(env); + Label notSharedModule(env); + BRANCH(IsSharedModule(*resolvedModule), &isSharedModule, ¬SharedModule); + Bind(&isSharedModule); + // resolvedModule = CallNGCRuntime(glue, RTSTUB_ID(UpdateSharedModule), {glue, *resolvedModule}); + Jump(¬SharedModule); + Bind(¬SharedModule); + result = GetModuleValue(glue, *resolvedModule, idxOfResolvedBinding); Jump(&exit); Bind(¬Hole); diff --git a/ecmascript/compiler/stub_builder.h b/ecmascript/compiler/stub_builder.h index 07003e6903..8ad19ed9af 100644 --- a/ecmascript/compiler/stub_builder.h +++ b/ecmascript/compiler/stub_builder.h @@ -1226,6 +1226,8 @@ public: inline GateRef GetModuleType(GateRef module); inline GateRef IsNativeModule(GateRef module); inline GateRef IsCjsModule(GateRef module); + inline GateRef GetSharedType(GateRef module); + inline GateRef IsSharedModule(GateRef module); inline GateRef GetCjsModuleFunction(GateRef glue); void ModuleEnvMustBeValid(GateRef glue, GateRef curEnv); GateRef SearchFromModuleCache(GateRef glue, GateRef moduleName); diff --git a/ecmascript/module/js_module_manager.cpp b/ecmascript/module/js_module_manager.cpp index 3922062c2c..09081ad14c 100644 --- a/ecmascript/module/js_module_manager.cpp +++ b/ecmascript/module/js_module_manager.cpp @@ -192,21 +192,6 @@ bool ModuleManager::NeedExecuteModule(const CString &referencing) return true; } -void ModuleManager::AddToInstantiatingSModuleList(const CString &record) -{ - InstantiatingSModuleList_.push_back(record); -} - -CVector ModuleManager::GetInstantiatingSModuleList() -{ - return InstantiatingSModuleList_; -} - -void ModuleManager::ClearInstantiatingSModuleList() -{ - InstantiatingSModuleList_.clear(); -} - void ModuleManager::Iterate(RootVisitor &v) { for (auto &it : resolvedModules_) { @@ -395,11 +380,6 @@ void ModuleManager::RemoveModuleFromCache(const CString& recordName) // this function only remove module's name from resolvedModules List, it's content still needed by sharedmodule void ModuleManager::RemoveModuleNameFromList(const CString& recordName) { - auto entry = resolvedModules_.find(recordName); - if (entry == resolvedModules_.end()) { // LCOV_EXCL_BR_LINE - LOG_ECMA(FATAL) << "Can not get module: " << recordName << - ", when try to remove the module"; - } resolvedModules_.erase(recordName); } diff --git a/ecmascript/module/js_module_manager.h b/ecmascript/module/js_module_manager.h index 3d23a42b43..18255ccdae 100644 --- a/ecmascript/module/js_module_manager.h +++ b/ecmascript/module/js_module_manager.h @@ -32,7 +32,6 @@ public: explicit ModuleManager(EcmaVM *vm); ~ModuleManager() { - InstantiatingSModuleList_.clear(); resolvedModules_.clear(); } @@ -63,7 +62,7 @@ public: JSHandle TryGetImportedModule(const CString& referencing); void Iterate(RootVisitor &v); - void AddToInstantiatingSModuleList(const CString &record); + ModuleExecuteMode GetExecuteMode() const { return isExecuteBuffer_.load(std::memory_order_acquire); @@ -136,10 +135,6 @@ private: NO_COPY_SEMANTIC(ModuleManager); NO_MOVE_SEMANTIC(ModuleManager); - CVector GetInstantiatingSModuleList(); - - void ClearInstantiatingSModuleList(); - void RemoveModuleFromCache(const CString &recordName); void RemoveModuleNameFromList(const CString &recordName); @@ -151,7 +146,6 @@ private: EcmaVM *vm_ {nullptr}; CUnorderedMap resolvedModules_; std::atomic isExecuteBuffer_ {ModuleExecuteMode::ExecuteZipMode}; - CVector InstantiatingSModuleList_; friend class EcmaVM; friend class PatchLoader; diff --git a/ecmascript/module/js_module_namespace.cpp b/ecmascript/module/js_module_namespace.cpp index 069a62bcab..377c8d3e82 100644 --- a/ecmascript/module/js_module_namespace.cpp +++ b/ecmascript/module/js_module_namespace.cpp @@ -154,6 +154,13 @@ OperationResult ModuleNamespace::GetProperty(JSThread *thread, const JSHandle sharedModule = SharedModuleManager::GetInstance()->GetSModule( + thread, module->GetEcmaModuleRecordNameString()); + if (sharedModule.GetTaggedValue().IsSourceTextModule()) { + module = sharedModule; + } + } result = module->GetModuleValue(thread, resolvedBind->GetIndex(), true); } break; diff --git a/ecmascript/module/js_module_source_text.cpp b/ecmascript/module/js_module_source_text.cpp index b0b2bb497b..b69265c07c 100644 --- a/ecmascript/module/js_module_source_text.cpp +++ b/ecmascript/module/js_module_source_text.cpp @@ -523,7 +523,6 @@ int SourceTextModule::Instantiate(JSThread *thread, const JSHandleTransferSModule(thread); return SourceTextModule::UNDEFINED_INDEX; } @@ -1109,7 +1108,8 @@ int SourceTextModule::InnerModuleEvaluation(JSThread *thread, JSHandlefindModuleMutexWithLock(thread, module); + SharedModuleManager* sharedModuleManager = SharedModuleManager::GetInstance(); + StateVisit &stateVisit = sharedModuleManager->FindModuleMutexWithLock(thread, module); ModuleStatus status = module->GetStatus(); if (status == ModuleStatus::EVALUATING && stateVisit.threadId == thread->GetThreadId()) { @@ -1121,7 +1121,9 @@ int SourceTextModule::InnerModuleEvaluation(JSThread *thread, JSHandle + TransferFromLocalToSharedModuleMapAndGetInsertedSModule(thread, module); + if (module->GetStatus() == ModuleStatus::INSTANTIATED) { stateVisit.threadId = thread->GetThreadId(); int idx = SourceTextModule::InnerModuleEvaluationUnsafe( thread, module, stack, errorStack, index, buffer, size, executeType); @@ -2230,10 +2232,22 @@ JSHandle SourceTextModule::GetRequestedModuleMayThrowError(JSThre return JSHandle::Cast(GetModuleFromCacheOrResolveNewOne(thread, module, requestedModules, idx)); } +/* + * case A import B + * if B is sharedModule, every thread will instantiate one if sharedModule B have not put on sharedModuleMap. + * In this case, current thread's B may not be the final shared module in sharedModuleMap, + * so we shoule use recordName instead of SourceTextModule, + * and use [GetImportedModule] to get the final sharedModule B. + * + * normal -> normal: SourceTextModule + * normal -> shared: recordName + * shared -> normal: recordName + * shared -> shared: recordName + */ void SourceTextModule::SetRequestedModules(JSThread *thread, JSHandle requestedModules, uint32_t idx, JSHandle requiredModule, bool isShared) { - if (!isShared) { + if (!isShared && !IsSharedModule(JSHandle::Cast(requiredModule))) { requestedModules->Set(thread, idx, requiredModule.GetTaggedValue()); } else { CString recordName = GetModuleName(requiredModule.GetTaggedValue()); diff --git a/ecmascript/module/js_shared_module_manager.cpp b/ecmascript/module/js_shared_module_manager.cpp index a49895d973..57d8b9c6ed 100644 --- a/ecmascript/module/js_shared_module_manager.cpp +++ b/ecmascript/module/js_shared_module_manager.cpp @@ -68,32 +68,36 @@ bool SharedModuleManager::SearchInSModuleManager(JSThread *thread, const CString RuntimeLockHolder locker(thread, mutex_); return SearchInSModuleManagerUnsafe(recordName); } -void SharedModuleManager::InsertInSModuleManager(JSThread *thread, const CString &recordName, - JSHandle &moduleRecord) + +bool SharedModuleManager::TryInsertInSModuleManager(JSThread *thread, const CString &recordName, + const JSHandle &moduleRecord) { RuntimeLockHolder locker(thread, mutex_); JSHandle module = JSHandle::Cast(moduleRecord); - if (!SearchInSModuleManagerUnsafe(recordName)) { - AddResolveImportedSModule(recordName, module.GetTaggedValue()); - StateVisit stateVisit; - sharedModuleMutex_.emplace(recordName, std::move(stateVisit)); - } + return AddResolveImportedSModule(recordName, module.GetTaggedValue()); } -void SharedModuleManager::TransferSModule(JSThread *thread) +void SharedModuleManager::AddToResolvedModulesAndCreateSharedModuleMutex( + JSThread *thread, const CString &recordName, JSTaggedValue module) { - ModuleManager *moduleManager = thread->GetModuleManager(); - CVector instantiatingSModuleList = moduleManager->GetInstantiatingSModuleList(); - for (auto s:instantiatingSModuleList) { - JSHandle module = moduleManager->HostGetImportedModule(s); - ASSERT(module->GetSharedType() == SharedTypes::SHARED_MODULE); - InsertInSModuleManager(thread, s, module); - moduleManager->RemoveModuleNameFromList(s); - } - moduleManager->ClearInstantiatingSModuleList(); + // Add to normal module resolvedModules_ + thread->GetModuleManager()->AddResolveImportedModule(recordName, module); + RuntimeLockHolder locker(thread, mutex_); + StateVisit stateVisit; + sharedModuleMutex_.emplace(recordName, std::move(stateVisit)); +} + +JSHandle SharedModuleManager::TransferFromLocalToSharedModuleMapAndGetInsertedSModule( + JSThread *thread, const JSHandle &module) +{ + ASSERT(module->GetSharedType() == SharedTypes::SHARED_MODULE); + CString recordName = module->GetEcmaModuleRecordNameString(); + bool success = TryInsertInSModuleManager(thread, recordName, module); + thread->GetModuleManager()->RemoveModuleNameFromList(recordName); + return success? module : GetSModule(thread, recordName); } -StateVisit &SharedModuleManager::findModuleMutexWithLock(JSThread *thread, const JSHandle &module) +StateVisit &SharedModuleManager::FindModuleMutexWithLock(JSThread *thread, const JSHandle &module) { RuntimeLockHolder locker(thread, mutex_); CString moduleName = SourceTextModule::GetModuleName(module.GetTaggedValue()); diff --git a/ecmascript/module/js_shared_module_manager.h b/ecmascript/module/js_shared_module_manager.h index 3e52b810f0..d458b48b07 100644 --- a/ecmascript/module/js_shared_module_manager.h +++ b/ecmascript/module/js_shared_module_manager.h @@ -43,16 +43,14 @@ public: void Iterate(RootVisitor &v); - StateVisit &findModuleMutexWithLock(JSThread *thread, const JSHandle &module); + StateVisit &FindModuleMutexWithLock(JSThread *thread, const JSHandle &module); bool SearchInSModuleManager(JSThread *thread, const CString &recordName); - void InsertInSModuleManager(JSThread *thread, const CString &recordName, - JSHandle &moduleRecord); - JSHandle GetSModule(JSThread *thread, const CString &recordName); - void PUBLIC_API TransferSModule(JSThread *thread); + JSHandle PUBLIC_API TransferFromLocalToSharedModuleMapAndGetInsertedSModule( + JSThread *thread, const JSHandle &module); bool IsInstantiatedSModule(JSThread *thread, const JSHandle &module); @@ -60,11 +58,15 @@ public: const CString &entryPoint, ClassKind classKind = ClassKind::NON_SENDABLE); JSHandle SModuleNamespaceCreate(JSThread *thread, const JSHandle &module, - const JSHandle &exports); + const JSHandle &exports); + + void AddToResolvedModulesAndCreateSharedModuleMutex(JSThread *thread, + const CString &recordName, + JSTaggedValue module); - inline void AddResolveImportedSModule(const CString &recordName, JSTaggedValue module) + inline bool AddResolveImportedSModule(const CString &recordName, JSTaggedValue module) { - resolvedSharedModules_.emplace(recordName, module); + return resolvedSharedModules_.try_emplace(recordName, module).second; } inline void UpdateResolveImportedSModule(const CString &recordName, JSTaggedValue module) @@ -101,6 +103,9 @@ private: JSHandle GetSModuleUnsafe(JSThread *thread, const CString &recordName); + bool TryInsertInSModuleManager(JSThread *thread, const CString &recordName, + const JSHandle &moduleRecord); + static constexpr uint32_t DEAULT_DICTIONART_CAPACITY = 4; CUnorderedMap resolvedSharedModules_; CMap sharedModuleMutex_; diff --git a/ecmascript/module/module_resolver.cpp b/ecmascript/module/module_resolver.cpp index f271f9d73f..639d79d4b1 100644 --- a/ecmascript/module/module_resolver.cpp +++ b/ecmascript/module/module_resolver.cpp @@ -161,8 +161,7 @@ JSHandle ModuleResolver::ResolveSharedImportedModuleWithMerge(JST return JSHandle(sharedModuleManager->GetSModule(thread, recordName)); } // before resolving module completely, shared-module put into isolate -thread resolvedModules_ temporarily. - ModuleManager *moduleManager = thread->GetModuleManager(); - JSHandle module = moduleManager->TryGetImportedModule(recordName); + JSHandle module = thread->GetModuleManager()->TryGetImportedModule(recordName); if (!module->IsUndefined()) { return module; } @@ -171,8 +170,8 @@ JSHandle ModuleResolver::ResolveSharedImportedModuleWithMerge(JST JSHandle moduleRecord = SharedModuleHelper::ParseSharedModule(thread, jsPandaFile, recordName, fileName, recordInfo); JSHandle::Cast(moduleRecord)->SetEcmaModuleRecordNameString(recordName); - moduleManager->AddResolveImportedModule(recordName, moduleRecord.GetTaggedValue()); - moduleManager->AddToInstantiatingSModuleList(recordName); + sharedModuleManager->AddToResolvedModulesAndCreateSharedModuleMutex( + thread, recordName, moduleRecord.GetTaggedValue()); return moduleRecord; } diff --git a/ecmascript/module/module_snapshot.cpp b/ecmascript/module/module_snapshot.cpp index ce1727ab1e..8c3cd0fedd 100644 --- a/ecmascript/module/module_snapshot.cpp +++ b/ecmascript/module/module_snapshot.cpp @@ -61,17 +61,15 @@ bool ModuleSnapshot::DeserializeData(const EcmaVM *vm, const CString &path, cons JSHandle deserializedModules = JSHandle::Cast(deserializer.ReadValue()); uint32_t length = deserializedModules->GetLength(); for (uint32_t i = 0; i < length; i++) { - JSTaggedValue value = deserializedModules->Get(thread, i); - JSHandle moduleHdl(thread, SourceTextModule::Cast(value.GetTaggedObject())); - CString moduleName = SourceTextModule::GetModuleName(moduleHdl.GetTaggedValue()); + JSTaggedValue module = deserializedModules->Get(thread, i); + JSHandle moduleHdl(thread, SourceTextModule::Cast(module.GetTaggedObject())); + CString moduleName = SourceTextModule::GetModuleName(module); if (SourceTextModule::IsSharedModule(moduleHdl)) { - if (moduleHdl->GetStatus() == ModuleStatus::INSTANTIATED) { - SharedModuleManager::GetInstance()->InsertInSModuleManager(thread, moduleName, moduleHdl); - } + SharedModuleManager::GetInstance()->AddToResolvedModulesAndCreateSharedModuleMutex( + thread, moduleName, module); continue; } - ModuleManager *moduleManager = thread->GetModuleManager(); - moduleManager->AddResolveImportedModule(moduleName, value); + thread->GetModuleManager()->AddResolveImportedModule(moduleName, module); } LOG_ECMA(INFO) << "ModuleSnapshot::DeserializeData success"; return true; diff --git a/ecmascript/module/module_value_accessor.cpp b/ecmascript/module/module_value_accessor.cpp index 2cb097ecf1..2f14161db6 100644 --- a/ecmascript/module/module_value_accessor.cpp +++ b/ecmascript/module/module_value_accessor.cpp @@ -18,8 +18,9 @@ #include "ecmascript/interpreter/slow_runtime_stub.h" #include "ecmascript/interpreter/frame_handler.h" #include "ecmascript/jspandafile/js_pandafile_executor.h" -#include "ecmascript/require/js_cjs_module.h" +#include "ecmascript/module/js_shared_module_manager.h" #include "ecmascript/module/module_path_helper.h" +#include "ecmascript/require/js_cjs_module.h" namespace panda::ecmascript { JSTaggedValue ModuleValueAccessor::GetModuleValueInner(JSThread *thread, int32_t index) @@ -308,6 +309,13 @@ JSTaggedValue ModuleValueAccessor::GetModuleValueFromIndexBinding(const GetModul EvaluateModuleIfNeeded(info.thread, resolvedModule); } RETURN_VALUE_IF_ABRUPT_COMPLETION(info.thread, JSTaggedValue::Exception()); + if (SourceTextModule::IsSharedModule(resolvedModule)) { + JSHandle sharedModule = SharedModuleManager::GetInstance()->GetSModule( + info.thread, resolvedModule->GetEcmaModuleRecordNameString()); + if (sharedModule.GetTaggedValue().IsSourceTextModule()) { + resolvedModule.Update(sharedModule); + } + } LogModuleLoadInfo(info.thread, info.module, resolvedModule, info.index, info.isSendable); return GetModuleValue(info.thread, resolvedModule, binding->GetIndex()); } diff --git a/ecmascript/module/tests/ecma_module_test.cpp b/ecmascript/module/tests/ecma_module_test.cpp index c7ef468f5f..05fe497b11 100644 --- a/ecmascript/module/tests/ecma_module_test.cpp +++ b/ecmascript/module/tests/ecma_module_test.cpp @@ -148,6 +148,15 @@ public: GetModuleValueFromBindingInfo info { thread, module, resolvedBinding, 0, isSendable }; return ModuleValueAccessor::GetModuleValueFromRecordIndexBinding(info); } + + template + static JSTaggedValue GetModuleValueFromIndexBinding(JSThread *thread, JSHandle module, + JSTaggedValue resolvedBinding, bool isSendable) + { + GetModuleValueFromBindingInfo info { thread, module, resolvedBinding, 0, isSendable }; + return ModuleValueAccessor::GetModuleValueFromIndexBinding(info); + } + template static JSTaggedValue GetModuleValueFromRecordBinding(JSThread *thread, JSHandle module, JSTaggedValue resolvedBinding, int32_t index, bool isSendable) @@ -3755,17 +3764,26 @@ HWTEST_F_L0(EcmaModuleTest, CloneEnvForSModule1) EXPECT_TRUE(elements->GetLength() == 1U); } -HWTEST_F_L0(EcmaModuleTest, InsertInSModuleManager) { +HWTEST_F_L0(EcmaModuleTest, TransferFromLocalToSharedModuleMapAndGetInsertedSModule) { SharedModuleManager* manager1 = SharedModuleManager::GetInstance(); ObjectFactory *objectFactory = thread->GetEcmaVM()->GetFactory(); JSHandle module1 = objectFactory->NewSSourceTextModule(); CString recordName = "test"; module1->SetEcmaModuleRecordNameString(recordName); - manager1->InsertInSModuleManager(thread, recordName, module1); - EXPECT_FALSE(thread->HasPendingException()); -} - -HWTEST_F_L0(EcmaModuleTest, findModuleMutexWithLock) { + module1->SetSharedType(SharedTypes::SHARED_MODULE); + // success + JSHandle res = + manager1->TransferFromLocalToSharedModuleMapAndGetInsertedSModule(thread, module1); + EXPECT_EQ(res, module1); + // insert fail + JSHandle module2 = objectFactory->NewSSourceTextModule(); + module2->SetEcmaModuleRecordNameString(recordName); + module2->SetSharedType(SharedTypes::SHARED_MODULE); + res = manager1->TransferFromLocalToSharedModuleMapAndGetInsertedSModule(thread, module2); + EXPECT_EQ(res, module1); +} + +HWTEST_F_L0(EcmaModuleTest, FindModuleMutexWithLock) { SharedModuleManager* manager1 = SharedModuleManager::GetInstance(); ObjectFactory *objectFactory = thread->GetEcmaVM()->GetFactory(); JSHandle module1 = objectFactory->NewSSourceTextModule(); @@ -3774,8 +3792,8 @@ HWTEST_F_L0(EcmaModuleTest, findModuleMutexWithLock) { module1->SetEcmaModuleFilenameString(baseFileName); CString recordName1 = "module_unexecute"; module1->SetEcmaModuleRecordNameString(recordName1); - manager1->InsertInSModuleManager(thread, recordName1, module1); - manager1->findModuleMutexWithLock(thread, module1); + manager1->AddToResolvedModulesAndCreateSharedModuleMutex(thread, recordName1, module1.GetTaggedValue()); + manager1->FindModuleMutexWithLock(thread, module1); EXPECT_FALSE(thread->HasPendingException()); } @@ -4234,4 +4252,40 @@ HWTEST_F_L0(EcmaModuleTest, RestoreMutableFields) EXPECT_EQ(module->GetException(thread), undefinedValue); EXPECT_EQ(module->GetNamespace(thread), undefinedValue); } + +HWTEST_F_L0(EcmaModuleTest, UpdateSharedModule) +{ + ObjectFactory *objectFactory = thread->GetEcmaVM()->GetFactory(); + JSHandle curmodule = objectFactory->NewSourceTextModule(); + JSHandle resolvedModule = objectFactory->NewSSourceTextModule(); + resolvedModule->SetEcmaModuleRecordNameString("updateSharedModule"); + resolvedModule->SetSharedType(SharedTypes::SHARED_MODULE); + JSHandle envRec = objectFactory->NewTaggedArray(1); + JSHandle resolvedBinding = JSHandle::Cast( + objectFactory->NewResolvedIndexBindingRecord(resolvedModule, 0)); + envRec->Set(thread, 0, resolvedBinding); + curmodule->SetEnvironment(thread, envRec); + JSTaggedValue res = MockModuleValueAccessor::GetModuleValueFromIndexBinding( + thread, curmodule, resolvedBinding.GetTaggedValue(), false); + EXPECT_TRUE(res.IsHole()); + + JSHandle resolvedModule2 = objectFactory->NewSSourceTextModule(); + CString recordName = "updateSharedModule"; + resolvedModule2->SetEcmaModuleRecordNameString(recordName); + resolvedModule2->SetSharedType(SharedTypes::SHARED_MODULE); + JSHandle localExportEntry = + objectFactory->NewSLocalExportEntry(JSHandle::Cast(objectFactory->NewFromASCII("exportName")), + JSHandle::Cast(objectFactory->NewFromASCII("localName")), 1); + JSHandle localExportEntries = objectFactory->NewSTaggedArray(1); + localExportEntries->Set(thread, 0, localExportEntry); + resolvedModule2->SetLocalExportEntries(thread, localExportEntries); + JSHandle val(objectFactory->NewFromUtf8("exportVal")); + + SharedModuleManager::GetInstance()-> + TransferFromLocalToSharedModuleMapAndGetInsertedSModule(thread, resolvedModule2); + SourceTextModule::StoreModuleValue(thread, resolvedModule2, 0, val); + res = MockModuleValueAccessor::GetModuleValueFromIndexBinding( + thread, curmodule, resolvedBinding.GetTaggedValue(), false); + EXPECT_EQ(res, val.GetTaggedValue()); +} } // namespace panda::test diff --git a/ecmascript/stubs/runtime_stub_list.h b/ecmascript/stubs/runtime_stub_list.h index 7ae2fc0fc5..37675f8da5 100644 --- a/ecmascript/stubs/runtime_stub_list.h +++ b/ecmascript/stubs/runtime_stub_list.h @@ -230,7 +230,8 @@ namespace panda::ecmascript { V(CopyArgvArray) \ V(MarkRSetCardTable) \ V(MarkInBuffer) \ - V(BatchMarkInBuffer) + V(BatchMarkInBuffer) \ + V(UpdateSharedModule) // When ASM enters C++ via CallNGCRuntime, if the C++ process requires GetGlobalEnv(), // the current globalenv in ASM must be set to glue before CallNGCRuntime! diff --git a/ecmascript/stubs/runtime_stubs.cpp b/ecmascript/stubs/runtime_stubs.cpp index 30ad89a993..5e87ba12ee 100644 --- a/ecmascript/stubs/runtime_stubs.cpp +++ b/ecmascript/stubs/runtime_stubs.cpp @@ -4971,6 +4971,19 @@ JSTaggedValue RuntimeStubs::FindPatchModule(uintptr_t argGlue, JSTaggedValue res return (thread->GetEcmaVM()->FindPatchModule(module->GetEcmaModuleRecordNameString())).GetTaggedValue(); } +JSTaggedValue RuntimeStubs::UpdateSharedModule(uintptr_t argGlue, JSTaggedValue resolvedModule) +{ + DISALLOW_GARBAGE_COLLECTION; + auto thread = JSThread::GlueToJSThread(argGlue); + JSHandle module(thread, resolvedModule); + JSHandle sharedModule = + SharedModuleManager::GetInstance()->GetSModule(thread, module->GetEcmaModuleRecordNameString()); + if (sharedModule.GetTaggedValue().IsSourceTextModule()) { + return sharedModule.GetTaggedValue(); + } + return module.GetTaggedValue(); +} + void RuntimeStubs::FatalPrintMisstakenResolvedBinding(int32_t index, JSTaggedValue curModule) { DISALLOW_GARBAGE_COLLECTION; -- Gitee From a138fc2e0b2699a5793c4a2fa62c609593206a2d Mon Sep 17 00:00:00 2001 From: yaochaonan Date: Wed, 9 Jul 2025 09:38:28 +0800 Subject: [PATCH 2/6] Signed-off-by: yaochaonan Change-Id: Ib42f0bd3545a7cb2ca577abf5d8a1d67a433e581 --- ecmascript/compiler/stub_builder.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ecmascript/compiler/stub_builder.cpp b/ecmascript/compiler/stub_builder.cpp index 3d61554776..2226dee16b 100644 --- a/ecmascript/compiler/stub_builder.cpp +++ b/ecmascript/compiler/stub_builder.cpp @@ -12242,13 +12242,13 @@ GateRef StubBuilder::LoadExternalmodulevar(GateRef glue, GateRef index, GateRef BRANCH(TaggedIsHole(resolvedModuleOfHotReload), ¬LdEndExecPatchMain, ¬Hole); Bind(¬LdEndExecPatchMain); - Label isSharedModule(env); - Label notSharedModule(env); - BRANCH(IsSharedModule(*resolvedModule), &isSharedModule, ¬SharedModule); - Bind(&isSharedModule); + // Label isSharedModule(env); + // Label notSharedModule(env); + // BRANCH(IsSharedModule(*resolvedModule), &isSharedModule, ¬SharedModule); + // Bind(&isSharedModule); // resolvedModule = CallNGCRuntime(glue, RTSTUB_ID(UpdateSharedModule), {glue, *resolvedModule}); - Jump(¬SharedModule); - Bind(¬SharedModule); + // Jump(¬SharedModule); + // Bind(¬SharedModule); result = GetModuleValue(glue, *resolvedModule, idxOfResolvedBinding); Jump(&exit); -- Gitee From d629021c91a330c9536a5e8073a499103d957048 Mon Sep 17 00:00:00 2001 From: yaochaonan Date: Wed, 9 Jul 2025 09:50:34 +0800 Subject: [PATCH 3/6] Signed-off-by: yaochaonan Change-Id: Ifdba22641aaaf2b07a4af3d406d9131338ff050f --- ecmascript/compiler/stub_builder.cpp | 12 ++++++------ ecmascript/stubs/runtime_stubs.h | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/ecmascript/compiler/stub_builder.cpp b/ecmascript/compiler/stub_builder.cpp index 2226dee16b..3d61554776 100644 --- a/ecmascript/compiler/stub_builder.cpp +++ b/ecmascript/compiler/stub_builder.cpp @@ -12242,13 +12242,13 @@ GateRef StubBuilder::LoadExternalmodulevar(GateRef glue, GateRef index, GateRef BRANCH(TaggedIsHole(resolvedModuleOfHotReload), ¬LdEndExecPatchMain, ¬Hole); Bind(¬LdEndExecPatchMain); - // Label isSharedModule(env); - // Label notSharedModule(env); - // BRANCH(IsSharedModule(*resolvedModule), &isSharedModule, ¬SharedModule); - // Bind(&isSharedModule); + Label isSharedModule(env); + Label notSharedModule(env); + BRANCH(IsSharedModule(*resolvedModule), &isSharedModule, ¬SharedModule); + Bind(&isSharedModule); // resolvedModule = CallNGCRuntime(glue, RTSTUB_ID(UpdateSharedModule), {glue, *resolvedModule}); - // Jump(¬SharedModule); - // Bind(¬SharedModule); + Jump(¬SharedModule); + Bind(¬SharedModule); result = GetModuleValue(glue, *resolvedModule, idxOfResolvedBinding); Jump(&exit); diff --git a/ecmascript/stubs/runtime_stubs.h b/ecmascript/stubs/runtime_stubs.h index 20806f567e..36351c09a0 100644 --- a/ecmascript/stubs/runtime_stubs.h +++ b/ecmascript/stubs/runtime_stubs.h @@ -176,6 +176,7 @@ public: static void ReverseArray(uintptr_t argGlue, JSTaggedType *dst, uint32_t length); static JSTaggedValue FindPatchModule(uintptr_t argGlue, JSTaggedValue resolvedModule); + static JSTaggedValue UpdateSharedModule(uintptr_t argGlue, JSTaggedValue resolvedModule); static void FatalPrintMisstakenResolvedBinding(int32_t index, JSTaggedValue curModule); static void LoadNativeModuleFailed(JSTaggedValue curModule); static void TraceLazyDeoptCommitSuccess(uintptr_t argGlue, JSHandle func); -- Gitee From 51e7ab719bdf4f1b3beb11b86bd30ba5e276da6d Mon Sep 17 00:00:00 2001 From: yaochaonan Date: Wed, 9 Jul 2025 09:50:52 +0800 Subject: [PATCH 4/6] Signed-off-by: yaochaonan Change-Id: I6f180065a7a0ae33bfaa4d9448800a7dd06cc38a --- ecmascript/compiler/stub_builder.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ecmascript/compiler/stub_builder.cpp b/ecmascript/compiler/stub_builder.cpp index 3d61554776..2226dee16b 100644 --- a/ecmascript/compiler/stub_builder.cpp +++ b/ecmascript/compiler/stub_builder.cpp @@ -12242,13 +12242,13 @@ GateRef StubBuilder::LoadExternalmodulevar(GateRef glue, GateRef index, GateRef BRANCH(TaggedIsHole(resolvedModuleOfHotReload), ¬LdEndExecPatchMain, ¬Hole); Bind(¬LdEndExecPatchMain); - Label isSharedModule(env); - Label notSharedModule(env); - BRANCH(IsSharedModule(*resolvedModule), &isSharedModule, ¬SharedModule); - Bind(&isSharedModule); + // Label isSharedModule(env); + // Label notSharedModule(env); + // BRANCH(IsSharedModule(*resolvedModule), &isSharedModule, ¬SharedModule); + // Bind(&isSharedModule); // resolvedModule = CallNGCRuntime(glue, RTSTUB_ID(UpdateSharedModule), {glue, *resolvedModule}); - Jump(¬SharedModule); - Bind(¬SharedModule); + // Jump(¬SharedModule); + // Bind(¬SharedModule); result = GetModuleValue(glue, *resolvedModule, idxOfResolvedBinding); Jump(&exit); -- Gitee From 4e52d861644e5bc0e1bc538792adfa811a829a20 Mon Sep 17 00:00:00 2001 From: yaochaonan Date: Wed, 9 Jul 2025 11:54:08 +0800 Subject: [PATCH 5/6] Signed-off-by: yaochaonan Change-Id: I8b2808e87989452126045cd6a388ef1c5c022d0f --- ecmascript/compiler/stub_builder.cpp | 14 +++++++------- ecmascript/stubs/runtime_stubs.cpp | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ecmascript/compiler/stub_builder.cpp b/ecmascript/compiler/stub_builder.cpp index 2226dee16b..de2c7ee1c2 100644 --- a/ecmascript/compiler/stub_builder.cpp +++ b/ecmascript/compiler/stub_builder.cpp @@ -12242,13 +12242,13 @@ GateRef StubBuilder::LoadExternalmodulevar(GateRef glue, GateRef index, GateRef BRANCH(TaggedIsHole(resolvedModuleOfHotReload), ¬LdEndExecPatchMain, ¬Hole); Bind(¬LdEndExecPatchMain); - // Label isSharedModule(env); - // Label notSharedModule(env); - // BRANCH(IsSharedModule(*resolvedModule), &isSharedModule, ¬SharedModule); - // Bind(&isSharedModule); - // resolvedModule = CallNGCRuntime(glue, RTSTUB_ID(UpdateSharedModule), {glue, *resolvedModule}); - // Jump(¬SharedModule); - // Bind(¬SharedModule); + Label isSharedModule(env); + Label notSharedModule(env); + BRANCH(IsSharedModule(*resolvedModule), &isSharedModule, ¬SharedModule); + Bind(&isSharedModule); + resolvedModule = CallNGCRuntime(glue, RTSTUB_ID(UpdateSharedModule), {glue, *resolvedModule}); + Jump(¬SharedModule); + Bind(¬SharedModule); result = GetModuleValue(glue, *resolvedModule, idxOfResolvedBinding); Jump(&exit); diff --git a/ecmascript/stubs/runtime_stubs.cpp b/ecmascript/stubs/runtime_stubs.cpp index 5e87ba12ee..fec55c8ea9 100644 --- a/ecmascript/stubs/runtime_stubs.cpp +++ b/ecmascript/stubs/runtime_stubs.cpp @@ -4976,11 +4976,11 @@ JSTaggedValue RuntimeStubs::UpdateSharedModule(uintptr_t argGlue, JSTaggedValue DISALLOW_GARBAGE_COLLECTION; auto thread = JSThread::GlueToJSThread(argGlue); JSHandle module(thread, resolvedModule); - JSHandle sharedModule = - SharedModuleManager::GetInstance()->GetSModule(thread, module->GetEcmaModuleRecordNameString()); - if (sharedModule.GetTaggedValue().IsSourceTextModule()) { - return sharedModule.GetTaggedValue(); - } + // JSHandle sharedModule = + // SharedModuleManager::GetInstance()->GetSModule(thread, module->GetEcmaModuleRecordNameString()); + // if (sharedModule.GetTaggedValue().IsSourceTextModule()) { + // return sharedModule.GetTaggedValue(); + // } return module.GetTaggedValue(); } -- Gitee From 5f04979078adf9daecc96c44dbcd29e1ad47b425 Mon Sep 17 00:00:00 2001 From: yaochaonan Date: Wed, 9 Jul 2025 11:55:21 +0800 Subject: [PATCH 6/6] Signed-off-by: yaochaonan Change-Id: Iea7b858b29087b7bc26ed495764e8b3c64823c31 --- ecmascript/stubs/runtime_stubs.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ecmascript/stubs/runtime_stubs.cpp b/ecmascript/stubs/runtime_stubs.cpp index fec55c8ea9..33628b8f52 100644 --- a/ecmascript/stubs/runtime_stubs.cpp +++ b/ecmascript/stubs/runtime_stubs.cpp @@ -4976,8 +4976,8 @@ JSTaggedValue RuntimeStubs::UpdateSharedModule(uintptr_t argGlue, JSTaggedValue DISALLOW_GARBAGE_COLLECTION; auto thread = JSThread::GlueToJSThread(argGlue); JSHandle module(thread, resolvedModule); - // JSHandle sharedModule = - // SharedModuleManager::GetInstance()->GetSModule(thread, module->GetEcmaModuleRecordNameString()); + JSHandle sharedModule = + SharedModuleManager::GetInstance()->GetSModule(thread, module->GetEcmaModuleRecordNameString()); // if (sharedModule.GetTaggedValue().IsSourceTextModule()) { // return sharedModule.GetTaggedValue(); // } -- Gitee