• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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/compiler/aot_file/aot_file_manager.h"
16 
17 #include <utility>
18 
19 #include "ecmascript/base/config.h"
20 #include "ecmascript/base/file_header.h"
21 #include "ecmascript/common.h"
22 #include "ecmascript/compiler/aot_file/an_file_data_manager.h"
23 #include "ecmascript/compiler/aot_file/elf_builder.h"
24 #include "ecmascript/compiler/aot_file/elf_reader.h"
25 #include "ecmascript/compiler/aot_snapshot/aot_snapshot_constants.h"
26 #include "ecmascript/compiler/aot_snapshot/snapshot_global_data.h"
27 #include "ecmascript/compiler/bc_call_signature.h"
28 #include "ecmascript/compiler/call_signature.h"
29 #include "ecmascript/compiler/common_stubs.h"
30 #include "ecmascript/compiler/compiler_log.h"
31 #include "ecmascript/deoptimizer/deoptimizer.h"
32 #include "ecmascript/ecma_vm.h"
33 #include "ecmascript/js_file_path.h"
34 #include "ecmascript/js_handle.h"
35 #include "ecmascript/js_runtime_options.h"
36 #include "ecmascript/js_tagged_value.h"
37 #include "ecmascript/js_thread.h"
38 #include "ecmascript/jspandafile/constpool_value.h"
39 #include "ecmascript/jspandafile/js_pandafile.h"
40 #include "ecmascript/jspandafile/program_object.h"
41 #include "ecmascript/log_wrapper.h"
42 #include "ecmascript/mem/region.h"
43 #include "ecmascript/message_string.h"
44 #include "ecmascript/snapshot/mem/snapshot.h"
45 #include "ecmascript/stackmap/ark_stackmap_parser.h"
46 #include "ecmascript/stackmap/llvm_stackmap_parser.h"
47 
48 namespace panda::ecmascript {
49 using CommonStubCSigns = kungfu::CommonStubCSigns;
50 using BytecodeStubCSigns = kungfu::BytecodeStubCSigns;
51 
Iterate(const RootVisitor & v)52 void AOTFileManager::Iterate(const RootVisitor &v)
53 {
54     for (auto &iter : aiDatum_) {
55         auto &aiData = iter.second;
56         for (auto &eachFileData : aiData) {
57             auto &cpMap = eachFileData.second.multiCpsMap_;
58             for (auto &eachCpPair : cpMap) {
59                 v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&eachCpPair.second)));
60             }
61         }
62     }
63 }
64 
DumpAOTInfo()65 void AOTFileManager::DumpAOTInfo()
66 {
67     AnFileDataManager *m = AnFileDataManager::GetInstance();
68     m->Dump();
69 }
70 
LoadStubFile(const std::string & fileName)71 void AOTFileManager::LoadStubFile(const std::string &fileName)
72 {
73     AnFileDataManager *anFileDataManager = AnFileDataManager::GetInstance();
74     if (!anFileDataManager->SafeLoad(fileName, AnFileDataManager::Type::STUB)) {
75         return;
76     }
77     auto info = anFileDataManager->SafeGetStubFileInfo();
78     auto stubs = info->GetStubs();
79     InitializeStubEntries(stubs);
80 }
81 
LoadAnFile(const std::string & fileName)82 bool AOTFileManager::LoadAnFile(const std::string &fileName)
83 {
84     AnFileDataManager *anFileDataManager = AnFileDataManager::GetInstance();
85     return anFileDataManager->SafeLoad(fileName, AnFileDataManager::Type::AOT);
86 }
87 
LoadAiFile(const std::string & filename)88 bool AOTFileManager::LoadAiFile([[maybe_unused]] const std::string &filename)
89 {
90     Snapshot snapshot(vm_);
91 #if !WIN_OR_MAC_OR_IOS_PLATFORM
92     return snapshot.Deserialize(SnapshotType::AI, filename.c_str());
93 #else
94     return true;
95 #endif
96 }
97 
LoadAiFile(const JSPandaFile * jsPandaFile)98 bool AOTFileManager::LoadAiFile(const JSPandaFile *jsPandaFile)
99 {
100     uint32_t anFileInfoIndex = GetAnFileIndex(jsPandaFile);
101     // this abc file does not have corresponding an file
102     if (anFileInfoIndex == INVALID_INDEX) {
103         return false;
104     }
105 
106     auto iter = aiDatum_.find(anFileInfoIndex);
107     // already loaded
108     if (iter != aiDatum_.end()) {
109         return false;
110     }
111 
112     AnFileDataManager *anFileDataManager = AnFileDataManager::GetInstance();
113     std::string aiFilename = anFileDataManager->GetDir();
114     aiFilename += JSFilePath::GetHapName(jsPandaFile) + AOTFileManager::FILE_EXTENSION_AI;
115     LoadAiFile(aiFilename);
116     return true;
117 }
118 
GetAnFileInfo(const JSPandaFile * jsPandaFile) const119 const std::shared_ptr<AnFileInfo> AOTFileManager::GetAnFileInfo(const JSPandaFile *jsPandaFile) const
120 {
121     uint32_t index = jsPandaFile->GetAOTFileInfoIndex();
122     if (index == INVALID_INDEX) {
123         return nullptr;
124     }
125     AnFileDataManager *anFileDataManager = AnFileDataManager::GetInstance();
126     return anFileDataManager->SafeGetAnFileInfo(index);
127 }
128 
GetFileIndex(uint32_t anFileInfoIndex,CString abcNormalizedName) const129 uint32_t AOTFileManager::GetFileIndex(uint32_t anFileInfoIndex, CString abcNormalizedName) const
130 {
131     auto fileIndex = INVALID_INDEX;
132     if (abcNormalizedName.find(JSFilePath::GetBaseName(STUB_AN_FILE)) == std::string::npos) {
133         auto aiDatumIter = aiDatum_.find(anFileInfoIndex);
134         if (aiDatumIter == aiDatum_.end()) {
135             return INVALID_INDEX;
136         }
137 
138         auto fileIter = aiDatumIter->second.find(abcNormalizedName);
139         if (fileIter == aiDatumIter->second.end()) {
140             return INVALID_INDEX;
141         }
142         fileIndex = fileIter->second.fileIndex_;
143     } else {
144         fileIndex = STUB_FILE_INDEX;
145     }
146     return fileIndex;
147 }
148 
IsLoadMain(const JSPandaFile * jsPandaFile,const CString & entry) const149 bool AOTFileManager::IsLoadMain(const JSPandaFile *jsPandaFile, const CString &entry) const
150 {
151     if (!jsPandaFile->IsLoadedAOT()) {
152         return false;
153     }
154 
155     const std::shared_ptr<AnFileInfo> anFileInfo = GetAnFileInfo(jsPandaFile);
156     if (anFileInfo == nullptr) {
157         return false;
158     }
159 
160     auto fileIndex = GetFileIndex(jsPandaFile->GetAOTFileInfoIndex(), jsPandaFile->GetNormalizedFileDesc().c_str());
161     if (fileIndex == INVALID_INDEX) {
162         return false;
163     }
164     return anFileInfo->IsLoadMain(fileIndex, jsPandaFile, entry);
165 }
166 
GetPandaFiles(uint32_t aotFileInfoIndex)167 std::list<CString> AOTFileManager::GetPandaFiles(uint32_t aotFileInfoIndex)
168 {
169     std::list<CString> abcFilesList {};
170     auto aiDatumIter = aiDatum_.find(aotFileInfoIndex);
171     if (aiDatumIter == aiDatum_.end()) {
172         return abcFilesList;
173     }
174     for (const auto& nameIter : aiDatumIter->second) {
175         abcFilesList.push_back(nameIter.first);
176     }
177     return abcFilesList;
178 }
179 
BindPandaFilesInAotFile(const std::string & aotFileBaseName,const std::string & moduleName)180 void AOTFileManager::BindPandaFilesInAotFile(const std::string &aotFileBaseName, const std::string &moduleName)
181 {
182     AnFileDataManager *anFileDataManager = AnFileDataManager::GetInstance();
183     uint32_t aotFileInfoIndex = anFileDataManager->SafeGetFileInfoIndex(aotFileBaseName + FILE_EXTENSION_AN);
184     if (aotFileInfoIndex == INVALID_INDEX) {
185         return;
186     }
187     auto abcFiles = GetPandaFiles(aotFileInfoIndex);
188     for (const auto &abcNormalizedName : abcFiles) {
189         const auto abcFile = JSPandaFileManager::GetInstance()->FindJSPandaFileByNormalizedName(abcNormalizedName);
190         if (!abcFile) {
191             LOG_ECMA(WARN) << "Can not find file: " << abcNormalizedName << " in module: " << moduleName;
192             continue;
193         }
194         if (!abcFile->IsLoadedAOT()) {
195             abcFile->SetAOTFileInfoIndex(aotFileInfoIndex);
196         }
197     }
198 }
199 
GetAnFileIndex(const JSPandaFile * jsPandaFile) const200 uint32_t AOTFileManager::GetAnFileIndex(const JSPandaFile *jsPandaFile) const
201 {
202     AnFileDataManager *anFileDataManager = AnFileDataManager::GetInstance();
203 
204     // run via command line
205     if (vm_->GetJSOptions().WasAOTOutputFileSet()) {
206         std::string jsPandaFileDesc = jsPandaFile->GetJSPandaFileDesc().c_str();
207         std::string baseName = JSFilePath::GetFileName(jsPandaFileDesc);
208         if (baseName.empty()) {
209             return INVALID_INDEX;
210         }
211         std::string anFileName = baseName + FILE_EXTENSION_AN;
212         return anFileDataManager->SafeGetFileInfoIndex(anFileName);
213     }
214 
215     // run from app hap
216     std::string hapName = JSFilePath::GetHapName(jsPandaFile);
217     if (hapName.empty()) {
218         return INVALID_INDEX;
219     }
220     std::string anFileName = hapName + FILE_EXTENSION_AN;
221     return anFileDataManager->SafeGetFileInfoIndex(anFileName);
222 }
223 
TryReadLock()224 bool AOTFileManager::TryReadLock()
225 {
226     AnFileDataManager *anFileDataManager = AnFileDataManager::GetInstance();
227     return anFileDataManager->SafeTryReadLock();
228 }
229 
InsideStub(uintptr_t pc)230 bool AOTFileManager::InsideStub(uintptr_t pc)
231 {
232     AnFileDataManager *anFileDataManager = AnFileDataManager::GetInstance();
233     return anFileDataManager->SafeInsideStub(pc);
234 }
235 
InsideAOT(uintptr_t pc)236 bool AOTFileManager::InsideAOT(uintptr_t pc)
237 {
238     AnFileDataManager *anFileDataManager = AnFileDataManager::GetInstance();
239     return anFileDataManager->SafeInsideAOT(pc);
240 }
241 
CalCallSiteInfo(uintptr_t retAddr)242 AOTFileInfo::CallSiteInfo AOTFileManager::CalCallSiteInfo(uintptr_t retAddr)
243 {
244     AnFileDataManager *anFileDataManager = AnFileDataManager::GetInstance();
245     return anFileDataManager->SafeCalCallSiteInfo(retAddr);
246 }
247 
PrintAOTEntry(const JSPandaFile * file,const Method * method,uintptr_t entry)248 void AOTFileManager::PrintAOTEntry(const JSPandaFile *file, const Method *method, uintptr_t entry)
249 {
250     uint32_t mId = method->GetMethodId().GetOffset();
251     std::string mName = method->GetMethodName(file);
252     auto &fileName = file->GetJSPandaFileDesc();
253     LOG_COMPILER(INFO) << "Bind " << mName << "@" << mId << "@" << fileName
254                        << " -> AOT-Entry = " << reinterpret_cast<void *>(entry);
255 }
256 
SetAOTMainFuncEntry(JSHandle<JSFunction> mainFunc,const JSPandaFile * jsPandaFile,std::string_view entryPoint)257 void AOTFileManager::SetAOTMainFuncEntry(JSHandle<JSFunction> mainFunc, const JSPandaFile *jsPandaFile,
258                                          std::string_view entryPoint)
259 {
260     AnFileDataManager *anFileDataManager = AnFileDataManager::GetInstance();
261     uint32_t anFileInfoIndex = jsPandaFile->GetAOTFileInfoIndex();
262     const std::shared_ptr<AnFileInfo> anFileInfo = anFileDataManager->SafeGetAnFileInfo(anFileInfoIndex);
263     auto aiDatumIter = aiDatum_.find(anFileInfoIndex);
264     if (aiDatumIter == aiDatum_.end()) {
265         LOG_ECMA(FATAL) << "can not find aiData by anFileInfoIndex " << anFileInfoIndex;
266         UNREACHABLE();
267     }
268     uint32_t fileIndex = GetFileIndex(jsPandaFile->GetAOTFileInfoIndex(), jsPandaFile->GetNormalizedFileDesc().c_str());
269     if (fileIndex == INVALID_INDEX) {
270         LOG_ECMA(FATAL) << "can not find aiData by anFileInfoIndex " << anFileInfoIndex
271                         << ", normalizedDesc: " << jsPandaFile->GetNormalizedFileDesc();
272         UNREACHABLE();
273     }
274     // get main func method
275     auto mainFuncMethodId = jsPandaFile->GetMainMethodIndex(entryPoint.data());
276     uint64_t mainEntry;
277     bool isFastCall;
278     std::tie(mainEntry, isFastCall) = anFileInfo->GetMainFuncEntry(fileIndex, mainFuncMethodId);
279     MethodLiteral *mainMethod = jsPandaFile->FindMethodLiteral(mainFuncMethodId);
280     mainMethod->SetAotCodeBit(true);
281     mainMethod->SetNativeBit(false);
282     Method *method = mainFunc->GetCallTarget();
283     method->SetDeoptThreshold(vm_->GetJSOptions().GetDeoptThreshold());
284     method->SetCodeEntryAndMarkAOT(static_cast<uintptr_t>(mainEntry));
285     method->SetIsFastCall(isFastCall);
286 #ifndef NDEBUG
287     PrintAOTEntry(jsPandaFile, method, mainEntry);
288 #endif
289 
290     MethodLiteral *methodLiteral = method->GetMethodLiteral();
291     methodLiteral->SetAotCodeBit(true);
292     methodLiteral->SetIsFastCall(isFastCall);
293 }
294 
SetAOTFuncEntry(const JSPandaFile * jsPandaFile,Method * method,uint32_t entryIndex,bool * canFastCall)295 void AOTFileManager::SetAOTFuncEntry(const JSPandaFile *jsPandaFile, Method *method,
296                                      uint32_t entryIndex, bool *canFastCall)
297 {
298     AnFileDataManager *anFileDataManager = AnFileDataManager::GetInstance();
299     uint32_t anFileInfoIndex = jsPandaFile->GetAOTFileInfoIndex();
300     const std::shared_ptr<AnFileInfo> anFileInfo = anFileDataManager->SafeGetAnFileInfo(anFileInfoIndex);
301     const AOTFileInfo::FuncEntryDes &entry = anFileInfo->GetStubDes(entryIndex);
302     uint64_t codeEntry = entry.codeAddr_;
303 #ifndef NDEBUG
304     PrintAOTEntry(jsPandaFile, method, codeEntry);
305 #endif
306     if (!codeEntry) {
307         return;
308     }
309     method->SetDeoptThreshold(vm_->GetJSOptions().GetDeoptThreshold());
310     method->SetCodeEntryAndMarkAOT(codeEntry);
311     method->SetIsFastCall(entry.isFastCall_);
312     if (canFastCall != nullptr) {
313         *canFastCall = entry.isFastCall_;
314     }
315 
316     MethodLiteral *methodLiteral = method->GetMethodLiteral();
317     methodLiteral->SetAotCodeBit(true);
318     methodLiteral->SetIsFastCall(entry.isFastCall_);
319 }
320 
GetStackMapParser() const321 kungfu::ArkStackMapParser *AOTFileManager::GetStackMapParser() const
322 {
323     return arkStackMapParser_;
324 }
325 
AdjustBCStubAndDebuggerStubEntries(JSThread * thread,const std::vector<AOTFileInfo::FuncEntryDes> & stubs,const AsmInterParsedOption & asmInterOpt)326 void AOTFileManager::AdjustBCStubAndDebuggerStubEntries(JSThread *thread,
327                                                         const std::vector<AOTFileInfo::FuncEntryDes> &stubs,
328                                                         const AsmInterParsedOption &asmInterOpt)
329 {
330     auto defaultBCStubDes = stubs[BytecodeStubCSigns::SingleStepDebugging];
331     auto defaultBCDebuggerStubDes = stubs[BytecodeStubCSigns::BCDebuggerEntry];
332     auto defaultBCDebuggerExceptionStubDes = stubs[BytecodeStubCSigns::BCDebuggerExceptionEntry];
333     ASSERT(defaultBCStubDes.kind_ == CallSignature::TargetKind::BYTECODE_HELPER_HANDLER);
334     if (asmInterOpt.handleStart >= 0 && asmInterOpt.handleStart <= asmInterOpt.handleEnd) {
335         for (int i = asmInterOpt.handleStart; i <= asmInterOpt.handleEnd; i++) {
336             thread->SetBCStubEntry(static_cast<size_t>(i), defaultBCStubDes.codeAddr_);
337         }
338 #define DISABLE_SINGLE_STEP_DEBUGGING(name) \
339     thread->SetBCStubEntry(BytecodeStubCSigns::ID_##name, stubs[BytecodeStubCSigns::ID_##name].codeAddr_);
340         INTERPRETER_DISABLE_SINGLE_STEP_DEBUGGING_BC_STUB_LIST(DISABLE_SINGLE_STEP_DEBUGGING)
341 #undef DISABLE_SINGLE_STEP_DEBUGGING
342     }
343     for (size_t i = 0; i < BCStubEntries::EXISTING_BC_HANDLER_STUB_ENTRIES_COUNT; i++) {
344         if (i == BytecodeStubCSigns::ID_ExceptionHandler) {
345             thread->SetBCDebugStubEntry(i, defaultBCDebuggerExceptionStubDes.codeAddr_);
346             continue;
347         }
348         thread->SetBCDebugStubEntry(i, defaultBCDebuggerStubDes.codeAddr_);
349     }
350 }
351 
InitializeStubEntries(const std::vector<AnFileInfo::FuncEntryDes> & stubs)352 void AOTFileManager::InitializeStubEntries(const std::vector<AnFileInfo::FuncEntryDes> &stubs)
353 {
354     auto thread = vm_->GetAssociatedJSThread();
355     size_t len = stubs.size();
356     for (size_t i = 0; i < len; i++) {
357         auto des = stubs[i];
358         if (des.IsCommonStub()) {
359             thread->SetFastStubEntry(des.indexInKindOrMethodId_, des.codeAddr_);
360         } else if (des.IsBCStub()) {
361             thread->SetBCStubEntry(des.indexInKindOrMethodId_, des.codeAddr_);
362 #if ECMASCRIPT_ENABLE_ASM_FILE_LOAD_LOG
363             auto start = GET_MESSAGE_STRING_ID(HandleLdundefined);
364             std::string format = MessageString::GetMessageString(des.indexInKindOrMethodId_ + start);
365             LOG_ECMA(DEBUG) << "bytecode index: " << des.indexInKindOrMethodId_ << " :" << format << " addr: 0x"
366                             << std::hex << des.codeAddr_;
367 #endif
368         } else if (des.IsBuiltinsStub()) {
369             thread->SetBuiltinStubEntry(des.indexInKindOrMethodId_, des.codeAddr_);
370 #if ECMASCRIPT_ENABLE_ASM_FILE_LOAD_LOG
371             int start = GET_MESSAGE_STRING_ID(StringCharCodeAt);
372             std::string format = MessageString::GetMessageString(des.indexInKindOrMethodId_ + start - 1);  // -1: NONE
373             LOG_ECMA(DEBUG) << "builtins index: " << std::dec << des.indexInKindOrMethodId_ << " :" << format
374                             << " addr: 0x" << std::hex << des.codeAddr_;
375 #endif
376         } else {
377             thread->RegisterRTInterface(des.indexInKindOrMethodId_, des.codeAddr_);
378 #if ECMASCRIPT_ENABLE_ASM_FILE_LOAD_LOG
379             int start = GET_MESSAGE_STRING_ID(CallRuntime);
380             std::string format = MessageString::GetMessageString(des.indexInKindOrMethodId_ + start);
381             LOG_ECMA(DEBUG) << "runtime index: " << std::dec << des.indexInKindOrMethodId_ << " :" << format
382                             << " addr: 0x" << std::hex << des.codeAddr_;
383 #endif
384         }
385     }
386     thread->CheckOrSwitchPGOStubs();
387     AsmInterParsedOption asmInterOpt = vm_->GetJSOptions().GetAsmInterParsedOption();
388     AdjustBCStubAndDebuggerStubEntries(thread, stubs, asmInterOpt);
389 }
390 
RewriteDataSection(uintptr_t dataSec,size_t size,uintptr_t newData,size_t newSize)391 bool AOTFileManager::RewriteDataSection(uintptr_t dataSec, size_t size, uintptr_t newData, size_t newSize)
392 {
393     if (memcpy_s(reinterpret_cast<void *>(dataSec), size, reinterpret_cast<void *>(newData), newSize) != EOK) {
394         LOG_FULL(FATAL) << "memset failed";
395         return false;
396     }
397     return true;
398 }
399 
ParseDeserializedData(const CString & snapshotFileName,JSTaggedValue deserializedData)400 void AOTFileManager::ParseDeserializedData(const CString &snapshotFileName, JSTaggedValue deserializedData)
401 {
402     AnFileDataManager *anFileDataManager = AnFileDataManager::GetInstance();
403     std::string baseName = JSFilePath::GetFileName(snapshotFileName.c_str());
404     uint32_t anFileInfoIndex = anFileDataManager->SafeGetFileInfoIndex(baseName + FILE_EXTENSION_AN);
405 
406     JSThread *thread = vm_->GetJSThread();
407     JSHandle<TaggedArray> aiData(thread, deserializedData);
408     uint32_t aiDataLen = aiData->GetLength();
409     ASSERT(aiDataLen % AOTSnapshotConstants::SNAPSHOT_DATA_ITEM_SIZE  == 0);
410     auto aiDatumResult = aiDatum_.try_emplace(anFileInfoIndex);
411     FileNameToMultiConstantPoolMap &fileNameToMulCpMap = aiDatumResult.first->second;
412 
413     JSMutableHandle<TaggedArray> fileInfo(thread, JSTaggedValue::Undefined());
414     JSMutableHandle<TaggedArray> cpList(thread, JSTaggedValue::Undefined());
415     for (uint32_t i = 0; i < aiDataLen; i += AOTSnapshotConstants::SNAPSHOT_DATA_ITEM_SIZE) {
416         // handle file info
417         fileInfo.Update(aiData->Get(i + SnapshotGlobalData::Cast(SnapshotGlobalData::CP_TOP_ITEM::PANDA_INFO_ID)));
418         auto nameOffset = SnapshotGlobalData::Cast(SnapshotGlobalData::CP_PANDA_INFO_ITEM::NAME_ID);
419         auto indexOffset = SnapshotGlobalData::Cast(SnapshotGlobalData::CP_PANDA_INFO_ITEM::INDEX_ID);
420         CString fileNameStr = EcmaStringAccessor(fileInfo->Get(nameOffset)).ToCString();
421         uint32_t fileIndex = fileInfo->Get(indexOffset).GetInt();
422         // handle constant pool
423         cpList.Update(aiData->Get(i + SnapshotGlobalData::Cast(SnapshotGlobalData::CP_TOP_ITEM::CP_ARRAY_ID)));
424         uint32_t cpLen = cpList->GetLength();
425         ASSERT(cpLen % AOTSnapshotConstants::SNAPSHOT_CP_ARRAY_ITEM_SIZE == 0);
426         auto &PandaCpInfoInserted = fileNameToMulCpMap.try_emplace(fileNameStr).first->second;
427         PandaCpInfoInserted.fileIndex_ = fileIndex;
428         MultiConstantPoolMap &cpMap = PandaCpInfoInserted.multiCpsMap_;
429         for (uint32_t pos = 0; pos < cpLen; pos += AOTSnapshotConstants::SNAPSHOT_CP_ARRAY_ITEM_SIZE) {
430             int32_t constantPoolID = cpList->Get(pos).GetInt();
431             JSTaggedValue cp = cpList->Get(pos + 1);
432             cpMap.insert({constantPoolID, cp});
433         }
434     }
435 }
436 
GetDeserializedConstantPool(const JSPandaFile * jsPandaFile,int32_t cpID)437 JSHandle<JSTaggedValue> AOTFileManager::GetDeserializedConstantPool(const JSPandaFile *jsPandaFile, int32_t cpID)
438 {
439     // The deserialization of the 'ai' data used by the multi-work
440     // is not implemented yet, so there may be a case where
441     // aiDatum_ is empty, in which case the Hole will be returned
442     if (aiDatum_.empty()) {
443         return JSHandle<JSTaggedValue>(vm_->GetJSThread(), JSTaggedValue::Hole());
444     }
445     uint32_t anFileInfoIndex = jsPandaFile->GetAOTFileInfoIndex();
446     auto aiDatumIter = aiDatum_.find(anFileInfoIndex);
447     if (aiDatumIter == aiDatum_.end()) {
448         LOG_COMPILER(FATAL) << "can not find aiData by anFileInfoIndex " << anFileInfoIndex;
449         UNREACHABLE();
450     }
451     const auto &fileNameToMulCpMap = aiDatumIter->second;
452     auto cpMapIter = fileNameToMulCpMap.find(jsPandaFile->GetNormalizedFileDesc());
453     if (cpMapIter == fileNameToMulCpMap.end()) {
454         LOG_COMPILER(FATAL) << "can not find constpools by fileName " << jsPandaFile->GetNormalizedFileDesc().c_str();
455         UNREACHABLE();
456     }
457     const CMap<int32_t, JSTaggedValue> &cpMap = cpMapIter->second.multiCpsMap_;
458     auto iter = cpMap.find(cpID);
459     if (iter == cpMap.end()) {
460         LOG_COMPILER(FATAL) << "can not find deserialized constantpool in anFileInfo, constantPoolID is " << cpID;
461         UNREACHABLE();
462     }
463     return JSHandle<JSTaggedValue>(uintptr_t(&iter->second));
464 }
465 
~AOTFileManager()466 AOTFileManager::~AOTFileManager()
467 {
468     if (arkStackMapParser_ != nullptr) {
469         delete arkStackMapParser_;
470         arkStackMapParser_ = nullptr;
471     }
472 }
473 
AOTFileManager(EcmaVM * vm)474 AOTFileManager::AOTFileManager(EcmaVM *vm) : vm_(vm), factory_(vm->GetFactory())
475 {
476     bool enableLog = vm->GetJSOptions().WasSetCompilerLogOption();
477     arkStackMapParser_ = new kungfu::ArkStackMapParser(enableLog);
478 }
479 
GetAbsolutePath(JSThread * thread,JSTaggedValue relativePathVal)480 JSTaggedValue AOTFileManager::GetAbsolutePath(JSThread *thread, JSTaggedValue relativePathVal)
481 {
482     ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
483     CString relativePath = ConvertToString(relativePathVal);
484     CString absPath;
485     if (!GetAbsolutePath(relativePath, absPath)) {
486         LOG_FULL(FATAL) << "Get Absolute Path failed";
487         return JSTaggedValue::Hole();
488     }
489     JSTaggedValue absPathVal = factory->NewFromUtf8(absPath).GetTaggedValue();
490     return absPathVal;
491 }
492 
GetAbsolutePath(const CString & relativePathCstr,CString & absPathCstr)493 bool AOTFileManager::GetAbsolutePath(const CString &relativePathCstr, CString &absPathCstr)
494 {
495     std::string relativePath = ConvertToStdString(relativePathCstr);
496     std::string absPath;
497     if (RealPath(relativePath, absPath)) {
498         absPathCstr = ConvertToString(absPath);
499         return true;
500     }
501     return false;
502 }
503 
GetHeap()504 const Heap *AOTFileManager::GetHeap()
505 {
506     if (vm_ == nullptr) {
507         return nullptr;
508     }
509     return vm_->GetHeap();
510 }
511 }  // namespace panda::ecmascript
512