14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2023 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/codegen/maple/litecg_codegen.h" 174514f5e3Sopenharmony_ci#if defined(PANDA_TARGET_MACOS) || defined(PANDA_TARGET_IOS) 184514f5e3Sopenharmony_ci#include "ecmascript/base/llvm_helper.h" 194514f5e3Sopenharmony_ci#endif 204514f5e3Sopenharmony_ci 214514f5e3Sopenharmony_ci#include <cstring> 224514f5e3Sopenharmony_ci#include <iomanip> 234514f5e3Sopenharmony_ci#include <vector> 244514f5e3Sopenharmony_ci 254514f5e3Sopenharmony_ci#include "ecmascript/compiler/call_signature.h" 264514f5e3Sopenharmony_ci#include "ecmascript/compiler/codegen/maple/litecg_ir_builder.h" 274514f5e3Sopenharmony_ci#include "ecmascript/compiler/codegen/maple/maple_be/include/litecg/litecg.h" 284514f5e3Sopenharmony_ci#include "ecmascript/compiler/codegen/maple/maple_be/include/litecg/lmir_builder.h" 294514f5e3Sopenharmony_ci#include "ecmascript/compiler/compiler_log.h" 304514f5e3Sopenharmony_ci#include "ecmascript/ecma_macros.h" 314514f5e3Sopenharmony_ci#include "ecmascript/mem/region.h" 324514f5e3Sopenharmony_ci#include "ecmascript/object_factory.h" 334514f5e3Sopenharmony_ci#include "ecmascript/stackmap/litecg/litecg_stackmap_type.h" 344514f5e3Sopenharmony_ci#include "ecmascript/stackmap/llvm/llvm_stackmap_parser.h" 354514f5e3Sopenharmony_ci#ifdef JIT_ENABLE_CODE_SIGN 364514f5e3Sopenharmony_ci#include "jit_buffer_integrity.h" 374514f5e3Sopenharmony_ci#include "ecmascript/compiler/jit_signcode.h" 384514f5e3Sopenharmony_ci#endif 394514f5e3Sopenharmony_ci 404514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu { 414514f5e3Sopenharmony_ci#ifdef JIT_ENABLE_CODE_SIGN 424514f5e3Sopenharmony_ciusing namespace panda::ecmascript::kungfu; 434514f5e3Sopenharmony_ciusing namespace OHOS::Security::CodeSign; 444514f5e3Sopenharmony_ci#endif 454514f5e3Sopenharmony_ciclass CompilerLog; 464514f5e3Sopenharmony_ci 474514f5e3Sopenharmony_ciusing namespace panda::ecmascript; 484514f5e3Sopenharmony_ci 494514f5e3Sopenharmony_ciLiteCGAssembler::LiteCGAssembler(LMIRModule &module, CodeInfo::CodeSpaceOnDemand &codeSpaceOnDemand, 504514f5e3Sopenharmony_ci const std::vector<std::string> &litecgOptions) 514514f5e3Sopenharmony_ci : Assembler(codeSpaceOnDemand), lmirModule(module), litecgOptions(litecgOptions) {} 524514f5e3Sopenharmony_ci 534514f5e3Sopenharmony_cistatic uint8_t *AllocateCodeSection(void *object, uint32_t size, [[maybe_unused]] uint32_t alignment, 544514f5e3Sopenharmony_ci const std::string §ionName) 554514f5e3Sopenharmony_ci{ 564514f5e3Sopenharmony_ci struct CodeInfo &state = *static_cast<struct CodeInfo *>(object); 574514f5e3Sopenharmony_ci return state.AllocaCodeSection(size, sectionName.c_str()); 584514f5e3Sopenharmony_ci} 594514f5e3Sopenharmony_ci 604514f5e3Sopenharmony_cistatic uint8_t *AllocateCodeSectionOnDemand(void *object, uint32_t size, [[maybe_unused]] uint32_t alignment, 614514f5e3Sopenharmony_ci const std::string §ionName) 624514f5e3Sopenharmony_ci{ 634514f5e3Sopenharmony_ci struct CodeInfo &state = *static_cast<struct CodeInfo *>(object); 644514f5e3Sopenharmony_ci return state.AllocaCodeSectionOnDemand(size, sectionName.c_str()); 654514f5e3Sopenharmony_ci} 664514f5e3Sopenharmony_ci 674514f5e3Sopenharmony_cistatic void SaveFunc2Addr(void *object, std::string funcName, uint32_t address) 684514f5e3Sopenharmony_ci{ 694514f5e3Sopenharmony_ci struct CodeInfo &state = *static_cast<struct CodeInfo *>(object); 704514f5e3Sopenharmony_ci state.SaveFunc2Addr(funcName, address); 714514f5e3Sopenharmony_ci} 724514f5e3Sopenharmony_ci 734514f5e3Sopenharmony_cistatic void SaveFunc2FPtoPrevSPDelta(void *object, std::string funcName, int32_t fp2PrevSpDelta) 744514f5e3Sopenharmony_ci{ 754514f5e3Sopenharmony_ci struct CodeInfo &state = *static_cast<struct CodeInfo *>(object); 764514f5e3Sopenharmony_ci state.SaveFunc2FPtoPrevSPDelta(funcName, fp2PrevSpDelta); 774514f5e3Sopenharmony_ci} 784514f5e3Sopenharmony_ci 794514f5e3Sopenharmony_cistatic void SaveFunc2CalleeOffsetInfo(void *object, std::string funcName, kungfu::CalleeRegAndOffsetVec calleeRegInfo) 804514f5e3Sopenharmony_ci{ 814514f5e3Sopenharmony_ci struct CodeInfo &state = *static_cast<struct CodeInfo *>(object); 824514f5e3Sopenharmony_ci state.SaveFunc2CalleeOffsetInfo(funcName, calleeRegInfo); 834514f5e3Sopenharmony_ci} 844514f5e3Sopenharmony_ci 854514f5e3Sopenharmony_cistatic void SavePC2DeoptInfo(void *object, uint64_t pc, std::vector<uint8_t> deoptInfo) 864514f5e3Sopenharmony_ci{ 874514f5e3Sopenharmony_ci struct CodeInfo &state = *static_cast<struct CodeInfo *>(object); 884514f5e3Sopenharmony_ci state.SavePC2DeoptInfo(pc, deoptInfo); 894514f5e3Sopenharmony_ci} 904514f5e3Sopenharmony_ci 914514f5e3Sopenharmony_civoid SavePC2CallSiteInfo(void *object, uint64_t pc, std::vector<uint8_t> callSiteInfo) 924514f5e3Sopenharmony_ci{ 934514f5e3Sopenharmony_ci struct CodeInfo &state = *static_cast<struct CodeInfo *>(object); 944514f5e3Sopenharmony_ci state.SavePC2CallSiteInfo(pc, callSiteInfo); 954514f5e3Sopenharmony_ci} 964514f5e3Sopenharmony_ci 974514f5e3Sopenharmony_civoid LiteCGAssembler::Run(const CompilerLog &log, [[maybe_unused]] bool fastCompileMode, bool isJit) 984514f5e3Sopenharmony_ci{ 994514f5e3Sopenharmony_ci std::vector<std::string> options(litecgOptions); 1004514f5e3Sopenharmony_ci if (log.OutputASM()) { 1014514f5e3Sopenharmony_ci options.push_back("--verbose-asm"); 1024514f5e3Sopenharmony_ci } 1034514f5e3Sopenharmony_ci if (log.OutputLLIR()) { 1044514f5e3Sopenharmony_ci options.push_back("-verbose"); 1054514f5e3Sopenharmony_ci } 1064514f5e3Sopenharmony_ci maple::litecg::LiteCG liteCG(*lmirModule.GetModule(), options); 1074514f5e3Sopenharmony_ci#ifdef ARK_LITECG_DEBUG 1084514f5e3Sopenharmony_ci if (log.OutputLLIR()) { 1094514f5e3Sopenharmony_ci std::string irFileName = lmirModule.GetModule()->GetFileName() + ".mpl"; 1104514f5e3Sopenharmony_ci liteCG.DumpIRToFile(irFileName); 1114514f5e3Sopenharmony_ci } 1124514f5e3Sopenharmony_ci#endif 1134514f5e3Sopenharmony_ci liteCG.SetupLiteCGEmitMemoryManager(&codeInfo_, isJit ? AllocateCodeSectionOnDemand : AllocateCodeSection, 1144514f5e3Sopenharmony_ci SaveFunc2Addr, SaveFunc2FPtoPrevSPDelta, SaveFunc2CalleeOffsetInfo, 1154514f5e3Sopenharmony_ci SavePC2DeoptInfo, SavePC2CallSiteInfo); 1164514f5e3Sopenharmony_ci#ifdef JIT_ENABLE_CODE_SIGN 1174514f5e3Sopenharmony_ci isJit &= JitFort::IsResourceAvailable(); 1184514f5e3Sopenharmony_ci if (isJit) { 1194514f5e3Sopenharmony_ci JitCodeSignerBase *jitSigner = CreateJitCodeSigner(JitBufferIntegrityLevel::Level0); 1204514f5e3Sopenharmony_ci JitSignCode *singleton = JitSignCode::GetInstance(); 1214514f5e3Sopenharmony_ci singleton->Reset(); 1224514f5e3Sopenharmony_ci singleton->SetCodeSigner(jitSigner); 1234514f5e3Sopenharmony_ci singleton->SetKind(1); 1244514f5e3Sopenharmony_ci } 1254514f5e3Sopenharmony_ci#endif 1264514f5e3Sopenharmony_ci liteCG.DoCG(isJit); 1274514f5e3Sopenharmony_ci} 1284514f5e3Sopenharmony_ci 1294514f5e3Sopenharmony_civoid LiteCGIRGeneratorImpl::GenerateCodeForStub(Circuit *circuit, const ControlFlowGraph &graph, size_t index, 1304514f5e3Sopenharmony_ci const CompilationConfig *cfg) 1314514f5e3Sopenharmony_ci{ 1324514f5e3Sopenharmony_ci (void)circuit; 1334514f5e3Sopenharmony_ci (void)graph; 1344514f5e3Sopenharmony_ci (void)index; 1354514f5e3Sopenharmony_ci (void)cfg; 1364514f5e3Sopenharmony_ci} 1374514f5e3Sopenharmony_ci 1384514f5e3Sopenharmony_civoid LiteCGIRGeneratorImpl::GenerateCode(Circuit *circuit, const ControlFlowGraph &graph, const CompilationConfig *cfg, 1394514f5e3Sopenharmony_ci const panda::ecmascript::MethodLiteral *methodLiteral, 1404514f5e3Sopenharmony_ci const JSPandaFile *jsPandaFile, const std::string &methodName, 1414514f5e3Sopenharmony_ci const FrameType frameType, 1424514f5e3Sopenharmony_ci bool enableOptInlining, [[maybe_unused]]bool enableBranchProfiling) 1434514f5e3Sopenharmony_ci{ 1444514f5e3Sopenharmony_ci circuit->SetFrameType(frameType); 1454514f5e3Sopenharmony_ci CallSignature::CallConv conv; 1464514f5e3Sopenharmony_ci if (methodLiteral->IsFastCall()) { 1474514f5e3Sopenharmony_ci conv = CallSignature::CallConv::CCallConv; 1484514f5e3Sopenharmony_ci } else { 1494514f5e3Sopenharmony_ci conv = CallSignature::CallConv::WebKitJSCallConv; 1504514f5e3Sopenharmony_ci } 1514514f5e3Sopenharmony_ci LiteCGIRBuilder builder(&graph, circuit, module_, cfg, conv, enableLog_, enableOptInlining, methodLiteral, 1524514f5e3Sopenharmony_ci jsPandaFile, methodName); 1534514f5e3Sopenharmony_ci builder.Build(); 1544514f5e3Sopenharmony_ci} 1554514f5e3Sopenharmony_ci 1564514f5e3Sopenharmony_civoid LiteCGAssembler::CollectAnStackMap(CGStackMapInfo &stackMapInfo) 1574514f5e3Sopenharmony_ci{ 1584514f5e3Sopenharmony_ci auto &liteCGStackMapInfo = static_cast<LiteCGStackMapInfo&>(stackMapInfo); 1594514f5e3Sopenharmony_ci const auto &codeInfo = GetCodeInfo(); 1604514f5e3Sopenharmony_ci liteCGStackMapInfo.AppendCallSiteInfo(codeInfo.GetPC2CallsiteInfo()); 1614514f5e3Sopenharmony_ci liteCGStackMapInfo.AppendDeoptInfo(codeInfo.GetPC2DeoptInfo()); 1624514f5e3Sopenharmony_ci} 1634514f5e3Sopenharmony_ci} // namespace panda::ecmascript::kungfu 164