diff --git a/ecmascript/compiler/aot_compiler_preprocessor.cpp b/ecmascript/compiler/aot_compiler_preprocessor.cpp index d4f383beca11a99031290aba623b8d6327411f01..f9b9411d6c08f2fedcb550a4c79e6d9235ff6879 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 b76f88af48b4e283b24232355cd6804b1931e579..c8eb5c744f16033021580467bea6de8367edf916 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 15f0ea8197777ab66aaa34302f910a57b198bdd7..92370ccdfa7cedb9f829c3fb342e5af73a54a781 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 b226427c0b0f2d54b60c7f6f378b960dff39bf23..0febd622ff9891f17a5cebcc2c5c6da757eddb8a 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 2f92b625399da62e3e651baf30d581e9ec17a470..de2c7ee1c2044a0f4eb54d3d396c1f1e8048a635 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 07003e69031f9173d9b85c1cf8e2c5dd44353f41..8ad19ed9af302878698a3155893ed0a655cb0794 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 3922062c2cb9f877009c32c6e0b5025b1084be75..09081ad14c6792881e8d7df71f811c8c372b78e2 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 3d23a42b43ab298b6e506274b78b1d6df6795d02..18255ccdaec11ed43214203670dbb32e0abc1968 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 069a62bcabe100748bda8a8f01e59681e1a92c20..377c8d3e823d830d36874f31e26dde5413ade276 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 b0b2bb497b9478c019879d696c25bc3e7cb9a8dd..b69265c07cf7ea3726712d4ccd17a9c20dda3d4e 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 a49895d97382807777d128a16faed0dbae3ae4ff..57d8b9c6ed2ac03a1115c891ac8f307228c390c9 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 3e52b810f04561e8e2aae99ba1c7b5625587832e..d458b48b07b0630be3c7189a5d998c29b5e3ce53 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 f271f9d73f8b2227f8a1b7f946039bbb13fc8d18..639d79d4b1a905fce1d486bdb769221ac14acfd5 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 ce1727ab1ed04154658dbaf1454db34966a0c808..8c3cd0fedd4765b03a9e72202ffd6252e40da415 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 2cb097ecf19a408f4c722de88b160b0d17b04450..2f14161db676d592c43f9521da6b555ce9f33fec 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 c7ef468f5f06230cc8741c4e495802f20bc1de9b..05fe497b11d7edeb7cf4d720d7e166a7feb77977 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 7ae2fc0fc59f5bf3bfb74c1ca19487551f35315c..37675f8da50281ec595483b329a808d81c6f5ca9 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 30ad89a993803adbc470a846df41cf3e04bbd122..33628b8f521c203398264687840688bfdea24d39 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; diff --git a/ecmascript/stubs/runtime_stubs.h b/ecmascript/stubs/runtime_stubs.h index 20806f567ec0dcc052a5f45f240b19e1500d3b2b..36351c09a052a0c167d2a6fe59ede46a4db2f801 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);