• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "ecmascript/module/js_shared_module_manager.h"
16 
17 #include "ecmascript/jspandafile/js_pandafile_executor.h"
18 #include "ecmascript/module/module_path_helper.h"
19 #include "ecmascript/runtime_lock.h"
20 
21 namespace panda::ecmascript {
22 using StringHelper = base::StringHelper;
23 using JSPandaFile = ecmascript::JSPandaFile;
24 using JSRecordInfo = ecmascript::JSPandaFile::JSRecordInfo;
25 
GetInstance()26 SharedModuleManager* SharedModuleManager::GetInstance()
27 {
28     static SharedModuleManager* instance = new SharedModuleManager();
29     return instance;
30 }
31 
Iterate(RootVisitor & v)32 void SharedModuleManager::Iterate(RootVisitor &v)
33 {
34     resolvedSharedModules_.ForEach(
35         [&v](auto iter) { iter->second.VisitRoot([&v](ObjectSlot slot) { v.VisitRoot(Root::ROOT_VM, slot); }); });
36 }
37 
SearchInSModuleManagerUnsafe(const CString & recordName)38 bool SharedModuleManager::SearchInSModuleManagerUnsafe(const CString &recordName)
39 {
40     auto entry = resolvedSharedModules_.Find(recordName);
41     if (entry) {
42         return true;
43     }
44     return false;
45 }
46 
GetSModuleUnsafe(JSThread * thread,const CString & recordName)47 JSHandle<SourceTextModule> SharedModuleManager::GetSModuleUnsafe(JSThread *thread, const CString &recordName)
48 {
49     auto entry = resolvedSharedModules_.Find(recordName);
50     if (!entry) {
51         return JSHandle<SourceTextModule>(thread->GlobalConstants()->GetHandledUndefined());
52     }
53     JSHandle<JSTaggedValue> module(thread, entry.value());
54     return JSHandle<SourceTextModule>::Cast(module);
55 }
56 
GetSModule(JSThread * thread,const CString & recordName)57 JSHandle<SourceTextModule> SharedModuleManager::GetSModule(JSThread *thread, const CString &recordName)
58 {
59     RuntimeLockHolder locker(thread, mutex_);
60     return GetSModuleUnsafe(thread, recordName);
61 }
62 
SearchInSModuleManager(JSThread * thread,const CString & recordName)63 bool SharedModuleManager::SearchInSModuleManager(JSThread *thread, const CString &recordName)
64 {
65     RuntimeLockHolder locker(thread, mutex_);
66     return SearchInSModuleManagerUnsafe(recordName);
67 }
68 
TryInsertInSModuleManager(JSThread * thread,const CString & recordName,const JSHandle<SourceTextModule> & moduleRecord)69 bool SharedModuleManager::TryInsertInSModuleManager(JSThread *thread, const CString &recordName,
70                                                     const JSHandle<SourceTextModule> &moduleRecord)
71 {
72     RuntimeLockHolder locker(thread, mutex_);
73     JSHandle<JSTaggedValue> module = JSHandle<JSTaggedValue>::Cast(moduleRecord);
74     return AddResolveImportedSModule(recordName, module.GetTaggedValue());
75 }
76 
AddToResolvedModulesAndCreateSharedModuleMutex(JSThread * thread,const CString & recordName,JSTaggedValue module)77 void SharedModuleManager::AddToResolvedModulesAndCreateSharedModuleMutex(
78     JSThread *thread, const CString &recordName, JSTaggedValue module)
79 {
80     // Add to normal module resolvedModules_
81     thread->GetModuleManager()->AddResolveImportedModule(recordName, module);
82     RuntimeLockHolder locker(thread, mutex_);
83     StateVisit stateVisit;
84     sharedModuleMutex_.emplace(recordName, std::move(stateVisit));
85 }
86 
TransferFromLocalToSharedModuleMapAndGetInsertedSModule(JSThread * thread,const JSHandle<SourceTextModule> & module)87 JSHandle<SourceTextModule> SharedModuleManager::TransferFromLocalToSharedModuleMapAndGetInsertedSModule(
88     JSThread *thread, const JSHandle<SourceTextModule> &module)
89 {
90     ASSERT(module->GetSharedType() == SharedTypes::SHARED_MODULE);
91     CString recordName = module->GetEcmaModuleRecordNameString();
92     bool success = TryInsertInSModuleManager(thread, recordName, module);
93     thread->GetModuleManager()->RemoveModuleNameFromList(recordName);
94     return success? module : GetSModule(thread, recordName);
95 }
96 
FindModuleMutexWithLock(JSThread * thread,const JSHandle<SourceTextModule> & module)97 StateVisit &SharedModuleManager::FindModuleMutexWithLock(JSThread *thread, const JSHandle<SourceTextModule> &module)
98 {
99     RuntimeLockHolder locker(thread, mutex_);
100     CString moduleName = SourceTextModule::GetModuleName(module.GetTaggedValue());
101     auto it = sharedModuleMutex_.find(moduleName);
102     if (it == sharedModuleMutex_.end()) { // LCOV_EXCL_BR_LINE
103         LOG_ECMA(FATAL) << " Get shared module mutex failed, moduleName is " << moduleName;
104     }
105     return it->second;
106 }
107 
IsInstantiatedSModule(JSThread * thread,const JSHandle<SourceTextModule> & module)108 bool SharedModuleManager::IsInstantiatedSModule(JSThread *thread, const JSHandle<SourceTextModule> &module)
109 {
110     RuntimeLockHolder locker(thread, mutex_);
111     return (module->GetStatus() >= ModuleStatus::INSTANTIATED);
112 }
113 
GenerateFuncModule(JSThread * thread,const JSPandaFile * jsPandaFile,const CString & entryPoint,ClassKind classKind)114 JSHandle<JSTaggedValue> SharedModuleManager::GenerateFuncModule(JSThread *thread, const JSPandaFile *jsPandaFile,
115                                                                 const CString &entryPoint, ClassKind classKind)
116 {
117     CString recordName = jsPandaFile->GetRecordName(entryPoint);
118     auto vm = thread->GetEcmaVM();
119     JSRecordInfo *recordInfo = jsPandaFile->CheckAndGetRecordInfo(recordName);
120     ASSERT(recordInfo != nullptr);
121     if (jsPandaFile->IsModule(recordInfo)) {
122         JSHandle<SourceTextModule> module;
123         if (jsPandaFile->IsSharedModule(recordInfo)) {
124             return JSHandle<JSTaggedValue>(GetSModule(thread, entryPoint));
125         } else {
126             ModuleManager *moduleManager = thread->GetModuleManager();
127             module = moduleManager->HostGetImportedModule(recordName);
128         }
129 
130         if (classKind == ClassKind::NON_SENDABLE) {
131             return JSHandle<JSTaggedValue>(module);
132         } else {
133             // Clone isolate module at shared-heap to mark sendable class.
134             return SendableClassModule::GenerateSendableFuncModule(thread, JSHandle<JSTaggedValue>(module));
135         }
136     }
137     return JSHandle<JSTaggedValue>(vm->GetFactory()->NewFromUtf8(recordName));
138 }
139 
SModuleNamespaceCreate(JSThread * thread,const JSHandle<JSTaggedValue> & module,const JSHandle<TaggedArray> & exports)140 JSHandle<ModuleNamespace> SharedModuleManager::SModuleNamespaceCreate(JSThread *thread,
141     const JSHandle<JSTaggedValue> &module, const JSHandle<TaggedArray> &exports)
142 {
143     RuntimeLockHolder locker(thread, mutex_);
144     return JSSharedModule::SModuleNamespaceCreate(thread, module, exports);
145 }
146 
SharedNativeObjDestory()147 void SharedModuleManager::SharedNativeObjDestory()
148 {
149     resolvedSharedModules_.ForEach([](auto it) {
150         CString key = it->first;
151         ASSERT(!key.empty());
152         GCRoot &root = it->second;
153         JSTaggedValue module = root.Read();
154         SourceTextModule::Cast(module)->DestoryLazyImportArray();
155         SourceTextModule::Cast(module)->DestoryEcmaModuleFilenameString();
156         SourceTextModule::Cast(module)->DestoryEcmaModuleRecordNameString();
157     });
158 }
159 } // namespace panda::ecmascript
160