c5a754cd创建于 2025年7月15日历史提交
/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "ecmascript/compiler/codegen/maple/litecg_codegen.h"
#if defined(PANDA_TARGET_MACOS) || defined(PANDA_TARGET_IOS)
#include "ecmascript/base/llvm_helper.h"
#endif


#include "ecmascript/compiler/codegen/maple/maple_be/include/litecg/litecg.h"
#include "ecmascript/compiler/compiler_log.h"
#include "ecmascript/stackmap/litecg/litecg_stackmap_type.h"
#ifdef JIT_ENABLE_CODE_SIGN
#include "jit_buffer_integrity.h"
#include "ecmascript/compiler/jit_signcode.h"
#endif

namespace panda::ecmascript::kungfu {
#ifdef JIT_ENABLE_CODE_SIGN
using namespace panda::ecmascript::kungfu;
using namespace OHOS::Security::CodeSign;
#endif
class CompilerLog;

using namespace panda::ecmascript;

LiteCGAssembler::LiteCGAssembler(LMIRModule &module, CodeInfo::CodeSpaceOnDemand &codeSpaceOnDemand,
                                 const std::vector<std::string> &litecgOptions)
    : Assembler(codeSpaceOnDemand, false), lmirModule(module), litecgOptions(litecgOptions) {}

static uint8_t *AllocateCodeSection(void *object, uint32_t size, [[maybe_unused]] uint32_t alignment,
                                    const std::string &sectionName)
{
    struct CodeInfo &state = *static_cast<struct CodeInfo *>(object);
    return state.AllocaCodeSection(size, sectionName.c_str());
}

static uint8_t *AllocateCodeSectionOnDemand(void *object, uint32_t size, [[maybe_unused]] uint32_t alignment,
                                            const std::string &sectionName)
{
    struct CodeInfo &state = *static_cast<struct CodeInfo *>(object);
    return state.AllocaCodeSectionOnDemand(size, sectionName.c_str());
}

static void SaveFunc2Addr(void *object, std::string funcName, uint32_t address)
{
    struct CodeInfo &state = *static_cast<struct CodeInfo *>(object);
    state.SaveFunc2Addr(funcName, address);
}

static void SaveFunc2FPtoPrevSPDelta(void *object, std::string funcName, int32_t fp2PrevSpDelta)
{
    struct CodeInfo &state = *static_cast<struct CodeInfo *>(object);
    state.SaveFunc2FPtoPrevSPDelta(funcName, fp2PrevSpDelta);
}

static void SaveFunc2CalleeOffsetInfo(void *object, std::string funcName, kungfu::CalleeRegAndOffsetVec calleeRegInfo)
{
    struct CodeInfo &state = *static_cast<struct CodeInfo *>(object);
    state.SaveFunc2CalleeOffsetInfo(funcName, calleeRegInfo);
}

static void SavePC2DeoptInfo(void *object, uint64_t pc, std::vector<uint8_t> deoptInfo)
{
    struct CodeInfo &state = *static_cast<struct CodeInfo *>(object);
    state.SavePC2DeoptInfo(pc, deoptInfo);
}

void SavePC2CallSiteInfo(void *object, uint64_t pc, std::vector<uint8_t> callSiteInfo)
{
    struct CodeInfo &state = *static_cast<struct CodeInfo *>(object);
    state.SavePC2CallSiteInfo(pc, callSiteInfo);
}

void LiteCGAssembler::Run(const CompilerLog &log, [[maybe_unused]] bool fastCompileMode, bool isJit)
{
    std::vector<std::string> options(litecgOptions);
    if (log.OutputASM()) {
        options.push_back("--verbose-asm");
    }
    if (log.OutputLLIR()) {
        options.push_back("-verbose");
    }
    maple::litecg::LiteCG liteCG(*lmirModule.GetModule(), options);
#ifdef ARK_LITECG_DEBUG
    if (log.OutputLLIR()) {
        std::string irFileName = lmirModule.GetModule()->GetFileName() + ".mpl";
        liteCG.DumpIRToFile(irFileName);
    }
#endif
    liteCG.SetupLiteCGEmitMemoryManager(&codeInfo_, isJit ? AllocateCodeSectionOnDemand : AllocateCodeSection,
                                        SaveFunc2Addr, SaveFunc2FPtoPrevSPDelta, SaveFunc2CalleeOffsetInfo,
                                        SavePC2DeoptInfo, SavePC2CallSiteInfo);
    liteCG.SetAotCodeCommentFile(GetAotCodeCommentFile());
#ifdef JIT_ENABLE_CODE_SIGN
    isJit &= JitFort::IsResourceAvailable();
    if (isJit) {
        JitCodeSigner *jitSigner = CreateJitCodeSigner();
        JitSignCode *singleton = JitSignCode::GetInstance();
        singleton->Reset();
        singleton->SetCodeSigner(jitSigner);
        singleton->SetKind(1);
    }
#endif
    liteCG.DoCG(isJit);
}

void LiteCGIRGeneratorImpl::GenerateCodeForStub(Circuit *circuit, const ControlFlowGraph &graph, size_t index,
                                                const CompilationConfig *cfg)
{
    (void)circuit;
    (void)graph;
    (void)index;
    (void)cfg;
}

void LiteCGIRGeneratorImpl::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, [[maybe_unused]]bool enableBranchProfiling)
{
    circuit->SetFrameType(frameType);
    CallSignature::CallConv conv;
    if (methodLiteral->IsFastCall()) {
        conv = CallSignature::CallConv::CCallConv;
    } else {
        conv = CallSignature::CallConv::WebKitJSCallConv;
    }
    LiteCGIRBuilder builder(&graph, circuit, module_, cfg, conv, enableLog_, enableOptInlining, methodLiteral,
                            jsPandaFile, methodName);
    builder.Build();
}

void LiteCGAssembler::CollectAnStackMap(CGStackMapInfo &stackMapInfo)
{
    auto &liteCGStackMapInfo = static_cast<LiteCGStackMapInfo&>(stackMapInfo);
    const auto &codeInfo = GetCodeInfo();
    liteCGStackMapInfo.AppendCallSiteInfo(codeInfo.GetPC2CallsiteInfo());
    liteCGStackMapInfo.AppendDeoptInfo(codeInfo.GetPC2DeoptInfo());
}
}  // namespace panda::ecmascript::kungfu