14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 54514f5e3Sopenharmony_ci * You may obtain a copy of the License at 64514f5e3Sopenharmony_ci * 74514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84514f5e3Sopenharmony_ci * 94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 134514f5e3Sopenharmony_ci * limitations under the License. 144514f5e3Sopenharmony_ci */ 154514f5e3Sopenharmony_ci 164514f5e3Sopenharmony_ci#include "ecmascript/compiler/file_generators.h" 174514f5e3Sopenharmony_ci 184514f5e3Sopenharmony_ci#include "ecmascript/common.h" 194514f5e3Sopenharmony_ci#include "ecmascript/compiler/aot_file/aot_file_manager.h" 204514f5e3Sopenharmony_ci#include "ecmascript/compiler/pgo_type/pgo_type_manager.h" 214514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_profiler_manager.h" 224514f5e3Sopenharmony_ci#include "ecmascript/platform/code_sign.h" 234514f5e3Sopenharmony_ci#include "ecmascript/platform/directory.h" 244514f5e3Sopenharmony_ci#include "ecmascript/platform/os.h" 254514f5e3Sopenharmony_ci#include "ecmascript/snapshot/mem/snapshot.h" 264514f5e3Sopenharmony_ci#include "ecmascript/stackmap/ark_stackmap_builder.h" 274514f5e3Sopenharmony_ci#include "ecmascript/stackmap/llvm/llvm_stackmap_parser.h" 284514f5e3Sopenharmony_ci#ifdef COMPILE_MAPLE 294514f5e3Sopenharmony_ci#include "ecmascript/compiler/codegen/maple/litecg_codegen.h" 304514f5e3Sopenharmony_ci#include "ecmascript/compiler/codegen/maple/litecg_ir_builder.h" 314514f5e3Sopenharmony_ci#include "ecmascript/compiler/codegen/maple/maple_be/include/litecg/litecg.h" 324514f5e3Sopenharmony_ci#include "ecmascript/stackmap/litecg/litecg_stackmap_type.h" 334514f5e3Sopenharmony_ci#ifdef JIT_ENABLE_CODE_SIGN 344514f5e3Sopenharmony_ci#include "ecmascript/compiler/jit_signcode.h" 354514f5e3Sopenharmony_ci#endif 364514f5e3Sopenharmony_ci#endif 374514f5e3Sopenharmony_ci#include "ecmascript/jit/jit.h" 384514f5e3Sopenharmony_ci#include "ecmascript/jit/jit_task.h" 394514f5e3Sopenharmony_ci#include "ecmascript/compiler/jit_compiler.h" 404514f5e3Sopenharmony_ci 414514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu { 424514f5e3Sopenharmony_civoid Module::CollectStackMapDes(ModuleSectionDes& des) const 434514f5e3Sopenharmony_ci{ 444514f5e3Sopenharmony_ci uint32_t stackmapSize = des.GetSecSize(ElfSecName::LLVM_STACKMAP); 454514f5e3Sopenharmony_ci std::unique_ptr<uint8_t[]> stackmapPtr(std::make_unique<uint8_t[]>(stackmapSize)); 464514f5e3Sopenharmony_ci uint64_t addr = des.GetSecAddr(ElfSecName::LLVM_STACKMAP); 474514f5e3Sopenharmony_ci if (addr == 0) { // assembler stub don't existed llvm stackmap 484514f5e3Sopenharmony_ci return; 494514f5e3Sopenharmony_ci } 504514f5e3Sopenharmony_ci uint64_t textAddr = des.GetSecAddr(ElfSecName::TEXT); 514514f5e3Sopenharmony_ci if (memcpy_s(stackmapPtr.get(), stackmapSize, reinterpret_cast<void *>(addr), stackmapSize) != EOK) { 524514f5e3Sopenharmony_ci LOG_COMPILER(FATAL) << "memcpy_s failed"; 534514f5e3Sopenharmony_ci UNREACHABLE(); 544514f5e3Sopenharmony_ci } 554514f5e3Sopenharmony_ci std::shared_ptr<uint8_t> ptr = nullptr; 564514f5e3Sopenharmony_ci uint32_t size = 0; 574514f5e3Sopenharmony_ci ArkStackMapBuilder builder; 584514f5e3Sopenharmony_ci std::tie(ptr, size) = builder.Run(std::move(stackmapPtr), textAddr, irModule_->GetTriple()); 594514f5e3Sopenharmony_ci des.EraseSec(ElfSecName::LLVM_STACKMAP); 604514f5e3Sopenharmony_ci des.SetArkStackMapPtr(ptr); 614514f5e3Sopenharmony_ci des.SetArkStackMapSize(size); 624514f5e3Sopenharmony_ci} 634514f5e3Sopenharmony_ci 644514f5e3Sopenharmony_civoid Module::CollectAnStackMapDes(ModuleSectionDes& des, uint64_t textOffset, 654514f5e3Sopenharmony_ci CGStackMapInfo &stackMapInfo) const 664514f5e3Sopenharmony_ci{ 674514f5e3Sopenharmony_ci#ifdef COMPILE_MAPLE 684514f5e3Sopenharmony_ci if (!IsLLVM()) { 694514f5e3Sopenharmony_ci static_cast<LiteCGAssembler*>(assembler_)->CollectAnStackMap(stackMapInfo); 704514f5e3Sopenharmony_ci return; 714514f5e3Sopenharmony_ci } 724514f5e3Sopenharmony_ci#endif 734514f5e3Sopenharmony_ci uint32_t stackmapSize = des.GetSecSize(ElfSecName::LLVM_STACKMAP); 744514f5e3Sopenharmony_ci std::unique_ptr<uint8_t[]> stackmapPtr(std::make_unique<uint8_t[]>(stackmapSize)); 754514f5e3Sopenharmony_ci uint64_t addr = des.GetSecAddr(ElfSecName::LLVM_STACKMAP); 764514f5e3Sopenharmony_ci if (addr == 0) { // assembler stub don't existed llvm stackmap 774514f5e3Sopenharmony_ci return; 784514f5e3Sopenharmony_ci } 794514f5e3Sopenharmony_ci uint64_t textAddr = des.GetSecAddr(ElfSecName::TEXT); 804514f5e3Sopenharmony_ci if (memcpy_s(stackmapPtr.get(), stackmapSize, reinterpret_cast<void *>(addr), stackmapSize) != EOK) { 814514f5e3Sopenharmony_ci LOG_COMPILER(FATAL) << "memcpy_s failed"; 824514f5e3Sopenharmony_ci UNREACHABLE(); 834514f5e3Sopenharmony_ci } 844514f5e3Sopenharmony_ci ArkStackMapBuilder builder; 854514f5e3Sopenharmony_ci builder.Collect(std::move(stackmapPtr), textAddr, textOffset, stackMapInfo); 864514f5e3Sopenharmony_ci des.EraseSec(ElfSecName::LLVM_STACKMAP); 874514f5e3Sopenharmony_ci} 884514f5e3Sopenharmony_ci 894514f5e3Sopenharmony_cistd::vector<uintptr_t> Module::GetFuncEntryPoints() 904514f5e3Sopenharmony_ci{ 914514f5e3Sopenharmony_ci std::vector<uintptr_t> entrys; 924514f5e3Sopenharmony_ci if (irModule_->GetModuleKind() != MODULE_LLVM) { 934514f5e3Sopenharmony_ci std::cout << "GetFuncEntryPoints is not supported for litecg currently" << std::endl; 944514f5e3Sopenharmony_ci return entrys; 954514f5e3Sopenharmony_ci } 964514f5e3Sopenharmony_ci LLVMModule *llvmModule = static_cast<LLVMModule *>(irModule_); 974514f5e3Sopenharmony_ci LLVMAssembler *assembler = static_cast<LLVMAssembler *>(assembler_); 984514f5e3Sopenharmony_ci auto engine = assembler->GetEngine(); 994514f5e3Sopenharmony_ci 1004514f5e3Sopenharmony_ci for (size_t j = 0; j < llvmModule->GetFuncCount(); j++) { 1014514f5e3Sopenharmony_ci LLVMValueRef func = llvmModule->GetFunction(j); 1024514f5e3Sopenharmony_ci ASSERT(func != nullptr); 1034514f5e3Sopenharmony_ci uintptr_t entry = reinterpret_cast<uintptr_t>(LLVMGetPointerToGlobal(engine, func)); 1044514f5e3Sopenharmony_ci entrys.push_back(entry); 1054514f5e3Sopenharmony_ci } 1064514f5e3Sopenharmony_ci return entrys; 1074514f5e3Sopenharmony_ci} 1084514f5e3Sopenharmony_ci 1094514f5e3Sopenharmony_civoid Module::CollectFuncEntryInfo(const std::vector<uintptr_t>& entrys, std::map<uintptr_t, std::string> &addr2name, 1104514f5e3Sopenharmony_ci StubFileInfo &stubInfo, uint32_t moduleIndex, const CompilerLog &log) 1114514f5e3Sopenharmony_ci{ 1124514f5e3Sopenharmony_ci LLVMModule *llvmModule = static_cast<LLVMModule*>(irModule_); 1134514f5e3Sopenharmony_ci LLVMAssembler *assembler = static_cast<LLVMAssembler*>(assembler_); 1144514f5e3Sopenharmony_ci auto codeBuff = assembler->GetSectionAddr(ElfSecName::TEXT); 1154514f5e3Sopenharmony_ci auto callSigns = llvmModule->GetCSigns(); 1164514f5e3Sopenharmony_ci const size_t funcCount = entrys.size(); 1174514f5e3Sopenharmony_ci funcCount_ = funcCount; 1184514f5e3Sopenharmony_ci startIndex_ = stubInfo.GetEntrySize(); 1194514f5e3Sopenharmony_ci 1204514f5e3Sopenharmony_ci for (size_t j = 0; j < funcCount; j++) { 1214514f5e3Sopenharmony_ci auto cs = callSigns[j]; 1224514f5e3Sopenharmony_ci LLVMValueRef func = llvmModule->GetFunction(j); 1234514f5e3Sopenharmony_ci ASSERT(func != nullptr); 1244514f5e3Sopenharmony_ci int delta = assembler->GetFpDeltaPrevFramSp(func, log); 1254514f5e3Sopenharmony_ci ASSERT(delta >= 0 && (delta % sizeof(uintptr_t) == 0)); 1264514f5e3Sopenharmony_ci uint32_t funcSize = 0; 1274514f5e3Sopenharmony_ci if (j < funcCount - 1) { 1284514f5e3Sopenharmony_ci funcSize = entrys[j + 1] - entrys[j]; 1294514f5e3Sopenharmony_ci } else { 1304514f5e3Sopenharmony_ci funcSize = codeBuff + assembler->GetSectionSize(ElfSecName::TEXT) - entrys[j]; 1314514f5e3Sopenharmony_ci } 1324514f5e3Sopenharmony_ci kungfu::CalleeRegAndOffsetVec info = assembler->GetCalleeReg2Offset(func, log); 1334514f5e3Sopenharmony_ci stubInfo.AddEntry(cs->GetTargetKind(), false, false, cs->GetID(), entrys[j] - codeBuff, 1344514f5e3Sopenharmony_ci AOTFileManager::STUB_FILE_INDEX, moduleIndex, delta, funcSize, info); 1354514f5e3Sopenharmony_ci ASSERT(!cs->GetName().empty()); 1364514f5e3Sopenharmony_ci addr2name[entrys[j]] = cs->GetName(); 1374514f5e3Sopenharmony_ci } 1384514f5e3Sopenharmony_ci} 1394514f5e3Sopenharmony_ci 1404514f5e3Sopenharmony_civoid Module::CollectFuncEntryInfo(std::map<uintptr_t, std::string> &addr2name, AnFileInfo &aotInfo, uint32_t fileIndex, 1414514f5e3Sopenharmony_ci uint32_t moduleIndex, const CompilerLog &log) 1424514f5e3Sopenharmony_ci{ 1434514f5e3Sopenharmony_ci#ifdef COMPILE_MAPLE 1444514f5e3Sopenharmony_ci if (irModule_->GetModuleKind() != MODULE_LLVM) { 1454514f5e3Sopenharmony_ci CollectFuncEntryInfoByLiteCG(addr2name, aotInfo, fileIndex, moduleIndex); 1464514f5e3Sopenharmony_ci return; 1474514f5e3Sopenharmony_ci } 1484514f5e3Sopenharmony_ci#endif 1494514f5e3Sopenharmony_ci LLVMAssembler *assembler = static_cast<LLVMAssembler*>(assembler_); 1504514f5e3Sopenharmony_ci auto engine = assembler->GetEngine(); 1514514f5e3Sopenharmony_ci std::vector<std::tuple<uint64_t, size_t, int, bool>> funcInfo; // entry idx delta 1524514f5e3Sopenharmony_ci std::vector<kungfu::CalleeRegAndOffsetVec> calleeSaveRegisters; // entry idx delta 1534514f5e3Sopenharmony_ci // 1.Compile all functions and collect function infos 1544514f5e3Sopenharmony_ci LLVMModule *llvmModule = static_cast<LLVMModule*>(irModule_); 1554514f5e3Sopenharmony_ci llvmModule->IteratefuncIndexMap([&](size_t idx, LLVMValueRef func, bool isFastCall) { 1564514f5e3Sopenharmony_ci uint64_t funcEntry = reinterpret_cast<uintptr_t>(LLVMGetPointerToGlobal(engine, func)); 1574514f5e3Sopenharmony_ci uint64_t length = 0; 1584514f5e3Sopenharmony_ci std::string funcName(LLVMGetValueName2(func, reinterpret_cast<size_t *>(&length))); 1594514f5e3Sopenharmony_ci ASSERT(length != 0); 1604514f5e3Sopenharmony_ci addr2name[funcEntry] = funcName; 1614514f5e3Sopenharmony_ci int delta = assembler->GetFpDeltaPrevFramSp(func, log); 1624514f5e3Sopenharmony_ci ASSERT(delta >= 0 && (delta % sizeof(uintptr_t) == 0)); 1634514f5e3Sopenharmony_ci funcInfo.emplace_back(std::tuple(funcEntry, idx, delta, isFastCall)); 1644514f5e3Sopenharmony_ci kungfu::CalleeRegAndOffsetVec info = assembler->GetCalleeReg2Offset(func, log); 1654514f5e3Sopenharmony_ci calleeSaveRegisters.emplace_back(info); 1664514f5e3Sopenharmony_ci }); 1674514f5e3Sopenharmony_ci // 2.After all functions compiled, the module sections would be fixed 1684514f5e3Sopenharmony_ci uintptr_t textAddr = GetTextAddr(); 1694514f5e3Sopenharmony_ci uint32_t textSize = GetTextSize(); 1704514f5e3Sopenharmony_ci uintptr_t rodataAddrBeforeText = 0; 1714514f5e3Sopenharmony_ci uint32_t rodataSizeBeforeText = 0; 1724514f5e3Sopenharmony_ci uintptr_t rodataAddrAfterText = 0; 1734514f5e3Sopenharmony_ci uint32_t rodataSizeAfterText = 0; 1744514f5e3Sopenharmony_ci std::tie(rodataAddrBeforeText, rodataSizeBeforeText, rodataAddrAfterText, rodataSizeAfterText) = 1754514f5e3Sopenharmony_ci GetMergedRODataAddrAndSize(textAddr); 1764514f5e3Sopenharmony_ci aotInfo.AlignTextSec(AOTFileInfo::PAGE_ALIGN); 1774514f5e3Sopenharmony_ci if (rodataSizeBeforeText != 0) { 1784514f5e3Sopenharmony_ci aotInfo.UpdateCurTextSecOffset(rodataSizeBeforeText); 1794514f5e3Sopenharmony_ci aotInfo.AlignTextSec(AOTFileInfo::TEXT_SEC_ALIGN); 1804514f5e3Sopenharmony_ci } 1814514f5e3Sopenharmony_ci 1824514f5e3Sopenharmony_ci const size_t funcCount = funcInfo.size(); 1834514f5e3Sopenharmony_ci funcCount_ = funcCount; 1844514f5e3Sopenharmony_ci startIndex_ = aotInfo.GetEntrySize(); 1854514f5e3Sopenharmony_ci // 3.Add function entries based on the module sections 1864514f5e3Sopenharmony_ci for (size_t i = 0; i < funcInfo.size(); i++) { 1874514f5e3Sopenharmony_ci uint64_t funcEntry; 1884514f5e3Sopenharmony_ci size_t idx; 1894514f5e3Sopenharmony_ci int delta; 1904514f5e3Sopenharmony_ci bool isFastCall; 1914514f5e3Sopenharmony_ci uint32_t funcSize; 1924514f5e3Sopenharmony_ci std::tie(funcEntry, idx, delta, isFastCall) = funcInfo[i]; 1934514f5e3Sopenharmony_ci if (i < funcCount - 1) { 1944514f5e3Sopenharmony_ci funcSize = std::get<0>(funcInfo[i + 1]) - funcEntry; 1954514f5e3Sopenharmony_ci } else { 1964514f5e3Sopenharmony_ci funcSize = textAddr + textSize - funcEntry; 1974514f5e3Sopenharmony_ci } 1984514f5e3Sopenharmony_ci auto found = addr2name[funcEntry].find(panda::ecmascript::JSPandaFile::ENTRY_FUNCTION_NAME); 1994514f5e3Sopenharmony_ci bool isMainFunc = found != std::string::npos; 2004514f5e3Sopenharmony_ci uint64_t offset = funcEntry - textAddr + aotInfo.GetCurTextSecOffset(); 2014514f5e3Sopenharmony_ci aotInfo.AddEntry(CallSignature::TargetKind::JSFUNCTION, isMainFunc, isFastCall, idx, 2024514f5e3Sopenharmony_ci offset, fileIndex, moduleIndex, delta, funcSize, calleeSaveRegisters[i]); 2034514f5e3Sopenharmony_ci } 2044514f5e3Sopenharmony_ci aotInfo.UpdateCurTextSecOffset(textSize); 2054514f5e3Sopenharmony_ci if (rodataSizeAfterText != 0) { 2064514f5e3Sopenharmony_ci aotInfo.AlignTextSec(AOTFileInfo::DATA_SEC_ALIGN); 2074514f5e3Sopenharmony_ci aotInfo.UpdateCurTextSecOffset(rodataSizeAfterText); 2084514f5e3Sopenharmony_ci } 2094514f5e3Sopenharmony_ci} 2104514f5e3Sopenharmony_ci 2114514f5e3Sopenharmony_ci#ifdef COMPILE_MAPLE 2124514f5e3Sopenharmony_civoid Module::CollectFuncEntryInfoByLiteCG(std::map<uintptr_t, std::string> &addr2name, AnFileInfo &aotInfo, 2134514f5e3Sopenharmony_ci uint32_t fileIndex, uint32_t moduleIndex) 2144514f5e3Sopenharmony_ci{ 2154514f5e3Sopenharmony_ci std::vector<std::tuple<uint64_t, size_t, int, bool>> funcInfo; // entry idx delta 2164514f5e3Sopenharmony_ci std::vector<kungfu::CalleeRegAndOffsetVec> calleeSaveRegisters; // entry idx delta 2174514f5e3Sopenharmony_ci // 1.Compile all functions and collect function infos 2184514f5e3Sopenharmony_ci LMIRModule *lmirModule = static_cast<LMIRModule*>(irModule_); 2194514f5e3Sopenharmony_ci LiteCGAssembler *assembler = static_cast<LiteCGAssembler*>(assembler_); 2204514f5e3Sopenharmony_ci const auto &func2Addr = assembler->GetCodeInfo().GetFuncInfos(); 2214514f5e3Sopenharmony_ci lmirModule->IteratefuncIndexMap([&](size_t idx, std::string funcName, bool isFastCall) { 2224514f5e3Sopenharmony_ci auto itr = func2Addr.find(funcName); 2234514f5e3Sopenharmony_ci if (itr == func2Addr.end()) { 2244514f5e3Sopenharmony_ci LOG_COMPILER(FATAL) << "get function address from emitter failed"; 2254514f5e3Sopenharmony_ci UNREACHABLE(); 2264514f5e3Sopenharmony_ci } 2274514f5e3Sopenharmony_ci uint64_t funcEntry = itr->second.addr; 2284514f5e3Sopenharmony_ci addr2name[funcEntry] = funcName; 2294514f5e3Sopenharmony_ci int delta = itr->second.fp2PrevFrameSpDelta; 2304514f5e3Sopenharmony_ci ASSERT(delta >= 0 && (delta % sizeof(uintptr_t) == 0)); 2314514f5e3Sopenharmony_ci funcInfo.emplace_back(std::tuple(funcEntry, idx, delta, isFastCall)); 2324514f5e3Sopenharmony_ci kungfu::CalleeRegAndOffsetVec info = itr->second.calleeRegInfo; 2334514f5e3Sopenharmony_ci calleeSaveRegisters.emplace_back(info); 2344514f5e3Sopenharmony_ci }); 2354514f5e3Sopenharmony_ci // 2.After all functions compiled, the module sections would be fixed 2364514f5e3Sopenharmony_ci uint32_t textSize = GetTextSize(); 2374514f5e3Sopenharmony_ci uint32_t rodataSizeBeforeText = 0; 2384514f5e3Sopenharmony_ci uint32_t rodataSizeAfterText = 0; 2394514f5e3Sopenharmony_ci 2404514f5e3Sopenharmony_ci aotInfo.AlignTextSec(AOTFileInfo::PAGE_ALIGN); 2414514f5e3Sopenharmony_ci if (rodataSizeBeforeText != 0) { 2424514f5e3Sopenharmony_ci aotInfo.UpdateCurTextSecOffset(rodataSizeBeforeText); 2434514f5e3Sopenharmony_ci aotInfo.AlignTextSec(AOTFileInfo::TEXT_SEC_ALIGN); 2444514f5e3Sopenharmony_ci } 2454514f5e3Sopenharmony_ci 2464514f5e3Sopenharmony_ci const size_t funcCount = funcInfo.size(); 2474514f5e3Sopenharmony_ci funcCount_ = funcCount; 2484514f5e3Sopenharmony_ci startIndex_ = aotInfo.GetEntrySize(); 2494514f5e3Sopenharmony_ci // 3.Add function entries based on the module sections 2504514f5e3Sopenharmony_ci for (size_t i = 0; i < funcInfo.size(); i++) { 2514514f5e3Sopenharmony_ci uint64_t funcEntry = 0; 2524514f5e3Sopenharmony_ci size_t idx; 2534514f5e3Sopenharmony_ci int delta; 2544514f5e3Sopenharmony_ci bool isFastCall; 2554514f5e3Sopenharmony_ci uint32_t funcSize; 2564514f5e3Sopenharmony_ci std::tie(funcEntry, idx, delta, isFastCall) = funcInfo[i]; 2574514f5e3Sopenharmony_ci if (i < funcCount - 1) { 2584514f5e3Sopenharmony_ci funcSize = std::get<0>(funcInfo[i + 1]) - funcEntry; 2594514f5e3Sopenharmony_ci } else { 2604514f5e3Sopenharmony_ci funcSize = textSize - funcEntry; 2614514f5e3Sopenharmony_ci } 2624514f5e3Sopenharmony_ci auto found = addr2name[funcEntry].find(panda::ecmascript::JSPandaFile::ENTRY_FUNCTION_NAME); 2634514f5e3Sopenharmony_ci bool isMainFunc = found != std::string::npos; 2644514f5e3Sopenharmony_ci uint64_t offset = funcEntry; 2654514f5e3Sopenharmony_ci aotInfo.AddEntry(CallSignature::TargetKind::JSFUNCTION, isMainFunc, isFastCall, idx, 2664514f5e3Sopenharmony_ci offset, fileIndex, moduleIndex, delta, funcSize, calleeSaveRegisters[i]); 2674514f5e3Sopenharmony_ci } 2684514f5e3Sopenharmony_ci aotInfo.UpdateCurTextSecOffset(textSize); 2694514f5e3Sopenharmony_ci if (rodataSizeAfterText != 0) { 2704514f5e3Sopenharmony_ci aotInfo.AlignTextSec(AOTFileInfo::DATA_SEC_ALIGN); 2714514f5e3Sopenharmony_ci aotInfo.UpdateCurTextSecOffset(rodataSizeAfterText); 2724514f5e3Sopenharmony_ci } 2734514f5e3Sopenharmony_ci} 2744514f5e3Sopenharmony_ci#endif 2754514f5e3Sopenharmony_ci 2764514f5e3Sopenharmony_civoid Module::CollectModuleSectionDes(ModuleSectionDes &moduleDes) const 2774514f5e3Sopenharmony_ci{ 2784514f5e3Sopenharmony_ci if (irModule_->GetModuleKind() != MODULE_LLVM) { 2794514f5e3Sopenharmony_ci std::cout << "CollectModuleSectionDes is not supported for litecg currently" << std::endl; 2804514f5e3Sopenharmony_ci return; 2814514f5e3Sopenharmony_ci } 2824514f5e3Sopenharmony_ci ASSERT(assembler_ != nullptr); 2834514f5e3Sopenharmony_ci LLVMAssembler *assembler = static_cast<LLVMAssembler*>(assembler_); 2844514f5e3Sopenharmony_ci assembler->IterateSecInfos([&](size_t i, std::pair<uint8_t *, size_t> secInfo) { 2854514f5e3Sopenharmony_ci auto curSec = ElfSection(i); 2864514f5e3Sopenharmony_ci ElfSecName sec = curSec.GetElfEnumValue(); 2874514f5e3Sopenharmony_ci if (IsRelaSection(sec)) { 2884514f5e3Sopenharmony_ci moduleDes.EraseSec(sec); 2894514f5e3Sopenharmony_ci } else { // aot need relocated; stub don't need collect relocated section 2904514f5e3Sopenharmony_ci moduleDes.SetSecAddrAndSize(sec, reinterpret_cast<uint64_t>(secInfo.first), secInfo.second); 2914514f5e3Sopenharmony_ci moduleDes.SetStartIndex(startIndex_); 2924514f5e3Sopenharmony_ci moduleDes.SetFuncCount(funcCount_); 2934514f5e3Sopenharmony_ci } 2944514f5e3Sopenharmony_ci }); 2954514f5e3Sopenharmony_ci CollectStackMapDes(moduleDes); 2964514f5e3Sopenharmony_ci} 2974514f5e3Sopenharmony_ci 2984514f5e3Sopenharmony_civoid Module::CollectAnModuleSectionDes(ModuleSectionDes &moduleDes, uint64_t textOffset, 2994514f5e3Sopenharmony_ci CGStackMapInfo &stackMapInfo) const 3004514f5e3Sopenharmony_ci{ 3014514f5e3Sopenharmony_ci ASSERT(assembler_ != nullptr); 3024514f5e3Sopenharmony_ci assembler_->IterateSecInfos([&](size_t i, std::pair<uint8_t *, size_t> secInfo) { 3034514f5e3Sopenharmony_ci auto curSec = ElfSection(i); 3044514f5e3Sopenharmony_ci ElfSecName sec = curSec.GetElfEnumValue(); 3054514f5e3Sopenharmony_ci // aot need relocated; stub don't need collect relocated section 3064514f5e3Sopenharmony_ci moduleDes.SetSecAddrAndSize(sec, reinterpret_cast<uint64_t>(secInfo.first), secInfo.second); 3074514f5e3Sopenharmony_ci moduleDes.SetStartIndex(startIndex_); 3084514f5e3Sopenharmony_ci moduleDes.SetFuncCount(funcCount_); 3094514f5e3Sopenharmony_ci }); 3104514f5e3Sopenharmony_ci CollectAnStackMapDes(moduleDes, textOffset, stackMapInfo); 3114514f5e3Sopenharmony_ci} 3124514f5e3Sopenharmony_ci 3134514f5e3Sopenharmony_ciuint32_t Module::GetSectionSize(ElfSecName sec) const 3144514f5e3Sopenharmony_ci{ 3154514f5e3Sopenharmony_ci return assembler_->GetSectionSize(sec); 3164514f5e3Sopenharmony_ci} 3174514f5e3Sopenharmony_ci 3184514f5e3Sopenharmony_ciuintptr_t Module::GetSectionAddr(ElfSecName sec) const 3194514f5e3Sopenharmony_ci{ 3204514f5e3Sopenharmony_ci return assembler_->GetSectionAddr(sec); 3214514f5e3Sopenharmony_ci} 3224514f5e3Sopenharmony_ci 3234514f5e3Sopenharmony_civoid Module::RunAssembler(const CompilerLog &log, bool fastCompileMode, bool isJit) 3244514f5e3Sopenharmony_ci{ 3254514f5e3Sopenharmony_ci assembler_->Run(log, fastCompileMode, isJit); 3264514f5e3Sopenharmony_ci} 3274514f5e3Sopenharmony_ci 3284514f5e3Sopenharmony_civoid Module::DisassemblerFunc(std::map<uintptr_t, std::string> &addr2name, uint64_t textOffset, 3294514f5e3Sopenharmony_ci const CompilerLog &log, const MethodLogList &logList, std::ostringstream &codeStream) 3304514f5e3Sopenharmony_ci{ 3314514f5e3Sopenharmony_ci if (irModule_->GetModuleKind() != MODULE_LLVM) { 3324514f5e3Sopenharmony_ci std::cout << "DisassemblerFunc is not supported for litecg currently" << std::endl; 3334514f5e3Sopenharmony_ci return; 3344514f5e3Sopenharmony_ci } 3354514f5e3Sopenharmony_ci auto *assembler = static_cast<LLVMAssembler*>(assembler_); 3364514f5e3Sopenharmony_ci assembler->Disassemble(addr2name, textOffset, log, logList, codeStream); 3374514f5e3Sopenharmony_ci} 3384514f5e3Sopenharmony_ci 3394514f5e3Sopenharmony_civoid Module::DestroyModule() 3404514f5e3Sopenharmony_ci{ 3414514f5e3Sopenharmony_ci if (irModule_ != nullptr) { 3424514f5e3Sopenharmony_ci delete irModule_; 3434514f5e3Sopenharmony_ci irModule_ = nullptr; 3444514f5e3Sopenharmony_ci } 3454514f5e3Sopenharmony_ci if (assembler_ != nullptr) { 3464514f5e3Sopenharmony_ci delete assembler_; 3474514f5e3Sopenharmony_ci assembler_ = nullptr; 3484514f5e3Sopenharmony_ci } 3494514f5e3Sopenharmony_ci} 3504514f5e3Sopenharmony_ci 3514514f5e3Sopenharmony_civoid StubFileGenerator::CollectAsmStubCodeInfo(std::map<uintptr_t, std::string> &addr2name, uint32_t bridgeModuleIdx) 3524514f5e3Sopenharmony_ci{ 3534514f5e3Sopenharmony_ci uint32_t funSize = 0; 3544514f5e3Sopenharmony_ci for (size_t i = 0; i < asmModule_.GetFunctionCount(); i++) { 3554514f5e3Sopenharmony_ci auto cs = asmModule_.GetCSign(i); 3564514f5e3Sopenharmony_ci auto entryOffset = asmModule_.GetFunction(cs->GetID()); 3574514f5e3Sopenharmony_ci if (i < asmModule_.GetFunctionCount() - 1) { 3584514f5e3Sopenharmony_ci auto nextcs = asmModule_.GetCSign(i + 1); 3594514f5e3Sopenharmony_ci funSize = asmModule_.GetFunction(nextcs->GetID()) - entryOffset; 3604514f5e3Sopenharmony_ci } else { 3614514f5e3Sopenharmony_ci funSize = asmModule_.GetBufferSize() - entryOffset; 3624514f5e3Sopenharmony_ci } 3634514f5e3Sopenharmony_ci stubInfo_.AddEntry(cs->GetTargetKind(), false, false, cs->GetID(), entryOffset, 3644514f5e3Sopenharmony_ci AOTFileManager::STUB_FILE_INDEX, bridgeModuleIdx, 0, funSize); 3654514f5e3Sopenharmony_ci ASSERT(!cs->GetName().empty()); 3664514f5e3Sopenharmony_ci addr2name[entryOffset] = cs->GetName(); 3674514f5e3Sopenharmony_ci } 3684514f5e3Sopenharmony_ci} 3694514f5e3Sopenharmony_ci 3704514f5e3Sopenharmony_civoid StubFileGenerator::CollectCodeInfo() 3714514f5e3Sopenharmony_ci{ 3724514f5e3Sopenharmony_ci std::map<uintptr_t, std::string> stubAddr2Name; 3734514f5e3Sopenharmony_ci std::vector<std::vector<uintptr_t>> entryPoints(modulePackage_.size()); 3744514f5e3Sopenharmony_ci 3754514f5e3Sopenharmony_ci if (!concurrentCompile_) { 3764514f5e3Sopenharmony_ci for (size_t i = 0; i < modulePackage_.size(); ++i) { 3774514f5e3Sopenharmony_ci entryPoints[i] = modulePackage_[i].GetFuncEntryPoints(); 3784514f5e3Sopenharmony_ci } 3794514f5e3Sopenharmony_ci } else if (!modulePackage_.empty()) { 3804514f5e3Sopenharmony_ci // For first module, run it in current thread. 3814514f5e3Sopenharmony_ci // For others, run them in child threads and wait for finish. 3824514f5e3Sopenharmony_ci std::vector<std::thread> threads; 3834514f5e3Sopenharmony_ci for (size_t i = 1; i < modulePackage_.size(); ++i) { 3844514f5e3Sopenharmony_ci threads.emplace_back([&, i]() { 3854514f5e3Sopenharmony_ci entryPoints[i] = modulePackage_[i].GetFuncEntryPoints(); 3864514f5e3Sopenharmony_ci }); 3874514f5e3Sopenharmony_ci } 3884514f5e3Sopenharmony_ci entryPoints[0] = modulePackage_[0].GetFuncEntryPoints(); 3894514f5e3Sopenharmony_ci for (auto& t : threads) { 3904514f5e3Sopenharmony_ci if (t.joinable()) { 3914514f5e3Sopenharmony_ci t.join(); 3924514f5e3Sopenharmony_ci } 3934514f5e3Sopenharmony_ci } 3944514f5e3Sopenharmony_ci } 3954514f5e3Sopenharmony_ci 3964514f5e3Sopenharmony_ci for (size_t i = 0; i < modulePackage_.size(); ++i) { 3974514f5e3Sopenharmony_ci modulePackage_[i].CollectFuncEntryInfo(entryPoints[i], stubAddr2Name, stubInfo_, i, GetLog()); 3984514f5e3Sopenharmony_ci ModuleSectionDes des; 3994514f5e3Sopenharmony_ci modulePackage_[i].CollectModuleSectionDes(des); 4004514f5e3Sopenharmony_ci stubInfo_.AddModuleDes(des); 4014514f5e3Sopenharmony_ci } 4024514f5e3Sopenharmony_ci std::map<uintptr_t, std::string> asmAddr2Name; 4034514f5e3Sopenharmony_ci // idx for bridge module is the one after last module in modulePackage 4044514f5e3Sopenharmony_ci CollectAsmStubCodeInfo(asmAddr2Name, modulePackage_.size()); 4054514f5e3Sopenharmony_ci if (log_->OutputASM()) { 4064514f5e3Sopenharmony_ci DisassembleAsmStubs(asmAddr2Name); 4074514f5e3Sopenharmony_ci DisassembleEachFunc(stubAddr2Name); 4084514f5e3Sopenharmony_ci } 4094514f5e3Sopenharmony_ci} 4104514f5e3Sopenharmony_ci 4114514f5e3Sopenharmony_civoid StubFileGenerator::DisassembleAsmStubs(std::map<uintptr_t, std::string> &addr2name) 4124514f5e3Sopenharmony_ci{ 4134514f5e3Sopenharmony_ci std::string tri = cfg_.GetTripleStr(); 4144514f5e3Sopenharmony_ci uint8_t *buf = reinterpret_cast<uint8_t*>(stubInfo_.GetAsmStubAddr()); 4154514f5e3Sopenharmony_ci size_t size = stubInfo_.GetAsmStubSize(); 4164514f5e3Sopenharmony_ci LLVMAssembler::Disassemble(&addr2name, tri, buf, size); 4174514f5e3Sopenharmony_ci} 4184514f5e3Sopenharmony_ci 4194514f5e3Sopenharmony_ciuint64_t AOTFileGenerator::RollbackTextSize(Module *module) 4204514f5e3Sopenharmony_ci{ 4214514f5e3Sopenharmony_ci uint64_t textAddr = module->GetSectionAddr(ElfSecName::TEXT); 4224514f5e3Sopenharmony_ci uint32_t textSize = module->GetSectionSize(ElfSecName::TEXT); 4234514f5e3Sopenharmony_ci uint64_t rodataAddrBeforeText = 0; 4244514f5e3Sopenharmony_ci uint32_t rodataSizeBeforeText = 0; 4254514f5e3Sopenharmony_ci uint64_t rodataAddrAfterText = 0; 4264514f5e3Sopenharmony_ci uint32_t rodataSizeAfterText = 0; 4274514f5e3Sopenharmony_ci if (module->IsLLVM()) { 4284514f5e3Sopenharmony_ci // In llvm the ro section is separated from the text section, but these all in text section in LiteCG. 4294514f5e3Sopenharmony_ci std::tie(rodataAddrBeforeText, rodataSizeBeforeText, rodataAddrAfterText, rodataSizeAfterText) = 4304514f5e3Sopenharmony_ci module->GetMergedRODataAddrAndSize(textAddr); 4314514f5e3Sopenharmony_ci } 4324514f5e3Sopenharmony_ci uint64_t textStart = 0; 4334514f5e3Sopenharmony_ci if (rodataSizeAfterText == 0) { 4344514f5e3Sopenharmony_ci textStart = aotInfo_.GetCurTextSecOffset() - textSize; 4354514f5e3Sopenharmony_ci } else { 4364514f5e3Sopenharmony_ci textStart = aotInfo_.GetCurTextSecOffset() - textSize - rodataSizeAfterText; 4374514f5e3Sopenharmony_ci textStart = AlignDown(textStart, AOTFileInfo::DATA_SEC_ALIGN); 4384514f5e3Sopenharmony_ci } 4394514f5e3Sopenharmony_ci return textStart; 4404514f5e3Sopenharmony_ci} 4414514f5e3Sopenharmony_ci 4424514f5e3Sopenharmony_civoid AOTFileGenerator::CollectCodeInfo(Module *module, uint32_t moduleIdx) 4434514f5e3Sopenharmony_ci{ 4444514f5e3Sopenharmony_ci std::map<uintptr_t, std::string> addr2name; 4454514f5e3Sopenharmony_ci uint32_t lastEntryIdx = aotInfo_.GetEntrySize(); 4464514f5e3Sopenharmony_ci pgo::ApEntityId abcId = INVALID_INDEX; 4474514f5e3Sopenharmony_ci pgo::PGOProfilerManager::GetInstance()->GetPandaFileId(curCompileFileName_.c_str(), abcId); 4484514f5e3Sopenharmony_ci module->CollectFuncEntryInfo(addr2name, aotInfo_, abcId, moduleIdx, GetLog()); 4494514f5e3Sopenharmony_ci aotInfo_.MappingEntryFuncsToAbcFiles(curCompileFileName_, lastEntryIdx, aotInfo_.GetEntrySize()); 4504514f5e3Sopenharmony_ci ModuleSectionDes des; 4514514f5e3Sopenharmony_ci uint64_t textOffset = RollbackTextSize(module); 4524514f5e3Sopenharmony_ci if (stackMapInfo_ == nullptr) { 4534514f5e3Sopenharmony_ci LOG_ECMA(FATAL) << "stackMapInfo_ isn't be initialized"; 4544514f5e3Sopenharmony_ci UNREACHABLE(); 4554514f5e3Sopenharmony_ci } 4564514f5e3Sopenharmony_ci module->CollectAnModuleSectionDes(des, textOffset, *stackMapInfo_); 4574514f5e3Sopenharmony_ci 4584514f5e3Sopenharmony_ci aotInfo_.AddModuleDes(des); 4594514f5e3Sopenharmony_ci if (module->IsLLVM() && log_->OutputASM()) { 4604514f5e3Sopenharmony_ci module->DisassemblerFunc(addr2name, textOffset, *(log_), *(logList_), codeStream_); 4614514f5e3Sopenharmony_ci } 4624514f5e3Sopenharmony_ci} 4634514f5e3Sopenharmony_ci 4644514f5e3Sopenharmony_ciModule* AOTFileGenerator::GetLatestModule() 4654514f5e3Sopenharmony_ci{ 4664514f5e3Sopenharmony_ci return &modulePackage_.back(); 4674514f5e3Sopenharmony_ci} 4684514f5e3Sopenharmony_ci 4694514f5e3Sopenharmony_ciuint32_t AOTFileGenerator::GetModuleVecSize() const 4704514f5e3Sopenharmony_ci{ 4714514f5e3Sopenharmony_ci return modulePackage_.size(); 4724514f5e3Sopenharmony_ci} 4734514f5e3Sopenharmony_ci 4744514f5e3Sopenharmony_ciModule* AOTFileGenerator::AddModule(const std::string &name, const std::string &triple, 4754514f5e3Sopenharmony_ci [[maybe_unused]] LOptions option, bool logDebug, [[maybe_unused]] bool isJit) 4764514f5e3Sopenharmony_ci{ 4774514f5e3Sopenharmony_ci#ifdef COMPILE_MAPLE 4784514f5e3Sopenharmony_ci if (useLiteCG_) { 4794514f5e3Sopenharmony_ci LMIRModule *irModule = new LMIRModule(compilationEnv_->GetNativeAreaAllocator(), name, logDebug, triple, isJit); 4804514f5e3Sopenharmony_ci LiteCGAssembler *ass = new LiteCGAssembler(*irModule, jitCodeSpace_, 4814514f5e3Sopenharmony_ci compilationEnv_->GetJSOptions().GetCompilerCodegenOptions()); 4824514f5e3Sopenharmony_ci modulePackage_.emplace_back(Module(irModule, ass)); 4834514f5e3Sopenharmony_ci if (stackMapInfo_ == nullptr) { 4844514f5e3Sopenharmony_ci stackMapInfo_ = new LiteCGStackMapInfo(); 4854514f5e3Sopenharmony_ci } 4864514f5e3Sopenharmony_ci return &modulePackage_.back(); 4874514f5e3Sopenharmony_ci } 4884514f5e3Sopenharmony_ci#endif 4894514f5e3Sopenharmony_ci LLVMModule *m = new LLVMModule(compilationEnv_->GetNativeAreaAllocator(), name, logDebug, triple); 4904514f5e3Sopenharmony_ci LLVMAssembler *ass = new LLVMAssembler(m, jitCodeSpace_, option); 4914514f5e3Sopenharmony_ci modulePackage_.emplace_back(Module(m, ass)); 4924514f5e3Sopenharmony_ci if (stackMapInfo_ == nullptr) { 4934514f5e3Sopenharmony_ci stackMapInfo_ = new LLVMStackMapInfo(); 4944514f5e3Sopenharmony_ci } 4954514f5e3Sopenharmony_ci return &modulePackage_.back(); 4964514f5e3Sopenharmony_ci} 4974514f5e3Sopenharmony_ci 4984514f5e3Sopenharmony_ciModule* StubFileGenerator::AddModule(NativeAreaAllocator *allocator, const std::string &name, const std::string &triple, 4994514f5e3Sopenharmony_ci LOptions option, bool logDebug, StubFileKind kind) 5004514f5e3Sopenharmony_ci{ 5014514f5e3Sopenharmony_ci LLVMModule* m = new LLVMModule(allocator, name, logDebug, triple); 5024514f5e3Sopenharmony_ci switch (kind) { 5034514f5e3Sopenharmony_ci case StubFileKind::BC: 5044514f5e3Sopenharmony_ci m->SetUpForBytecodeHandlerStubs(); 5054514f5e3Sopenharmony_ci break; 5064514f5e3Sopenharmony_ci case StubFileKind::COM: 5074514f5e3Sopenharmony_ci m->SetUpForCommonStubs(); 5084514f5e3Sopenharmony_ci break; 5094514f5e3Sopenharmony_ci case StubFileKind::BUILTIN: 5104514f5e3Sopenharmony_ci m->SetUpForBuiltinsStubs(); 5114514f5e3Sopenharmony_ci break; 5124514f5e3Sopenharmony_ci case StubFileKind::BASELINE: 5134514f5e3Sopenharmony_ci m->SetUpForBaselineStubs(); 5144514f5e3Sopenharmony_ci break; 5154514f5e3Sopenharmony_ci default: 5164514f5e3Sopenharmony_ci LOG_ECMA(FATAL) << "unsupported stub file kind"; 5174514f5e3Sopenharmony_ci UNREACHABLE(); 5184514f5e3Sopenharmony_ci break; 5194514f5e3Sopenharmony_ci } 5204514f5e3Sopenharmony_ci LLVMAssembler* ass = new LLVMAssembler(m, jitCodeSpace_, option); 5214514f5e3Sopenharmony_ci modulePackage_.emplace_back(Module(m, ass)); 5224514f5e3Sopenharmony_ci return &modulePackage_.back(); 5234514f5e3Sopenharmony_ci} 5244514f5e3Sopenharmony_ci 5254514f5e3Sopenharmony_civoid StubFileGenerator::RunLLVMAssembler() 5264514f5e3Sopenharmony_ci{ 5274514f5e3Sopenharmony_ci if (!concurrentCompile_) { 5284514f5e3Sopenharmony_ci for (auto &m: modulePackage_) { 5294514f5e3Sopenharmony_ci m.RunAssembler(*(this->log_), false); 5304514f5e3Sopenharmony_ci } 5314514f5e3Sopenharmony_ci } else if (!modulePackage_.empty()) { 5324514f5e3Sopenharmony_ci // For first module, run it in current thread. 5334514f5e3Sopenharmony_ci // For others, run them in child threads and wait for finish. 5344514f5e3Sopenharmony_ci std::vector<std::thread> threads; 5354514f5e3Sopenharmony_ci for (size_t i = 1; i < modulePackage_.size(); ++i) { 5364514f5e3Sopenharmony_ci const CompilerLog &log = *(this->log_); 5374514f5e3Sopenharmony_ci threads.emplace_back([&, i] { 5384514f5e3Sopenharmony_ci modulePackage_[i].RunAssembler(log, false); 5394514f5e3Sopenharmony_ci }); 5404514f5e3Sopenharmony_ci } 5414514f5e3Sopenharmony_ci modulePackage_[0].RunAssembler(*(this->log_), false); 5424514f5e3Sopenharmony_ci for (auto& t : threads) { 5434514f5e3Sopenharmony_ci if (t.joinable()) { 5444514f5e3Sopenharmony_ci t.join(); 5454514f5e3Sopenharmony_ci } 5464514f5e3Sopenharmony_ci } 5474514f5e3Sopenharmony_ci } 5484514f5e3Sopenharmony_ci} 5494514f5e3Sopenharmony_ci 5504514f5e3Sopenharmony_civoid StubFileGenerator::RunAsmAssembler() 5514514f5e3Sopenharmony_ci{ 5524514f5e3Sopenharmony_ci NativeAreaAllocator allocator; 5534514f5e3Sopenharmony_ci Chunk chunk(&allocator); 5544514f5e3Sopenharmony_ci asmModule_.Run(&cfg_, &chunk); 5554514f5e3Sopenharmony_ci 5564514f5e3Sopenharmony_ci auto buffer = asmModule_.GetBuffer(); 5574514f5e3Sopenharmony_ci auto bufferSize = asmModule_.GetBufferSize(); 5584514f5e3Sopenharmony_ci if (bufferSize == 0U) { 5594514f5e3Sopenharmony_ci return; 5604514f5e3Sopenharmony_ci } 5614514f5e3Sopenharmony_ci stubInfo_.AddAsmStubELFInfo(asmModule_.GetCSigns(), asmModule_.GetStubsOffset()); 5624514f5e3Sopenharmony_ci stubInfo_.FillAsmStubTempHolder(buffer, bufferSize); 5634514f5e3Sopenharmony_ci stubInfo_.accumulateTotalSize(bufferSize); 5644514f5e3Sopenharmony_ci} 5654514f5e3Sopenharmony_ci 5664514f5e3Sopenharmony_civoid StubFileGenerator::SaveStubFile(const std::string &filename) 5674514f5e3Sopenharmony_ci{ 5684514f5e3Sopenharmony_ci RunLLVMAssembler(); 5694514f5e3Sopenharmony_ci RunAsmAssembler(); 5704514f5e3Sopenharmony_ci CollectCodeInfo(); 5714514f5e3Sopenharmony_ci stubInfo_.Save(filename, cfg_.GetTriple()); 5724514f5e3Sopenharmony_ci} 5734514f5e3Sopenharmony_ci 5744514f5e3Sopenharmony_civoid AOTFileGenerator::CompileLatestModuleThenDestroy(bool isJit) 5754514f5e3Sopenharmony_ci{ 5764514f5e3Sopenharmony_ci Module *latestModule = GetLatestModule(); 5774514f5e3Sopenharmony_ci#ifdef COMPILE_MAPLE 5784514f5e3Sopenharmony_ci static uint32_t lastModulePC = 0; 5794514f5e3Sopenharmony_ci if (useLiteCG_ && compilationEnv_->IsJitCompiler()) { 5804514f5e3Sopenharmony_ci lastModulePC = 0; 5814514f5e3Sopenharmony_ci } 5824514f5e3Sopenharmony_ci if (latestModule->GetModule()->GetModuleKind() != MODULE_LLVM) { 5834514f5e3Sopenharmony_ci LMIRModule *lmirModule = static_cast<LMIRModule*>(latestModule->GetModule()); 5844514f5e3Sopenharmony_ci lastModulePC = AlignUp(lastModulePC, AOTFileInfo::PAGE_ALIGN); 5854514f5e3Sopenharmony_ci lmirModule->GetModule()->SetLastModulePC(lastModulePC); 5864514f5e3Sopenharmony_ci // pass triple to litecg 5874514f5e3Sopenharmony_ci lmirModule->GetModule()->SetIsAArch64(isAArch64()); 5884514f5e3Sopenharmony_ci } 5894514f5e3Sopenharmony_ci#endif 5904514f5e3Sopenharmony_ci ASSERT(GetModuleVecSize() > 0); 5914514f5e3Sopenharmony_ci uint32_t latestModuleIdx = GetModuleVecSize() - 1; 5924514f5e3Sopenharmony_ci { 5934514f5e3Sopenharmony_ci TimeScope timescope("LLVMIROpt", const_cast<CompilerLog *>(log_)); 5944514f5e3Sopenharmony_ci bool fastCompileMode = compilationEnv_->GetJSOptions().GetFastAOTCompileMode(); 5954514f5e3Sopenharmony_ci latestModule->RunAssembler(*(log_), fastCompileMode, isJit); 5964514f5e3Sopenharmony_ci } 5974514f5e3Sopenharmony_ci { 5984514f5e3Sopenharmony_ci TimeScope timescope("LLVMCodeGen", const_cast<CompilerLog *>(log_)); 5994514f5e3Sopenharmony_ci CollectCodeInfo(latestModule, latestModuleIdx); 6004514f5e3Sopenharmony_ci } 6014514f5e3Sopenharmony_ci // message has been put into aotInfo, so latestModule could be destroyed 6024514f5e3Sopenharmony_ci#ifdef COMPILE_MAPLE 6034514f5e3Sopenharmony_ci if (latestModule->GetModule()->GetModuleKind() != MODULE_LLVM) { 6044514f5e3Sopenharmony_ci LMIRModule *lmirModule = static_cast<LMIRModule*>(latestModule->GetModule()); 6054514f5e3Sopenharmony_ci lastModulePC = lmirModule->GetModule()->GetCurModulePC(); 6064514f5e3Sopenharmony_ci } 6074514f5e3Sopenharmony_ci#endif 6084514f5e3Sopenharmony_ci latestModule->DestroyModule(); 6094514f5e3Sopenharmony_ci} 6104514f5e3Sopenharmony_ci 6114514f5e3Sopenharmony_civoid AOTFileGenerator::DestroyCollectedStackMapInfo() 6124514f5e3Sopenharmony_ci{ 6134514f5e3Sopenharmony_ci if (stackMapInfo_ != nullptr) { 6144514f5e3Sopenharmony_ci delete stackMapInfo_; 6154514f5e3Sopenharmony_ci stackMapInfo_ = nullptr; 6164514f5e3Sopenharmony_ci } 6174514f5e3Sopenharmony_ci} 6184514f5e3Sopenharmony_ci 6194514f5e3Sopenharmony_civoid AOTFileGenerator::GenerateMergedStackmapSection() 6204514f5e3Sopenharmony_ci{ 6214514f5e3Sopenharmony_ci ArkStackMapBuilder builder; 6224514f5e3Sopenharmony_ci std::shared_ptr<uint8_t> ptr = nullptr; 6234514f5e3Sopenharmony_ci uint32_t size = 0; 6244514f5e3Sopenharmony_ci if (stackMapInfo_ == nullptr) { 6254514f5e3Sopenharmony_ci LOG_ECMA(FATAL) << "stackMapInfo_ isn't be initialized"; 6264514f5e3Sopenharmony_ci UNREACHABLE(); 6274514f5e3Sopenharmony_ci } 6284514f5e3Sopenharmony_ci std::tie(ptr, size) = builder.GenerateArkStackMap(*stackMapInfo_, cfg_.GetTriple()); 6294514f5e3Sopenharmony_ci aotInfo_.UpdateStackMap(ptr, size, 0); 6304514f5e3Sopenharmony_ci DestroyCollectedStackMapInfo(); 6314514f5e3Sopenharmony_ci} 6324514f5e3Sopenharmony_ci 6334514f5e3Sopenharmony_cibool AOTFileGenerator::CreateDirIfNotExist(const std::string &filename) 6344514f5e3Sopenharmony_ci{ 6354514f5e3Sopenharmony_ci std::string realPath; 6364514f5e3Sopenharmony_ci if (!panda::ecmascript::RealPath(filename, realPath, false)) { 6374514f5e3Sopenharmony_ci return false; 6384514f5e3Sopenharmony_ci } 6394514f5e3Sopenharmony_ci auto index = realPath.find_last_of('/'); 6404514f5e3Sopenharmony_ci if (index == std::string::npos) { 6414514f5e3Sopenharmony_ci return true; 6424514f5e3Sopenharmony_ci } 6434514f5e3Sopenharmony_ci std::string path = realPath.substr(0, index); 6444514f5e3Sopenharmony_ci if (!panda::ecmascript::ForceCreateDirectory(path)) { 6454514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "Fail to make dir: " << path; 6464514f5e3Sopenharmony_ci return false; 6474514f5e3Sopenharmony_ci } 6484514f5e3Sopenharmony_ci return panda::ecmascript::SetDirModeAsDefault(path); 6494514f5e3Sopenharmony_ci} 6504514f5e3Sopenharmony_ci 6514514f5e3Sopenharmony_cibool AOTFileGenerator::SaveAOTFile(const std::string &filename, const std::string &appSignature) 6524514f5e3Sopenharmony_ci{ 6534514f5e3Sopenharmony_ci if (aotInfo_.GetTotalCodeSize() == 0) { 6544514f5e3Sopenharmony_ci LOG_COMPILER(WARN) << "error: code size of generated an file is empty!"; 6554514f5e3Sopenharmony_ci return false; 6564514f5e3Sopenharmony_ci } 6574514f5e3Sopenharmony_ci if (!CreateDirIfNotExist(filename)) { 6584514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "Fail to access dir: " << filename; 6594514f5e3Sopenharmony_ci return false; 6604514f5e3Sopenharmony_ci } 6614514f5e3Sopenharmony_ci PrintMergedCodeComment(); 6624514f5e3Sopenharmony_ci GenerateMergedStackmapSection(); 6634514f5e3Sopenharmony_ci aotInfo_.GenerateMethodToEntryIndexMap(); 6644514f5e3Sopenharmony_ci if (!aotInfo_.Save(filename, cfg_.GetTriple())) { 6654514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "Fail to save an file: " << filename; 6664514f5e3Sopenharmony_ci return false; 6674514f5e3Sopenharmony_ci } 6684514f5e3Sopenharmony_ci if (!panda::ecmascript::SetFileModeAsDefault(filename)) { 6694514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "Fail to set an file mode:" << filename; 6704514f5e3Sopenharmony_ci return false; 6714514f5e3Sopenharmony_ci } 6724514f5e3Sopenharmony_ci SetSecurityLabel(filename); 6734514f5e3Sopenharmony_ci panda::ecmascript::CodeSignatureForAOTFile(filename, appSignature); 6744514f5e3Sopenharmony_ci return true; 6754514f5e3Sopenharmony_ci} 6764514f5e3Sopenharmony_ci 6774514f5e3Sopenharmony_civoid AOTFileGenerator::SaveEmptyAOTFile(const std::string& filename, const std::string& appSignature, bool isAnFile) 6784514f5e3Sopenharmony_ci{ 6794514f5e3Sopenharmony_ci if (!CreateDirIfNotExist(filename)) { 6804514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "Fail to access dir: " << filename; 6814514f5e3Sopenharmony_ci return; 6824514f5e3Sopenharmony_ci } 6834514f5e3Sopenharmony_ci std::string realPath; 6844514f5e3Sopenharmony_ci if (!RealPath(filename, realPath, false)) { 6854514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "Fail to get realPath: " << filename; 6864514f5e3Sopenharmony_ci return; 6874514f5e3Sopenharmony_ci } 6884514f5e3Sopenharmony_ci if (FileExist(realPath.c_str())) { 6894514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "AOT file: " << realPath << " exist, skip create empty file"; 6904514f5e3Sopenharmony_ci return; 6914514f5e3Sopenharmony_ci } 6924514f5e3Sopenharmony_ci const char* rawPath = realPath.c_str(); 6934514f5e3Sopenharmony_ci std::ofstream file(rawPath, std::ofstream::binary); 6944514f5e3Sopenharmony_ci file.close(); 6954514f5e3Sopenharmony_ci if (!panda::ecmascript::SetFileModeAsDefault(filename)) { 6964514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "Fail to set file mode: " << filename; 6974514f5e3Sopenharmony_ci } 6984514f5e3Sopenharmony_ci if (isAnFile) { 6994514f5e3Sopenharmony_ci panda::ecmascript::CodeSignatureForAOTFile(filename, appSignature); 7004514f5e3Sopenharmony_ci } 7014514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "create empty AOT file: " << realPath << " due to illegal AP file"; 7024514f5e3Sopenharmony_ci} 7034514f5e3Sopenharmony_ci 7044514f5e3Sopenharmony_cibool AOTFileGenerator::GetMemoryCodeInfos(MachineCodeDesc &machineCodeDesc) 7054514f5e3Sopenharmony_ci{ 7064514f5e3Sopenharmony_ci if (aotInfo_.GetTotalCodeSize() == 0) { 7074514f5e3Sopenharmony_ci LOG_COMPILER(WARN) << "error: code size of generated an file is empty!"; 7084514f5e3Sopenharmony_ci return false; 7094514f5e3Sopenharmony_ci } 7104514f5e3Sopenharmony_ci 7114514f5e3Sopenharmony_ci if (log_->OutputASM()) { 7124514f5e3Sopenharmony_ci PrintMergedCodeComment(); 7134514f5e3Sopenharmony_ci } 7144514f5e3Sopenharmony_ci GenerateMergedStackmapSection(); 7154514f5e3Sopenharmony_ci 7164514f5e3Sopenharmony_ci // get func entry Map 7174514f5e3Sopenharmony_ci aotInfo_.GenerateMethodToEntryIndexMap(); 7184514f5e3Sopenharmony_ci 7194514f5e3Sopenharmony_ci uint64_t funcEntryAddr = reinterpret_cast<uint64_t>(aotInfo_.GetStubs().data()); 7204514f5e3Sopenharmony_ci ASSERT(aotInfo_.GetStubs().size() <= 2); // jsfunc + __llvm_deoptimize, 2 : size 7214514f5e3Sopenharmony_ci uint32_t funcEntrySize = sizeof(AOTFileInfo::FuncEntryDes) * aotInfo_.GetStubs().size(); 7224514f5e3Sopenharmony_ci 7234514f5e3Sopenharmony_ci ASSERT(aotInfo_.GetModuleSectionDes().size() == 1); 7244514f5e3Sopenharmony_ci auto &moduleSectionDes = aotInfo_.GetModuleSectionDes()[0]; 7254514f5e3Sopenharmony_ci // get code data 7264514f5e3Sopenharmony_ci uint64_t textAddr = moduleSectionDes.GetSecAddr(ElfSecName::TEXT); 7274514f5e3Sopenharmony_ci size_t textSize = moduleSectionDes.GetSecSize(ElfSecName::TEXT); 7284514f5e3Sopenharmony_ci 7294514f5e3Sopenharmony_ci uint64_t rodataAddrBeforeText = 0; 7304514f5e3Sopenharmony_ci uint32_t rodataSizeBeforeText = 0; 7314514f5e3Sopenharmony_ci uint64_t rodataAddrAfterText = 0; 7324514f5e3Sopenharmony_ci uint32_t rodataSizeAfterText = 0; 7334514f5e3Sopenharmony_ci std::tie(rodataAddrBeforeText, rodataSizeBeforeText, rodataAddrAfterText, rodataSizeAfterText) = 7344514f5e3Sopenharmony_ci moduleSectionDes.GetMergedRODataAddrAndSize(textAddr); 7354514f5e3Sopenharmony_ci 7364514f5e3Sopenharmony_ci machineCodeDesc.rodataAddrBeforeText = rodataAddrBeforeText; 7374514f5e3Sopenharmony_ci machineCodeDesc.rodataSizeBeforeText = rodataSizeBeforeText; 7384514f5e3Sopenharmony_ci machineCodeDesc.rodataAddrAfterText = rodataAddrAfterText; 7394514f5e3Sopenharmony_ci machineCodeDesc.rodataSizeAfterText = rodataSizeAfterText; 7404514f5e3Sopenharmony_ci 7414514f5e3Sopenharmony_ci#ifdef JIT_ENABLE_CODE_SIGN 7424514f5e3Sopenharmony_ci machineCodeDesc.codeSigner = 0; 7434514f5e3Sopenharmony_ci JitSignCode *singleton = JitSignCode::GetInstance(); 7444514f5e3Sopenharmony_ci if (singleton->GetCodeSigner() != 0) { 7454514f5e3Sopenharmony_ci LOG_JIT(DEBUG) << "In GetMemoryCodeInfos, signer = " << singleton->GetCodeSigner(); 7464514f5e3Sopenharmony_ci LOG_JIT(DEBUG) << " signTableSize = " << singleton->signTableSize_; 7474514f5e3Sopenharmony_ci machineCodeDesc.codeSigner = reinterpret_cast<uintptr_t>(singleton->GetCodeSigner()); 7484514f5e3Sopenharmony_ci } 7494514f5e3Sopenharmony_ci#endif 7504514f5e3Sopenharmony_ci 7514514f5e3Sopenharmony_ci uint64_t stackMapPtr = reinterpret_cast<uint64_t>(moduleSectionDes.GetArkStackMapSharePtr().get()); 7524514f5e3Sopenharmony_ci size_t stackMapSize = moduleSectionDes.GetArkStackMapSize(); 7534514f5e3Sopenharmony_ci 7544514f5e3Sopenharmony_ci machineCodeDesc.codeAddr = textAddr; 7554514f5e3Sopenharmony_ci machineCodeDesc.codeSize = textSize; 7564514f5e3Sopenharmony_ci machineCodeDesc.funcEntryDesAddr = funcEntryAddr; 7574514f5e3Sopenharmony_ci machineCodeDesc.funcEntryDesSize = funcEntrySize; 7584514f5e3Sopenharmony_ci machineCodeDesc.stackMapOrOffsetTableAddr = stackMapPtr; 7594514f5e3Sopenharmony_ci machineCodeDesc.stackMapOrOffsetTableSize = stackMapSize; 7604514f5e3Sopenharmony_ci machineCodeDesc.codeType = MachineCodeType::FAST_JIT_CODE; 7614514f5e3Sopenharmony_ci 7624514f5e3Sopenharmony_ci if (Jit::GetInstance()->IsEnableJitFort() && Jit::GetInstance()->IsEnableAsyncCopyToFort() && 7634514f5e3Sopenharmony_ci JitCompiler::AllocFromFortAndCopy(*compilationEnv_, machineCodeDesc) == false) { 7644514f5e3Sopenharmony_ci return false; 7654514f5e3Sopenharmony_ci } 7664514f5e3Sopenharmony_ci return true; 7674514f5e3Sopenharmony_ci} 7684514f5e3Sopenharmony_ci 7694514f5e3Sopenharmony_civoid AOTFileGenerator::JitCreateLitecgModule() 7704514f5e3Sopenharmony_ci{ 7714514f5e3Sopenharmony_ci#ifdef COMPILE_MAPLE 7724514f5e3Sopenharmony_ci Module *latestModule = GetLatestModule(); 7734514f5e3Sopenharmony_ci if (latestModule->GetModule()->GetModuleKind() != MODULE_LLVM) { 7744514f5e3Sopenharmony_ci LMIRModule *lmirModule = static_cast<LMIRModule*>(latestModule->GetModule()); 7754514f5e3Sopenharmony_ci lmirModule->JitCreateLitecgModule(); 7764514f5e3Sopenharmony_ci } 7774514f5e3Sopenharmony_ci#endif 7784514f5e3Sopenharmony_ci} 7794514f5e3Sopenharmony_ci 7804514f5e3Sopenharmony_cibool AOTFileGenerator::isAArch64() const 7814514f5e3Sopenharmony_ci{ 7824514f5e3Sopenharmony_ci return cfg_.IsAArch64(); 7834514f5e3Sopenharmony_ci} 7844514f5e3Sopenharmony_ci 7854514f5e3Sopenharmony_cibool AOTFileGenerator::SaveSnapshotFile() 7864514f5e3Sopenharmony_ci{ 7874514f5e3Sopenharmony_ci TimeScope timescope("LLVMCodeGenPass-AI", const_cast<CompilerLog *>(log_)); 7884514f5e3Sopenharmony_ci Snapshot snapshot(compilationEnv_->GetEcmaVM()); 7894514f5e3Sopenharmony_ci const CString snapshotPath(compilationEnv_->GetJSOptions().GetAOTOutputFile().c_str()); 7904514f5e3Sopenharmony_ci const auto &methodToEntryIndexMap = aotInfo_.GetMethodToEntryIndexMap(); 7914514f5e3Sopenharmony_ci PGOTypeManager *ptManager = compilationEnv_->GetPTManager(); 7924514f5e3Sopenharmony_ci ptManager->GetAOTSnapshot().ResolveSnapshotData(methodToEntryIndexMap); 7934514f5e3Sopenharmony_ci 7944514f5e3Sopenharmony_ci CString aiPath = snapshotPath + AOTFileManager::FILE_EXTENSION_AI; 7954514f5e3Sopenharmony_ci if (!CreateDirIfNotExist(aiPath.c_str())) { 7964514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "Fail to access dir: " << aiPath; 7974514f5e3Sopenharmony_ci return false; 7984514f5e3Sopenharmony_ci } 7994514f5e3Sopenharmony_ci snapshot.Serialize(aiPath); 8004514f5e3Sopenharmony_ci if (!panda::ecmascript::SetFileModeAsDefault(aiPath.c_str())) { 8014514f5e3Sopenharmony_ci LOG_COMPILER(ERROR) << "Fail to set ai file mode:" << aiPath; 8024514f5e3Sopenharmony_ci return false; 8034514f5e3Sopenharmony_ci } 8044514f5e3Sopenharmony_ci SetSecurityLabel(aiPath.c_str()); 8054514f5e3Sopenharmony_ci return true; 8064514f5e3Sopenharmony_ci} 8074514f5e3Sopenharmony_ci} // namespace panda::ecmascript::kungfu 808