14514f5e3Sopenharmony_ci 24514f5e3Sopenharmony_ci/* 34514f5e3Sopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 44514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 54514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License. 64514f5e3Sopenharmony_ci * You may obtain a copy of the License at 74514f5e3Sopenharmony_ci * 84514f5e3Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 94514f5e3Sopenharmony_ci * 104514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 114514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 124514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and 144514f5e3Sopenharmony_ci * limitations under the License. 154514f5e3Sopenharmony_ci */ 164514f5e3Sopenharmony_ci 174514f5e3Sopenharmony_ci#include "ecmascript/interpreter/frame_handler.h" 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/program_object.h" 204514f5e3Sopenharmony_ci 214514f5e3Sopenharmony_cinamespace panda::ecmascript { 224514f5e3Sopenharmony_ciFrameHandler::FrameHandler(const JSThread *thread) 234514f5e3Sopenharmony_ci : sp_(const_cast<JSTaggedType *>(thread->GetCurrentFrame())), thread_(thread) 244514f5e3Sopenharmony_ci{ 254514f5e3Sopenharmony_ci AdvanceToJSFrame(); 264514f5e3Sopenharmony_ci} 274514f5e3Sopenharmony_ci 284514f5e3Sopenharmony_ciARK_INLINE void FrameHandler::AdvanceToJSFrame() 294514f5e3Sopenharmony_ci{ 304514f5e3Sopenharmony_ci if (!thread_->IsAsmInterpreter()) { 314514f5e3Sopenharmony_ci return; 324514f5e3Sopenharmony_ci } 334514f5e3Sopenharmony_ci FrameIterator it(sp_, thread_); 344514f5e3Sopenharmony_ci for (; !it.Done(); it.Advance()) { 354514f5e3Sopenharmony_ci FrameType t = it.GetFrameType(); 364514f5e3Sopenharmony_ci if (IsBaselineBuiltinFrame(t)) { 374514f5e3Sopenharmony_ci FindAndSetBaselineNativePc(it); 384514f5e3Sopenharmony_ci } 394514f5e3Sopenharmony_ci if (IsJSFrame(t) || IsJSEntryFrame(t)) { 404514f5e3Sopenharmony_ci break; 414514f5e3Sopenharmony_ci } 424514f5e3Sopenharmony_ci } 434514f5e3Sopenharmony_ci sp_ = it.GetSp(); 444514f5e3Sopenharmony_ci} 454514f5e3Sopenharmony_ci 464514f5e3Sopenharmony_ciARK_INLINE void FrameHandler::PrevJSFrame() 474514f5e3Sopenharmony_ci{ 484514f5e3Sopenharmony_ci if (!thread_->IsAsmInterpreter()) { 494514f5e3Sopenharmony_ci FrameIterator it(sp_, thread_); 504514f5e3Sopenharmony_ci if (IsBaselineBuiltinFrame(it.GetFrameType())) { 514514f5e3Sopenharmony_ci FindAndSetBaselineNativePc(it); 524514f5e3Sopenharmony_ci } 534514f5e3Sopenharmony_ci it.Advance(); 544514f5e3Sopenharmony_ci sp_ = it.GetSp(); 554514f5e3Sopenharmony_ci return; 564514f5e3Sopenharmony_ci } 574514f5e3Sopenharmony_ci AdvanceToJSFrame(); 584514f5e3Sopenharmony_ci FrameIterator it(sp_, thread_); 594514f5e3Sopenharmony_ci FrameType t = it.GetFrameType(); 604514f5e3Sopenharmony_ci if (t == FrameType::ASM_INTERPRETER_FRAME) { 614514f5e3Sopenharmony_ci auto frame = it.GetFrame<AsmInterpretedFrame>(); 624514f5e3Sopenharmony_ci if (thread_->IsAsmInterpreter()) { 634514f5e3Sopenharmony_ci fp_ = frame->GetCurrentFramePointer(); 644514f5e3Sopenharmony_ci } 654514f5e3Sopenharmony_ci } 664514f5e3Sopenharmony_ci it.Advance(); 674514f5e3Sopenharmony_ci sp_ = it.GetSp(); 684514f5e3Sopenharmony_ci AdvanceToJSFrame(); 694514f5e3Sopenharmony_ci} 704514f5e3Sopenharmony_ci 714514f5e3Sopenharmony_ciJSTaggedType* FrameHandler::GetPrevJSFrame() 724514f5e3Sopenharmony_ci{ 734514f5e3Sopenharmony_ci PrevJSFrame(); 744514f5e3Sopenharmony_ci return GetSp(); 754514f5e3Sopenharmony_ci} 764514f5e3Sopenharmony_ci 774514f5e3Sopenharmony_ciuint32_t FrameHandler::GetNumberArgs() 784514f5e3Sopenharmony_ci{ 794514f5e3Sopenharmony_ci if (thread_->IsAsmInterpreter()) { 804514f5e3Sopenharmony_ci auto *frame = AsmInterpretedFrame::GetFrameFromSp(sp_); 814514f5e3Sopenharmony_ci return static_cast<uint32_t>(frame->GetCurrentFramePointer() - sp_); 824514f5e3Sopenharmony_ci } 834514f5e3Sopenharmony_ci ASSERT(IsInterpretedFrame()); 844514f5e3Sopenharmony_ci JSTaggedType *prevSp = nullptr; 854514f5e3Sopenharmony_ci FrameIterator it(sp_, thread_); 864514f5e3Sopenharmony_ci if (IsAsmInterpretedFrame()) { 874514f5e3Sopenharmony_ci auto *frame = it.GetFrame<AsmInterpretedFrame>(); 884514f5e3Sopenharmony_ci prevSp = frame->GetPrevFrameFp(); 894514f5e3Sopenharmony_ci } else { 904514f5e3Sopenharmony_ci auto *frame = it.GetFrame<InterpretedFrame>(); 914514f5e3Sopenharmony_ci prevSp = frame->GetPrevFrameFp(); 924514f5e3Sopenharmony_ci } 934514f5e3Sopenharmony_ci auto prevSpEnd = reinterpret_cast<JSTaggedType*>(GetInterpretedFrameEnd(prevSp)); 944514f5e3Sopenharmony_ci return static_cast<uint32_t>(prevSpEnd - sp_); 954514f5e3Sopenharmony_ci} 964514f5e3Sopenharmony_ci 974514f5e3Sopenharmony_ciJSTaggedValue FrameHandler::GetVRegValue(size_t index) const 984514f5e3Sopenharmony_ci{ 994514f5e3Sopenharmony_ci ASSERT(IsInterpretedFrame()); 1004514f5e3Sopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 1014514f5e3Sopenharmony_ci return JSTaggedValue(sp_[index]); 1024514f5e3Sopenharmony_ci} 1034514f5e3Sopenharmony_ci 1044514f5e3Sopenharmony_civoid FrameHandler::SetVRegValue(size_t index, JSTaggedValue value) 1054514f5e3Sopenharmony_ci{ 1064514f5e3Sopenharmony_ci ASSERT(IsInterpretedFrame()); 1074514f5e3Sopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) 1084514f5e3Sopenharmony_ci sp_[index] = value.GetRawData(); 1094514f5e3Sopenharmony_ci} 1104514f5e3Sopenharmony_ci 1114514f5e3Sopenharmony_civoid FrameHandler::FindAndSetBaselineNativePc(FrameIterator it) 1124514f5e3Sopenharmony_ci{ 1134514f5e3Sopenharmony_ci ASSERT(IsBaselineBuiltinFrame(it.GetFrameType())); 1144514f5e3Sopenharmony_ci auto *frame = it.GetFrame<BaselineBuiltinFrame>(); 1154514f5e3Sopenharmony_ci baselineNativePc_ = frame->GetReturnAddr(); 1164514f5e3Sopenharmony_ci} 1174514f5e3Sopenharmony_ci 1184514f5e3Sopenharmony_ciJSTaggedValue FrameHandler::GetAcc() const 1194514f5e3Sopenharmony_ci{ 1204514f5e3Sopenharmony_ci ASSERT(IsInterpretedFrame()); 1214514f5e3Sopenharmony_ci FrameIterator it(sp_, thread_); 1224514f5e3Sopenharmony_ci if (IsAsmInterpretedFrame()) { 1234514f5e3Sopenharmony_ci auto *frame = it.GetFrame<AsmInterpretedFrame>(); 1244514f5e3Sopenharmony_ci return frame->acc; 1254514f5e3Sopenharmony_ci } else { 1264514f5e3Sopenharmony_ci auto *frame = it.GetFrame<InterpretedFrame>(); 1274514f5e3Sopenharmony_ci return frame->acc; 1284514f5e3Sopenharmony_ci } 1294514f5e3Sopenharmony_ci} 1304514f5e3Sopenharmony_ci 1314514f5e3Sopenharmony_ciuint32_t FrameHandler::GetBytecodeOffset() const 1324514f5e3Sopenharmony_ci{ 1334514f5e3Sopenharmony_ci ASSERT(IsInterpretedFrame()); 1344514f5e3Sopenharmony_ci Method *method = GetMethod(); 1354514f5e3Sopenharmony_ci auto offset = GetPc() - method->GetBytecodeArray(); 1364514f5e3Sopenharmony_ci return static_cast<uint32_t>(offset); 1374514f5e3Sopenharmony_ci} 1384514f5e3Sopenharmony_ci 1394514f5e3Sopenharmony_ciMethod *FrameHandler::GetMethod() const 1404514f5e3Sopenharmony_ci{ 1414514f5e3Sopenharmony_ci ASSERT(IsJSFrame()); 1424514f5e3Sopenharmony_ci auto function = GetFunction(); 1434514f5e3Sopenharmony_ci return ECMAObject::Cast(function.GetTaggedObject())->GetCallTarget(); 1444514f5e3Sopenharmony_ci} 1454514f5e3Sopenharmony_ci 1464514f5e3Sopenharmony_ciconst JSPandaFile* FrameHandler::GetJSPandaFile() const 1474514f5e3Sopenharmony_ci{ 1484514f5e3Sopenharmony_ci auto method = GetMethod(); 1494514f5e3Sopenharmony_ci return method->GetJSPandaFile(); 1504514f5e3Sopenharmony_ci} 1514514f5e3Sopenharmony_ci 1524514f5e3Sopenharmony_cistd::string FrameHandler::GetFileName() const 1534514f5e3Sopenharmony_ci{ 1544514f5e3Sopenharmony_ci auto pandaFile = GetJSPandaFile(); 1554514f5e3Sopenharmony_ci ASSERT(pandaFile != nullptr); 1564514f5e3Sopenharmony_ci return pandaFile->GetJSPandaFileDesc().c_str(); 1574514f5e3Sopenharmony_ci} 1584514f5e3Sopenharmony_ci 1594514f5e3Sopenharmony_ciuint32_t FrameHandler::GetAbcId() const 1604514f5e3Sopenharmony_ci{ 1614514f5e3Sopenharmony_ci std::string abcName = GetFileName(); 1624514f5e3Sopenharmony_ci pgo::PGOProfilerManager* pm = pgo::PGOProfilerManager::GetInstance(); 1634514f5e3Sopenharmony_ci uint32_t abcId; 1644514f5e3Sopenharmony_ci if (!pm->GetPandaFileId(CString(abcName), abcId) && !abcName.empty()) { 1654514f5e3Sopenharmony_ci LOG_ECMA(ERROR) << "Get method abc id failed. abcName: " << abcName; 1664514f5e3Sopenharmony_ci } 1674514f5e3Sopenharmony_ci return abcId; 1684514f5e3Sopenharmony_ci} 1694514f5e3Sopenharmony_ci 1704514f5e3Sopenharmony_ciuint32_t FrameHandler::GetMethodId() const 1714514f5e3Sopenharmony_ci{ 1724514f5e3Sopenharmony_ci return GetMethod()->GetMethodId().GetOffset(); 1734514f5e3Sopenharmony_ci} 1744514f5e3Sopenharmony_ci 1754514f5e3Sopenharmony_ciMethod *FrameHandler::CheckAndGetMethod() const 1764514f5e3Sopenharmony_ci{ 1774514f5e3Sopenharmony_ci ASSERT(IsJSFrame()); 1784514f5e3Sopenharmony_ci auto function = GetFunction(); 1794514f5e3Sopenharmony_ci if (function.IsJSFunctionBase() || function.IsJSProxy()) { 1804514f5e3Sopenharmony_ci return ECMAObject::Cast(function.GetTaggedObject())->GetCallTarget(); 1814514f5e3Sopenharmony_ci } 1824514f5e3Sopenharmony_ci return nullptr; 1834514f5e3Sopenharmony_ci} 1844514f5e3Sopenharmony_ci 1854514f5e3Sopenharmony_ciJSTaggedValue FrameHandler::GetThis() const 1864514f5e3Sopenharmony_ci{ 1874514f5e3Sopenharmony_ci ASSERT(IsInterpretedFrame()); 1884514f5e3Sopenharmony_ci FrameIterator it(sp_, thread_); 1894514f5e3Sopenharmony_ci if (IsAsmInterpretedFrame()) { 1904514f5e3Sopenharmony_ci auto *frame = it.GetFrame<AsmInterpretedFrame>(); 1914514f5e3Sopenharmony_ci return frame->thisObj; 1924514f5e3Sopenharmony_ci } else { 1934514f5e3Sopenharmony_ci auto *frame = it.GetFrame<InterpretedFrame>(); 1944514f5e3Sopenharmony_ci return frame->thisObj; 1954514f5e3Sopenharmony_ci } 1964514f5e3Sopenharmony_ci} 1974514f5e3Sopenharmony_ci 1984514f5e3Sopenharmony_ciJSTaggedValue FrameHandler::GetFunction() const 1994514f5e3Sopenharmony_ci{ 2004514f5e3Sopenharmony_ci ASSERT(IsJSFrame()); 2014514f5e3Sopenharmony_ci if (thread_->IsAsmInterpreter()) { 2024514f5e3Sopenharmony_ci FrameType type = GetFrameType(); 2034514f5e3Sopenharmony_ci switch (type) { 2044514f5e3Sopenharmony_ci case FrameType::ASM_INTERPRETER_FRAME: 2054514f5e3Sopenharmony_ci case FrameType::INTERPRETER_CONSTRUCTOR_FRAME: { 2064514f5e3Sopenharmony_ci auto frame = AsmInterpretedFrame::GetFrameFromSp(sp_); 2074514f5e3Sopenharmony_ci return frame->function; 2084514f5e3Sopenharmony_ci } 2094514f5e3Sopenharmony_ci case FrameType::BUILTIN_FRAME_WITH_ARGV: { 2104514f5e3Sopenharmony_ci auto *frame = BuiltinWithArgvFrame::GetFrameFromSp(sp_); 2114514f5e3Sopenharmony_ci return frame->GetFunction(); 2124514f5e3Sopenharmony_ci } 2134514f5e3Sopenharmony_ci case FrameType::BUILTIN_ENTRY_FRAME: 2144514f5e3Sopenharmony_ci case FrameType::BUILTIN_FRAME: { 2154514f5e3Sopenharmony_ci auto *frame = BuiltinFrame::GetFrameFromSp(sp_); 2164514f5e3Sopenharmony_ci return frame->GetFunction(); 2174514f5e3Sopenharmony_ci } 2184514f5e3Sopenharmony_ci case FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME: 2194514f5e3Sopenharmony_ci case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: { 2204514f5e3Sopenharmony_ci auto *frame = OptimizedJSFunctionFrame::GetFrameFromSp(sp_); 2214514f5e3Sopenharmony_ci return frame->GetFunction(); 2224514f5e3Sopenharmony_ci } 2234514f5e3Sopenharmony_ci case FrameType::FASTJIT_FUNCTION_FRAME: 2244514f5e3Sopenharmony_ci case FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME: { 2254514f5e3Sopenharmony_ci auto *frame = FASTJITFunctionFrame::GetFrameFromSp(sp_); 2264514f5e3Sopenharmony_ci return frame->GetFunction(); 2274514f5e3Sopenharmony_ci } 2284514f5e3Sopenharmony_ci case FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME : 2294514f5e3Sopenharmony_ci case FrameType::INTERPRETER_FRAME: 2304514f5e3Sopenharmony_ci case FrameType::INTERPRETER_FAST_NEW_FRAME: 2314514f5e3Sopenharmony_ci case FrameType::INTERPRETER_ENTRY_FRAME: 2324514f5e3Sopenharmony_ci case FrameType::ASM_INTERPRETER_ENTRY_FRAME: 2334514f5e3Sopenharmony_ci case FrameType::ASM_INTERPRETER_BRIDGE_FRAME: 2344514f5e3Sopenharmony_ci case FrameType::INTERPRETER_BUILTIN_FRAME: 2354514f5e3Sopenharmony_ci case FrameType::OPTIMIZED_FRAME: 2364514f5e3Sopenharmony_ci case FrameType::BASELINE_BUILTIN_FRAME: 2374514f5e3Sopenharmony_ci case FrameType::ASM_BRIDGE_FRAME: 2384514f5e3Sopenharmony_ci case FrameType::LEAVE_FRAME: 2394514f5e3Sopenharmony_ci case FrameType::LEAVE_FRAME_WITH_ARGV: 2404514f5e3Sopenharmony_ci case FrameType::BUILTIN_CALL_LEAVE_FRAME: 2414514f5e3Sopenharmony_ci case FrameType::OPTIMIZED_ENTRY_FRAME: 2424514f5e3Sopenharmony_ci default: { 2434514f5e3Sopenharmony_ci LOG_FULL(FATAL) << "frame type error!"; 2444514f5e3Sopenharmony_ci UNREACHABLE(); 2454514f5e3Sopenharmony_ci } 2464514f5e3Sopenharmony_ci } 2474514f5e3Sopenharmony_ci } else { 2484514f5e3Sopenharmony_ci FrameType type = GetFrameType(); 2494514f5e3Sopenharmony_ci if (type == FrameType::INTERPRETER_FRAME || type == FrameType::INTERPRETER_FAST_NEW_FRAME) { 2504514f5e3Sopenharmony_ci auto *frame = InterpretedFrame::GetFrameFromSp(sp_); 2514514f5e3Sopenharmony_ci return frame->function; 2524514f5e3Sopenharmony_ci } else { 2534514f5e3Sopenharmony_ci auto *frame = InterpretedBuiltinFrame::GetFrameFromSp(sp_); 2544514f5e3Sopenharmony_ci return frame->function; 2554514f5e3Sopenharmony_ci } 2564514f5e3Sopenharmony_ci } 2574514f5e3Sopenharmony_ci} 2584514f5e3Sopenharmony_ci 2594514f5e3Sopenharmony_ciconst uint8_t *FrameHandler::GetPc() const 2604514f5e3Sopenharmony_ci{ 2614514f5e3Sopenharmony_ci ASSERT(IsJSFrame()); 2624514f5e3Sopenharmony_ci FrameIterator it(sp_, thread_); 2634514f5e3Sopenharmony_ci if (IsAsmInterpretedFrame()) { 2644514f5e3Sopenharmony_ci auto *frame = it.GetFrame<AsmInterpretedFrame>(); 2654514f5e3Sopenharmony_ci return frame->GetPc(); 2664514f5e3Sopenharmony_ci } else { 2674514f5e3Sopenharmony_ci auto *frame = it.GetFrame<InterpretedFrame>(); 2684514f5e3Sopenharmony_ci return frame->GetPc(); 2694514f5e3Sopenharmony_ci } 2704514f5e3Sopenharmony_ci} 2714514f5e3Sopenharmony_ci 2724514f5e3Sopenharmony_ciConstantPool *FrameHandler::GetConstpool() const 2734514f5e3Sopenharmony_ci{ 2744514f5e3Sopenharmony_ci ASSERT(IsInterpretedFrame()); 2754514f5e3Sopenharmony_ci auto method = GetMethod(); 2764514f5e3Sopenharmony_ci JSTaggedValue constpool = method->GetConstantPool(); 2774514f5e3Sopenharmony_ci return ConstantPool::Cast(constpool.GetTaggedObject()); 2784514f5e3Sopenharmony_ci} 2794514f5e3Sopenharmony_ci 2804514f5e3Sopenharmony_ciJSTaggedValue FrameHandler::GetEnv() const 2814514f5e3Sopenharmony_ci{ 2824514f5e3Sopenharmony_ci ASSERT(IsInterpretedFrame()); 2834514f5e3Sopenharmony_ci FrameIterator it(sp_, thread_); 2844514f5e3Sopenharmony_ci if (IsAsmInterpretedFrame()) { 2854514f5e3Sopenharmony_ci auto *frame = it.GetFrame<AsmInterpretedFrame>(); 2864514f5e3Sopenharmony_ci return frame->GetEnv(); 2874514f5e3Sopenharmony_ci } else { 2884514f5e3Sopenharmony_ci auto *frame = it.GetFrame<InterpretedFrame>(); 2894514f5e3Sopenharmony_ci return frame->env; 2904514f5e3Sopenharmony_ci } 2914514f5e3Sopenharmony_ci} 2924514f5e3Sopenharmony_ci 2934514f5e3Sopenharmony_civoid FrameHandler::DumpStack(std::ostream &os) const 2944514f5e3Sopenharmony_ci{ 2954514f5e3Sopenharmony_ci size_t i = 0; 2964514f5e3Sopenharmony_ci FrameHandler frameHandler(thread_); 2974514f5e3Sopenharmony_ci for (; frameHandler.HasFrame(); frameHandler.PrevJSFrame()) { 2984514f5e3Sopenharmony_ci os << "[" << i++ 2994514f5e3Sopenharmony_ci << "]:" << frameHandler.GetMethod()->ParseFunctionName() 3004514f5e3Sopenharmony_ci << "\n"; 3014514f5e3Sopenharmony_ci } 3024514f5e3Sopenharmony_ci} 3034514f5e3Sopenharmony_ci 3044514f5e3Sopenharmony_civoid FrameHandler::DumpPC(std::ostream &os, const uint8_t *pc) const 3054514f5e3Sopenharmony_ci{ 3064514f5e3Sopenharmony_ci FrameHandler frameHandler(thread_); 3074514f5e3Sopenharmony_ci ASSERT(frameHandler.HasFrame()); 3084514f5e3Sopenharmony_ci // NOLINTNEXTLINE(cppcoreguidelines-narrowing-conversions, bugprone-narrowing-conversions) 3094514f5e3Sopenharmony_ci int offset = pc - frameHandler.GetMethod()->GetBytecodeArray(); 3104514f5e3Sopenharmony_ci os << "offset: " << offset << "\n"; 3114514f5e3Sopenharmony_ci} 3124514f5e3Sopenharmony_ci 3134514f5e3Sopenharmony_ciARK_INLINE uintptr_t FrameHandler::GetInterpretedFrameEnd(JSTaggedType *prevSp) const 3144514f5e3Sopenharmony_ci{ 3154514f5e3Sopenharmony_ci uintptr_t end = 0U; 3164514f5e3Sopenharmony_ci FrameIterator it(prevSp, thread_); 3174514f5e3Sopenharmony_ci FrameType type = it.GetFrameType(); 3184514f5e3Sopenharmony_ci switch (type) { 3194514f5e3Sopenharmony_ci case FrameType::ASM_INTERPRETER_FRAME: 3204514f5e3Sopenharmony_ci case FrameType::INTERPRETER_CONSTRUCTOR_FRAME: { 3214514f5e3Sopenharmony_ci auto frame = it.GetFrame<AsmInterpretedFrame>(); 3224514f5e3Sopenharmony_ci end = ToUintPtr(frame); 3234514f5e3Sopenharmony_ci break; 3244514f5e3Sopenharmony_ci } 3254514f5e3Sopenharmony_ci case FrameType::INTERPRETER_FRAME: 3264514f5e3Sopenharmony_ci case FrameType::INTERPRETER_FAST_NEW_FRAME: { 3274514f5e3Sopenharmony_ci auto frame = it.GetFrame<InterpretedFrame>(); 3284514f5e3Sopenharmony_ci end = ToUintPtr(frame); 3294514f5e3Sopenharmony_ci break; 3304514f5e3Sopenharmony_ci } 3314514f5e3Sopenharmony_ci case FrameType::INTERPRETER_ENTRY_FRAME: { 3324514f5e3Sopenharmony_ci auto frame = it.GetFrame<InterpretedEntryFrame>(); 3334514f5e3Sopenharmony_ci end = ToUintPtr(frame); 3344514f5e3Sopenharmony_ci break; 3354514f5e3Sopenharmony_ci } 3364514f5e3Sopenharmony_ci case FrameType::INTERPRETER_BUILTIN_FRAME: { 3374514f5e3Sopenharmony_ci auto frame = it.GetFrame<InterpretedBuiltinFrame>(); 3384514f5e3Sopenharmony_ci end = ToUintPtr(frame); 3394514f5e3Sopenharmony_ci break; 3404514f5e3Sopenharmony_ci } 3414514f5e3Sopenharmony_ci case FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME : 3424514f5e3Sopenharmony_ci case FrameType::BUILTIN_FRAME_WITH_ARGV: 3434514f5e3Sopenharmony_ci case FrameType::BUILTIN_ENTRY_FRAME: 3444514f5e3Sopenharmony_ci case FrameType::BUILTIN_FRAME: 3454514f5e3Sopenharmony_ci case FrameType::OPTIMIZED_FRAME: 3464514f5e3Sopenharmony_ci case FrameType::ASM_BRIDGE_FRAME: 3474514f5e3Sopenharmony_ci case FrameType::LEAVE_FRAME: 3484514f5e3Sopenharmony_ci case FrameType::BASELINE_BUILTIN_FRAME: 3494514f5e3Sopenharmony_ci case FrameType::LEAVE_FRAME_WITH_ARGV: 3504514f5e3Sopenharmony_ci case FrameType::BUILTIN_CALL_LEAVE_FRAME: 3514514f5e3Sopenharmony_ci case FrameType::OPTIMIZED_ENTRY_FRAME: 3524514f5e3Sopenharmony_ci case FrameType::ASM_INTERPRETER_ENTRY_FRAME: 3534514f5e3Sopenharmony_ci case FrameType::ASM_INTERPRETER_BRIDGE_FRAME: 3544514f5e3Sopenharmony_ci default: { 3554514f5e3Sopenharmony_ci LOG_FULL(FATAL) << "frame type error!"; 3564514f5e3Sopenharmony_ci UNREACHABLE(); 3574514f5e3Sopenharmony_ci } 3584514f5e3Sopenharmony_ci } 3594514f5e3Sopenharmony_ci return end; 3604514f5e3Sopenharmony_ci} 3614514f5e3Sopenharmony_ci 3624514f5e3Sopenharmony_civoid FrameHandler::IterateAssembleStack(const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor, 3634514f5e3Sopenharmony_ci const RootBaseAndDerivedVisitor &derivedVisitor) 3644514f5e3Sopenharmony_ci{ 3654514f5e3Sopenharmony_ci JSTaggedType *current = const_cast<JSTaggedType *>(thread_->GetLastLeaveFrame()); 3664514f5e3Sopenharmony_ci IterateFrameChain(current, visitor, rangeVisitor, derivedVisitor); 3674514f5e3Sopenharmony_ci} 3684514f5e3Sopenharmony_ci 3694514f5e3Sopenharmony_ci// We seperate InterpretedEntryFrame from assemble stack when asm interpreter is enable. 3704514f5e3Sopenharmony_ci// To protect EcmaRuntimeCallInfo on InterpretedEntryFrame, we iterate InterpretedEntryFrame on thread sp individually. 3714514f5e3Sopenharmony_ci// And only InterpretedEntryFrame is on thread sp when asm interpreter is enable. 3724514f5e3Sopenharmony_civoid FrameHandler::IterateEcmaRuntimeCallInfo(const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) 3734514f5e3Sopenharmony_ci{ 3744514f5e3Sopenharmony_ci ASSERT(thread_->IsAsmInterpreter()); 3754514f5e3Sopenharmony_ci JSTaggedType *current = const_cast<JSTaggedType *>(thread_->GetCurrentSPFrame()); 3764514f5e3Sopenharmony_ci for (FrameIterator it(current, thread_); !it.Done(); it.Advance()) { 3774514f5e3Sopenharmony_ci ASSERT(it.GetFrameType() == FrameType::INTERPRETER_ENTRY_FRAME); 3784514f5e3Sopenharmony_ci auto frame = it.GetFrame<InterpretedEntryFrame>(); 3794514f5e3Sopenharmony_ci frame->GCIterate(it, visitor, rangeVisitor); 3804514f5e3Sopenharmony_ci } 3814514f5e3Sopenharmony_ci} 3824514f5e3Sopenharmony_ci 3834514f5e3Sopenharmony_civoid FrameHandler::Iterate(const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor, 3844514f5e3Sopenharmony_ci const RootBaseAndDerivedVisitor &derivedVisitor) 3854514f5e3Sopenharmony_ci{ 3864514f5e3Sopenharmony_ci if (thread_->IsAsmInterpreter()) { 3874514f5e3Sopenharmony_ci IterateEcmaRuntimeCallInfo(visitor, rangeVisitor); 3884514f5e3Sopenharmony_ci IterateAssembleStack(visitor, rangeVisitor, derivedVisitor); 3894514f5e3Sopenharmony_ci return; 3904514f5e3Sopenharmony_ci } 3914514f5e3Sopenharmony_ci JSTaggedType *current = const_cast<JSTaggedType *>(thread_->GetCurrentSPFrame()); 3924514f5e3Sopenharmony_ci FrameType frameType = FrameHandler::GetFrameType(current); 3934514f5e3Sopenharmony_ci if (frameType != FrameType::INTERPRETER_ENTRY_FRAME) { 3944514f5e3Sopenharmony_ci auto leaveFrame = const_cast<JSTaggedType *>(thread_->GetLastLeaveFrame()); 3954514f5e3Sopenharmony_ci if (leaveFrame != nullptr) { 3964514f5e3Sopenharmony_ci current = leaveFrame; 3974514f5e3Sopenharmony_ci } 3984514f5e3Sopenharmony_ci } 3994514f5e3Sopenharmony_ci // lazy assignment: only Iterate need arkStackMapParser_ in order to high improve performance 4004514f5e3Sopenharmony_ci if (arkStackMapParser_ == nullptr) { 4014514f5e3Sopenharmony_ci arkStackMapParser_ = 4024514f5e3Sopenharmony_ci const_cast<JSThread *>(thread_)->GetEcmaVM()->GetAOTFileManager()->GetStackMapParser(); 4034514f5e3Sopenharmony_ci } 4044514f5e3Sopenharmony_ci IterateFrameChain(current, visitor, rangeVisitor, derivedVisitor); 4054514f5e3Sopenharmony_ci} 4064514f5e3Sopenharmony_ci 4074514f5e3Sopenharmony_civoid FrameHandler::IterateFrameChain(JSTaggedType *start, const RootVisitor &visitor, 4084514f5e3Sopenharmony_ci const RootRangeVisitor &rangeVisitor, const RootBaseAndDerivedVisitor &derivedVisitor) const 4094514f5e3Sopenharmony_ci{ 4104514f5e3Sopenharmony_ci JSTaggedType *current = start; 4114514f5e3Sopenharmony_ci // if the current frame type is BASELINE_BUILTIN_FRAME, the upper frame must be BaselineFrame. 4124514f5e3Sopenharmony_ci // isBaselineFrame is used to differentiate the AsmInterpterFrame and BaselineFrame 4134514f5e3Sopenharmony_ci bool isBaselineFrame = false; 4144514f5e3Sopenharmony_ci for (FrameIterator it(current, thread_); !it.Done(); it.Advance<GCVisitedFlag::VISITED>()) { 4154514f5e3Sopenharmony_ci FrameType type = it.GetFrameType(); 4164514f5e3Sopenharmony_ci switch (type) { 4174514f5e3Sopenharmony_ci case FrameType::OPTIMIZED_FRAME: { 4184514f5e3Sopenharmony_ci auto frame = it.GetFrame<OptimizedFrame>(); 4194514f5e3Sopenharmony_ci frame->GCIterate(it, visitor, rangeVisitor, derivedVisitor); 4204514f5e3Sopenharmony_ci break; 4214514f5e3Sopenharmony_ci } 4224514f5e3Sopenharmony_ci case FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME: 4234514f5e3Sopenharmony_ci case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: { 4244514f5e3Sopenharmony_ci auto frame = it.GetFrame<OptimizedJSFunctionFrame>(); 4254514f5e3Sopenharmony_ci frame->GCIterate(it, visitor, rangeVisitor, derivedVisitor, type); 4264514f5e3Sopenharmony_ci break; 4274514f5e3Sopenharmony_ci } 4284514f5e3Sopenharmony_ci case FrameType::BASELINE_BUILTIN_FRAME: { 4294514f5e3Sopenharmony_ci isBaselineFrame = true; 4304514f5e3Sopenharmony_ci auto frame = it.GetFrame<BaselineBuiltinFrame>(); 4314514f5e3Sopenharmony_ci frame->GCIterate(it, visitor, rangeVisitor, derivedVisitor); 4324514f5e3Sopenharmony_ci break; 4334514f5e3Sopenharmony_ci } 4344514f5e3Sopenharmony_ci case FrameType::FASTJIT_FUNCTION_FRAME: 4354514f5e3Sopenharmony_ci case FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME: { 4364514f5e3Sopenharmony_ci auto frame = it.GetFrame<FASTJITFunctionFrame>(); 4374514f5e3Sopenharmony_ci frame->GCIterate(it, visitor, rangeVisitor, derivedVisitor, type); 4384514f5e3Sopenharmony_ci break; 4394514f5e3Sopenharmony_ci } 4404514f5e3Sopenharmony_ci case FrameType::ASM_INTERPRETER_FRAME: 4414514f5e3Sopenharmony_ci case FrameType::INTERPRETER_CONSTRUCTOR_FRAME: { 4424514f5e3Sopenharmony_ci auto frame = it.GetFrame<AsmInterpretedFrame>(); 4434514f5e3Sopenharmony_ci frame->GCIterate(it, visitor, rangeVisitor, derivedVisitor, isBaselineFrame); 4444514f5e3Sopenharmony_ci isBaselineFrame = false; 4454514f5e3Sopenharmony_ci break; 4464514f5e3Sopenharmony_ci } 4474514f5e3Sopenharmony_ci case FrameType::INTERPRETER_FRAME: 4484514f5e3Sopenharmony_ci case FrameType::INTERPRETER_FAST_NEW_FRAME: { 4494514f5e3Sopenharmony_ci auto frame = it.GetFrame<InterpretedFrame>(); 4504514f5e3Sopenharmony_ci frame->GCIterate(it, visitor, rangeVisitor); 4514514f5e3Sopenharmony_ci break; 4524514f5e3Sopenharmony_ci } 4534514f5e3Sopenharmony_ci case FrameType::INTERPRETER_BUILTIN_FRAME: { 4544514f5e3Sopenharmony_ci auto frame = it.GetFrame<InterpretedBuiltinFrame>(); 4554514f5e3Sopenharmony_ci frame->GCIterate(it, visitor, rangeVisitor); 4564514f5e3Sopenharmony_ci break; 4574514f5e3Sopenharmony_ci } 4584514f5e3Sopenharmony_ci case FrameType::LEAVE_FRAME: { 4594514f5e3Sopenharmony_ci auto frame = it.GetFrame<OptimizedLeaveFrame>(); 4604514f5e3Sopenharmony_ci frame->GCIterate(it, visitor, rangeVisitor); 4614514f5e3Sopenharmony_ci break; 4624514f5e3Sopenharmony_ci } 4634514f5e3Sopenharmony_ci case FrameType::LEAVE_FRAME_WITH_ARGV: { 4644514f5e3Sopenharmony_ci auto frame = it.GetFrame<OptimizedWithArgvLeaveFrame>(); 4654514f5e3Sopenharmony_ci frame->GCIterate(it, visitor, rangeVisitor); 4664514f5e3Sopenharmony_ci break; 4674514f5e3Sopenharmony_ci } 4684514f5e3Sopenharmony_ci case FrameType::BUILTIN_CALL_LEAVE_FRAME: { 4694514f5e3Sopenharmony_ci auto frame = it.GetFrame<OptimizedBuiltinLeaveFrame>(); 4704514f5e3Sopenharmony_ci frame->GCIterate(it, visitor, rangeVisitor); 4714514f5e3Sopenharmony_ci break; 4724514f5e3Sopenharmony_ci } 4734514f5e3Sopenharmony_ci case FrameType::BUILTIN_FRAME_WITH_ARGV: { 4744514f5e3Sopenharmony_ci auto frame = it.GetFrame<BuiltinWithArgvFrame>(); 4754514f5e3Sopenharmony_ci frame->GCIterate(it, visitor, rangeVisitor); 4764514f5e3Sopenharmony_ci break; 4774514f5e3Sopenharmony_ci } 4784514f5e3Sopenharmony_ci case FrameType::BUILTIN_ENTRY_FRAME: 4794514f5e3Sopenharmony_ci case FrameType::BUILTIN_FRAME: { 4804514f5e3Sopenharmony_ci auto frame = it.GetFrame<BuiltinFrame>(); 4814514f5e3Sopenharmony_ci frame->GCIterate(it, visitor, rangeVisitor); 4824514f5e3Sopenharmony_ci break; 4834514f5e3Sopenharmony_ci } 4844514f5e3Sopenharmony_ci case FrameType::INTERPRETER_ENTRY_FRAME: { 4854514f5e3Sopenharmony_ci auto frame = it.GetFrame<InterpretedEntryFrame>(); 4864514f5e3Sopenharmony_ci frame->GCIterate(it, visitor, rangeVisitor); 4874514f5e3Sopenharmony_ci break; 4884514f5e3Sopenharmony_ci } 4894514f5e3Sopenharmony_ci case FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME: 4904514f5e3Sopenharmony_ci case FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME: 4914514f5e3Sopenharmony_ci case FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME: 4924514f5e3Sopenharmony_ci case FrameType::OPTIMIZED_ENTRY_FRAME: 4934514f5e3Sopenharmony_ci case FrameType::ASM_BRIDGE_FRAME: 4944514f5e3Sopenharmony_ci case FrameType::ASM_INTERPRETER_ENTRY_FRAME: 4954514f5e3Sopenharmony_ci case FrameType::ASM_INTERPRETER_BRIDGE_FRAME: { 4964514f5e3Sopenharmony_ci break; 4974514f5e3Sopenharmony_ci } 4984514f5e3Sopenharmony_ci default: { 4994514f5e3Sopenharmony_ci LOG_FULL(FATAL) << "frame type error!"; 5004514f5e3Sopenharmony_ci UNREACHABLE(); 5014514f5e3Sopenharmony_ci } 5024514f5e3Sopenharmony_ci } 5034514f5e3Sopenharmony_ci } 5044514f5e3Sopenharmony_ci} 5054514f5e3Sopenharmony_ci} // namespace panda::ecmascript 506