14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2022-2024 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/bytecode_info_collector.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/literal_data_extractor.h"
194514f5e3Sopenharmony_ci#include "ecmascript/module/module_path_helper.h"
204514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_profiler_decoder.h"
214514f5e3Sopenharmony_ci#include "libpandafile/code_data_accessor.h"
224514f5e3Sopenharmony_ci#include "libpandafile/class_data_accessor-inl.h"
234514f5e3Sopenharmony_ci#include "libpandafile/index_accessor.h"
244514f5e3Sopenharmony_ci#include "libpandafile/method_data_accessor-inl.h"
254514f5e3Sopenharmony_ci
264514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu {
274514f5e3Sopenharmony_citemplate<class T, class... Args>
284514f5e3Sopenharmony_cistatic T *InitializeMemory(T *mem, Args... args)
294514f5e3Sopenharmony_ci{
304514f5e3Sopenharmony_ci    return new (mem) T(std::forward<Args>(args)...);
314514f5e3Sopenharmony_ci}
324514f5e3Sopenharmony_ci
334514f5e3Sopenharmony_ciBytecodeInfoCollector::BytecodeInfoCollector(CompilationEnv *env, JSPandaFile *jsPandaFile,
344514f5e3Sopenharmony_ci                                             PGOProfilerDecoder &pfDecoder,
354514f5e3Sopenharmony_ci                                             size_t maxAotMethodSize)
364514f5e3Sopenharmony_ci    : compilationEnv_(env),
374514f5e3Sopenharmony_ci      jsPandaFile_(jsPandaFile),
384514f5e3Sopenharmony_ci      bytecodeInfo_(maxAotMethodSize),
394514f5e3Sopenharmony_ci      pfDecoder_(pfDecoder),
404514f5e3Sopenharmony_ci      snapshotCPData_(new SnapshotConstantPoolData(env->GetEcmaVM(), jsPandaFile, &pfDecoder))
414514f5e3Sopenharmony_ci{
424514f5e3Sopenharmony_ci    ASSERT(env->IsAotCompiler());
434514f5e3Sopenharmony_ci    ProcessClasses();
444514f5e3Sopenharmony_ci}
454514f5e3Sopenharmony_ci
464514f5e3Sopenharmony_ciBytecodeInfoCollector::BytecodeInfoCollector(CompilationEnv *env, JSPandaFile *jsPandaFile,
474514f5e3Sopenharmony_ci                                             PGOProfilerDecoder &pfDecoder)
484514f5e3Sopenharmony_ci    : compilationEnv_(env),
494514f5e3Sopenharmony_ci      jsPandaFile_(jsPandaFile),
504514f5e3Sopenharmony_ci      // refactor: jit max method size
514514f5e3Sopenharmony_ci      bytecodeInfo_(env->GetJSOptions().GetMaxAotMethodSize()),
524514f5e3Sopenharmony_ci      pfDecoder_(pfDecoder),
534514f5e3Sopenharmony_ci      snapshotCPData_(nullptr) // jit no need
544514f5e3Sopenharmony_ci{
554514f5e3Sopenharmony_ci    ASSERT(env->IsJitCompiler());
564514f5e3Sopenharmony_ci    ProcessCurrMethod();
574514f5e3Sopenharmony_ci}
584514f5e3Sopenharmony_ci
594514f5e3Sopenharmony_civoid BytecodeInfoCollector::ProcessClasses()
604514f5e3Sopenharmony_ci{
614514f5e3Sopenharmony_ci    ASSERT(jsPandaFile_ != nullptr && jsPandaFile_->GetMethodLiterals() != nullptr);
624514f5e3Sopenharmony_ci    MethodLiteral *methods = jsPandaFile_->GetMethodLiterals();
634514f5e3Sopenharmony_ci    const panda_file::File *pf = jsPandaFile_->GetPandaFile();
644514f5e3Sopenharmony_ci    size_t methodIdx = 0;
654514f5e3Sopenharmony_ci    std::map<uint32_t, std::pair<size_t, uint32_t>> processedMethod;
664514f5e3Sopenharmony_ci    Span<const uint32_t> classIndexes = jsPandaFile_->GetClasses();
674514f5e3Sopenharmony_ci
684514f5e3Sopenharmony_ci    auto &recordNamePtrs = bytecodeInfo_.GetRecordNamePtrs();
694514f5e3Sopenharmony_ci    auto &methodPcInfos = bytecodeInfo_.GetMethodPcInfos();
704514f5e3Sopenharmony_ci    for (const uint32_t index : classIndexes) {
714514f5e3Sopenharmony_ci        panda_file::File::EntityId classId(index);
724514f5e3Sopenharmony_ci        if (jsPandaFile_->IsExternal(classId)) {
734514f5e3Sopenharmony_ci            continue;
744514f5e3Sopenharmony_ci        }
754514f5e3Sopenharmony_ci        panda_file::ClassDataAccessor cda(*pf, classId);
764514f5e3Sopenharmony_ci        CString desc = utf::Mutf8AsCString(cda.GetDescriptor());
774514f5e3Sopenharmony_ci        const std::shared_ptr<CString> recordNamePtr = std::make_shared<CString>(JSPandaFile::ParseEntryPoint(desc));
784514f5e3Sopenharmony_ci        cda.EnumerateMethods([this, methods, &methodIdx, pf, &processedMethod,
794514f5e3Sopenharmony_ci            &recordNamePtrs, &methodPcInfos, &recordNamePtr] (panda_file::MethodDataAccessor &mda) {
804514f5e3Sopenharmony_ci            auto methodId = mda.GetMethodId();
814514f5e3Sopenharmony_ci
824514f5e3Sopenharmony_ci            // Generate all constpool
834514f5e3Sopenharmony_ci            compilationEnv_->FindOrCreateConstPool(jsPandaFile_, methodId);
844514f5e3Sopenharmony_ci
854514f5e3Sopenharmony_ci            auto methodOffset = methodId.GetOffset();
864514f5e3Sopenharmony_ci            CString name = reinterpret_cast<const char *>(jsPandaFile_->GetStringData(mda.GetNameId()).data);
874514f5e3Sopenharmony_ci            if (JSPandaFile::IsEntryOrPatch(name)) {
884514f5e3Sopenharmony_ci                jsPandaFile_->UpdateMainMethodIndex(methodOffset, *recordNamePtr);
894514f5e3Sopenharmony_ci                recordNamePtrs.emplace_back(recordNamePtr);
904514f5e3Sopenharmony_ci            }
914514f5e3Sopenharmony_ci
924514f5e3Sopenharmony_ci            MethodLiteral *methodLiteral = methods + (methodIdx++);
934514f5e3Sopenharmony_ci            InitializeMemory(methodLiteral, methodId);
944514f5e3Sopenharmony_ci            methodLiteral->Initialize(jsPandaFile_);
954514f5e3Sopenharmony_ci
964514f5e3Sopenharmony_ci            ASSERT(jsPandaFile_->IsNewVersion());
974514f5e3Sopenharmony_ci            panda_file::IndexAccessor indexAccessor(*pf, methodId);
984514f5e3Sopenharmony_ci            panda_file::FunctionKind funcKind = indexAccessor.GetFunctionKind();
994514f5e3Sopenharmony_ci            bool isShared = JSPandaFile::IsSendableFunctionKind(funcKind);
1004514f5e3Sopenharmony_ci            methodLiteral->SetIsShared(isShared);
1014514f5e3Sopenharmony_ci            FunctionKind kind = JSPandaFile::GetFunctionKind(funcKind);
1024514f5e3Sopenharmony_ci            methodLiteral->SetFunctionKind(kind);
1034514f5e3Sopenharmony_ci
1044514f5e3Sopenharmony_ci            auto codeId = mda.GetCodeId();
1054514f5e3Sopenharmony_ci            ASSERT(codeId.has_value());
1064514f5e3Sopenharmony_ci            panda_file::CodeDataAccessor codeDataAccessor(*pf, codeId.value());
1074514f5e3Sopenharmony_ci            uint32_t codeSize = codeDataAccessor.GetCodeSize();
1084514f5e3Sopenharmony_ci            const uint8_t *insns = codeDataAccessor.GetInstructions();
1094514f5e3Sopenharmony_ci            auto it = processedMethod.find(methodOffset);
1104514f5e3Sopenharmony_ci            if (it == processedMethod.end()) {
1114514f5e3Sopenharmony_ci                CollectMethodPcsFromBC(codeSize, insns, methodLiteral,
1124514f5e3Sopenharmony_ci                    methodOffset, recordNamePtr);
1134514f5e3Sopenharmony_ci                ASSERT(methodPcInfos.size() > 0);
1144514f5e3Sopenharmony_ci                processedMethod[methodOffset] = std::make_pair(methodPcInfos.size() - 1, methodOffset);
1154514f5e3Sopenharmony_ci            }
1164514f5e3Sopenharmony_ci
1174514f5e3Sopenharmony_ci            SetMethodPcInfoIndex(methodOffset, processedMethod[methodOffset], recordNamePtr);
1184514f5e3Sopenharmony_ci            jsPandaFile_->SetMethodLiteralToMap(methodLiteral);
1194514f5e3Sopenharmony_ci            pfDecoder_.MatchAndMarkMethod(jsPandaFile_, *recordNamePtr, name.c_str(), methodId);
1204514f5e3Sopenharmony_ci        });
1214514f5e3Sopenharmony_ci    }
1224514f5e3Sopenharmony_ci    LOG_COMPILER(INFO) << "Total number of methods in file: " << jsPandaFile_->GetJSPandaFileDesc()
1234514f5e3Sopenharmony_ci                       << " is: " << methodIdx;
1244514f5e3Sopenharmony_ci}
1254514f5e3Sopenharmony_ci
1264514f5e3Sopenharmony_civoid BytecodeInfoCollector::ProcessCurrMethod()
1274514f5e3Sopenharmony_ci{
1284514f5e3Sopenharmony_ci    ProcessMethod(compilationEnv_->GetMethodLiteral());
1294514f5e3Sopenharmony_ci}
1304514f5e3Sopenharmony_ci
1314514f5e3Sopenharmony_civoid BytecodeInfoCollector::ProcessMethod(MethodLiteral *methodLiteral)
1324514f5e3Sopenharmony_ci{
1334514f5e3Sopenharmony_ci    if (UNLIKELY(methodLiteral == nullptr)) {
1344514f5e3Sopenharmony_ci        return;
1354514f5e3Sopenharmony_ci    }
1364514f5e3Sopenharmony_ci    panda_file::File::EntityId methodIdx = methodLiteral->GetMethodId();
1374514f5e3Sopenharmony_ci    auto methodOffset = methodIdx.GetOffset();
1384514f5e3Sopenharmony_ci    if (processedMethod_.find(methodOffset) != processedMethod_.end()) {
1394514f5e3Sopenharmony_ci        return;
1404514f5e3Sopenharmony_ci    }
1414514f5e3Sopenharmony_ci
1424514f5e3Sopenharmony_ci    auto &recordNamePtrs = bytecodeInfo_.GetRecordNamePtrs();
1434514f5e3Sopenharmony_ci    auto &methodPcInfos = bytecodeInfo_.GetMethodPcInfos();
1444514f5e3Sopenharmony_ci    const std::shared_ptr<CString> recordNamePtr =
1454514f5e3Sopenharmony_ci        std::make_shared<CString>(jsPandaFile_->GetRecordNameWithBundlePack(methodIdx));
1464514f5e3Sopenharmony_ci    recordNamePtrs.emplace_back(recordNamePtr);
1474514f5e3Sopenharmony_ci    ASSERT(jsPandaFile_->IsNewVersion());
1484514f5e3Sopenharmony_ci
1494514f5e3Sopenharmony_ci    const panda_file::File *pf = jsPandaFile_->GetPandaFile();
1504514f5e3Sopenharmony_ci    panda_file::MethodDataAccessor mda(*pf, methodIdx);
1514514f5e3Sopenharmony_ci    auto codeId = mda.GetCodeId();
1524514f5e3Sopenharmony_ci    ASSERT(codeId.has_value());
1534514f5e3Sopenharmony_ci    panda_file::CodeDataAccessor codeDataAccessor(*pf, codeId.value());
1544514f5e3Sopenharmony_ci    uint32_t codeSize = codeDataAccessor.GetCodeSize();
1554514f5e3Sopenharmony_ci    const uint8_t *insns = codeDataAccessor.GetInstructions();
1564514f5e3Sopenharmony_ci
1574514f5e3Sopenharmony_ci    CollectMethodPcsFromBC(codeSize, insns, methodLiteral, methodOffset, recordNamePtr);
1584514f5e3Sopenharmony_ci    ASSERT(methodPcInfos.size() > 0);
1594514f5e3Sopenharmony_ci    SetMethodPcInfoIndex(methodOffset, {methodPcInfos.size() - 1, methodOffset}, recordNamePtr);
1604514f5e3Sopenharmony_ci    processedMethod_.emplace(methodOffset);
1614514f5e3Sopenharmony_ci}
1624514f5e3Sopenharmony_ci
1634514f5e3Sopenharmony_civoid BytecodeInfoCollector::CollectMethodPcsFromBC(const uint32_t insSz, const uint8_t *insArr,
1644514f5e3Sopenharmony_ci                                                   MethodLiteral *method, uint32_t methodOffset,
1654514f5e3Sopenharmony_ci                                                   const std::shared_ptr<CString> recordNamePtr)
1664514f5e3Sopenharmony_ci{
1674514f5e3Sopenharmony_ci    auto bcIns = BytecodeInst(insArr);
1684514f5e3Sopenharmony_ci    auto bcInsLast = bcIns.JumpTo(insSz);
1694514f5e3Sopenharmony_ci    int32_t bcIndex = 0;
1704514f5e3Sopenharmony_ci    auto &methodPcInfos = bytecodeInfo_.GetMethodPcInfos();
1714514f5e3Sopenharmony_ci    methodPcInfos.emplace_back(MethodPcInfo { {}, insSz });
1724514f5e3Sopenharmony_ci    auto &pcOffsets = methodPcInfos.back().pcOffsets;
1734514f5e3Sopenharmony_ci    const uint8_t *curPc = bcIns.GetAddress();
1744514f5e3Sopenharmony_ci    bool canFastCall = true;
1754514f5e3Sopenharmony_ci    bool noGC = true;
1764514f5e3Sopenharmony_ci    bool debuggerStmt = false;
1774514f5e3Sopenharmony_ci    uint32_t newtargetIndex = method->GetNewTargetVregIndex();
1784514f5e3Sopenharmony_ci    bool canTypedCall = true;
1794514f5e3Sopenharmony_ci
1804514f5e3Sopenharmony_ci    while (bcIns.GetAddress() != bcInsLast.GetAddress()) {
1814514f5e3Sopenharmony_ci        curPc = bcIns.GetAddress();
1824514f5e3Sopenharmony_ci        auto metaData = bytecodes_.GetBytecodeMetaData(curPc);
1834514f5e3Sopenharmony_ci        bool opcodeSupprotFastCall = true;
1844514f5e3Sopenharmony_ci        bool opcodeSupportTypeByteCall = true;
1854514f5e3Sopenharmony_ci        CollectMethodInfoFromBC(bcIns, method, bcIndex, recordNamePtr,
1864514f5e3Sopenharmony_ci                                &opcodeSupprotFastCall, &opcodeSupportTypeByteCall);
1874514f5e3Sopenharmony_ci        bool vregSupportFastCall = !IsVRegUsed(bcIns, metaData, newtargetIndex);
1884514f5e3Sopenharmony_ci        if (!opcodeSupprotFastCall || !vregSupportFastCall) {
1894514f5e3Sopenharmony_ci            canFastCall = false;
1904514f5e3Sopenharmony_ci        }
1914514f5e3Sopenharmony_ci        if (!opcodeSupportTypeByteCall) {
1924514f5e3Sopenharmony_ci            canTypedCall = false;
1934514f5e3Sopenharmony_ci        }
1944514f5e3Sopenharmony_ci        if (snapshotCPData_ != nullptr) {
1954514f5e3Sopenharmony_ci            snapshotCPData_->Record(bcIns, bcIndex, *recordNamePtr, method);
1964514f5e3Sopenharmony_ci        }
1974514f5e3Sopenharmony_ci        pgoBCInfo_.Record(bcIns, bcIndex, *recordNamePtr, method);
1984514f5e3Sopenharmony_ci        if (noGC && !metaData.IsNoGC()) {
1994514f5e3Sopenharmony_ci            noGC = false;
2004514f5e3Sopenharmony_ci        }
2014514f5e3Sopenharmony_ci        if (!debuggerStmt && metaData.HasDebuggerStmt()) {
2024514f5e3Sopenharmony_ci            debuggerStmt = true;
2034514f5e3Sopenharmony_ci        }
2044514f5e3Sopenharmony_ci        auto nextInst = bcIns.GetNext();
2054514f5e3Sopenharmony_ci        bcIns = nextInst;
2064514f5e3Sopenharmony_ci        pcOffsets.emplace_back(curPc);
2074514f5e3Sopenharmony_ci        bcIndex++;
2084514f5e3Sopenharmony_ci    }
2094514f5e3Sopenharmony_ci    bytecodeInfo_.SetMethodOffsetToFastCallInfo(methodOffset, canFastCall, noGC);
2104514f5e3Sopenharmony_ci    method->SetIsFastCall(canFastCall);
2114514f5e3Sopenharmony_ci    method->SetNoGCBit(noGC);
2124514f5e3Sopenharmony_ci    method->SetHasDebuggerStmtBit(debuggerStmt);
2134514f5e3Sopenharmony_ci    method->SetCanTypedCall(canTypedCall);
2144514f5e3Sopenharmony_ci}
2154514f5e3Sopenharmony_ci
2164514f5e3Sopenharmony_ci// static
2174514f5e3Sopenharmony_cibool BytecodeInfoCollector::IsVRegUsed(const BytecodeInstruction &inst, const BytecodeMetaData &metaData, uint32_t idx)
2184514f5e3Sopenharmony_ci{
2194514f5e3Sopenharmony_ci    if (idx == 0) {
2204514f5e3Sopenharmony_ci        return false;
2214514f5e3Sopenharmony_ci    }
2224514f5e3Sopenharmony_ci    uint32_t vregCount = metaData.GetVRegCount();
2234514f5e3Sopenharmony_ci    for (uint32_t i = 0; i < vregCount; i++) {
2244514f5e3Sopenharmony_ci        ASSERT(inst.HasVReg(inst.GetFormat(), i));
2254514f5e3Sopenharmony_ci        uint16_t vregIdx = inst.GetVReg(i);
2264514f5e3Sopenharmony_ci        if (vregIdx == idx) {
2274514f5e3Sopenharmony_ci            return true;
2284514f5e3Sopenharmony_ci        }
2294514f5e3Sopenharmony_ci    }
2304514f5e3Sopenharmony_ci    return false;
2314514f5e3Sopenharmony_ci}
2324514f5e3Sopenharmony_ci
2334514f5e3Sopenharmony_civoid BytecodeInfoCollector::SetMethodPcInfoIndex(uint32_t methodOffset,
2344514f5e3Sopenharmony_ci                                                 const std::pair<size_t, uint32_t> &processedMethodInfo,
2354514f5e3Sopenharmony_ci                                                 const std::shared_ptr<CString> recordNamePtr)
2364514f5e3Sopenharmony_ci{
2374514f5e3Sopenharmony_ci    auto processedMethodPcInfoIndex = processedMethodInfo.first;
2384514f5e3Sopenharmony_ci    auto &methodList = bytecodeInfo_.GetMethodList();
2394514f5e3Sopenharmony_ci
2404514f5e3Sopenharmony_ci    auto iter = methodList.find(methodOffset);
2414514f5e3Sopenharmony_ci    if (iter != methodList.end()) {
2424514f5e3Sopenharmony_ci        MethodInfo &methodInfo = iter->second;
2434514f5e3Sopenharmony_ci        methodInfo.SetMethodPcInfoIndex(processedMethodPcInfoIndex);
2444514f5e3Sopenharmony_ci        return;
2454514f5e3Sopenharmony_ci    }
2464514f5e3Sopenharmony_ci    MethodInfo info(GetNewMethodInfoID(), processedMethodPcInfoIndex, recordNamePtr);
2474514f5e3Sopenharmony_ci    methodList.emplace(methodOffset, info);
2484514f5e3Sopenharmony_ci}
2494514f5e3Sopenharmony_ci
2504514f5e3Sopenharmony_civoid BytecodeInfoCollector::CollectMethods(const MethodLiteral *method, const std::shared_ptr<CString> recordNamePtr)
2514514f5e3Sopenharmony_ci{
2524514f5e3Sopenharmony_ci    auto methodId = method->GetMethodId().GetOffset();
2534514f5e3Sopenharmony_ci    CollectMethods(methodId, recordNamePtr);
2544514f5e3Sopenharmony_ci}
2554514f5e3Sopenharmony_ci
2564514f5e3Sopenharmony_civoid BytecodeInfoCollector::CollectMethods(uint32_t methodId, const std::shared_ptr<CString> recordNamePtr)
2574514f5e3Sopenharmony_ci{
2584514f5e3Sopenharmony_ci    auto &methodList = bytecodeInfo_.GetMethodList();
2594514f5e3Sopenharmony_ci    if (methodList.find(methodId) == methodList.end()) {
2604514f5e3Sopenharmony_ci        methodList.emplace(methodId, MethodInfo(GetNewMethodInfoID(), 0, recordNamePtr));
2614514f5e3Sopenharmony_ci    }
2624514f5e3Sopenharmony_ci}
2634514f5e3Sopenharmony_ci
2644514f5e3Sopenharmony_civoid BytecodeInfoCollector::CollectInnerMethodsFromLiteral(uint64_t index, const std::shared_ptr<CString> recordNamePtr)
2654514f5e3Sopenharmony_ci{
2664514f5e3Sopenharmony_ci    std::vector<uint32_t> methodOffsets;
2674514f5e3Sopenharmony_ci    LiteralDataExtractor::GetMethodOffsets(jsPandaFile_, index, methodOffsets);
2684514f5e3Sopenharmony_ci    for (auto methodOffset : methodOffsets) {
2694514f5e3Sopenharmony_ci        CollectMethods(methodOffset, recordNamePtr);
2704514f5e3Sopenharmony_ci    }
2714514f5e3Sopenharmony_ci}
2724514f5e3Sopenharmony_ci
2734514f5e3Sopenharmony_civoid BytecodeInfoCollector::CollectInnerMethodsFromNewLiteral(panda_file::File::EntityId literalId,
2744514f5e3Sopenharmony_ci                                                              const std::shared_ptr<CString> recordNamePtr)
2754514f5e3Sopenharmony_ci{
2764514f5e3Sopenharmony_ci    std::vector<uint32_t> methodOffsets;
2774514f5e3Sopenharmony_ci    LiteralDataExtractor::GetMethodOffsets(jsPandaFile_, literalId, methodOffsets);
2784514f5e3Sopenharmony_ci    for (auto methodOffset : methodOffsets) {
2794514f5e3Sopenharmony_ci        CollectMethods(methodOffset, recordNamePtr);
2804514f5e3Sopenharmony_ci    }
2814514f5e3Sopenharmony_ci}
2824514f5e3Sopenharmony_ci
2834514f5e3Sopenharmony_civoid BytecodeInfoCollector::CollectMethodInfoFromBC(const BytecodeInstruction &bcIns, const MethodLiteral *method,
2844514f5e3Sopenharmony_ci                                                    int32_t bcIndex, const std::shared_ptr<CString> recordNamePtr,
2854514f5e3Sopenharmony_ci                                                    bool *canFastCall, bool *canTypedCall)
2864514f5e3Sopenharmony_ci{
2874514f5e3Sopenharmony_ci    if (!(bcIns.HasFlag(BytecodeInstruction::Flags::STRING_ID) &&
2884514f5e3Sopenharmony_ci        BytecodeInstruction::HasId(BytecodeInstruction::GetFormat(bcIns.GetOpcode()), 0))) {
2894514f5e3Sopenharmony_ci        CollectMethods(method, recordNamePtr);
2904514f5e3Sopenharmony_ci        BytecodeInstruction::Opcode opcode = static_cast<BytecodeInstruction::Opcode>(bcIns.GetOpcode());
2914514f5e3Sopenharmony_ci        switch (opcode) {
2924514f5e3Sopenharmony_ci            uint32_t innerMethodId;
2934514f5e3Sopenharmony_ci            case BytecodeInstruction::Opcode::DEFINEFUNC_IMM8_ID16_IMM8:
2944514f5e3Sopenharmony_ci            case BytecodeInstruction::Opcode::DEFINEFUNC_IMM16_ID16_IMM8:
2954514f5e3Sopenharmony_ci            case BytecodeInstruction::Opcode::DEFINEMETHOD_IMM8_ID16_IMM8:
2964514f5e3Sopenharmony_ci            case BytecodeInstruction::Opcode::DEFINEMETHOD_IMM16_ID16_IMM8: {
2974514f5e3Sopenharmony_ci                innerMethodId = jsPandaFile_->ResolveMethodIndex(method->GetMethodId(),
2984514f5e3Sopenharmony_ci                    static_cast<uint16_t>(bcIns.GetId().AsRawValue())).GetOffset();
2994514f5e3Sopenharmony_ci                CollectMethods(innerMethodId, recordNamePtr);
3004514f5e3Sopenharmony_ci                break;
3014514f5e3Sopenharmony_ci            }
3024514f5e3Sopenharmony_ci            case BytecodeInstruction::Opcode::DEFINECLASSWITHBUFFER_IMM8_ID16_ID16_IMM16_V8:{
3034514f5e3Sopenharmony_ci                auto entityId = jsPandaFile_->ResolveMethodIndex(method->GetMethodId(),
3044514f5e3Sopenharmony_ci                    (bcIns.GetId <BytecodeInstruction::Format::IMM8_ID16_ID16_IMM16_V8, 0>()).AsRawValue());
3054514f5e3Sopenharmony_ci                classDefBCIndexes_.insert(bcIndex);
3064514f5e3Sopenharmony_ci                innerMethodId = entityId.GetOffset();
3074514f5e3Sopenharmony_ci                CollectMethods(innerMethodId, recordNamePtr);
3084514f5e3Sopenharmony_ci                auto literalId = jsPandaFile_->ResolveMethodIndex(method->GetMethodId(),
3094514f5e3Sopenharmony_ci                    (bcIns.GetId <BytecodeInstruction::Format::IMM8_ID16_ID16_IMM16_V8, 1>()).AsRawValue());
3104514f5e3Sopenharmony_ci                CollectInnerMethodsFromNewLiteral(literalId, recordNamePtr);
3114514f5e3Sopenharmony_ci                break;
3124514f5e3Sopenharmony_ci            }
3134514f5e3Sopenharmony_ci            case BytecodeInstruction::Opcode::DEFINECLASSWITHBUFFER_IMM16_ID16_ID16_IMM16_V8: {
3144514f5e3Sopenharmony_ci                auto entityId = jsPandaFile_->ResolveMethodIndex(method->GetMethodId(),
3154514f5e3Sopenharmony_ci                    (bcIns.GetId <BytecodeInstruction::Format::IMM16_ID16_ID16_IMM16_V8, 0>()).AsRawValue());
3164514f5e3Sopenharmony_ci                classDefBCIndexes_.insert(bcIndex);
3174514f5e3Sopenharmony_ci                innerMethodId = entityId.GetOffset();
3184514f5e3Sopenharmony_ci                CollectMethods(innerMethodId, recordNamePtr);
3194514f5e3Sopenharmony_ci                auto literalId = jsPandaFile_->ResolveMethodIndex(method->GetMethodId(),
3204514f5e3Sopenharmony_ci                    (bcIns.GetId <BytecodeInstruction::Format::IMM16_ID16_ID16_IMM16_V8, 1>()).AsRawValue());
3214514f5e3Sopenharmony_ci                CollectInnerMethodsFromNewLiteral(literalId, recordNamePtr);
3224514f5e3Sopenharmony_ci                break;
3234514f5e3Sopenharmony_ci            }
3244514f5e3Sopenharmony_ci            case BytecodeInstruction::Opcode::CREATEARRAYWITHBUFFER_IMM8_ID16:
3254514f5e3Sopenharmony_ci            case BytecodeInstruction::Opcode::CREATEARRAYWITHBUFFER_IMM16_ID16:
3264514f5e3Sopenharmony_ci            case BytecodeInstruction::Opcode::CREATEOBJECTWITHBUFFER_IMM8_ID16:
3274514f5e3Sopenharmony_ci            case BytecodeInstruction::Opcode::CREATEOBJECTWITHBUFFER_IMM16_ID16: {
3284514f5e3Sopenharmony_ci                auto literalId = jsPandaFile_->ResolveMethodIndex(method->GetMethodId(),
3294514f5e3Sopenharmony_ci                    static_cast<uint16_t>(bcIns.GetId().AsRawValue()));
3304514f5e3Sopenharmony_ci                CollectInnerMethodsFromNewLiteral(literalId, recordNamePtr);
3314514f5e3Sopenharmony_ci                break;
3324514f5e3Sopenharmony_ci            }
3334514f5e3Sopenharmony_ci            case BytecodeInstruction::Opcode::DEPRECATED_CREATEARRAYWITHBUFFER_PREF_IMM16:
3344514f5e3Sopenharmony_ci            case BytecodeInstruction::Opcode::DEPRECATED_CREATEOBJECTWITHBUFFER_PREF_IMM16: {
3354514f5e3Sopenharmony_ci                auto imm = bcIns.GetImm<BytecodeInstruction::Format::PREF_IMM16>();
3364514f5e3Sopenharmony_ci                CollectInnerMethodsFromLiteral(imm, recordNamePtr);
3374514f5e3Sopenharmony_ci                break;
3384514f5e3Sopenharmony_ci            }
3394514f5e3Sopenharmony_ci            case EcmaOpcode::RESUMEGENERATOR:
3404514f5e3Sopenharmony_ci            case EcmaOpcode::SUSPENDGENERATOR_V8:
3414514f5e3Sopenharmony_ci            case EcmaOpcode::SUPERCALLTHISRANGE_IMM8_IMM8_V8:
3424514f5e3Sopenharmony_ci            case EcmaOpcode::WIDE_SUPERCALLTHISRANGE_PREF_IMM16_V8:
3434514f5e3Sopenharmony_ci            case EcmaOpcode::SUPERCALLARROWRANGE_IMM8_IMM8_V8:
3444514f5e3Sopenharmony_ci            case EcmaOpcode::WIDE_SUPERCALLARROWRANGE_PREF_IMM16_V8: {
3454514f5e3Sopenharmony_ci                *canFastCall = false;
3464514f5e3Sopenharmony_ci                break;
3474514f5e3Sopenharmony_ci            }
3484514f5e3Sopenharmony_ci            case EcmaOpcode::CALLRUNTIME_SUPERCALLFORWARDALLARGS_PREF_V8:
3494514f5e3Sopenharmony_ci            case EcmaOpcode::SUPERCALLSPREAD_IMM8_V8:
3504514f5e3Sopenharmony_ci            case EcmaOpcode::GETUNMAPPEDARGS:
3514514f5e3Sopenharmony_ci            case EcmaOpcode::COPYRESTARGS_IMM8:
3524514f5e3Sopenharmony_ci            case EcmaOpcode::WIDE_COPYRESTARGS_PREF_IMM16: {
3534514f5e3Sopenharmony_ci                *canFastCall = false;
3544514f5e3Sopenharmony_ci                *canTypedCall = false;
3554514f5e3Sopenharmony_ci                break;
3564514f5e3Sopenharmony_ci            }
3574514f5e3Sopenharmony_ci            default:
3584514f5e3Sopenharmony_ci                break;
3594514f5e3Sopenharmony_ci        }
3604514f5e3Sopenharmony_ci    }
3614514f5e3Sopenharmony_ci}
3624514f5e3Sopenharmony_ci}  // namespace panda::ecmascript::kungfu
363