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