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/frames.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_ci#include "ecmascript/dfx/stackinfo/js_stackinfo.h"
194514f5e3Sopenharmony_ci#include "ecmascript/ecma_context.h"
204514f5e3Sopenharmony_ci#include "ecmascript/stackmap/ark_stackmap_parser.h"
214514f5e3Sopenharmony_ci
224514f5e3Sopenharmony_cinamespace panda::ecmascript {
234514f5e3Sopenharmony_ciFrameIterator::FrameIterator(JSTaggedType *sp, const JSThread *thread) : current_(sp), thread_(thread)
244514f5e3Sopenharmony_ci{
254514f5e3Sopenharmony_ci    if (thread != nullptr) {
264514f5e3Sopenharmony_ci        arkStackMapParser_ =
274514f5e3Sopenharmony_ci            const_cast<JSThread *>(thread)->GetEcmaVM()->GetAOTFileManager()->GetStackMapParser();
284514f5e3Sopenharmony_ci    }
294514f5e3Sopenharmony_ci}
304514f5e3Sopenharmony_ci
314514f5e3Sopenharmony_ciint FrameIterator::ComputeDelta(const Method *method) const
324514f5e3Sopenharmony_ci{
334514f5e3Sopenharmony_ci    if (method == nullptr || isJITFrame_) {
344514f5e3Sopenharmony_ci        return fpDeltaPrevFrameSp_;
354514f5e3Sopenharmony_ci    }
364514f5e3Sopenharmony_ci    return method->GetFpDelta();
374514f5e3Sopenharmony_ci}
384514f5e3Sopenharmony_ci
394514f5e3Sopenharmony_ciMethod *FrameIterator::CheckAndGetMethod() const
404514f5e3Sopenharmony_ci{
414514f5e3Sopenharmony_ci    auto function = GetFunction();
424514f5e3Sopenharmony_ci    if (function.CheckIsJSFunctionBase() || function.CheckIsJSProxy()) {
434514f5e3Sopenharmony_ci        return ECMAObject::Cast(function.GetTaggedObject())->GetCallTarget();
444514f5e3Sopenharmony_ci    }
454514f5e3Sopenharmony_ci    return nullptr;
464514f5e3Sopenharmony_ci}
474514f5e3Sopenharmony_ci
484514f5e3Sopenharmony_ciJSTaggedValue FrameIterator::GetFunction() const
494514f5e3Sopenharmony_ci{
504514f5e3Sopenharmony_ci    FrameType type = GetFrameType();
514514f5e3Sopenharmony_ci    switch (type) {
524514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME:
534514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
544514f5e3Sopenharmony_ci            auto frame = GetFrame<OptimizedJSFunctionFrame>();
554514f5e3Sopenharmony_ci            return frame->GetFunction();
564514f5e3Sopenharmony_ci        }
574514f5e3Sopenharmony_ci        case FrameType::ASM_INTERPRETER_FRAME:
584514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_CONSTRUCTOR_FRAME: {
594514f5e3Sopenharmony_ci            auto frame = GetFrame<AsmInterpretedFrame>();
604514f5e3Sopenharmony_ci            return frame->function;
614514f5e3Sopenharmony_ci        }
624514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_FRAME:
634514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_FAST_NEW_FRAME: {
644514f5e3Sopenharmony_ci            auto frame = GetFrame<InterpretedFrame>();
654514f5e3Sopenharmony_ci            return frame->function;
664514f5e3Sopenharmony_ci        }
674514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_BUILTIN_FRAME: {
684514f5e3Sopenharmony_ci            auto frame = GetFrame<InterpretedBuiltinFrame>();
694514f5e3Sopenharmony_ci            return frame->function;
704514f5e3Sopenharmony_ci        }
714514f5e3Sopenharmony_ci        case FrameType::BUILTIN_FRAME_WITH_ARGV: {
724514f5e3Sopenharmony_ci            auto *frame = BuiltinWithArgvFrame::GetFrameFromSp(GetSp());
734514f5e3Sopenharmony_ci            return frame->GetFunction();
744514f5e3Sopenharmony_ci        }
754514f5e3Sopenharmony_ci        case FrameType::BUILTIN_ENTRY_FRAME:
764514f5e3Sopenharmony_ci        case FrameType::BUILTIN_FRAME: {
774514f5e3Sopenharmony_ci            auto *frame = BuiltinFrame::GetFrameFromSp(GetSp());
784514f5e3Sopenharmony_ci            return frame->GetFunction();
794514f5e3Sopenharmony_ci        }
804514f5e3Sopenharmony_ci        case FrameType::BUILTIN_CALL_LEAVE_FRAME: {
814514f5e3Sopenharmony_ci            auto *frame = OptimizedBuiltinLeaveFrame::GetFrameFromSp(GetSp());
824514f5e3Sopenharmony_ci            return JSTaggedValue(*(frame->GetArgv()));
834514f5e3Sopenharmony_ci        }
844514f5e3Sopenharmony_ci        case FrameType::FASTJIT_FUNCTION_FRAME:
854514f5e3Sopenharmony_ci        case FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME: {
864514f5e3Sopenharmony_ci            auto frame = FASTJITFunctionFrame::GetFrameFromSp(GetSp());
874514f5e3Sopenharmony_ci            return frame->GetFunction();
884514f5e3Sopenharmony_ci        }
894514f5e3Sopenharmony_ci        case FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME :
904514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_FRAME:
914514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_ENTRY_FRAME:
924514f5e3Sopenharmony_ci        case FrameType::ASM_BRIDGE_FRAME:
934514f5e3Sopenharmony_ci        case FrameType::LEAVE_FRAME:
944514f5e3Sopenharmony_ci        case FrameType::BASELINE_BUILTIN_FRAME:
954514f5e3Sopenharmony_ci        case FrameType::LEAVE_FRAME_WITH_ARGV:
964514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_ENTRY_FRAME:
974514f5e3Sopenharmony_ci        case FrameType::ASM_INTERPRETER_ENTRY_FRAME:
984514f5e3Sopenharmony_ci        case FrameType::ASM_INTERPRETER_BRIDGE_FRAME:
994514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME:
1004514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME: {
1014514f5e3Sopenharmony_ci            return JSTaggedValue::Undefined();
1024514f5e3Sopenharmony_ci        }
1034514f5e3Sopenharmony_ci        default: {
1044514f5e3Sopenharmony_ci            LOG_FULL(FATAL) << "Unknown frame type: " << static_cast<uintptr_t>(type);
1054514f5e3Sopenharmony_ci            UNREACHABLE();
1064514f5e3Sopenharmony_ci        }
1074514f5e3Sopenharmony_ci    }
1084514f5e3Sopenharmony_ci}
1094514f5e3Sopenharmony_ci
1104514f5e3Sopenharmony_ciAOTFileInfo::CallSiteInfo FrameIterator::TryCalCallSiteInfoFromMachineCode(uintptr_t retAddr) const
1114514f5e3Sopenharmony_ci{
1124514f5e3Sopenharmony_ci    FrameType type = GetFrameType();
1134514f5e3Sopenharmony_ci    if (type == FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME ||
1144514f5e3Sopenharmony_ci        type == FrameType::OPTIMIZED_JS_FUNCTION_FRAME ||
1154514f5e3Sopenharmony_ci        type == FrameType::FASTJIT_FUNCTION_FRAME ||
1164514f5e3Sopenharmony_ci        type == FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME) {
1174514f5e3Sopenharmony_ci        auto machineCode = thread_->GetEcmaVM()->GetHeap()->GetMachineCodeObject(retAddr);
1184514f5e3Sopenharmony_ci        ASSERT(machineCode != nullptr);
1194514f5e3Sopenharmony_ci        const_cast<FrameIterator*>(this)->machineCode_ = reinterpret_cast<JSTaggedType>(machineCode);
1204514f5e3Sopenharmony_ci        return reinterpret_cast<MachineCode*>(machineCode_)->CalCallSiteInfo();
1214514f5e3Sopenharmony_ci    }
1224514f5e3Sopenharmony_ci    return {};
1234514f5e3Sopenharmony_ci}
1244514f5e3Sopenharmony_ci
1254514f5e3Sopenharmony_cistd::pair<AOTFileInfo::CallSiteInfo, bool> FrameIterator::CalCallSiteInfo(uintptr_t retAddr, bool isDeopt) const
1264514f5e3Sopenharmony_ci{
1274514f5e3Sopenharmony_ci    auto callSiteInfo = const_cast<JSThread *>(thread_)->GetCurrentEcmaContext()->CalCallSiteInfo(retAddr, isDeopt);
1284514f5e3Sopenharmony_ci    if (std::get<1>(callSiteInfo) != nullptr) { // 1 : stackMapAddr
1294514f5e3Sopenharmony_ci        return std::make_pair(callSiteInfo, false);
1304514f5e3Sopenharmony_ci    }
1314514f5e3Sopenharmony_ci    // try get jit code
1324514f5e3Sopenharmony_ci    callSiteInfo = TryCalCallSiteInfoFromMachineCode(retAddr);
1334514f5e3Sopenharmony_ci    return std::make_pair(callSiteInfo, true);
1344514f5e3Sopenharmony_ci}
1354514f5e3Sopenharmony_ci
1364514f5e3Sopenharmony_citemplate <GCVisitedFlag GCVisit>
1374514f5e3Sopenharmony_civoid FrameIterator::Advance()
1384514f5e3Sopenharmony_ci{
1394514f5e3Sopenharmony_ci    ASSERT(!Done());
1404514f5e3Sopenharmony_ci    FrameType t = GetFrameType();
1414514f5e3Sopenharmony_ci    bool needCalCallSiteInfo = false;
1424514f5e3Sopenharmony_ci    switch (t) {
1434514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_FRAME : {
1444514f5e3Sopenharmony_ci            auto frame = GetFrame<OptimizedFrame>();
1454514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
1464514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
1474514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
1484514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
1494514f5e3Sopenharmony_ci                optimizedReturnAddr_ = frame->GetReturnAddr();
1504514f5e3Sopenharmony_ci                needCalCallSiteInfo = true;
1514514f5e3Sopenharmony_ci            }
1524514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
1534514f5e3Sopenharmony_ci            break;
1544514f5e3Sopenharmony_ci        }
1554514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_ENTRY_FRAME : {
1564514f5e3Sopenharmony_ci            auto frame = GetFrame<OptimizedEntryFrame>();
1574514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
1584514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
1594514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
1604514f5e3Sopenharmony_ci                optimizedReturnAddr_ = 0;
1614514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = 0;
1624514f5e3Sopenharmony_ci            }
1634514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
1644514f5e3Sopenharmony_ci            break;
1654514f5e3Sopenharmony_ci        }
1664514f5e3Sopenharmony_ci        case FrameType::BASELINE_BUILTIN_FRAME: {
1674514f5e3Sopenharmony_ci            auto frame = GetFrame<BaselineBuiltinFrame>();
1684514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
1694514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
1704514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
1714514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = 0;
1724514f5e3Sopenharmony_ci                optimizedReturnAddr_ = 0;
1734514f5e3Sopenharmony_ci            }
1744514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
1754514f5e3Sopenharmony_ci            break;
1764514f5e3Sopenharmony_ci        }
1774514f5e3Sopenharmony_ci        case FrameType::ASM_BRIDGE_FRAME : {
1784514f5e3Sopenharmony_ci            auto frame = GetFrame<AsmBridgeFrame>();
1794514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
1804514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
1814514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
1824514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
1834514f5e3Sopenharmony_ci                optimizedReturnAddr_ = frame->GetReturnAddr();
1844514f5e3Sopenharmony_ci                needCalCallSiteInfo = true;
1854514f5e3Sopenharmony_ci            }
1864514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
1874514f5e3Sopenharmony_ci            break;
1884514f5e3Sopenharmony_ci        }
1894514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME: {
1904514f5e3Sopenharmony_ci            auto frame = GetFrame<OptimizedJSFunctionUnfoldArgVFrame>();
1914514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
1924514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
1934514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
1944514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = frame->GetPrevFrameSp();
1954514f5e3Sopenharmony_ci                optimizedReturnAddr_ = frame->GetReturnAddr();
1964514f5e3Sopenharmony_ci                needCalCallSiteInfo = true;
1974514f5e3Sopenharmony_ci            }
1984514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
1994514f5e3Sopenharmony_ci            break;
2004514f5e3Sopenharmony_ci        }
2014514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME: {
2024514f5e3Sopenharmony_ci            auto frame = GetFrame<OptimizedJSFunctionFrame>();
2034514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
2044514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
2054514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
2064514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
2074514f5e3Sopenharmony_ci                optimizedReturnAddr_ = frame->GetReturnAddr();
2084514f5e3Sopenharmony_ci                needCalCallSiteInfo = true;
2094514f5e3Sopenharmony_ci            }
2104514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
2114514f5e3Sopenharmony_ci            break;
2124514f5e3Sopenharmony_ci        }
2134514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME:
2144514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
2154514f5e3Sopenharmony_ci            auto frame = GetFrame<OptimizedJSFunctionFrame>();
2164514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
2174514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
2184514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
2194514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
2204514f5e3Sopenharmony_ci                optimizedReturnAddr_ = frame->GetReturnAddr();
2214514f5e3Sopenharmony_ci                needCalCallSiteInfo = true;
2224514f5e3Sopenharmony_ci            }
2234514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
2244514f5e3Sopenharmony_ci            break;
2254514f5e3Sopenharmony_ci        }
2264514f5e3Sopenharmony_ci        case FrameType::LEAVE_FRAME : {
2274514f5e3Sopenharmony_ci            auto frame = GetFrame<OptimizedLeaveFrame>();
2284514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
2294514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
2304514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
2314514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
2324514f5e3Sopenharmony_ci                optimizedReturnAddr_ = frame->GetReturnAddr();
2334514f5e3Sopenharmony_ci                needCalCallSiteInfo = true;
2344514f5e3Sopenharmony_ci            }
2354514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
2364514f5e3Sopenharmony_ci            break;
2374514f5e3Sopenharmony_ci        }
2384514f5e3Sopenharmony_ci        case FrameType::LEAVE_FRAME_WITH_ARGV : {
2394514f5e3Sopenharmony_ci            auto frame = GetFrame<OptimizedWithArgvLeaveFrame>();
2404514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
2414514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
2424514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
2434514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
2444514f5e3Sopenharmony_ci                optimizedReturnAddr_ = frame->GetReturnAddr();
2454514f5e3Sopenharmony_ci                needCalCallSiteInfo = true;
2464514f5e3Sopenharmony_ci            }
2474514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
2484514f5e3Sopenharmony_ci            break;
2494514f5e3Sopenharmony_ci        }
2504514f5e3Sopenharmony_ci        case FrameType::BUILTIN_CALL_LEAVE_FRAME : {
2514514f5e3Sopenharmony_ci            auto frame = GetFrame<OptimizedBuiltinLeaveFrame>();
2524514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
2534514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
2544514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
2554514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
2564514f5e3Sopenharmony_ci                optimizedReturnAddr_ = frame->GetReturnAddr();
2574514f5e3Sopenharmony_ci                needCalCallSiteInfo = true;
2584514f5e3Sopenharmony_ci            }
2594514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
2604514f5e3Sopenharmony_ci            break;
2614514f5e3Sopenharmony_ci        }
2624514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_FRAME:
2634514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_FAST_NEW_FRAME : {
2644514f5e3Sopenharmony_ci            auto frame = GetFrame<InterpretedFrame>();
2654514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
2664514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
2674514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
2684514f5e3Sopenharmony_ci                optimizedReturnAddr_ = 0;
2694514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = 0;
2704514f5e3Sopenharmony_ci            }
2714514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
2724514f5e3Sopenharmony_ci            break;
2734514f5e3Sopenharmony_ci        }
2744514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_BUILTIN_FRAME: {
2754514f5e3Sopenharmony_ci            auto frame = GetFrame<InterpretedBuiltinFrame>();
2764514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
2774514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
2784514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
2794514f5e3Sopenharmony_ci                optimizedReturnAddr_ = 0;
2804514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = 0;
2814514f5e3Sopenharmony_ci            }
2824514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
2834514f5e3Sopenharmony_ci            break;
2844514f5e3Sopenharmony_ci        }
2854514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_CONSTRUCTOR_FRAME:
2864514f5e3Sopenharmony_ci        case FrameType::ASM_INTERPRETER_FRAME : {
2874514f5e3Sopenharmony_ci            auto frame = GetFrame<AsmInterpretedFrame>();
2884514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
2894514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
2904514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
2914514f5e3Sopenharmony_ci                optimizedReturnAddr_ = 0;
2924514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = 0;
2934514f5e3Sopenharmony_ci            }
2944514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
2954514f5e3Sopenharmony_ci            break;
2964514f5e3Sopenharmony_ci        }
2974514f5e3Sopenharmony_ci        case FrameType::BUILTIN_FRAME : {
2984514f5e3Sopenharmony_ci            auto frame = GetFrame<BuiltinFrame>();
2994514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
3004514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
3014514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
3024514f5e3Sopenharmony_ci                optimizedReturnAddr_ = frame->GetReturnAddr();
3034514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
3044514f5e3Sopenharmony_ci                needCalCallSiteInfo = true;
3054514f5e3Sopenharmony_ci            }
3064514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
3074514f5e3Sopenharmony_ci            break;
3084514f5e3Sopenharmony_ci        }
3094514f5e3Sopenharmony_ci        case FrameType::BUILTIN_ENTRY_FRAME : {
3104514f5e3Sopenharmony_ci            auto frame = GetFrame<BuiltinFrame>();
3114514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
3124514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
3134514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
3144514f5e3Sopenharmony_ci                optimizedReturnAddr_ = frame->GetReturnAddr();
3154514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
3164514f5e3Sopenharmony_ci                needCalCallSiteInfo = false;
3174514f5e3Sopenharmony_ci            }
3184514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
3194514f5e3Sopenharmony_ci            break;
3204514f5e3Sopenharmony_ci        }
3214514f5e3Sopenharmony_ci        case FrameType::BUILTIN_FRAME_WITH_ARGV : {
3224514f5e3Sopenharmony_ci            auto frame = GetFrame<BuiltinWithArgvFrame>();
3234514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
3244514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
3254514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
3264514f5e3Sopenharmony_ci                optimizedReturnAddr_ = frame->GetReturnAddr();
3274514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
3284514f5e3Sopenharmony_ci                needCalCallSiteInfo = true;
3294514f5e3Sopenharmony_ci            }
3304514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
3314514f5e3Sopenharmony_ci            break;
3324514f5e3Sopenharmony_ci        }
3334514f5e3Sopenharmony_ci        case FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME : {
3344514f5e3Sopenharmony_ci            auto frame = GetFrame<BuiltinWithArgvFrame>();
3354514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
3364514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
3374514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
3384514f5e3Sopenharmony_ci                optimizedReturnAddr_ = frame->GetReturnAddr();
3394514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
3404514f5e3Sopenharmony_ci                needCalCallSiteInfo = true;
3414514f5e3Sopenharmony_ci            }
3424514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
3434514f5e3Sopenharmony_ci            break;
3444514f5e3Sopenharmony_ci        }
3454514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_ENTRY_FRAME : {
3464514f5e3Sopenharmony_ci            auto frame = GetFrame<InterpretedEntryFrame>();
3474514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
3484514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
3494514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
3504514f5e3Sopenharmony_ci                optimizedReturnAddr_ = 0;
3514514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = 0;
3524514f5e3Sopenharmony_ci            }
3534514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
3544514f5e3Sopenharmony_ci            break;
3554514f5e3Sopenharmony_ci        }
3564514f5e3Sopenharmony_ci        case FrameType::ASM_INTERPRETER_ENTRY_FRAME : {
3574514f5e3Sopenharmony_ci            auto frame = GetFrame<AsmInterpretedEntryFrame>();
3584514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
3594514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
3604514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
3614514f5e3Sopenharmony_ci                optimizedReturnAddr_ = 0;
3624514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = 0;
3634514f5e3Sopenharmony_ci            }
3644514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
3654514f5e3Sopenharmony_ci            break;
3664514f5e3Sopenharmony_ci        }
3674514f5e3Sopenharmony_ci        case FrameType::ASM_INTERPRETER_BRIDGE_FRAME : {
3684514f5e3Sopenharmony_ci            auto frame = GetFrame<AsmInterpretedBridgeFrame>();
3694514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
3704514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
3714514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
3724514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
3734514f5e3Sopenharmony_ci                optimizedReturnAddr_ = frame->GetReturnAddr();
3744514f5e3Sopenharmony_ci                needCalCallSiteInfo = true;
3754514f5e3Sopenharmony_ci            }
3764514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
3774514f5e3Sopenharmony_ci            break;
3784514f5e3Sopenharmony_ci        }
3794514f5e3Sopenharmony_ci        case FrameType::FASTJIT_FUNCTION_FRAME:
3804514f5e3Sopenharmony_ci        case FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME: {
3814514f5e3Sopenharmony_ci            auto frame = GetFrame<FASTJITFunctionFrame>();
3824514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::VISITED ||
3834514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::HYBRID_STACK ||
3844514f5e3Sopenharmony_ci                          GCVisit == GCVisitedFlag::DEOPT) {
3854514f5e3Sopenharmony_ci                optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
3864514f5e3Sopenharmony_ci                optimizedReturnAddr_ = frame->GetReturnAddr();
3874514f5e3Sopenharmony_ci                needCalCallSiteInfo = true;
3884514f5e3Sopenharmony_ci            }
3894514f5e3Sopenharmony_ci            current_ = frame->GetPrevFrameFp();
3904514f5e3Sopenharmony_ci            break;
3914514f5e3Sopenharmony_ci        }
3924514f5e3Sopenharmony_ci        default: {
3934514f5e3Sopenharmony_ci            if constexpr (GCVisit == GCVisitedFlag::HYBRID_STACK) {
3944514f5e3Sopenharmony_ci                current_ = nullptr;
3954514f5e3Sopenharmony_ci                break;
3964514f5e3Sopenharmony_ci            }
3974514f5e3Sopenharmony_ci            LOG_ECMA(FATAL) << "this branch is unreachable";
3984514f5e3Sopenharmony_ci            UNREACHABLE();
3994514f5e3Sopenharmony_ci        }
4004514f5e3Sopenharmony_ci    }
4014514f5e3Sopenharmony_ci    if constexpr (GCVisit == GCVisitedFlag::VISITED ||
4024514f5e3Sopenharmony_ci                  GCVisit == GCVisitedFlag::HYBRID_STACK ||
4034514f5e3Sopenharmony_ci                  GCVisit == GCVisitedFlag::DEOPT) {
4044514f5e3Sopenharmony_ci        if (!needCalCallSiteInfo) {
4054514f5e3Sopenharmony_ci            return;
4064514f5e3Sopenharmony_ci        }
4074514f5e3Sopenharmony_ci        uint64_t textStart = 0;
4084514f5e3Sopenharmony_ci        AOTFileInfo::CallSiteInfo callSiteInfo;
4094514f5e3Sopenharmony_ci        if constexpr (GCVisit == GCVisitedFlag::DEOPT) {
4104514f5e3Sopenharmony_ci            std::tie(callSiteInfo, isJITFrame_) = CalCallSiteInfo(optimizedReturnAddr_, true);
4114514f5e3Sopenharmony_ci        } else {
4124514f5e3Sopenharmony_ci            std::tie(callSiteInfo, isJITFrame_) = CalCallSiteInfo(optimizedReturnAddr_, false);
4134514f5e3Sopenharmony_ci        }
4144514f5e3Sopenharmony_ci        std::tie(textStart, stackMapAddr_, fpDeltaPrevFrameSp_, calleeRegInfo_) = callSiteInfo;
4154514f5e3Sopenharmony_ci        ASSERT(optimizedReturnAddr_ >= textStart);
4164514f5e3Sopenharmony_ci        optimizedReturnAddr_ = optimizedReturnAddr_ - textStart;
4174514f5e3Sopenharmony_ci    }
4184514f5e3Sopenharmony_ci}
4194514f5e3Sopenharmony_citemplate void FrameIterator::Advance<GCVisitedFlag::VISITED>();
4204514f5e3Sopenharmony_citemplate void FrameIterator::Advance<GCVisitedFlag::IGNORED>();
4214514f5e3Sopenharmony_citemplate void FrameIterator::Advance<GCVisitedFlag::HYBRID_STACK>();
4224514f5e3Sopenharmony_citemplate void FrameIterator::Advance<GCVisitedFlag::DEOPT>();
4234514f5e3Sopenharmony_ci
4244514f5e3Sopenharmony_ciuintptr_t FrameIterator::GetPrevFrameCallSiteSp() const
4254514f5e3Sopenharmony_ci{
4264514f5e3Sopenharmony_ci    if (Done()) {
4274514f5e3Sopenharmony_ci        return 0;
4284514f5e3Sopenharmony_ci    }
4294514f5e3Sopenharmony_ci    auto type = GetFrameType();
4304514f5e3Sopenharmony_ci    switch (type) {
4314514f5e3Sopenharmony_ci        case FrameType::LEAVE_FRAME: {
4324514f5e3Sopenharmony_ci            auto frame = GetFrame<OptimizedLeaveFrame>();
4334514f5e3Sopenharmony_ci            return frame->GetCallSiteSp();
4344514f5e3Sopenharmony_ci        }
4354514f5e3Sopenharmony_ci        case FrameType::LEAVE_FRAME_WITH_ARGV: {
4364514f5e3Sopenharmony_ci            auto frame = GetFrame<OptimizedWithArgvLeaveFrame>();
4374514f5e3Sopenharmony_ci            return frame->GetCallSiteSp();
4384514f5e3Sopenharmony_ci        }
4394514f5e3Sopenharmony_ci        case FrameType::BUILTIN_CALL_LEAVE_FRAME: {
4404514f5e3Sopenharmony_ci            auto frame = GetFrame<OptimizedBuiltinLeaveFrame>();
4414514f5e3Sopenharmony_ci            return frame->GetCallSiteSp();
4424514f5e3Sopenharmony_ci        }
4434514f5e3Sopenharmony_ci        case FrameType::BUILTIN_FRAME_WITH_ARGV: {
4444514f5e3Sopenharmony_ci            auto frame = GetFrame<BuiltinWithArgvFrame>();
4454514f5e3Sopenharmony_ci            return frame->GetCallSiteSp();
4464514f5e3Sopenharmony_ci        }
4474514f5e3Sopenharmony_ci        case FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME: {
4484514f5e3Sopenharmony_ci            auto frame = GetFrame<BuiltinWithArgvFrame>();
4494514f5e3Sopenharmony_ci            return frame->GetCallSiteSp();
4504514f5e3Sopenharmony_ci        }
4514514f5e3Sopenharmony_ci        case FrameType::BUILTIN_FRAME: {
4524514f5e3Sopenharmony_ci            auto frame = GetFrame<BuiltinFrame>();
4534514f5e3Sopenharmony_ci            return frame->GetCallSiteSp();
4544514f5e3Sopenharmony_ci        }
4554514f5e3Sopenharmony_ci        case FrameType::ASM_INTERPRETER_BRIDGE_FRAME: {
4564514f5e3Sopenharmony_ci            auto frame = GetFrame<AsmInterpretedBridgeFrame>();
4574514f5e3Sopenharmony_ci            return frame->GetCallSiteSp();
4584514f5e3Sopenharmony_ci        }
4594514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_FRAME:
4604514f5e3Sopenharmony_ci        case FrameType::BASELINE_BUILTIN_FRAME:  // maybe we can store fpDelta somewhere else for these 2 cases
4614514f5e3Sopenharmony_ci        case FrameType::FASTJIT_FUNCTION_FRAME:
4624514f5e3Sopenharmony_ci        case FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME: {
4634514f5e3Sopenharmony_ci            ASSERT(thread_ != nullptr);
4644514f5e3Sopenharmony_ci            auto callSiteSp = reinterpret_cast<uintptr_t>(current_) + fpDeltaPrevFrameSp_;
4654514f5e3Sopenharmony_ci            return callSiteSp;
4664514f5e3Sopenharmony_ci        }
4674514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME:
4684514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
4694514f5e3Sopenharmony_ci            ASSERT(thread_ != nullptr);
4704514f5e3Sopenharmony_ci            auto method = CheckAndGetMethod();
4714514f5e3Sopenharmony_ci            ASSERT(method != nullptr);
4724514f5e3Sopenharmony_ci            int delta = ComputeDelta(method);
4734514f5e3Sopenharmony_ci            auto callSiteSp = reinterpret_cast<uintptr_t>(current_) + delta;
4744514f5e3Sopenharmony_ci            return callSiteSp;
4754514f5e3Sopenharmony_ci        }
4764514f5e3Sopenharmony_ci        case FrameType::ASM_BRIDGE_FRAME: {
4774514f5e3Sopenharmony_ci            auto frame = GetFrame<AsmBridgeFrame>();
4784514f5e3Sopenharmony_ci            return frame->GetCallSiteSp();
4794514f5e3Sopenharmony_ci        }
4804514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME: {
4814514f5e3Sopenharmony_ci            auto frame = GetFrame<OptimizedJSFunctionUnfoldArgVFrame>();
4824514f5e3Sopenharmony_ci            return frame->GetPrevFrameSp();
4834514f5e3Sopenharmony_ci        }
4844514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME : {
4854514f5e3Sopenharmony_ci            auto callSiteSp = OptimizedJSFunctionFrame::ComputeArgsConfigFrameSp(current_);
4864514f5e3Sopenharmony_ci            return callSiteSp;
4874514f5e3Sopenharmony_ci        }
4884514f5e3Sopenharmony_ci        case FrameType::BUILTIN_ENTRY_FRAME:
4894514f5e3Sopenharmony_ci        case FrameType::ASM_INTERPRETER_FRAME:
4904514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_CONSTRUCTOR_FRAME:
4914514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_FRAME:
4924514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_FAST_NEW_FRAME:
4934514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_ENTRY_FRAME:
4944514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_BUILTIN_FRAME:
4954514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_ENTRY_FRAME:
4964514f5e3Sopenharmony_ci        case FrameType::ASM_INTERPRETER_ENTRY_FRAME: {
4974514f5e3Sopenharmony_ci            break;
4984514f5e3Sopenharmony_ci        }
4994514f5e3Sopenharmony_ci        default: {
5004514f5e3Sopenharmony_ci            LOG_FULL(FATAL) << "Unknown frame type: " << static_cast<uintptr_t>(type);
5014514f5e3Sopenharmony_ci        }
5024514f5e3Sopenharmony_ci    }
5034514f5e3Sopenharmony_ci    return 0;
5044514f5e3Sopenharmony_ci}
5054514f5e3Sopenharmony_ci
5064514f5e3Sopenharmony_cistd::map<uint32_t, uint32_t> FrameIterator::GetInlinedMethodInfo()
5074514f5e3Sopenharmony_ci{
5084514f5e3Sopenharmony_ci    std::map<uint32_t, uint32_t> inlineMethodInfos;
5094514f5e3Sopenharmony_ci    FrameType type = this->GetFrameType();
5104514f5e3Sopenharmony_ci    switch (type) {
5114514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME:
5124514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
5134514f5e3Sopenharmony_ci            CollectMethodOffsetInfo(inlineMethodInfos);
5144514f5e3Sopenharmony_ci            break;
5154514f5e3Sopenharmony_ci        }
5164514f5e3Sopenharmony_ci        case FrameType::FASTJIT_FUNCTION_FRAME:
5174514f5e3Sopenharmony_ci        case FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME: {
5184514f5e3Sopenharmony_ci            CollectMethodOffsetInfo(inlineMethodInfos);
5194514f5e3Sopenharmony_ci            break;
5204514f5e3Sopenharmony_ci        }
5214514f5e3Sopenharmony_ci        default: {
5224514f5e3Sopenharmony_ci            break;
5234514f5e3Sopenharmony_ci        }
5244514f5e3Sopenharmony_ci    }
5254514f5e3Sopenharmony_ci    return inlineMethodInfos;
5264514f5e3Sopenharmony_ci}
5274514f5e3Sopenharmony_ci
5284514f5e3Sopenharmony_ciuint32_t FrameIterator::GetBytecodeOffset() const
5294514f5e3Sopenharmony_ci{
5304514f5e3Sopenharmony_ci    FrameType type = this->GetFrameType();
5314514f5e3Sopenharmony_ci    switch (type) {
5324514f5e3Sopenharmony_ci        case FrameType::ASM_INTERPRETER_FRAME:
5334514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_CONSTRUCTOR_FRAME: {
5344514f5e3Sopenharmony_ci            auto *frame = this->GetFrame<AsmInterpretedFrame>();
5354514f5e3Sopenharmony_ci            Method *method = ECMAObject::Cast(frame->function.GetTaggedObject())->GetCallTarget();
5364514f5e3Sopenharmony_ci            auto offset = frame->GetPc() - method->GetBytecodeArray();
5374514f5e3Sopenharmony_ci            return static_cast<uint32_t>(offset);
5384514f5e3Sopenharmony_ci        }
5394514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_FRAME:
5404514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_FAST_NEW_FRAME: {
5414514f5e3Sopenharmony_ci            auto *frame = this->GetFrame<InterpretedFrame>();
5424514f5e3Sopenharmony_ci            Method *method = ECMAObject::Cast(frame->function.GetTaggedObject())->GetCallTarget();
5434514f5e3Sopenharmony_ci            auto offset = frame->GetPc() - method->GetBytecodeArray();
5444514f5e3Sopenharmony_ci            return static_cast<uint32_t>(offset);
5454514f5e3Sopenharmony_ci        }
5464514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME:
5474514f5e3Sopenharmony_ci        case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
5484514f5e3Sopenharmony_ci            auto frame = this->GetFrame<OptimizedJSFunctionFrame>();
5494514f5e3Sopenharmony_ci            ConstInfo constInfo;
5504514f5e3Sopenharmony_ci            frame->CollectPcOffsetInfo(*this, constInfo);
5514514f5e3Sopenharmony_ci            if (!constInfo.empty()) {
5524514f5e3Sopenharmony_ci                return constInfo[0];
5534514f5e3Sopenharmony_ci            }
5544514f5e3Sopenharmony_ci            [[fallthrough]];
5554514f5e3Sopenharmony_ci        }
5564514f5e3Sopenharmony_ci        case FrameType::FASTJIT_FUNCTION_FRAME:
5574514f5e3Sopenharmony_ci        case FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME: {
5584514f5e3Sopenharmony_ci            auto frame = this->GetFrame<FASTJITFunctionFrame>();
5594514f5e3Sopenharmony_ci            ConstInfo constInfo;
5604514f5e3Sopenharmony_ci            frame->CollectPcOffsetInfo(*this, constInfo);
5614514f5e3Sopenharmony_ci            if (!constInfo.empty()) {
5624514f5e3Sopenharmony_ci                return constInfo[0];
5634514f5e3Sopenharmony_ci            }
5644514f5e3Sopenharmony_ci            [[fallthrough]];
5654514f5e3Sopenharmony_ci        }
5664514f5e3Sopenharmony_ci        default: {
5674514f5e3Sopenharmony_ci            break;
5684514f5e3Sopenharmony_ci        }
5694514f5e3Sopenharmony_ci    }
5704514f5e3Sopenharmony_ci    return 0;
5714514f5e3Sopenharmony_ci}
5724514f5e3Sopenharmony_ci
5734514f5e3Sopenharmony_ciuintptr_t FrameIterator::GetPrevFrame() const
5744514f5e3Sopenharmony_ci{
5754514f5e3Sopenharmony_ci    FrameType type = GetFrameType();
5764514f5e3Sopenharmony_ci    uintptr_t end = 0U;
5774514f5e3Sopenharmony_ci    switch (type) {
5784514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_FRAME:
5794514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_FAST_NEW_FRAME: {
5804514f5e3Sopenharmony_ci            auto prevFrame = GetFrame<InterpretedFrame>();
5814514f5e3Sopenharmony_ci            end = ToUintPtr(prevFrame);
5824514f5e3Sopenharmony_ci            break;
5834514f5e3Sopenharmony_ci        }
5844514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_ENTRY_FRAME: {
5854514f5e3Sopenharmony_ci            auto prevFrame = GetFrame<InterpretedEntryFrame>();
5864514f5e3Sopenharmony_ci            end = ToUintPtr(prevFrame);
5874514f5e3Sopenharmony_ci            break;
5884514f5e3Sopenharmony_ci        }
5894514f5e3Sopenharmony_ci        case FrameType::INTERPRETER_BUILTIN_FRAME: {
5904514f5e3Sopenharmony_ci            auto prevFrame = GetFrame<InterpretedBuiltinFrame>();
5914514f5e3Sopenharmony_ci            end = ToUintPtr(prevFrame);
5924514f5e3Sopenharmony_ci            break;
5934514f5e3Sopenharmony_ci        }
5944514f5e3Sopenharmony_ci        default: {
5954514f5e3Sopenharmony_ci            LOG_FULL(FATAL) << "Unknown frame type: " << static_cast<uintptr_t>(type);
5964514f5e3Sopenharmony_ci        }
5974514f5e3Sopenharmony_ci    }
5984514f5e3Sopenharmony_ci    return end;
5994514f5e3Sopenharmony_ci}
6004514f5e3Sopenharmony_ci
6014514f5e3Sopenharmony_cibool FrameIterator::IteratorStackMap(const RootVisitor &visitor, const RootBaseAndDerivedVisitor &derivedVisitor) const
6024514f5e3Sopenharmony_ci{
6034514f5e3Sopenharmony_ci    ASSERT(arkStackMapParser_ != nullptr);
6044514f5e3Sopenharmony_ci    if (!stackMapAddr_) {  // enter by assembler, no stack map
6054514f5e3Sopenharmony_ci        return true;
6064514f5e3Sopenharmony_ci    }
6074514f5e3Sopenharmony_ci
6084514f5e3Sopenharmony_ci    return arkStackMapParser_->IteratorStackMap(visitor, derivedVisitor, optimizedReturnAddr_,
6094514f5e3Sopenharmony_ci        reinterpret_cast<uintptr_t>(current_), optimizedCallSiteSp_, stackMapAddr_);
6104514f5e3Sopenharmony_ci}
6114514f5e3Sopenharmony_ci
6124514f5e3Sopenharmony_ciARK_INLINE void OptimizedFrame::GCIterate(const FrameIterator &it,
6134514f5e3Sopenharmony_ci    const RootVisitor &visitor,
6144514f5e3Sopenharmony_ci    [[maybe_unused]] const RootRangeVisitor &rangeVisitor,
6154514f5e3Sopenharmony_ci    const RootBaseAndDerivedVisitor &derivedVisitor) const
6164514f5e3Sopenharmony_ci{
6174514f5e3Sopenharmony_ci    bool ret = it.IteratorStackMap(visitor, derivedVisitor);
6184514f5e3Sopenharmony_ci    if (!ret) {
6194514f5e3Sopenharmony_ci#ifndef NDEBUG
6204514f5e3Sopenharmony_ci        LOG_ECMA(DEBUG) << " stackmap don't found returnAddr " << it.GetOptimizedReturnAddr();
6214514f5e3Sopenharmony_ci#endif
6224514f5e3Sopenharmony_ci    }
6234514f5e3Sopenharmony_ci}
6244514f5e3Sopenharmony_ci
6254514f5e3Sopenharmony_ciARK_INLINE void BaselineBuiltinFrame::GCIterate([[maybe_unused]]const FrameIterator &it,
6264514f5e3Sopenharmony_ci    [[maybe_unused]]const RootVisitor &visitor,
6274514f5e3Sopenharmony_ci    [[maybe_unused]] const RootRangeVisitor &rangeVisitor,
6284514f5e3Sopenharmony_ci    [[maybe_unused]]const RootBaseAndDerivedVisitor &derivedVisitor) const
6294514f5e3Sopenharmony_ci{
6304514f5e3Sopenharmony_ci    bool ret = it.IteratorStackMap(visitor, derivedVisitor);
6314514f5e3Sopenharmony_ci    if (!ret) {
6324514f5e3Sopenharmony_ci#ifndef NDEBUG
6334514f5e3Sopenharmony_ci        LOG_ECMA(DEBUG) << " stackmap don't found returnAddr " << it.GetOptimizedReturnAddr();
6344514f5e3Sopenharmony_ci#endif
6354514f5e3Sopenharmony_ci    }
6364514f5e3Sopenharmony_ci}
6374514f5e3Sopenharmony_ci
6384514f5e3Sopenharmony_civoid FrameIterator::CollectPcOffsetInfo(ConstInfo &info) const
6394514f5e3Sopenharmony_ci{
6404514f5e3Sopenharmony_ci    arkStackMapParser_->GetConstInfo(optimizedReturnAddr_, info, stackMapAddr_);
6414514f5e3Sopenharmony_ci}
6424514f5e3Sopenharmony_ci
6434514f5e3Sopenharmony_civoid FrameIterator::CollectMethodOffsetInfo(std::map<uint32_t, uint32_t> &info) const
6444514f5e3Sopenharmony_ci{
6454514f5e3Sopenharmony_ci    arkStackMapParser_->GetMethodOffsetInfo(optimizedReturnAddr_, info, stackMapAddr_);
6464514f5e3Sopenharmony_ci}
6474514f5e3Sopenharmony_ci
6484514f5e3Sopenharmony_civoid FrameIterator::CollectArkDeopt(std::vector<kungfu::ARKDeopt>& deopts) const
6494514f5e3Sopenharmony_ci{
6504514f5e3Sopenharmony_ci    arkStackMapParser_->GetArkDeopt(optimizedReturnAddr_, stackMapAddr_, deopts);
6514514f5e3Sopenharmony_ci}
6524514f5e3Sopenharmony_ci
6534514f5e3Sopenharmony_ciARK_INLINE JSTaggedType* OptimizedJSFunctionFrame::GetArgv(const FrameIterator &it) const
6544514f5e3Sopenharmony_ci{
6554514f5e3Sopenharmony_ci    uintptr_t *preFrameSp = ComputePrevFrameSp(it);
6564514f5e3Sopenharmony_ci    return GetArgv(preFrameSp);
6574514f5e3Sopenharmony_ci}
6584514f5e3Sopenharmony_ci
6594514f5e3Sopenharmony_ciARK_INLINE uintptr_t* OptimizedJSFunctionFrame::ComputePrevFrameSp(const FrameIterator &it) const
6604514f5e3Sopenharmony_ci{
6614514f5e3Sopenharmony_ci    const JSTaggedType *sp = it.GetSp();
6624514f5e3Sopenharmony_ci    Method *method = it.CheckAndGetMethod();
6634514f5e3Sopenharmony_ci    ASSERT(method != nullptr);
6644514f5e3Sopenharmony_ci    int delta = it.ComputeDelta(method);
6654514f5e3Sopenharmony_ci    ASSERT((delta > 0) && (delta % sizeof(uintptr_t) == 0));
6664514f5e3Sopenharmony_ci    uintptr_t *preFrameSp = reinterpret_cast<uintptr_t *>(const_cast<JSTaggedType *>(sp)) + delta / sizeof(uintptr_t);
6674514f5e3Sopenharmony_ci    return preFrameSp;
6684514f5e3Sopenharmony_ci}
6694514f5e3Sopenharmony_ci
6704514f5e3Sopenharmony_civoid OptimizedJSFunctionFrame::CollectPcOffsetInfo(const FrameIterator &it, ConstInfo &info) const
6714514f5e3Sopenharmony_ci{
6724514f5e3Sopenharmony_ci    it.CollectPcOffsetInfo(info);
6734514f5e3Sopenharmony_ci}
6744514f5e3Sopenharmony_ci
6754514f5e3Sopenharmony_ciARK_INLINE void OptimizedJSFunctionFrame::GCIterate(const FrameIterator &it,
6764514f5e3Sopenharmony_ci    const RootVisitor &visitor,
6774514f5e3Sopenharmony_ci    [[maybe_unused]] const RootRangeVisitor &rangeVisitor,
6784514f5e3Sopenharmony_ci    const RootBaseAndDerivedVisitor &derivedVisitor, FrameType frameType) const
6794514f5e3Sopenharmony_ci{
6804514f5e3Sopenharmony_ci    OptimizedJSFunctionFrame *frame = OptimizedJSFunctionFrame::GetFrameFromSp(it.GetSp());
6814514f5e3Sopenharmony_ci    uintptr_t *jsFuncPtr = reinterpret_cast<uintptr_t *>(frame);
6824514f5e3Sopenharmony_ci    uintptr_t jsFuncSlot = ToUintPtr(jsFuncPtr);
6834514f5e3Sopenharmony_ci    visitor(Root::ROOT_FRAME, ObjectSlot(jsFuncSlot));
6844514f5e3Sopenharmony_ci    if (frameType == FrameType::OPTIMIZED_JS_FUNCTION_FRAME) {
6854514f5e3Sopenharmony_ci        uintptr_t *preFrameSp = frame->ComputePrevFrameSp(it);
6864514f5e3Sopenharmony_ci        auto argc = frame->GetArgc(preFrameSp);
6874514f5e3Sopenharmony_ci        JSTaggedType *argv = frame->GetArgv(reinterpret_cast<uintptr_t *>(preFrameSp));
6884514f5e3Sopenharmony_ci        if (argc > 0) {
6894514f5e3Sopenharmony_ci            uintptr_t start = ToUintPtr(argv); // argv
6904514f5e3Sopenharmony_ci            uintptr_t end = ToUintPtr(argv + argc);
6914514f5e3Sopenharmony_ci            rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
6924514f5e3Sopenharmony_ci        }
6934514f5e3Sopenharmony_ci    }
6944514f5e3Sopenharmony_ci
6954514f5e3Sopenharmony_ci    auto machineCodeSlot = ObjectSlot(ToUintPtr(it.GetMachineCodeSlot()));
6964514f5e3Sopenharmony_ci    if (machineCodeSlot.GetTaggedType() != JSTaggedValue::VALUE_UNDEFINED) {
6974514f5e3Sopenharmony_ci        visitor(Root::ROOT_FRAME, machineCodeSlot);
6984514f5e3Sopenharmony_ci    }
6994514f5e3Sopenharmony_ci
7004514f5e3Sopenharmony_ci    bool ret = it.IteratorStackMap(visitor, derivedVisitor);
7014514f5e3Sopenharmony_ci    if (!ret) {
7024514f5e3Sopenharmony_ci#ifndef NDEBUG
7034514f5e3Sopenharmony_ci        LOG_ECMA(DEBUG) << " stackmap don't found returnAddr " << it.GetOptimizedReturnAddr();
7044514f5e3Sopenharmony_ci#endif
7054514f5e3Sopenharmony_ci    }
7064514f5e3Sopenharmony_ci}
7074514f5e3Sopenharmony_ci
7084514f5e3Sopenharmony_civoid OptimizedJSFunctionFrame::GetDeoptBundleInfo(const FrameIterator &it, std::vector<kungfu::ARKDeopt>& deopts) const
7094514f5e3Sopenharmony_ci{
7104514f5e3Sopenharmony_ci    it.CollectArkDeopt(deopts);
7114514f5e3Sopenharmony_ci}
7124514f5e3Sopenharmony_ci
7134514f5e3Sopenharmony_civoid OptimizedJSFunctionFrame::GetFuncCalleeRegAndOffset(
7144514f5e3Sopenharmony_ci    const FrameIterator &it, kungfu::CalleeRegAndOffsetVec &ret) const
7154514f5e3Sopenharmony_ci{
7164514f5e3Sopenharmony_ci    it.GetCalleeRegAndOffsetVec(ret);
7174514f5e3Sopenharmony_ci}
7184514f5e3Sopenharmony_ci
7194514f5e3Sopenharmony_ciARK_INLINE JSTaggedType* FASTJITFunctionFrame::GetArgv(const FrameIterator &it) const
7204514f5e3Sopenharmony_ci{
7214514f5e3Sopenharmony_ci    uintptr_t *preFrameSp = ComputePrevFrameSp(it);
7224514f5e3Sopenharmony_ci    return GetArgv(preFrameSp);
7234514f5e3Sopenharmony_ci}
7244514f5e3Sopenharmony_ci
7254514f5e3Sopenharmony_ciARK_INLINE uintptr_t* FASTJITFunctionFrame::ComputePrevFrameSp(const FrameIterator &it) const
7264514f5e3Sopenharmony_ci{
7274514f5e3Sopenharmony_ci    const JSTaggedType *sp = it.GetSp();
7284514f5e3Sopenharmony_ci    int delta = it.ComputeDelta();
7294514f5e3Sopenharmony_ci    ASSERT((delta > 0) && (delta % sizeof(uintptr_t) == 0));
7304514f5e3Sopenharmony_ci    uintptr_t *preFrameSp = reinterpret_cast<uintptr_t *>(const_cast<JSTaggedType *>(sp)) + delta / sizeof(uintptr_t);
7314514f5e3Sopenharmony_ci    return preFrameSp;
7324514f5e3Sopenharmony_ci}
7334514f5e3Sopenharmony_ci
7344514f5e3Sopenharmony_civoid FASTJITFunctionFrame::CollectPcOffsetInfo(const FrameIterator &it, ConstInfo &info) const
7354514f5e3Sopenharmony_ci{
7364514f5e3Sopenharmony_ci    it.CollectPcOffsetInfo(info);
7374514f5e3Sopenharmony_ci}
7384514f5e3Sopenharmony_ci
7394514f5e3Sopenharmony_ciARK_INLINE void FASTJITFunctionFrame::GCIterate(const FrameIterator &it,
7404514f5e3Sopenharmony_ci    const RootVisitor &visitor,
7414514f5e3Sopenharmony_ci    [[maybe_unused]] const RootRangeVisitor &rangeVisitor,
7424514f5e3Sopenharmony_ci    const RootBaseAndDerivedVisitor &derivedVisitor, FrameType frameType) const
7434514f5e3Sopenharmony_ci{
7444514f5e3Sopenharmony_ci    FASTJITFunctionFrame *frame = FASTJITFunctionFrame::GetFrameFromSp(it.GetSp());
7454514f5e3Sopenharmony_ci    uintptr_t jsFuncSlot = GetFuncAddrFromSp(it.GetSp());
7464514f5e3Sopenharmony_ci    visitor(Root::ROOT_FRAME, ObjectSlot(jsFuncSlot));
7474514f5e3Sopenharmony_ci    if (frameType == FrameType::FASTJIT_FUNCTION_FRAME) {
7484514f5e3Sopenharmony_ci        uintptr_t *preFrameSp = frame->ComputePrevFrameSp(it);
7494514f5e3Sopenharmony_ci        auto argc = frame->GetArgc(preFrameSp);
7504514f5e3Sopenharmony_ci        JSTaggedType *argv = frame->GetArgv(reinterpret_cast<uintptr_t *>(preFrameSp));
7514514f5e3Sopenharmony_ci        if (argc > 0) {
7524514f5e3Sopenharmony_ci            uintptr_t start = ToUintPtr(argv); // argv
7534514f5e3Sopenharmony_ci            uintptr_t end = ToUintPtr(argv + argc);
7544514f5e3Sopenharmony_ci            rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
7554514f5e3Sopenharmony_ci        }
7564514f5e3Sopenharmony_ci    }
7574514f5e3Sopenharmony_ci
7584514f5e3Sopenharmony_ci    auto machineCodeSlot = ObjectSlot(ToUintPtr(it.GetMachineCodeSlot()));
7594514f5e3Sopenharmony_ci    if (machineCodeSlot.GetTaggedType() != JSTaggedValue::VALUE_UNDEFINED) {
7604514f5e3Sopenharmony_ci        visitor(Root::ROOT_FRAME, machineCodeSlot);
7614514f5e3Sopenharmony_ci    }
7624514f5e3Sopenharmony_ci
7634514f5e3Sopenharmony_ci    bool ret = it.IteratorStackMap(visitor, derivedVisitor);
7644514f5e3Sopenharmony_ci    if (!ret) {
7654514f5e3Sopenharmony_ci#ifndef NDEBUG
7664514f5e3Sopenharmony_ci        LOG_ECMA(DEBUG) << " stackmap don't found returnAddr " << it.GetOptimizedReturnAddr();
7674514f5e3Sopenharmony_ci#endif
7684514f5e3Sopenharmony_ci    }
7694514f5e3Sopenharmony_ci}
7704514f5e3Sopenharmony_ci
7714514f5e3Sopenharmony_civoid FASTJITFunctionFrame::GetDeoptBundleInfo(const FrameIterator &it, std::vector<kungfu::ARKDeopt>& deopts) const
7724514f5e3Sopenharmony_ci{
7734514f5e3Sopenharmony_ci    it.CollectArkDeopt(deopts);
7744514f5e3Sopenharmony_ci}
7754514f5e3Sopenharmony_ci
7764514f5e3Sopenharmony_civoid FASTJITFunctionFrame::GetFuncCalleeRegAndOffset(
7774514f5e3Sopenharmony_ci    const FrameIterator &it, kungfu::CalleeRegAndOffsetVec &ret) const
7784514f5e3Sopenharmony_ci{
7794514f5e3Sopenharmony_ci    it.GetCalleeRegAndOffsetVec(ret);
7804514f5e3Sopenharmony_ci}
7814514f5e3Sopenharmony_ci
7824514f5e3Sopenharmony_ciARK_INLINE void AsmInterpretedFrame::GCIterate(const FrameIterator &it,
7834514f5e3Sopenharmony_ci    const RootVisitor &visitor,
7844514f5e3Sopenharmony_ci    const RootRangeVisitor &rangeVisitor,
7854514f5e3Sopenharmony_ci    const RootBaseAndDerivedVisitor &derivedVisitor,
7864514f5e3Sopenharmony_ci    bool isBaselineFrame) const
7874514f5e3Sopenharmony_ci{
7884514f5e3Sopenharmony_ci    AsmInterpretedFrame *frame = AsmInterpretedFrame::GetFrameFromSp(it.GetSp());
7894514f5e3Sopenharmony_ci    uintptr_t start = ToUintPtr(it.GetSp());
7904514f5e3Sopenharmony_ci    uintptr_t end = ToUintPtr(frame->GetCurrentFramePointer());
7914514f5e3Sopenharmony_ci    rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
7924514f5e3Sopenharmony_ci    visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->function)));
7934514f5e3Sopenharmony_ci    visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->thisObj)));
7944514f5e3Sopenharmony_ci    if (frame->pc != nullptr || isBaselineFrame) {
7954514f5e3Sopenharmony_ci        visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->acc)));
7964514f5e3Sopenharmony_ci        visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->env)));
7974514f5e3Sopenharmony_ci    }
7984514f5e3Sopenharmony_ci
7994514f5e3Sopenharmony_ci    if (isBaselineFrame) {
8004514f5e3Sopenharmony_ci        return;
8014514f5e3Sopenharmony_ci    }
8024514f5e3Sopenharmony_ci    bool ret = it.IteratorStackMap(visitor, derivedVisitor);
8034514f5e3Sopenharmony_ci    if (!ret) {
8044514f5e3Sopenharmony_ci#ifndef NDEBUG
8054514f5e3Sopenharmony_ci        LOG_ECMA(DEBUG) << " stackmap don't found returnAddr " << it.GetOptimizedReturnAddr();
8064514f5e3Sopenharmony_ci#endif
8074514f5e3Sopenharmony_ci    }
8084514f5e3Sopenharmony_ci}
8094514f5e3Sopenharmony_ci
8104514f5e3Sopenharmony_ciARK_INLINE void InterpretedFrame::GCIterate(const FrameIterator &it,
8114514f5e3Sopenharmony_ci                                            const RootVisitor &visitor,
8124514f5e3Sopenharmony_ci                                            const RootRangeVisitor &rangeVisitor) const
8134514f5e3Sopenharmony_ci{
8144514f5e3Sopenharmony_ci    auto sp = it.GetSp();
8154514f5e3Sopenharmony_ci    InterpretedFrame *frame = InterpretedFrame::GetFrameFromSp(sp);
8164514f5e3Sopenharmony_ci    if (frame->function.IsHole()) {
8174514f5e3Sopenharmony_ci        return;
8184514f5e3Sopenharmony_ci    }
8194514f5e3Sopenharmony_ci
8204514f5e3Sopenharmony_ci    JSTaggedType *prevSp = frame->GetPrevFrameFp();
8214514f5e3Sopenharmony_ci    uintptr_t start = ToUintPtr(sp);
8224514f5e3Sopenharmony_ci    const JSThread *thread = it.GetThread();
8234514f5e3Sopenharmony_ci    FrameIterator prevIt(prevSp, thread);
8244514f5e3Sopenharmony_ci    uintptr_t end = prevIt.GetPrevFrame();
8254514f5e3Sopenharmony_ci
8264514f5e3Sopenharmony_ci    rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
8274514f5e3Sopenharmony_ci    visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->function)));
8284514f5e3Sopenharmony_ci    visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->thisObj)));
8294514f5e3Sopenharmony_ci
8304514f5e3Sopenharmony_ci    // pc == nullptr, init InterpretedFrame & native InterpretedFrame.
8314514f5e3Sopenharmony_ci    if (frame->pc != nullptr) {
8324514f5e3Sopenharmony_ci        visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->acc)));
8334514f5e3Sopenharmony_ci        visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->constpool)));
8344514f5e3Sopenharmony_ci        visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->env)));
8354514f5e3Sopenharmony_ci        visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->profileTypeInfo)));
8364514f5e3Sopenharmony_ci    }
8374514f5e3Sopenharmony_ci}
8384514f5e3Sopenharmony_ci
8394514f5e3Sopenharmony_ciARK_INLINE void InterpretedBuiltinFrame::GCIterate(const FrameIterator &it,
8404514f5e3Sopenharmony_ci                                                   const RootVisitor &visitor,
8414514f5e3Sopenharmony_ci                                                   const RootRangeVisitor &rangeVisitor) const
8424514f5e3Sopenharmony_ci{
8434514f5e3Sopenharmony_ci    auto sp = it.GetSp();
8444514f5e3Sopenharmony_ci    InterpretedBuiltinFrame *frame = InterpretedBuiltinFrame::GetFrameFromSp(sp);
8454514f5e3Sopenharmony_ci    JSTaggedType *prevSp = frame->GetPrevFrameFp();
8464514f5e3Sopenharmony_ci    const JSThread *thread = it.GetThread();
8474514f5e3Sopenharmony_ci    FrameIterator prevIt(prevSp, thread);
8484514f5e3Sopenharmony_ci
8494514f5e3Sopenharmony_ci    uintptr_t start = ToUintPtr(sp + 2); // 2: numArgs & thread.
8504514f5e3Sopenharmony_ci    uintptr_t end = prevIt.GetPrevFrame();
8514514f5e3Sopenharmony_ci    rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
8524514f5e3Sopenharmony_ci    visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->function)));
8534514f5e3Sopenharmony_ci}
8544514f5e3Sopenharmony_ci
8554514f5e3Sopenharmony_ciARK_INLINE void OptimizedLeaveFrame::GCIterate(const FrameIterator &it,
8564514f5e3Sopenharmony_ci    [[maybe_unused]] const RootVisitor &visitor,
8574514f5e3Sopenharmony_ci    const RootRangeVisitor &rangeVisitor) const
8584514f5e3Sopenharmony_ci{
8594514f5e3Sopenharmony_ci    const JSTaggedType *sp = it.GetSp();
8604514f5e3Sopenharmony_ci    OptimizedLeaveFrame *frame = OptimizedLeaveFrame::GetFrameFromSp(sp);
8614514f5e3Sopenharmony_ci    if (frame->argc > 0) {
8624514f5e3Sopenharmony_ci        JSTaggedType *argv = reinterpret_cast<JSTaggedType *>(&frame->argc + 1);
8634514f5e3Sopenharmony_ci        uintptr_t start = ToUintPtr(argv); // argv
8644514f5e3Sopenharmony_ci        uintptr_t end = ToUintPtr(argv + frame->argc);
8654514f5e3Sopenharmony_ci        rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
8664514f5e3Sopenharmony_ci    }
8674514f5e3Sopenharmony_ci}
8684514f5e3Sopenharmony_ci
8694514f5e3Sopenharmony_ciARK_INLINE void OptimizedWithArgvLeaveFrame::GCIterate(const FrameIterator &it,
8704514f5e3Sopenharmony_ci    [[maybe_unused]] const RootVisitor &visitor,
8714514f5e3Sopenharmony_ci    const RootRangeVisitor &rangeVisitor) const
8724514f5e3Sopenharmony_ci{
8734514f5e3Sopenharmony_ci    const JSTaggedType *sp = it.GetSp();
8744514f5e3Sopenharmony_ci    OptimizedWithArgvLeaveFrame *frame = OptimizedWithArgvLeaveFrame::GetFrameFromSp(sp);
8754514f5e3Sopenharmony_ci    if (frame->argc > 0) {
8764514f5e3Sopenharmony_ci        uintptr_t* argvPtr = reinterpret_cast<uintptr_t *>(&frame->argc + 1);
8774514f5e3Sopenharmony_ci        JSTaggedType *argv = reinterpret_cast<JSTaggedType *>(*argvPtr);
8784514f5e3Sopenharmony_ci        uintptr_t start = ToUintPtr(argv); // argv
8794514f5e3Sopenharmony_ci        uintptr_t end = ToUintPtr(argv + frame->argc);
8804514f5e3Sopenharmony_ci        rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
8814514f5e3Sopenharmony_ci    }
8824514f5e3Sopenharmony_ci}
8834514f5e3Sopenharmony_ci
8844514f5e3Sopenharmony_ciARK_INLINE void OptimizedBuiltinLeaveFrame::GCIterate(const FrameIterator &it,
8854514f5e3Sopenharmony_ci    [[maybe_unused]] const RootVisitor &visitor,
8864514f5e3Sopenharmony_ci    const RootRangeVisitor &rangeVisitor) const
8874514f5e3Sopenharmony_ci{
8884514f5e3Sopenharmony_ci    const JSTaggedType *sp = it.GetSp();
8894514f5e3Sopenharmony_ci    OptimizedBuiltinLeaveFrame *frame = OptimizedBuiltinLeaveFrame::GetFrameFromSp(sp);
8904514f5e3Sopenharmony_ci    if (frame->argc > 0) {
8914514f5e3Sopenharmony_ci        JSTaggedType *argv = reinterpret_cast<JSTaggedType *>(&frame->argc + 1);
8924514f5e3Sopenharmony_ci        uintptr_t start = ToUintPtr(argv); // argv
8934514f5e3Sopenharmony_ci        uintptr_t end = ToUintPtr(argv + frame->argc);
8944514f5e3Sopenharmony_ci        rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
8954514f5e3Sopenharmony_ci    }
8964514f5e3Sopenharmony_ci}
8974514f5e3Sopenharmony_ci
8984514f5e3Sopenharmony_ciARK_INLINE void BuiltinWithArgvFrame::GCIterate(const FrameIterator &it,
8994514f5e3Sopenharmony_ci    [[maybe_unused]] const RootVisitor &visitor,
9004514f5e3Sopenharmony_ci    const RootRangeVisitor &rangeVisitor) const
9014514f5e3Sopenharmony_ci{
9024514f5e3Sopenharmony_ci    const JSTaggedType *sp = it.GetSp();
9034514f5e3Sopenharmony_ci    auto frame = BuiltinWithArgvFrame::GetFrameFromSp(sp);
9044514f5e3Sopenharmony_ci    auto argc = static_cast<uint32_t>(frame->GetNumArgs()) + NUM_MANDATORY_JSFUNC_ARGS;
9054514f5e3Sopenharmony_ci    JSTaggedType *argv = reinterpret_cast<JSTaggedType *>(frame->GetStackArgsAddress());
9064514f5e3Sopenharmony_ci    uintptr_t start = ToUintPtr(argv);
9074514f5e3Sopenharmony_ci    uintptr_t end = ToUintPtr(argv + argc);
9084514f5e3Sopenharmony_ci    rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
9094514f5e3Sopenharmony_ci}
9104514f5e3Sopenharmony_ci
9114514f5e3Sopenharmony_ciARK_INLINE void BuiltinFrame::GCIterate(const FrameIterator &it,
9124514f5e3Sopenharmony_ci    const RootVisitor &visitor,
9134514f5e3Sopenharmony_ci    const RootRangeVisitor &rangeVisitor) const
9144514f5e3Sopenharmony_ci{
9154514f5e3Sopenharmony_ci    const JSTaggedType *sp = it.GetSp();
9164514f5e3Sopenharmony_ci    auto frame = BuiltinFrame::GetFrameFromSp(sp);
9174514f5e3Sopenharmony_ci    // no need to visit stack map for entry frame
9184514f5e3Sopenharmony_ci    if (frame->type == FrameType::BUILTIN_ENTRY_FRAME) {
9194514f5e3Sopenharmony_ci        // only visit function
9204514f5e3Sopenharmony_ci        visitor(Root::ROOT_FRAME, ObjectSlot(frame->GetStackArgsAddress()));
9214514f5e3Sopenharmony_ci        return;
9224514f5e3Sopenharmony_ci    }
9234514f5e3Sopenharmony_ci    JSTaggedType *argv = reinterpret_cast<JSTaggedType *>(frame->GetStackArgsAddress());
9244514f5e3Sopenharmony_ci    auto argc = frame->GetNumArgs();
9254514f5e3Sopenharmony_ci    uintptr_t start = ToUintPtr(argv);
9264514f5e3Sopenharmony_ci    uintptr_t end = ToUintPtr(argv + argc);
9274514f5e3Sopenharmony_ci    rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
9284514f5e3Sopenharmony_ci}
9294514f5e3Sopenharmony_ci
9304514f5e3Sopenharmony_ciARK_INLINE void InterpretedEntryFrame::GCIterate(const FrameIterator &it,
9314514f5e3Sopenharmony_ci    [[maybe_unused]] const RootVisitor &visitor,
9324514f5e3Sopenharmony_ci    const RootRangeVisitor &rangeVisitor) const
9334514f5e3Sopenharmony_ci{
9344514f5e3Sopenharmony_ci    const JSTaggedType* sp = it.GetSp();
9354514f5e3Sopenharmony_ci    InterpretedEntryFrame *frame = InterpretedEntryFrame::GetFrameFromSp(sp);
9364514f5e3Sopenharmony_ci    JSTaggedType *prevSp = frame->GetPrevFrameFp();
9374514f5e3Sopenharmony_ci    if (prevSp == nullptr) {
9384514f5e3Sopenharmony_ci        return;
9394514f5e3Sopenharmony_ci    }
9404514f5e3Sopenharmony_ci
9414514f5e3Sopenharmony_ci    const JSThread *thread = it.GetThread();
9424514f5e3Sopenharmony_ci    FrameIterator prevIt(prevSp, thread);
9434514f5e3Sopenharmony_ci    uintptr_t start = ToUintPtr(sp + 2); // 2: numArgs & thread.
9444514f5e3Sopenharmony_ci    uintptr_t end = prevIt.GetPrevFrame();
9454514f5e3Sopenharmony_ci    rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
9464514f5e3Sopenharmony_ci}
9474514f5e3Sopenharmony_ci}  // namespace panda::ecmascript
948