• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ecmascript/frames.h"
17 
18 #include "ecmascript/dfx/stackinfo/js_stackinfo.h"
19 #include "ecmascript/ecma_context.h"
20 #include "ecmascript/stackmap/ark_stackmap_parser.h"
21 
22 namespace panda::ecmascript {
FrameIterator(JSTaggedType * sp,const JSThread * thread)23 FrameIterator::FrameIterator(JSTaggedType *sp, const JSThread *thread) : current_(sp), thread_(thread)
24 {
25     if (thread != nullptr) {
26         arkStackMapParser_ =
27             const_cast<JSThread *>(thread)->GetEcmaVM()->GetAOTFileManager()->GetStackMapParser();
28     }
29 }
30 
ComputeDelta(const Method * method) const31 int FrameIterator::ComputeDelta(const Method *method) const
32 {
33     if (method == nullptr || isJITFrame_) {
34         return fpDeltaPrevFrameSp_;
35     }
36     return method->GetFpDelta();
37 }
38 
CheckAndGetMethod() const39 Method *FrameIterator::CheckAndGetMethod() const
40 {
41     auto function = GetFunction();
42     if (function.CheckIsJSFunctionBase() || function.CheckIsJSProxy()) {
43         return ECMAObject::Cast(function.GetTaggedObject())->GetCallTarget();
44     }
45     return nullptr;
46 }
47 
GetFunction() const48 JSTaggedValue FrameIterator::GetFunction() const
49 {
50     FrameType type = GetFrameType();
51     switch (type) {
52         case FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME:
53         case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
54             auto frame = GetFrame<OptimizedJSFunctionFrame>();
55             return frame->GetFunction();
56         }
57         case FrameType::ASM_INTERPRETER_FRAME:
58         case FrameType::INTERPRETER_CONSTRUCTOR_FRAME: {
59             auto frame = GetFrame<AsmInterpretedFrame>();
60             return frame->function;
61         }
62         case FrameType::INTERPRETER_FRAME:
63         case FrameType::INTERPRETER_FAST_NEW_FRAME: {
64             auto frame = GetFrame<InterpretedFrame>();
65             return frame->function;
66         }
67         case FrameType::INTERPRETER_BUILTIN_FRAME: {
68             auto frame = GetFrame<InterpretedBuiltinFrame>();
69             return frame->function;
70         }
71         case FrameType::BUILTIN_FRAME_WITH_ARGV: {
72             auto *frame = BuiltinWithArgvFrame::GetFrameFromSp(GetSp());
73             return frame->GetFunction();
74         }
75         case FrameType::BUILTIN_ENTRY_FRAME:
76         case FrameType::BUILTIN_FRAME: {
77             auto *frame = BuiltinFrame::GetFrameFromSp(GetSp());
78             return frame->GetFunction();
79         }
80         case FrameType::BUILTIN_CALL_LEAVE_FRAME: {
81             auto *frame = OptimizedBuiltinLeaveFrame::GetFrameFromSp(GetSp());
82             return JSTaggedValue(*(frame->GetArgv()));
83         }
84         case FrameType::FASTJIT_FUNCTION_FRAME:
85         case FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME: {
86             auto frame = FASTJITFunctionFrame::GetFrameFromSp(GetSp());
87             return frame->GetFunction();
88         }
89         case FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME :
90         case FrameType::OPTIMIZED_FRAME:
91         case FrameType::OPTIMIZED_ENTRY_FRAME:
92         case FrameType::ASM_BRIDGE_FRAME:
93         case FrameType::LEAVE_FRAME:
94         case FrameType::BASELINE_BUILTIN_FRAME:
95         case FrameType::LEAVE_FRAME_WITH_ARGV:
96         case FrameType::INTERPRETER_ENTRY_FRAME:
97         case FrameType::ASM_INTERPRETER_ENTRY_FRAME:
98         case FrameType::ASM_INTERPRETER_BRIDGE_FRAME:
99         case FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME:
100         case FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME: {
101             return JSTaggedValue::Undefined();
102         }
103         default: {
104             LOG_FULL(FATAL) << "Unknown frame type: " << static_cast<uintptr_t>(type);
105             UNREACHABLE();
106         }
107     }
108 }
109 
TryCalCallSiteInfoFromMachineCode(uintptr_t retAddr) const110 AOTFileInfo::CallSiteInfo FrameIterator::TryCalCallSiteInfoFromMachineCode(uintptr_t retAddr) const
111 {
112     FrameType type = GetFrameType();
113     if (type == FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME ||
114         type == FrameType::OPTIMIZED_JS_FUNCTION_FRAME ||
115         type == FrameType::FASTJIT_FUNCTION_FRAME ||
116         type == FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME) {
117         auto machineCode = thread_->GetEcmaVM()->GetHeap()->GetMachineCodeObject(retAddr);
118         ASSERT(machineCode != nullptr);
119         const_cast<FrameIterator*>(this)->machineCode_ = reinterpret_cast<JSTaggedType>(machineCode);
120         return reinterpret_cast<MachineCode*>(machineCode_)->CalCallSiteInfo(retAddr);
121     }
122     return {};
123 }
124 
CalCallSiteInfo(uintptr_t retAddr,bool isDeopt) const125 std::pair<AOTFileInfo::CallSiteInfo, bool> FrameIterator::CalCallSiteInfo(uintptr_t retAddr, bool isDeopt) const
126 {
127     auto callSiteInfo = const_cast<JSThread *>(thread_)->GetCurrentEcmaContext()->CalCallSiteInfo(retAddr, isDeopt);
128     if (std::get<1>(callSiteInfo) != nullptr) { // 1 : stackMapAddr
129         return std::make_pair(callSiteInfo, false);
130     }
131     // try get jit code
132     callSiteInfo = TryCalCallSiteInfoFromMachineCode(retAddr);
133     return std::make_pair(callSiteInfo, true);
134 }
135 
136 template <GCVisitedFlag GCVisit>
Advance()137 void FrameIterator::Advance()
138 {
139     ASSERT(!Done());
140     FrameType t = GetFrameType();
141     bool needCalCallSiteInfo = false;
142     switch (t) {
143         case FrameType::OPTIMIZED_FRAME : {
144             auto frame = GetFrame<OptimizedFrame>();
145             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
146                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
147                           GCVisit == GCVisitedFlag::DEOPT) {
148                 optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
149                 optimizedReturnAddr_ = frame->GetReturnAddr();
150                 needCalCallSiteInfo = true;
151             }
152             current_ = frame->GetPrevFrameFp();
153             break;
154         }
155         case FrameType::OPTIMIZED_ENTRY_FRAME : {
156             auto frame = GetFrame<OptimizedEntryFrame>();
157             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
158                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
159                           GCVisit == GCVisitedFlag::DEOPT) {
160                 optimizedReturnAddr_ = 0;
161                 optimizedCallSiteSp_ = 0;
162             }
163             current_ = frame->GetPrevFrameFp();
164             break;
165         }
166         case FrameType::BASELINE_BUILTIN_FRAME: {
167             auto frame = GetFrame<BaselineBuiltinFrame>();
168             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
169                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
170                           GCVisit == GCVisitedFlag::DEOPT) {
171                 optimizedCallSiteSp_ = 0;
172                 optimizedReturnAddr_ = 0;
173             }
174             current_ = frame->GetPrevFrameFp();
175             break;
176         }
177         case FrameType::ASM_BRIDGE_FRAME : {
178             auto frame = GetFrame<AsmBridgeFrame>();
179             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
180                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
181                           GCVisit == GCVisitedFlag::DEOPT) {
182                 optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
183                 optimizedReturnAddr_ = frame->GetReturnAddr();
184                 needCalCallSiteInfo = true;
185             }
186             current_ = frame->GetPrevFrameFp();
187             break;
188         }
189         case FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME: {
190             auto frame = GetFrame<OptimizedJSFunctionUnfoldArgVFrame>();
191             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
192                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
193                           GCVisit == GCVisitedFlag::DEOPT) {
194                 optimizedCallSiteSp_ = frame->GetPrevFrameSp();
195                 optimizedReturnAddr_ = frame->GetReturnAddr();
196                 needCalCallSiteInfo = true;
197             }
198             current_ = frame->GetPrevFrameFp();
199             break;
200         }
201         case FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME: {
202             auto frame = GetFrame<OptimizedJSFunctionFrame>();
203             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
204                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
205                           GCVisit == GCVisitedFlag::DEOPT) {
206                 optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
207                 optimizedReturnAddr_ = frame->GetReturnAddr();
208                 needCalCallSiteInfo = true;
209             }
210             current_ = frame->GetPrevFrameFp();
211             break;
212         }
213         case FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME:
214         case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
215             auto frame = GetFrame<OptimizedJSFunctionFrame>();
216             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
217                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
218                           GCVisit == GCVisitedFlag::DEOPT) {
219                 optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
220                 optimizedReturnAddr_ = frame->GetReturnAddr();
221                 needCalCallSiteInfo = true;
222             }
223             current_ = frame->GetPrevFrameFp();
224             break;
225         }
226         case FrameType::LEAVE_FRAME : {
227             auto frame = GetFrame<OptimizedLeaveFrame>();
228             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
229                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
230                           GCVisit == GCVisitedFlag::DEOPT) {
231                 optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
232                 optimizedReturnAddr_ = frame->GetReturnAddr();
233                 needCalCallSiteInfo = true;
234             }
235             current_ = frame->GetPrevFrameFp();
236             break;
237         }
238         case FrameType::LEAVE_FRAME_WITH_ARGV : {
239             auto frame = GetFrame<OptimizedWithArgvLeaveFrame>();
240             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
241                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
242                           GCVisit == GCVisitedFlag::DEOPT) {
243                 optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
244                 optimizedReturnAddr_ = frame->GetReturnAddr();
245                 needCalCallSiteInfo = true;
246             }
247             current_ = frame->GetPrevFrameFp();
248             break;
249         }
250         case FrameType::BUILTIN_CALL_LEAVE_FRAME : {
251             auto frame = GetFrame<OptimizedBuiltinLeaveFrame>();
252             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
253                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
254                           GCVisit == GCVisitedFlag::DEOPT) {
255                 optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
256                 optimizedReturnAddr_ = frame->GetReturnAddr();
257                 needCalCallSiteInfo = true;
258             }
259             current_ = frame->GetPrevFrameFp();
260             break;
261         }
262         case FrameType::INTERPRETER_FRAME:
263         case FrameType::INTERPRETER_FAST_NEW_FRAME : {
264             auto frame = GetFrame<InterpretedFrame>();
265             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
266                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
267                           GCVisit == GCVisitedFlag::DEOPT) {
268                 optimizedReturnAddr_ = 0;
269                 optimizedCallSiteSp_ = 0;
270             }
271             current_ = frame->GetPrevFrameFp();
272             break;
273         }
274         case FrameType::INTERPRETER_BUILTIN_FRAME: {
275             auto frame = GetFrame<InterpretedBuiltinFrame>();
276             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
277                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
278                           GCVisit == GCVisitedFlag::DEOPT) {
279                 optimizedReturnAddr_ = 0;
280                 optimizedCallSiteSp_ = 0;
281             }
282             current_ = frame->GetPrevFrameFp();
283             break;
284         }
285         case FrameType::INTERPRETER_CONSTRUCTOR_FRAME:
286         case FrameType::ASM_INTERPRETER_FRAME : {
287             auto frame = GetFrame<AsmInterpretedFrame>();
288             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
289                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
290                           GCVisit == GCVisitedFlag::DEOPT) {
291                 optimizedReturnAddr_ = 0;
292                 optimizedCallSiteSp_ = 0;
293             }
294             current_ = frame->GetPrevFrameFp();
295             break;
296         }
297         case FrameType::BUILTIN_FRAME : {
298             auto frame = GetFrame<BuiltinFrame>();
299             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
300                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
301                           GCVisit == GCVisitedFlag::DEOPT) {
302                 optimizedReturnAddr_ = frame->GetReturnAddr();
303                 optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
304                 needCalCallSiteInfo = true;
305             }
306             current_ = frame->GetPrevFrameFp();
307             break;
308         }
309         case FrameType::BUILTIN_ENTRY_FRAME : {
310             auto frame = GetFrame<BuiltinFrame>();
311             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
312                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
313                           GCVisit == GCVisitedFlag::DEOPT) {
314                 optimizedReturnAddr_ = frame->GetReturnAddr();
315                 optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
316                 needCalCallSiteInfo = false;
317             }
318             current_ = frame->GetPrevFrameFp();
319             break;
320         }
321         case FrameType::BUILTIN_FRAME_WITH_ARGV : {
322             auto frame = GetFrame<BuiltinWithArgvFrame>();
323             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
324                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
325                           GCVisit == GCVisitedFlag::DEOPT) {
326                 optimizedReturnAddr_ = frame->GetReturnAddr();
327                 optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
328                 needCalCallSiteInfo = true;
329             }
330             current_ = frame->GetPrevFrameFp();
331             break;
332         }
333         case FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME : {
334             auto frame = GetFrame<BuiltinWithArgvFrame>();
335             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
336                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
337                           GCVisit == GCVisitedFlag::DEOPT) {
338                 optimizedReturnAddr_ = frame->GetReturnAddr();
339                 optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
340                 needCalCallSiteInfo = true;
341             }
342             current_ = frame->GetPrevFrameFp();
343             break;
344         }
345         case FrameType::INTERPRETER_ENTRY_FRAME : {
346             auto frame = GetFrame<InterpretedEntryFrame>();
347             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
348                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
349                           GCVisit == GCVisitedFlag::DEOPT) {
350                 optimizedReturnAddr_ = 0;
351                 optimizedCallSiteSp_ = 0;
352             }
353             current_ = frame->GetPrevFrameFp();
354             break;
355         }
356         case FrameType::ASM_INTERPRETER_ENTRY_FRAME : {
357             auto frame = GetFrame<AsmInterpretedEntryFrame>();
358             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
359                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
360                           GCVisit == GCVisitedFlag::DEOPT) {
361                 optimizedReturnAddr_ = 0;
362                 optimizedCallSiteSp_ = 0;
363             }
364             current_ = frame->GetPrevFrameFp();
365             break;
366         }
367         case FrameType::ASM_INTERPRETER_BRIDGE_FRAME : {
368             auto frame = GetFrame<AsmInterpretedBridgeFrame>();
369             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
370                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
371                           GCVisit == GCVisitedFlag::DEOPT) {
372                 optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
373                 optimizedReturnAddr_ = frame->GetReturnAddr();
374                 needCalCallSiteInfo = true;
375             }
376             current_ = frame->GetPrevFrameFp();
377             break;
378         }
379         case FrameType::FASTJIT_FUNCTION_FRAME:
380         case FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME: {
381             auto frame = GetFrame<FASTJITFunctionFrame>();
382             if constexpr (GCVisit == GCVisitedFlag::VISITED ||
383                           GCVisit == GCVisitedFlag::HYBRID_STACK ||
384                           GCVisit == GCVisitedFlag::DEOPT) {
385                 optimizedCallSiteSp_ = GetPrevFrameCallSiteSp();
386                 optimizedReturnAddr_ = frame->GetReturnAddr();
387                 needCalCallSiteInfo = true;
388             }
389             current_ = frame->GetPrevFrameFp();
390             break;
391         }
392         default: {
393             if constexpr (GCVisit == GCVisitedFlag::HYBRID_STACK) {
394                 current_ = nullptr;
395                 break;
396             }
397             LOG_ECMA(FATAL) << "this branch is unreachable";
398             UNREACHABLE();
399         }
400     }
401     if constexpr (GCVisit == GCVisitedFlag::VISITED ||
402                   GCVisit == GCVisitedFlag::HYBRID_STACK ||
403                   GCVisit == GCVisitedFlag::DEOPT) {
404         if (!needCalCallSiteInfo) {
405             return;
406         }
407         uint64_t textStart = 0;
408         AOTFileInfo::CallSiteInfo callSiteInfo;
409         if constexpr (GCVisit == GCVisitedFlag::DEOPT) {
410             std::tie(callSiteInfo, isJITFrame_) = CalCallSiteInfo(optimizedReturnAddr_, true);
411         } else {
412             std::tie(callSiteInfo, isJITFrame_) = CalCallSiteInfo(optimizedReturnAddr_, false);
413         }
414         std::tie(textStart, stackMapAddr_, fpDeltaPrevFrameSp_, calleeRegInfo_) = callSiteInfo;
415         ASSERT(optimizedReturnAddr_ >= textStart);
416         optimizedReturnAddr_ = optimizedReturnAddr_ - textStart;
417     }
418 }
419 template void FrameIterator::Advance<GCVisitedFlag::VISITED>();
420 template void FrameIterator::Advance<GCVisitedFlag::IGNORED>();
421 template void FrameIterator::Advance<GCVisitedFlag::HYBRID_STACK>();
422 template void FrameIterator::Advance<GCVisitedFlag::DEOPT>();
423 
GetPrevFrameCallSiteSp() const424 uintptr_t FrameIterator::GetPrevFrameCallSiteSp() const
425 {
426     if (Done()) {
427         return 0;
428     }
429     auto type = GetFrameType();
430     switch (type) {
431         case FrameType::LEAVE_FRAME: {
432             auto frame = GetFrame<OptimizedLeaveFrame>();
433             return frame->GetCallSiteSp();
434         }
435         case FrameType::LEAVE_FRAME_WITH_ARGV: {
436             auto frame = GetFrame<OptimizedWithArgvLeaveFrame>();
437             return frame->GetCallSiteSp();
438         }
439         case FrameType::BUILTIN_CALL_LEAVE_FRAME: {
440             auto frame = GetFrame<OptimizedBuiltinLeaveFrame>();
441             return frame->GetCallSiteSp();
442         }
443         case FrameType::BUILTIN_FRAME_WITH_ARGV: {
444             auto frame = GetFrame<BuiltinWithArgvFrame>();
445             return frame->GetCallSiteSp();
446         }
447         case FrameType::BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME: {
448             auto frame = GetFrame<BuiltinWithArgvFrame>();
449             return frame->GetCallSiteSp();
450         }
451         case FrameType::BUILTIN_FRAME: {
452             auto frame = GetFrame<BuiltinFrame>();
453             return frame->GetCallSiteSp();
454         }
455         case FrameType::ASM_INTERPRETER_BRIDGE_FRAME: {
456             auto frame = GetFrame<AsmInterpretedBridgeFrame>();
457             return frame->GetCallSiteSp();
458         }
459         case FrameType::OPTIMIZED_FRAME:
460         case FrameType::BASELINE_BUILTIN_FRAME:  // maybe we can store fpDelta somewhere else for these 2 cases
461         case FrameType::FASTJIT_FUNCTION_FRAME:
462         case FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME: {
463             ASSERT(thread_ != nullptr);
464             auto callSiteSp = reinterpret_cast<uintptr_t>(current_) + fpDeltaPrevFrameSp_;
465             return callSiteSp;
466         }
467         case FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME:
468         case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
469             ASSERT(thread_ != nullptr);
470             auto method = CheckAndGetMethod();
471             ASSERT(method != nullptr);
472             int delta = ComputeDelta(method);
473             auto callSiteSp = reinterpret_cast<uintptr_t>(current_) + delta;
474             return callSiteSp;
475         }
476         case FrameType::ASM_BRIDGE_FRAME: {
477             auto frame = GetFrame<AsmBridgeFrame>();
478             return frame->GetCallSiteSp();
479         }
480         case FrameType::OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME: {
481             auto frame = GetFrame<OptimizedJSFunctionUnfoldArgVFrame>();
482             return frame->GetPrevFrameSp();
483         }
484         case FrameType::OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME : {
485             auto callSiteSp = OptimizedJSFunctionFrame::ComputeArgsConfigFrameSp(current_);
486             return callSiteSp;
487         }
488         case FrameType::BUILTIN_ENTRY_FRAME:
489         case FrameType::ASM_INTERPRETER_FRAME:
490         case FrameType::INTERPRETER_CONSTRUCTOR_FRAME:
491         case FrameType::INTERPRETER_FRAME:
492         case FrameType::INTERPRETER_FAST_NEW_FRAME:
493         case FrameType::OPTIMIZED_ENTRY_FRAME:
494         case FrameType::INTERPRETER_BUILTIN_FRAME:
495         case FrameType::INTERPRETER_ENTRY_FRAME:
496         case FrameType::ASM_INTERPRETER_ENTRY_FRAME: {
497             break;
498         }
499         default: {
500             LOG_FULL(FATAL) << "Unknown frame type: " << static_cast<uintptr_t>(type);
501         }
502     }
503     return 0;
504 }
505 
GetInlinedMethodInfo()506 std::map<uint32_t, uint32_t> FrameIterator::GetInlinedMethodInfo()
507 {
508     std::map<uint32_t, uint32_t> inlineMethodInfos;
509     FrameType type = this->GetFrameType();
510     switch (type) {
511         case FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME:
512         case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
513             CollectMethodOffsetInfo(inlineMethodInfos);
514             break;
515         }
516         case FrameType::FASTJIT_FUNCTION_FRAME:
517         case FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME: {
518             CollectMethodOffsetInfo(inlineMethodInfos);
519             break;
520         }
521         default: {
522             break;
523         }
524     }
525     return inlineMethodInfos;
526 }
527 
GetBytecodeOffset() const528 uint32_t FrameIterator::GetBytecodeOffset() const
529 {
530     FrameType type = this->GetFrameType();
531     switch (type) {
532         case FrameType::ASM_INTERPRETER_FRAME:
533         case FrameType::INTERPRETER_CONSTRUCTOR_FRAME: {
534             auto *frame = this->GetFrame<AsmInterpretedFrame>();
535             Method *method = ECMAObject::Cast(frame->function.GetTaggedObject())->GetCallTarget();
536             auto offset = frame->GetPc() - method->GetBytecodeArray();
537             return static_cast<uint32_t>(offset);
538         }
539         case FrameType::INTERPRETER_FRAME:
540         case FrameType::INTERPRETER_FAST_NEW_FRAME: {
541             auto *frame = this->GetFrame<InterpretedFrame>();
542             Method *method = ECMAObject::Cast(frame->function.GetTaggedObject())->GetCallTarget();
543             auto offset = frame->GetPc() - method->GetBytecodeArray();
544             return static_cast<uint32_t>(offset);
545         }
546         case FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME:
547         case FrameType::OPTIMIZED_JS_FUNCTION_FRAME: {
548             auto frame = this->GetFrame<OptimizedJSFunctionFrame>();
549             ConstInfo constInfo;
550             frame->CollectPcOffsetInfo(*this, constInfo);
551             if (!constInfo.empty()) {
552                 return constInfo[0];
553             }
554             [[fallthrough]];
555         }
556         case FrameType::FASTJIT_FUNCTION_FRAME:
557         case FrameType::FASTJIT_FAST_CALL_FUNCTION_FRAME: {
558             auto frame = this->GetFrame<FASTJITFunctionFrame>();
559             ConstInfo constInfo;
560             frame->CollectPcOffsetInfo(*this, constInfo);
561             if (!constInfo.empty()) {
562                 return constInfo[0];
563             }
564             [[fallthrough]];
565         }
566         default: {
567             break;
568         }
569     }
570     return 0;
571 }
572 
GetPrevFrame() const573 uintptr_t FrameIterator::GetPrevFrame() const
574 {
575     FrameType type = GetFrameType();
576     uintptr_t end = 0U;
577     switch (type) {
578         case FrameType::INTERPRETER_FRAME:
579         case FrameType::INTERPRETER_FAST_NEW_FRAME: {
580             auto prevFrame = GetFrame<InterpretedFrame>();
581             end = ToUintPtr(prevFrame);
582             break;
583         }
584         case FrameType::INTERPRETER_ENTRY_FRAME: {
585             auto prevFrame = GetFrame<InterpretedEntryFrame>();
586             end = ToUintPtr(prevFrame);
587             break;
588         }
589         case FrameType::INTERPRETER_BUILTIN_FRAME: {
590             auto prevFrame = GetFrame<InterpretedBuiltinFrame>();
591             end = ToUintPtr(prevFrame);
592             break;
593         }
594         default: {
595             LOG_FULL(FATAL) << "Unknown frame type: " << static_cast<uintptr_t>(type);
596         }
597     }
598     return end;
599 }
600 
IteratorStackMap(const RootVisitor & visitor,const RootBaseAndDerivedVisitor & derivedVisitor) const601 bool FrameIterator::IteratorStackMap(const RootVisitor &visitor, const RootBaseAndDerivedVisitor &derivedVisitor) const
602 {
603     ASSERT(arkStackMapParser_ != nullptr);
604     if (!stackMapAddr_) {  // enter by assembler, no stack map
605         return true;
606     }
607 
608     return arkStackMapParser_->IteratorStackMap(visitor, derivedVisitor, optimizedReturnAddr_,
609         reinterpret_cast<uintptr_t>(current_), optimizedCallSiteSp_, stackMapAddr_);
610 }
611 
GCIterate(const FrameIterator & it,const RootVisitor & visitor,const RootRangeVisitor & rangeVisitor,const RootBaseAndDerivedVisitor & derivedVisitor) const612 ARK_INLINE void OptimizedFrame::GCIterate(const FrameIterator &it,
613     const RootVisitor &visitor,
614     [[maybe_unused]] const RootRangeVisitor &rangeVisitor,
615     const RootBaseAndDerivedVisitor &derivedVisitor) const
616 {
617     bool ret = it.IteratorStackMap(visitor, derivedVisitor);
618     if (!ret) {
619 #ifndef NDEBUG
620         LOG_ECMA(DEBUG) << " stackmap don't found returnAddr " << it.GetOptimizedReturnAddr();
621 #endif
622     }
623 }
624 
GCIterate(const FrameIterator & it,const RootVisitor & visitor,const RootRangeVisitor & rangeVisitor,const RootBaseAndDerivedVisitor & derivedVisitor) const625 ARK_INLINE void BaselineBuiltinFrame::GCIterate([[maybe_unused]]const FrameIterator &it,
626     [[maybe_unused]]const RootVisitor &visitor,
627     [[maybe_unused]] const RootRangeVisitor &rangeVisitor,
628     [[maybe_unused]]const RootBaseAndDerivedVisitor &derivedVisitor) const
629 {
630     bool ret = it.IteratorStackMap(visitor, derivedVisitor);
631     if (!ret) {
632 #ifndef NDEBUG
633         LOG_ECMA(DEBUG) << " stackmap don't found returnAddr " << it.GetOptimizedReturnAddr();
634 #endif
635     }
636 }
637 
CollectPcOffsetInfo(ConstInfo & info) const638 void FrameIterator::CollectPcOffsetInfo(ConstInfo &info) const
639 {
640     arkStackMapParser_->GetConstInfo(optimizedReturnAddr_, info, stackMapAddr_);
641 }
642 
CollectMethodOffsetInfo(std::map<uint32_t,uint32_t> & info) const643 void FrameIterator::CollectMethodOffsetInfo(std::map<uint32_t, uint32_t> &info) const
644 {
645     arkStackMapParser_->GetMethodOffsetInfo(optimizedReturnAddr_, info, stackMapAddr_);
646 }
647 
CollectArkDeopt(std::vector<kungfu::ARKDeopt> & deopts) const648 void FrameIterator::CollectArkDeopt(std::vector<kungfu::ARKDeopt>& deopts) const
649 {
650     arkStackMapParser_->GetArkDeopt(optimizedReturnAddr_, stackMapAddr_, deopts);
651 }
652 
GetArgv(const FrameIterator & it) const653 ARK_INLINE JSTaggedType* OptimizedJSFunctionFrame::GetArgv(const FrameIterator &it) const
654 {
655     uintptr_t *preFrameSp = ComputePrevFrameSp(it);
656     return GetArgv(preFrameSp);
657 }
658 
ComputePrevFrameSp(const FrameIterator & it) const659 ARK_INLINE uintptr_t* OptimizedJSFunctionFrame::ComputePrevFrameSp(const FrameIterator &it) const
660 {
661     const JSTaggedType *sp = it.GetSp();
662     Method *method = it.CheckAndGetMethod();
663     ASSERT(method != nullptr);
664     int delta = it.ComputeDelta(method);
665     ASSERT((delta > 0) && (delta % sizeof(uintptr_t) == 0));
666     uintptr_t *preFrameSp = reinterpret_cast<uintptr_t *>(const_cast<JSTaggedType *>(sp)) + delta / sizeof(uintptr_t);
667     return preFrameSp;
668 }
669 
CollectPcOffsetInfo(const FrameIterator & it,ConstInfo & info) const670 void OptimizedJSFunctionFrame::CollectPcOffsetInfo(const FrameIterator &it, ConstInfo &info) const
671 {
672     it.CollectPcOffsetInfo(info);
673 }
674 
GCIterate(const FrameIterator & it,const RootVisitor & visitor,const RootRangeVisitor & rangeVisitor,const RootBaseAndDerivedVisitor & derivedVisitor,FrameType frameType) const675 ARK_INLINE void OptimizedJSFunctionFrame::GCIterate(const FrameIterator &it,
676     const RootVisitor &visitor,
677     [[maybe_unused]] const RootRangeVisitor &rangeVisitor,
678     const RootBaseAndDerivedVisitor &derivedVisitor, FrameType frameType) const
679 {
680     OptimizedJSFunctionFrame *frame = OptimizedJSFunctionFrame::GetFrameFromSp(it.GetSp());
681     uintptr_t *jsFuncPtr = reinterpret_cast<uintptr_t *>(frame);
682     uintptr_t jsFuncSlot = ToUintPtr(jsFuncPtr);
683     visitor(Root::ROOT_FRAME, ObjectSlot(jsFuncSlot));
684     if (frameType == FrameType::OPTIMIZED_JS_FUNCTION_FRAME) {
685         uintptr_t *preFrameSp = frame->ComputePrevFrameSp(it);
686         auto argc = frame->GetArgc(preFrameSp);
687         JSTaggedType *argv = frame->GetArgv(reinterpret_cast<uintptr_t *>(preFrameSp));
688         if (argc > 0) {
689             uintptr_t start = ToUintPtr(argv); // argv
690             uintptr_t end = ToUintPtr(argv + argc);
691             rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
692         }
693     }
694 
695     auto machineCodeSlot = ObjectSlot(ToUintPtr(it.GetMachineCodeSlot()));
696     if (machineCodeSlot.GetTaggedType() != JSTaggedValue::VALUE_UNDEFINED) {
697         visitor(Root::ROOT_FRAME, machineCodeSlot);
698     }
699 
700     bool ret = it.IteratorStackMap(visitor, derivedVisitor);
701     if (!ret) {
702 #ifndef NDEBUG
703         LOG_ECMA(DEBUG) << " stackmap don't found returnAddr " << it.GetOptimizedReturnAddr();
704 #endif
705     }
706 }
707 
GetDeoptBundleInfo(const FrameIterator & it,std::vector<kungfu::ARKDeopt> & deopts) const708 void OptimizedJSFunctionFrame::GetDeoptBundleInfo(const FrameIterator &it, std::vector<kungfu::ARKDeopt>& deopts) const
709 {
710     it.CollectArkDeopt(deopts);
711 }
712 
GetFuncCalleeRegAndOffset(const FrameIterator & it,kungfu::CalleeRegAndOffsetVec & ret) const713 void OptimizedJSFunctionFrame::GetFuncCalleeRegAndOffset(
714     const FrameIterator &it, kungfu::CalleeRegAndOffsetVec &ret) const
715 {
716     it.GetCalleeRegAndOffsetVec(ret);
717 }
718 
GetArgv(const FrameIterator & it) const719 ARK_INLINE JSTaggedType* FASTJITFunctionFrame::GetArgv(const FrameIterator &it) const
720 {
721     uintptr_t *preFrameSp = ComputePrevFrameSp(it);
722     return GetArgv(preFrameSp);
723 }
724 
ComputePrevFrameSp(const FrameIterator & it) const725 ARK_INLINE uintptr_t* FASTJITFunctionFrame::ComputePrevFrameSp(const FrameIterator &it) const
726 {
727     const JSTaggedType *sp = it.GetSp();
728     int delta = it.ComputeDelta();
729     ASSERT((delta > 0) && (delta % sizeof(uintptr_t) == 0));
730     uintptr_t *preFrameSp = reinterpret_cast<uintptr_t *>(const_cast<JSTaggedType *>(sp)) + delta / sizeof(uintptr_t);
731     return preFrameSp;
732 }
733 
CollectPcOffsetInfo(const FrameIterator & it,ConstInfo & info) const734 void FASTJITFunctionFrame::CollectPcOffsetInfo(const FrameIterator &it, ConstInfo &info) const
735 {
736     it.CollectPcOffsetInfo(info);
737 }
738 
GCIterate(const FrameIterator & it,const RootVisitor & visitor,const RootRangeVisitor & rangeVisitor,const RootBaseAndDerivedVisitor & derivedVisitor,FrameType frameType) const739 ARK_INLINE void FASTJITFunctionFrame::GCIterate(const FrameIterator &it,
740     const RootVisitor &visitor,
741     [[maybe_unused]] const RootRangeVisitor &rangeVisitor,
742     const RootBaseAndDerivedVisitor &derivedVisitor, FrameType frameType) const
743 {
744     FASTJITFunctionFrame *frame = FASTJITFunctionFrame::GetFrameFromSp(it.GetSp());
745     uintptr_t jsFuncSlot = GetFuncAddrFromSp(it.GetSp());
746     visitor(Root::ROOT_FRAME, ObjectSlot(jsFuncSlot));
747     if (frameType == FrameType::FASTJIT_FUNCTION_FRAME) {
748         uintptr_t *preFrameSp = frame->ComputePrevFrameSp(it);
749         auto argc = frame->GetArgc(preFrameSp);
750         JSTaggedType *argv = frame->GetArgv(reinterpret_cast<uintptr_t *>(preFrameSp));
751         if (argc > 0) {
752             uintptr_t start = ToUintPtr(argv); // argv
753             uintptr_t end = ToUintPtr(argv + argc);
754             rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
755         }
756     }
757 
758     auto machineCodeSlot = ObjectSlot(ToUintPtr(it.GetMachineCodeSlot()));
759     if (machineCodeSlot.GetTaggedType() != JSTaggedValue::VALUE_UNDEFINED) {
760         visitor(Root::ROOT_FRAME, machineCodeSlot);
761     }
762 
763     bool ret = it.IteratorStackMap(visitor, derivedVisitor);
764     if (!ret) {
765 #ifndef NDEBUG
766         LOG_ECMA(DEBUG) << " stackmap don't found returnAddr " << it.GetOptimizedReturnAddr();
767 #endif
768     }
769 }
770 
GetDeoptBundleInfo(const FrameIterator & it,std::vector<kungfu::ARKDeopt> & deopts) const771 void FASTJITFunctionFrame::GetDeoptBundleInfo(const FrameIterator &it, std::vector<kungfu::ARKDeopt>& deopts) const
772 {
773     it.CollectArkDeopt(deopts);
774 }
775 
GetFuncCalleeRegAndOffset(const FrameIterator & it,kungfu::CalleeRegAndOffsetVec & ret) const776 void FASTJITFunctionFrame::GetFuncCalleeRegAndOffset(
777     const FrameIterator &it, kungfu::CalleeRegAndOffsetVec &ret) const
778 {
779     it.GetCalleeRegAndOffsetVec(ret);
780 }
781 
GCIterate(const FrameIterator & it,const RootVisitor & visitor,const RootRangeVisitor & rangeVisitor,const RootBaseAndDerivedVisitor & derivedVisitor,bool isBaselineFrame) const782 ARK_INLINE void AsmInterpretedFrame::GCIterate(const FrameIterator &it,
783     const RootVisitor &visitor,
784     const RootRangeVisitor &rangeVisitor,
785     const RootBaseAndDerivedVisitor &derivedVisitor,
786     bool isBaselineFrame) const
787 {
788     AsmInterpretedFrame *frame = AsmInterpretedFrame::GetFrameFromSp(it.GetSp());
789     uintptr_t start = ToUintPtr(it.GetSp());
790     uintptr_t end = ToUintPtr(frame->GetCurrentFramePointer());
791     rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
792     visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->function)));
793     visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->thisObj)));
794     if (frame->pc != nullptr || isBaselineFrame) {
795         visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->acc)));
796         visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->env)));
797     }
798 
799     if (isBaselineFrame) {
800         return;
801     }
802     bool ret = it.IteratorStackMap(visitor, derivedVisitor);
803     if (!ret) {
804 #ifndef NDEBUG
805         LOG_ECMA(DEBUG) << " stackmap don't found returnAddr " << it.GetOptimizedReturnAddr();
806 #endif
807     }
808 }
809 
GCIterate(const FrameIterator & it,const RootVisitor & visitor,const RootRangeVisitor & rangeVisitor) const810 ARK_INLINE void InterpretedFrame::GCIterate(const FrameIterator &it,
811                                             const RootVisitor &visitor,
812                                             const RootRangeVisitor &rangeVisitor) const
813 {
814     auto sp = it.GetSp();
815     InterpretedFrame *frame = InterpretedFrame::GetFrameFromSp(sp);
816     if (frame->function.IsHole()) {
817         return;
818     }
819 
820     JSTaggedType *prevSp = frame->GetPrevFrameFp();
821     uintptr_t start = ToUintPtr(sp);
822     const JSThread *thread = it.GetThread();
823     FrameIterator prevIt(prevSp, thread);
824     uintptr_t end = prevIt.GetPrevFrame();
825 
826     rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
827     visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->function)));
828     visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->thisObj)));
829 
830     // pc == nullptr, init InterpretedFrame & native InterpretedFrame.
831     if (frame->pc != nullptr) {
832         visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->acc)));
833         visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->constpool)));
834         visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->env)));
835         visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->profileTypeInfo)));
836     }
837 }
838 
GCIterate(const FrameIterator & it,const RootVisitor & visitor,const RootRangeVisitor & rangeVisitor) const839 ARK_INLINE void InterpretedBuiltinFrame::GCIterate(const FrameIterator &it,
840                                                    const RootVisitor &visitor,
841                                                    const RootRangeVisitor &rangeVisitor) const
842 {
843     auto sp = it.GetSp();
844     InterpretedBuiltinFrame *frame = InterpretedBuiltinFrame::GetFrameFromSp(sp);
845     JSTaggedType *prevSp = frame->GetPrevFrameFp();
846     const JSThread *thread = it.GetThread();
847     FrameIterator prevIt(prevSp, thread);
848 
849     uintptr_t start = ToUintPtr(sp + 2); // 2: numArgs & thread.
850     uintptr_t end = prevIt.GetPrevFrame();
851     rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
852     visitor(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->function)));
853 }
854 
GCIterate(const FrameIterator & it,const RootVisitor & visitor,const RootRangeVisitor & rangeVisitor) const855 ARK_INLINE void OptimizedLeaveFrame::GCIterate(const FrameIterator &it,
856     [[maybe_unused]] const RootVisitor &visitor,
857     const RootRangeVisitor &rangeVisitor) const
858 {
859     const JSTaggedType *sp = it.GetSp();
860     OptimizedLeaveFrame *frame = OptimizedLeaveFrame::GetFrameFromSp(sp);
861     if (frame->argc > 0) {
862         JSTaggedType *argv = reinterpret_cast<JSTaggedType *>(&frame->argc + 1);
863         uintptr_t start = ToUintPtr(argv); // argv
864         uintptr_t end = ToUintPtr(argv + frame->argc);
865         rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
866     }
867 }
868 
GCIterate(const FrameIterator & it,const RootVisitor & visitor,const RootRangeVisitor & rangeVisitor) const869 ARK_INLINE void OptimizedWithArgvLeaveFrame::GCIterate(const FrameIterator &it,
870     [[maybe_unused]] const RootVisitor &visitor,
871     const RootRangeVisitor &rangeVisitor) const
872 {
873     const JSTaggedType *sp = it.GetSp();
874     OptimizedWithArgvLeaveFrame *frame = OptimizedWithArgvLeaveFrame::GetFrameFromSp(sp);
875     if (frame->argc > 0) {
876         uintptr_t* argvPtr = reinterpret_cast<uintptr_t *>(&frame->argc + 1);
877         JSTaggedType *argv = reinterpret_cast<JSTaggedType *>(*argvPtr);
878         uintptr_t start = ToUintPtr(argv); // argv
879         uintptr_t end = ToUintPtr(argv + frame->argc);
880         rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
881     }
882 }
883 
GCIterate(const FrameIterator & it,const RootVisitor & visitor,const RootRangeVisitor & rangeVisitor) const884 ARK_INLINE void OptimizedBuiltinLeaveFrame::GCIterate(const FrameIterator &it,
885     [[maybe_unused]] const RootVisitor &visitor,
886     const RootRangeVisitor &rangeVisitor) const
887 {
888     const JSTaggedType *sp = it.GetSp();
889     OptimizedBuiltinLeaveFrame *frame = OptimizedBuiltinLeaveFrame::GetFrameFromSp(sp);
890     if (frame->argc > 0) {
891         JSTaggedType *argv = reinterpret_cast<JSTaggedType *>(&frame->argc + 1);
892         uintptr_t start = ToUintPtr(argv); // argv
893         uintptr_t end = ToUintPtr(argv + frame->argc);
894         rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
895     }
896 }
897 
GCIterate(const FrameIterator & it,const RootVisitor & visitor,const RootRangeVisitor & rangeVisitor) const898 ARK_INLINE void BuiltinWithArgvFrame::GCIterate(const FrameIterator &it,
899     [[maybe_unused]] const RootVisitor &visitor,
900     const RootRangeVisitor &rangeVisitor) const
901 {
902     const JSTaggedType *sp = it.GetSp();
903     auto frame = BuiltinWithArgvFrame::GetFrameFromSp(sp);
904     auto argc = static_cast<uint32_t>(frame->GetNumArgs()) + NUM_MANDATORY_JSFUNC_ARGS;
905     JSTaggedType *argv = reinterpret_cast<JSTaggedType *>(frame->GetStackArgsAddress());
906     uintptr_t start = ToUintPtr(argv);
907     uintptr_t end = ToUintPtr(argv + argc);
908     rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
909 }
910 
GCIterate(const FrameIterator & it,const RootVisitor & visitor,const RootRangeVisitor & rangeVisitor) const911 ARK_INLINE void BuiltinFrame::GCIterate(const FrameIterator &it,
912     const RootVisitor &visitor,
913     const RootRangeVisitor &rangeVisitor) const
914 {
915     const JSTaggedType *sp = it.GetSp();
916     auto frame = BuiltinFrame::GetFrameFromSp(sp);
917     // no need to visit stack map for entry frame
918     if (frame->type == FrameType::BUILTIN_ENTRY_FRAME) {
919         // only visit function
920         visitor(Root::ROOT_FRAME, ObjectSlot(frame->GetStackArgsAddress()));
921         return;
922     }
923     JSTaggedType *argv = reinterpret_cast<JSTaggedType *>(frame->GetStackArgsAddress());
924     auto argc = frame->GetNumArgs();
925     uintptr_t start = ToUintPtr(argv);
926     uintptr_t end = ToUintPtr(argv + argc);
927     rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
928 }
929 
GCIterate(const FrameIterator & it,const RootVisitor & visitor,const RootRangeVisitor & rangeVisitor) const930 ARK_INLINE void InterpretedEntryFrame::GCIterate(const FrameIterator &it,
931     [[maybe_unused]] const RootVisitor &visitor,
932     const RootRangeVisitor &rangeVisitor) const
933 {
934     const JSTaggedType* sp = it.GetSp();
935     InterpretedEntryFrame *frame = InterpretedEntryFrame::GetFrameFromSp(sp);
936     JSTaggedType *prevSp = frame->GetPrevFrameFp();
937     if (prevSp == nullptr) {
938         return;
939     }
940 
941     const JSThread *thread = it.GetThread();
942     FrameIterator prevIt(prevSp, thread);
943     uintptr_t start = ToUintPtr(sp + 2); // 2: numArgs & thread.
944     uintptr_t end = prevIt.GetPrevFrame();
945     rangeVisitor(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
946 }
947 }  // namespace panda::ecmascript
948