• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 
16 #include "ecmascript/compiler/codegen/maple/litecg_codegen.h"
17 #if defined(PANDA_TARGET_MACOS) || defined(PANDA_TARGET_IOS)
18 #include "ecmascript/base/llvm_helper.h"
19 #endif
20 
21 #include <cstring>
22 #include <iomanip>
23 #include <vector>
24 
25 #include "ecmascript/compiler/call_signature.h"
26 #include "ecmascript/compiler/codegen/maple/litecg_ir_builder.h"
27 #include "ecmascript/compiler/codegen/maple/maple_be/include/litecg/litecg.h"
28 #include "ecmascript/compiler/codegen/maple/maple_be/include/litecg/lmir_builder.h"
29 #include "ecmascript/compiler/compiler_log.h"
30 #include "ecmascript/compiler/debug_info.h"
31 #include "ecmascript/ecma_macros.h"
32 #include "ecmascript/mem/region.h"
33 #include "ecmascript/object_factory.h"
34 #include "ecmascript/stackmap/litecg/litecg_stackmap_type.h"
35 #include "ecmascript/stackmap/llvm/llvm_stackmap_parser.h"
36 #ifdef JIT_ENABLE_CODE_SIGN
37 #include "jit_buffer_integrity.h"
38 #include "ecmascript/compiler/jit_signcode.h"
39 #endif
40 
41 namespace panda::ecmascript::kungfu {
42 #ifdef JIT_ENABLE_CODE_SIGN
43 using namespace panda::ecmascript::kungfu;
44 using namespace OHOS::Security::CodeSign;
45 #endif
46 class CompilerLog;
47 
48 using namespace panda::ecmascript;
49 
LiteCGAssembler(LMIRModule & module,CodeInfo::CodeSpaceOnDemand & codeSpaceOnDemand,const std::vector<std::string> & litecgOptions)50 LiteCGAssembler::LiteCGAssembler(LMIRModule &module, CodeInfo::CodeSpaceOnDemand &codeSpaceOnDemand,
51                                  const std::vector<std::string> &litecgOptions)
52     : Assembler(codeSpaceOnDemand), lmirModule(module), litecgOptions(litecgOptions) {}
53 
AllocateCodeSection(void * object,uint32_t size,uint32_t alignment,const std::string & sectionName)54 static uint8_t *AllocateCodeSection(void *object, uint32_t size, [[maybe_unused]] uint32_t alignment,
55                                     const std::string &sectionName)
56 {
57     struct CodeInfo &state = *static_cast<struct CodeInfo *>(object);
58     return state.AllocaCodeSection(size, sectionName.c_str());
59 }
60 
AllocateCodeSectionOnDemand(void * object,uint32_t size,uint32_t alignment,const std::string & sectionName)61 static uint8_t *AllocateCodeSectionOnDemand(void *object, uint32_t size, [[maybe_unused]] uint32_t alignment,
62                                             const std::string &sectionName)
63 {
64     struct CodeInfo &state = *static_cast<struct CodeInfo *>(object);
65     return state.AllocaCodeSectionOnDemand(size, sectionName.c_str());
66 }
67 
SaveFunc2Addr(void * object,std::string funcName,uint32_t address)68 static void SaveFunc2Addr(void *object, std::string funcName, uint32_t address)
69 {
70     struct CodeInfo &state = *static_cast<struct CodeInfo *>(object);
71     state.SaveFunc2Addr(funcName, address);
72 }
73 
SaveFunc2FPtoPrevSPDelta(void * object,std::string funcName,int32_t fp2PrevSpDelta)74 static void SaveFunc2FPtoPrevSPDelta(void *object, std::string funcName, int32_t fp2PrevSpDelta)
75 {
76     struct CodeInfo &state = *static_cast<struct CodeInfo *>(object);
77     state.SaveFunc2FPtoPrevSPDelta(funcName, fp2PrevSpDelta);
78 }
79 
SaveFunc2CalleeOffsetInfo(void * object,std::string funcName,kungfu::CalleeRegAndOffsetVec calleeRegInfo)80 static void SaveFunc2CalleeOffsetInfo(void *object, std::string funcName, kungfu::CalleeRegAndOffsetVec calleeRegInfo)
81 {
82     struct CodeInfo &state = *static_cast<struct CodeInfo *>(object);
83     state.SaveFunc2CalleeOffsetInfo(funcName, calleeRegInfo);
84 }
85 
SavePC2DeoptInfo(void * object,uint64_t pc,std::vector<uint8_t> deoptInfo)86 static void SavePC2DeoptInfo(void *object, uint64_t pc, std::vector<uint8_t> deoptInfo)
87 {
88     struct CodeInfo &state = *static_cast<struct CodeInfo *>(object);
89     state.SavePC2DeoptInfo(pc, deoptInfo);
90 }
91 
SavePC2CallSiteInfo(void * object,uint64_t pc,std::vector<uint8_t> callSiteInfo)92 void SavePC2CallSiteInfo(void *object, uint64_t pc, std::vector<uint8_t> callSiteInfo)
93 {
94     struct CodeInfo &state = *static_cast<struct CodeInfo *>(object);
95     state.SavePC2CallSiteInfo(pc, callSiteInfo);
96 }
97 
Run(const CompilerLog & log,bool fastCompileMode,bool isJit)98 void LiteCGAssembler::Run(const CompilerLog &log, [[maybe_unused]] bool fastCompileMode, bool isJit)
99 {
100     std::vector<std::string> options(litecgOptions);
101     if (log.OutputASM()) {
102         options.push_back("--verbose-asm");
103     }
104     if (log.OutputLLIR()) {
105         options.push_back("-verbose");
106     }
107     maple::litecg::LiteCG liteCG(*lmirModule.GetModule(), options);
108     if (log.OutputLLIR()) {
109         std::string irFileName = lmirModule.GetModule()->GetFileName() + ".mpl";
110         liteCG.DumpIRToFile(irFileName);
111     }
112     liteCG.SetupLiteCGEmitMemoryManager(&codeInfo_, isJit ? AllocateCodeSectionOnDemand : AllocateCodeSection,
113                                         SaveFunc2Addr, SaveFunc2FPtoPrevSPDelta, SaveFunc2CalleeOffsetInfo,
114                                         SavePC2DeoptInfo, SavePC2CallSiteInfo);
115 #ifdef JIT_ENABLE_CODE_SIGN
116     isJit &= JitFort::IsResourceAvailable();
117     if (isJit) {
118         JitCodeSignerBase *jitSigner = CreateJitCodeSigner(JitBufferIntegrityLevel::Level0);
119         JitSignCode *singleton = JitSignCode::GetInstance();
120         singleton->Reset();
121         singleton->SetCodeSigner(jitSigner);
122         singleton->SetKind(1);
123     }
124 #endif
125     liteCG.DoCG(isJit);
126 }
127 
GenerateCodeForStub(Circuit * circuit,const ControlFlowGraph & graph,size_t index,const CompilationConfig * cfg)128 void LiteCGIRGeneratorImpl::GenerateCodeForStub(Circuit *circuit, const ControlFlowGraph &graph, size_t index,
129                                                 const CompilationConfig *cfg)
130 {
131     (void)circuit;
132     (void)graph;
133     (void)index;
134     (void)cfg;
135 }
136 
GenerateCode(Circuit * circuit,const ControlFlowGraph & graph,const CompilationConfig * cfg,const panda::ecmascript::MethodLiteral * methodLiteral,const JSPandaFile * jsPandaFile,const std::string & methodName,const FrameType frameType,bool enableOptInlining,bool enableBranchProfiling)137 void LiteCGIRGeneratorImpl::GenerateCode(Circuit *circuit, const ControlFlowGraph &graph, const CompilationConfig *cfg,
138                                          const panda::ecmascript::MethodLiteral *methodLiteral,
139                                          const JSPandaFile *jsPandaFile, const std::string &methodName,
140                                          const FrameType frameType,
141                                          bool enableOptInlining, [[maybe_unused]]bool enableBranchProfiling)
142 {
143     circuit->SetFrameType(frameType);
144     CallSignature::CallConv conv;
145     if (methodLiteral->IsFastCall()) {
146         conv = CallSignature::CallConv::CCallConv;
147     } else {
148         conv = CallSignature::CallConv::WebKitJSCallConv;
149     }
150     LiteCGIRBuilder builder(&graph, circuit, module_, cfg, conv, enableLog_, enableOptInlining, methodLiteral,
151                             jsPandaFile, methodName);
152     builder.Build();
153 }
154 
CollectAnStackMap(CGStackMapInfo & stackMapInfo)155 void LiteCGAssembler::CollectAnStackMap(CGStackMapInfo &stackMapInfo)
156 {
157     auto &liteCGStackMapInfo = static_cast<LiteCGStackMapInfo&>(stackMapInfo);
158     const auto &codeInfo = GetCodeInfo();
159     liteCGStackMapInfo.AppendCallSiteInfo(codeInfo.GetPC2CallsiteInfo());
160     liteCGStackMapInfo.AppendDeoptInfo(codeInfo.GetPC2DeoptInfo());
161 }
162 }  // namespace panda::ecmascript::kungfu
163