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