• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 #ifndef ECMASCRIPT_FRAMES_H
17 #define ECMASCRIPT_FRAMES_H
18 
19 #include "ecmascript/base/aligned_struct.h"
20 #include "ecmascript/js_tagged_value.h"
21 #include "ecmascript/mem/visitor.h"
22 #include "ecmascript/method.h"
23 #include "ecmascript/stackmap/ark_stackmap.h"
24 #include "ecmascript/stackmap/llvm_stackmap_type.h"
25 
26 namespace panda::ecmascript {
27 class JSThread;
28 class EcmaVM;
29 class FrameIterator;
30 namespace kungfu {
31     class ArkStackMapParser;
32 };
33 
34 // Here list all scenarios of calling between Runtime/CInterpreter/ASMInterpreter/AOTCompiler/CBuiltin/ASMBuitlin.
35 // Please note that the "[]" means a must frame while "<>" means an optional frame. Each case is from top to down.
36 //
37 // * Runtime (C++) => CInterpreter:
38 //          1) [INTERPRETER_FRAME]
39 //
40 // * Runtime (C++) -> AOTCompiler:
41 //          1) [OPTIMIZED_ENTRY_FRAME]
42 //             <OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME>
43 //             <OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME>
44 //             [OPTIMIZED_JS_FUNCTION_FRAME]
45 //
46 // * Runtime (C++) => ASMInterpreter:
47 //          1) [INTERPRETER_ENTRY_FRAME][ASM_INTERPRETER_FRAME]
48 //
49 // * Runtime (C++) => CBuiltin:
50 //          1) [not supported]
51 //
52 // * Runtime (C++) => ASMBuiltin:
53 //          1) [not supported]
54 //
55 // * CInterpreter => CInterpreter:
56 //          1) [INTERPRETER_FRAME]
57 //
58 // * CInterpreter => Runtime (C++):
59 //          1) [INTERPRETER_FAST_NEW_FRAME]
60 //          2) [INTERPRETER_CONSTRUCTOR_FRAME]
61 //
62 // * CInterpreter => AOTCompiler:
63 //          1) [not supported]
64 //
65 // * CInterperter => CBuiltin:
66 //          1) [INTERPRETER_BUILTIN_FRAME]
67 //
68 // * CInterpreter => ASMBuiltin:
69 //          1) [not supported]
70 //
71 // * ASMInterpreter => Runtime (C++):
72 //          1) [LEAVE_FRAME]
73 //          2) [LEAVE_FRAME_WITH_ARGV]
74 //
75 // * ASMInterpreter => AOTCompiler:
76 //          1) [OPTIMIZED_ENTRY_FRAME]
77 //             <OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME>
78 //             <OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME>
79 //             [OPTIMIZED_JS_FUNCTION_FRAME]
80 //
81 // * ASMInterpreter => ASMInterpreter:
82 //          1) [ASM_INTERPRETER_FRAME]
83 //
84 // * ASMInterpreter => AsmBuiltin:
85 //          1) [BUILTIN_ENTRY_FRAME]
86 //             [BUILTIN_FRAME]
87 //          2) [BUILTIN_ENTRY_FRAME]
88 //             [BUILTIN_FRAME_WITH_ARGV]
89 //
90 // * ASMInterpreter => CBuiltin:
91 //          1) [LEAVE_FRAME]
92 //          2) [LEAVE_FRAME_WITH_ARGV]
93 //
94 // * AOTCompiler => Runtime (C++):
95 //          1) [LEAVE_FRAME]
96 //          2) [LEAVE_FRAME_WITH_ARGV]
97 //
98 // * AOTCompiler => ASMInterpreter:
99 //          1) [ASM_INTERPRETER_BRIDGE_FRAME]
100 //          2) [ASM_INTERPRETER_FRAME]
101 //
102 // * AOTCompiler => CBuiltin:
103 //          1) [LEAVE_FRAME]
104 //          2) [LEAVE_FRAME_WITH_ARGV]
105 //
106 // * AOTCompiler => ASMBuiltin:
107 //          1) [BUILTIN_ENTRY_FRAME]
108 //             [BUILTIN_FRAME]
109 //          2) [BUILTIN_ENTRY_FRAME]
110 //             [BUILTIN_FRAME_WITH_ARGV]
111 
112 
113 enum class FrameType: uintptr_t {
114     OPTIMIZED_FRAME = 0,
115     OPTIMIZED_ENTRY_FRAME,
116     OPTIMIZED_JS_FUNCTION_FRAME,
117     OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME,
118     ASM_BRIDGE_FRAME,
119     LEAVE_FRAME,
120     LEAVE_FRAME_WITH_ARGV,
121     BUILTIN_CALL_LEAVE_FRAME,
122     INTERPRETER_FRAME,
123     ASM_INTERPRETER_FRAME,
124     INTERPRETER_CONSTRUCTOR_FRAME,
125     BUILTIN_FRAME,
126     BUILTIN_FRAME_WITH_ARGV,
127     BUILTIN_ENTRY_FRAME,
128     INTERPRETER_BUILTIN_FRAME,
129     INTERPRETER_FAST_NEW_FRAME,
130     INTERPRETER_ENTRY_FRAME,
131     ASM_INTERPRETER_ENTRY_FRAME,
132     ASM_INTERPRETER_BRIDGE_FRAME,
133     OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME,
134     OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME,
135     BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME,
136 
137     FRAME_TYPE_FIRST = OPTIMIZED_FRAME,
138     FRAME_TYPE_LAST = OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME,
139     INTERPRETER_FIRST = INTERPRETER_FRAME,
140     INTERPRETER_LAST = INTERPRETER_FAST_NEW_FRAME,
141     BUILTIN_FIRST = BUILTIN_FRAME,
142     BUILTIN_LAST = BUILTIN_ENTRY_FRAME,
143 };
144 
145 enum class JSCallMode : uintptr_t {
146     CALL_ARG0 = 0,
147     CALL_ARG1,
148     CALL_ARG2,
149     CALL_ARG3,
150     CALL_THIS_ARG0,
151     CALL_THIS_ARG1,
152     CALL_THIS_ARG2,
153     CALL_THIS_ARG3,
154     CALL_WITH_ARGV,
155     CALL_THIS_WITH_ARGV,
156     CALL_CONSTRUCTOR_WITH_ARGV,
157     DEPRECATED_CALL_ARG0,
158     DEPRECATED_CALL_ARG1,
159     DEPRECATED_CALL_ARG2,
160     DEPRECATED_CALL_ARG3,
161     DEPRECATED_CALL_WITH_ARGV,
162     DEPRECATED_CALL_THIS_WITH_ARGV,
163     DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV,
164     CALL_GETTER,
165     CALL_SETTER,
166     CALL_THIS_ARG3_WITH_RETURN,
167     CALL_THIS_ARGV_WITH_RETURN,
168     CALL_ENTRY,
169     CALL_GENERATOR,
170     CALL_FROM_AOT,
171 };
172 
173 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
174 struct OptimizedFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
175                                                    base::AlignedPointer,
176                                                    base::AlignedPointer,
177                                                    base::AlignedPointer> {
178 public:
179     void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor,
180         const RootBaseAndDerivedVisitor &derivedVisitor) const;
181 
182     static size_t GetTypeOffset(bool isArch32 = false)
183     {
184         return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
185     }
186 
187     static size_t GetPrevOffset(bool isArch32 = false)
188     {
189         return GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
190     }
191 
ComputeReservedSizeOptimizedFrame192     static size_t ComputeReservedSize(size_t slotSize)
193     {
194         size_t slotOffset = static_cast<size_t>(Index::PrevFpIndex) - static_cast<size_t>(Index::TypeIndex);
195         return slotSize * slotOffset;
196     }
197 
GetTypeOptimizedFrame198     FrameType GetType() const
199     {
200         return type;
201     }
202 private:
203     enum class Index : size_t {
204         TypeIndex = 0,
205         PrevFpIndex,
206         ReturnAddrIndex,
207         NumOfMembers
208     };
209     static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
210 
GetFrameFromSpOptimizedFrame211     static OptimizedFrame* GetFrameFromSp(const JSTaggedType *sp)
212     {
213         return reinterpret_cast<OptimizedFrame *>(reinterpret_cast<uintptr_t>(sp) -
214             MEMBER_OFFSET(OptimizedFrame, prevFp));
215     }
GetPrevFrameFpOptimizedFrame216     inline JSTaggedType* GetPrevFrameFp()
217     {
218         return prevFp;
219     }
GetReturnAddrOptimizedFrame220     uintptr_t GetReturnAddr() const
221     {
222         return returnAddr;
223     }
224 
225     alignas(EAS) FrameType type {0};
226     alignas(EAS) JSTaggedType *prevFp {nullptr};
227     alignas(EAS) uintptr_t returnAddr {0};
228     friend class FrameIterator;
229 };
230 STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedFrame), OptimizedFrame::SizeArch32, OptimizedFrame::SizeArch64);
231 
232 struct AsmBridgeFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
233                                                    base::AlignedPointer,
234                                                    base::AlignedPointer,
235                                                    base::AlignedPointer> {
236 public:
237     static size_t GetTypeOffset(bool isArch32 = false)
238     {
239         return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
240     }
241 
242     static size_t GetPrevOffset(bool isArch32 = false)
243     {
244         return GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
245     }
246 
GetCallSiteSpAsmBridgeFrame247     uintptr_t GetCallSiteSp() const
248     {
249         return ToUintPtr(this) + sizeof(AsmBridgeFrame);
250     }
251 
GetTypeAsmBridgeFrame252     FrameType GetType() const
253     {
254         return type;
255     }
256 
257 private:
258     enum class Index : size_t {
259         TypeIndex = 0,
260         PrevFpIndex,
261         ReturnAddrIndex,
262         NumOfMembers
263     };
264     static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
265 
GetFrameFromSpAsmBridgeFrame266     static AsmBridgeFrame* GetFrameFromSp(const JSTaggedType *sp)
267     {
268         return reinterpret_cast<AsmBridgeFrame *>(reinterpret_cast<uintptr_t>(sp) -
269             MEMBER_OFFSET(AsmBridgeFrame, prevFp));
270     }
GetPrevFrameFpAsmBridgeFrame271     inline JSTaggedType* GetPrevFrameFp()
272     {
273         return prevFp;
274     }
GetReturnAddrAsmBridgeFrame275     uintptr_t GetReturnAddr() const
276     {
277         return returnAddr;
278     }
279     alignas(EAS) FrameType type {0};
280     alignas(EAS) JSTaggedType *prevFp {nullptr};
281     alignas(EAS) uintptr_t returnAddr {0};
282     friend class FrameIterator;
283 };
284 STATIC_ASSERT_EQ_ARCH(sizeof(AsmBridgeFrame), AsmBridgeFrame::SizeArch32, AsmBridgeFrame::SizeArch64);
285 
286 // * OptimizedUnfoldArgVFrame layout description as the following:
287 //      sp ----> |--------------------------| ---------------
288 //               |       returnAddr         |               ^
289 //  currentFp--> |--------------------------|               |
290 //               |       prevFp             |               |
291 //               |--------------------------|   OptimizedUnfoldArgVFrame
292 //               |       frameType          |               |
293 //               |--------------------------|               |
294 //               |       currentFp          |               v
295 //               +--------------------------+ ---------------
296 //
297 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
298 struct OptimizedJSFunctionUnfoldArgVFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
299                                                                        base::AlignedPointer,
300                                                                        base::AlignedPointer,
301                                                                        base::AlignedPointer,
302                                                                        base::AlignedPointer> {
303 public:
304     static size_t GetTypeOffset(bool isArch32 = false)
305     {
306         return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
307     }
308 
309     static size_t GetPrevOffset(bool isArch32 = false)
310     {
311         return GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
312     }
313 
GetTypeOptimizedJSFunctionUnfoldArgVFrame314     FrameType GetType() const
315     {
316         return type;
317     }
318 
319 private:
320     enum class Index : size_t {
321         CallSiteSpIndex = 0,
322         TypeIndex,
323         PrevFpIndex,
324         ReturnAddrIndex,
325         NumOfMembers
326     };
327     static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
328 
GetFrameFromSpOptimizedJSFunctionUnfoldArgVFrame329     static OptimizedJSFunctionUnfoldArgVFrame* GetFrameFromSp(const JSTaggedType *sp)
330     {
331         return reinterpret_cast<OptimizedJSFunctionUnfoldArgVFrame *>(reinterpret_cast<uintptr_t>(sp) -
332             MEMBER_OFFSET(OptimizedJSFunctionUnfoldArgVFrame, prevFp));
333     }
GetPrevFrameFpOptimizedJSFunctionUnfoldArgVFrame334     inline JSTaggedType* GetPrevFrameFp() const
335     {
336         return prevFp;
337     }
GetReturnAddrOptimizedJSFunctionUnfoldArgVFrame338     uintptr_t GetReturnAddr() const
339     {
340         return returnAddr;
341     }
GetPrevFrameSpOptimizedJSFunctionUnfoldArgVFrame342     uintptr_t GetPrevFrameSp() const
343     {
344         return callSiteSp;
345     }
346     alignas(EAS) uintptr_t callSiteSp {0};
347     alignas(EAS) FrameType type {0};
348     alignas(EAS) JSTaggedType *prevFp {nullptr};
349     alignas(EAS) uintptr_t returnAddr {0};
350     friend class FrameIterator;
351 };
352 STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedJSFunctionUnfoldArgVFrame),
353     OptimizedJSFunctionUnfoldArgVFrame::SizeArch32, OptimizedJSFunctionUnfoldArgVFrame::SizeArch64);
354 
355 // * The OptimizedJSFunctionArgsConfig Frame's structure is illustrated as the following:
356 //          +--------------------------+
357 //          |         arg[N-1]         |
358 //          +--------------------------+
359 //          |         . . . .          |
360 //          +--------------------------+
361 //          |         arg[0]           |
362 //          +--------------------------+
363 //          |         argC             |
364 //  sp ---> +--------------------------+ -----------------
365 //          |                          |                 ^
366 //          |        prevFP            |                 |
367 //          |--------------------------|    OptimizedJSFunctionArgsConfigFrame
368 //          |       frameType          |                 |
369 //          |                          |                 V
370 //          +--------------------------+ -----------------
371 //
372 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
373 struct OptimizedJSFunctionArgConfigFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
374                                                                       base::AlignedPointer,
375                                                                       base::AlignedPointer> {
376 public:
377     static size_t GetTypeOffset(bool isArch32 = false)
378     {
379         return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
380     }
381 
382     static size_t GetPrevOffset(bool isArch32 = false)
383     {
384         return GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
385     }
386 
GetTypeOptimizedJSFunctionArgConfigFrame387     FrameType GetType() const
388     {
389         return type;
390     }
391 
392 private:
393     enum class Index : size_t {
394         TypeIndex = 0,
395         PrevFpIndex,
396         NumOfMembers
397     };
398     static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
399 
GetFrameFromSpOptimizedJSFunctionArgConfigFrame400     static OptimizedJSFunctionArgConfigFrame* GetFrameFromSp(const JSTaggedType *sp)
401     {
402         return reinterpret_cast<OptimizedJSFunctionArgConfigFrame *>(reinterpret_cast<uintptr_t>(sp) -
403             MEMBER_OFFSET(OptimizedJSFunctionArgConfigFrame, prevFp));
404     }
GetPrevFrameFpOptimizedJSFunctionArgConfigFrame405     inline JSTaggedType* GetPrevFrameFp()
406     {
407         return prevFp;
408     }
409 
410     alignas(EAS) FrameType type {0};
411     alignas(EAS) JSTaggedType *prevFp {nullptr};
412     friend class FrameIterator;
413 };
414 STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedJSFunctionArgConfigFrame),
415                       OptimizedJSFunctionArgConfigFrame::SizeArch32,
416                       OptimizedJSFunctionArgConfigFrame::SizeArch64);
417 
418 // * OptimizedJSFunctionFrame layout description as the following:
419 //               +--------------------------+
420 //               |        arg[N-1]          |
421 //               +--------------------------+
422 //               |       ...                |
423 //               +--------------------------+
424 //               |       arg[1]             |
425 //               +--------------------------+
426 //               |       arg[0]             |
427 //               +--------------------------+
428 //               |       this               |
429 //               +--------------------------+
430 //               |       new-target         |
431 //               +--------------------------+
432 //               |       call-target        |
433 //               |--------------------------|
434 //               |       argc               |
435 //      sp ----> |--------------------------| ---------------
436 //               |       returnAddr         |               ^
437 //               |--------------------------|               |
438 //               |       callsiteFp         |               |
439 //               |--------------------------|   OptimizedJSFunctionFrame
440 //               |       frameType          |               |
441 //               |--------------------------|               |
442 //               |       call-target        |               v
443 //               +--------------------------+ ---------------
444 //
445 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
446 struct OptimizedJSFunctionFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(),
447                                                              JSTaggedValue,
448                                                              base::AlignedPointer,
449                                                              base::AlignedPointer,
450                                                              base::AlignedPointer> {
451 public:
452     using ConstInfo = kungfu::LLVMStackMapType::ConstInfo;
453     enum class Index : size_t {
454         JSFuncIndex = 0,
455         TypeIndex,
456         PrevFpIndex,
457         ReturnAddrIndex,
458         NumOfMembers
459     };
460     static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
461 
GetFunctionDeltaReturnAddrOptimizedJSFunctionFrame462     static constexpr size_t GetFunctionDeltaReturnAddr()
463     {
464         return static_cast<size_t>(Index::ReturnAddrIndex) - static_cast<size_t>(Index::JSFuncIndex);
465     }
466 
GetPrevFrameFpOptimizedJSFunctionFrame467     inline JSTaggedType* GetPrevFrameFp()
468     {
469         return prevFp;
470     }
471 
GetArgvOptimizedJSFunctionFrame472     JSTaggedType* GetArgv(uintptr_t *preFrameSp) const
473     {
474         return reinterpret_cast<JSTaggedType *>(preFrameSp + sizeof(uint64_t) / sizeof(uintptr_t));
475     }
476 
GetArgcOptimizedJSFunctionFrame477     size_t GetArgc(uintptr_t *preFrameSp) const
478     {
479         return *preFrameSp;
480     }
481 
482     JSTaggedType* GetArgv(const FrameIterator &it) const;
483 
GetReturnAddrOptimizedJSFunctionFrame484     uintptr_t GetReturnAddr() const
485     {
486         return returnAddr;
487     }
488 
489     void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor,
490         const RootBaseAndDerivedVisitor &derivedVisitor, FrameType frameType) const;
491     void CollectPcOffsetInfo(const FrameIterator &it, ConstInfo &info) const;
492 
GetFunctionOptimizedJSFunctionFrame493     inline JSTaggedValue GetFunction() const
494     {
495         return jsFunc;
496     }
497 
ComputeArgsConfigFrameSpOptimizedJSFunctionFrame498     static uintptr_t ComputeArgsConfigFrameSp(JSTaggedType *fp)
499     {
500         const size_t offset = 2;  // 2: skip prevFp and return address.
501         return reinterpret_cast<uintptr_t>(fp) + offset * sizeof(uintptr_t);
502     }
503 
504     static size_t GetTypeOffset(bool isArch32 = false)
505     {
506         return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
507     }
508 
509     static size_t GetPrevOffset(bool isArch32 = false)
510     {
511         return GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
512     }
513 
ComputeReservedJSFuncOffsetOptimizedJSFunctionFrame514     static size_t ComputeReservedJSFuncOffset(size_t slotSize)
515     {
516         size_t slotOffset = static_cast<size_t>(Index::PrevFpIndex) - static_cast<size_t>(Index::JSFuncIndex);
517         return slotSize * slotOffset;
518     }
519 
GetTypeOptimizedJSFunctionFrame520     FrameType GetType() const
521     {
522         return type;
523     }
524 
525     friend class FrameIterator;
526     friend class FrameHandler;
527     void GetDeoptBundleInfo(const FrameIterator &it, std::vector<kungfu::ARKDeopt>& deopts) const;
528     void GetFuncCalleeRegAndOffset(
529         const FrameIterator &it, kungfu::CalleeRegAndOffsetVec &ret) const;
530     uintptr_t* ComputePrevFrameSp(const FrameIterator &it) const;
531 
532 private:
GetFrameFromSpOptimizedJSFunctionFrame533     static OptimizedJSFunctionFrame* GetFrameFromSp(const JSTaggedType *sp)
534     {
535         return reinterpret_cast<OptimizedJSFunctionFrame *>(reinterpret_cast<uintptr_t>(sp) -
536             MEMBER_OFFSET(OptimizedJSFunctionFrame, prevFp));
537     }
538 
539     // dynamic callee saveregisters for x86-64
540     alignas(EAS) JSTaggedValue jsFunc {JSTaggedValue::Undefined()};
541     alignas(EAS) FrameType type {0};
542     alignas(EAS) JSTaggedType *prevFp {nullptr};
543     alignas(EAS) uintptr_t returnAddr {0};
544     // dynamic callee saveregisters for arm64
545 };
546 STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedJSFunctionFrame),
547                       OptimizedJSFunctionFrame::SizeArch32,
548                       OptimizedJSFunctionFrame::SizeArch64);
549 // 2: return addr & prevFp, type and js function should be pairs to update type and js function at the same time.
550 static_assert((OptimizedJSFunctionFrame::GetFunctionDeltaReturnAddr() % 2) == 1);
551 
552 // * The JSFunctionEntry Frame's structure is illustrated as the following:
553 //          +--------------------------+
554 //          |      . . . . . .         |
555 //  sp ---> +--------------------------+ -----------------
556 //          |        prevFP            |                 ^
557 //          |--------------------------|                 |
558 //          |       frameType          |      JSFunctionEntryFrame
559 //          |--------------------------|                 |
560 //          |    preLeaveFrameFp       |                 v
561 //          +--------------------------+ -----------------
562 
563 struct OptimizedEntryFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
564                                                         base::AlignedPointer,
565                                                         base::AlignedPointer,
566                                                         base::AlignedPointer> {
567 public:
568     enum class CallType : size_t {
569         CALL_FUNC = 0,
570         CALL_NEW,
571     };
572 
573     enum class Index : size_t {
574         PreLeaveFrameFpIndex = 0,
575         TypeIndex,
576         PrevFpIndex,
577         NumOfMembers
578     };
579 
580     static size_t GetTypeOffset(bool isArch32 = false)
581     {
582         return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
583     }
584 
585     static size_t GetLeaveFrameFpOffset(bool isArch32 = false)
586     {
587         return GetOffset<static_cast<size_t>(Index::PreLeaveFrameFpIndex)>(isArch32);
588     }
589 
GetPrevFrameFpOptimizedEntryFrame590     inline JSTaggedType* GetPrevFrameFp()
591     {
592         return preLeaveFrameFp;
593     }
594 
ComputeReservedSizeOptimizedEntryFrame595     static size_t ComputeReservedSize(size_t slotSize)
596     {
597         size_t slotOffset = static_cast<size_t>(Index::PrevFpIndex) - static_cast<size_t>(Index::PreLeaveFrameFpIndex);
598         return slotSize * slotOffset;
599     }
600 
GetTypeOptimizedEntryFrame601     FrameType GetType() const
602     {
603         return type;
604     }
605     friend class FrameIterator;
606 
607 private:
GetFrameFromSpOptimizedEntryFrame608     static OptimizedEntryFrame* GetFrameFromSp(const JSTaggedType *sp)
609     {
610         return reinterpret_cast<OptimizedEntryFrame *>(reinterpret_cast<uintptr_t>(sp) -
611                                                        MEMBER_OFFSET(OptimizedEntryFrame, prevFp));
612     }
613 
GetLeaveFpOptimizedEntryFrame614     JSTaggedType* GetLeaveFp() const
615     {
616         return preLeaveFrameFp;
617     }
618 
GetPrevFpOptimizedEntryFrame619     JSTaggedType* GetPrevFp() const
620     {
621         return prevFp;
622     }
623 
624     alignas(EAS) JSTaggedType *preLeaveFrameFp {nullptr};
625     alignas(EAS) FrameType type {0};
626     alignas(EAS) JSTaggedType *prevFp {nullptr};
627 };
628 STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedEntryFrame), OptimizedEntryFrame::SizeArch32, OptimizedEntryFrame::SizeArch64);
629 
630 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
631 struct InterpretedFrameBase : public base::AlignedStruct<base::AlignedPointer::Size(),
632                                                          base::AlignedPointer,
633                                                          base::AlignedSize> {
634     enum class Index : size_t {
635         PrevIndex = 0,
636         TypeIndex,
637         NumOfMembers
638     };
639     static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
640 
GetPrevFrameFpInterpretedFrameBase641     inline JSTaggedType* GetPrevFrameFp()
642     {
643         return prev;
644     }
645 
GetFrameFromSpInterpretedFrameBase646     static InterpretedFrameBase* GetFrameFromSp(const JSTaggedType *sp)
647     {
648         return reinterpret_cast<InterpretedFrameBase *>(const_cast<JSTaggedType *>(sp)) - 1;
649     }
650 
651     static size_t GetPrevOffset(bool isArch32 = false)
652     {
653         return GetOffset<static_cast<size_t>(Index::PrevIndex)>(isArch32);
654     }
655 
656     static size_t GetTypeOffset(bool isArch32 = false)
657     {
658         return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
659     }
660 
GetSizeInterpretedFrameBase661     static constexpr size_t GetSize(bool isArch32)
662     {
663         return isArch32 ? InterpretedFrameBase::SizeArch32 : InterpretedFrameBase::SizeArch64;
664     }
665 
666     alignas(EAS) JSTaggedType *prev {nullptr}; // for llvm :c-fp ; for interrupt: thread-fp for gc
667     alignas(EAS) FrameType type {FrameType::OPTIMIZED_FRAME}; // 0
668 };
669 STATIC_ASSERT_EQ_ARCH(sizeof(InterpretedFrameBase),
670                       InterpretedFrameBase::SizeArch32,
671                       InterpretedFrameBase::SizeArch64);
672 
673 // Interpreter Frame Layout as the following:
674 //   +----------------------------------+
675 //   |    argv[n-1]                     |
676 //   |----------------------------------|
677 //   |    ......                        |
678 //   |----------------------------------|
679 //   |    thisArg [maybe not exist]     |
680 //   |----------------------------------|
681 //   |    newTarget [maybe not exist]   |
682 //   |----------------------------------|
683 //   |    ......                        |
684 //   |----------------------------------|
685 //   |    Vregs [not exist in native]   |
686 //   +----------------------------------+--------+
687 //   |    base.frameType                |        ^
688 //   |----------------------------------|        |
689 //   |    base.prev(prev stack pointer) |        |
690 //   |----------------------------------|        |
691 //   |    pc(bytecode addr)             |        |
692 //   |----------------------------------|        |
693 //   |    sp(current stack pointer)     |        |
694 //   |----------------------------------|        |
695 //   |    env                           |        |
696 //   |----------------------------------|        |
697 //   |    acc                           |        |
698 //   |----------------------------------|   InterpretedFrame
699 //   |    profileTypeInfo               |        |
700 //   |----------------------------------|        |
701 //   |    thisObj                       |        |
702 //   |----------------------------------|        |
703 //   |    function                      |        |
704 //   |----------------------------------|        |
705 //   |    constpool                     |        v
706 //   +----------------------------------+--------+
707 //
708 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
709 struct InterpretedFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(),
710                                                      JSTaggedValue,
711                                                      JSTaggedValue,
712                                                      JSTaggedValue,
713                                                      JSTaggedValue,
714                                                      JSTaggedValue,
715                                                      JSTaggedValue,
716                                                      base::AlignedPointer,
717                                                      InterpretedFrameBase> {
718 public:
719     enum class Index : size_t {
720         ConstPoolIndex = 0,
721         FunctionIndex,
722         ThisObjIndex,
723         ProFileTypeInfoIndex,
724         AccIndex,
725         EnvIndex,
726         PcIndex,
727         BaseIndex,
728         NumOfMembers
729     };
730     static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
731 
GetPrevFrameFpInterpretedFrame732     inline JSTaggedType* GetPrevFrameFp() const
733     {
734         return base.prev;
735     }
736 
GetFrameFromSpInterpretedFrame737     static InterpretedFrame* GetFrameFromSp(const JSTaggedType *sp)
738     {
739         return reinterpret_cast<InterpretedFrame *>(const_cast<JSTaggedType *>(sp)) - 1;
740     }
741 
GetPcInterpretedFrame742     inline const uint8_t *GetPc() const
743     {
744         return pc;
745     }
746 
GetEnvInterpretedFrame747     inline JSTaggedValue GetEnv() const
748     {
749         return env;
750     }
751 
NumOfMembersInterpretedFrame752     static uint32_t NumOfMembers()
753     {
754         return sizeof(InterpretedFrame) / JSTaggedValue::TaggedTypeSize();
755     }
756 
757     static size_t GetTypeOffset(bool isArch32 = false)
758     {
759         return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32) +
760             InterpretedFrameBase::GetTypeOffset(isArch32);
761     }
762 
763     static size_t GetPrevOffset(bool isArch32 = false)
764     {
765         return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32) +
766             InterpretedFrameBase::GetPrevOffset(isArch32);
767     }
768 
769     void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const;
770 
771     alignas(EAS) JSTaggedValue constpool {JSTaggedValue::Hole()};
772     alignas(EAS) JSTaggedValue function {JSTaggedValue::Hole()};
773     alignas(EAS) JSTaggedValue thisObj {JSTaggedValue::Hole()};
774     alignas(EAS) JSTaggedValue profileTypeInfo {JSTaggedValue::Hole()};
775     alignas(EAS) JSTaggedValue acc {JSTaggedValue::Hole()};
776     alignas(EAS) JSTaggedValue env {JSTaggedValue::Hole()};
777     alignas(EAS) const uint8_t *pc {nullptr};
778     alignas(EAS) InterpretedFrameBase base;
779     friend class FrameIterator;
780 };
781 STATIC_ASSERT_EQ_ARCH(sizeof(InterpretedFrame), InterpretedFrame::SizeArch32, InterpretedFrame::SizeArch64);
782 
783 // * InterpretedBuiltinFrame layout description as the following:
784 //               |--------------------------| ---------------
785 //               |         . . . . .        |               ^
786 //               |    InterpretedFrameBase  |               |
787 //               |         . . . . .        |               |
788 //               |--------------------------|    InterpretedBuiltinFrame
789 //               |       bytecode-PC        |               |
790 //               |--------------------------|               |
791 //               |       call-target        |               v
792 //               +--------------------------+ ---------------
793 //
794 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
795 struct InterpretedBuiltinFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(),
796                                                             JSTaggedValue,
797                                                             base::AlignedPointer,
798                                                             InterpretedFrameBase> {
799     enum class Index : size_t {
800         FunctionIndex = 0,
801         PcIndex,
802         BaseIndex,
803         NumOfMembers
804     };
805     static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
806 
GetPrevFrameFpInterpretedBuiltinFrame807     inline JSTaggedType* GetPrevFrameFp()
808     {
809         return base.prev;
810     }
811 
GetFrameFromSpInterpretedBuiltinFrame812     static InterpretedBuiltinFrame* GetFrameFromSp(const JSTaggedType *sp)
813     {
814         return reinterpret_cast<InterpretedBuiltinFrame *>(const_cast<JSTaggedType *>(sp)) - 1;
815     }
816 
NumOfMembersInterpretedBuiltinFrame817     static uint32_t NumOfMembers()
818     {
819         return sizeof(InterpretedBuiltinFrame) / JSTaggedValue::TaggedTypeSize();
820     }
821 
822     static size_t GetTypeOffset(bool isArch32 = false)
823     {
824         return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32) +
825             InterpretedFrameBase::GetTypeOffset(isArch32);
826     }
827 
828     static size_t GetPrevOffset(bool isArch32 = false)
829     {
830         return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32) +
831             InterpretedFrameBase::GetPrevOffset(isArch32);
832     }
833 
834     void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const;
835 
836     alignas(EAS) JSTaggedValue function {JSTaggedValue::Hole()};
837     alignas(EAS) const uint8_t *pc {nullptr};
838     alignas(EAS) InterpretedFrameBase base;
839 };
840 STATIC_ASSERT_EQ_ARCH(sizeof(InterpretedBuiltinFrame),
841                       InterpretedBuiltinFrame::SizeArch32,
842                       InterpretedBuiltinFrame::SizeArch64);
843 
844 // AsmInterpretedFrame Layout as the following:
845 //   +----------------------------------+
846 //   |    argv[n-1]                     |
847 //   |----------------------------------|
848 //   |    ......                        |
849 //   |----------------------------------|
850 //   |    thisArg [maybe not exist]     |
851 //   |----------------------------------|
852 //   |    newTarget [maybe not exist]   |
853 //   |----------------------------------|
854 //   |    ......                        |
855 //   |----------------------------------|
856 //   |    Vregs [not exist in native]   |
857 //   +----------------------------------+--------+
858 //   |        .  .  .   .               |        ^
859 //   |     InterpretedFrameBase         |        |
860 //   |        .  .  .   .               |        |
861 //   |----------------------------------|        |
862 //   |    pc(bytecode addr)             |        |
863 //   |----------------------------------|        |
864 //   |    sp(current stack pointer)     |        |
865 //   |----------------------------------|   AsmInterpretedFrame
866 //   |    callSize                      |        |
867 //   |----------------------------------|        |
868 //   |    env                           |        |
869 //   |----------------------------------|        |
870 //   |    acc                           |        |
871 //   |----------------------------------|        |
872 //   |    thisObj                       |        |
873 //   |----------------------------------|        |
874 //   |    call-target                   |        v
875 //   +----------------------------------+--------+
876 //
877 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
878 struct AsmInterpretedFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(),
879                                                         JSTaggedValue,
880                                                         JSTaggedValue,
881                                                         JSTaggedValue,
882                                                         JSTaggedValue,
883                                                         base::AlignedPointer,
884                                                         base::AlignedPointer,
885                                                         base::AlignedPointer,
886                                                         InterpretedFrameBase> {
887     enum class Index : size_t {
888         FunctionIndex = 0,
889         ThisObjIndex,
890         AccIndex,
891         EnvIndex,
892         CallSizeIndex,
893         FpIndex,
894         PcIndex,
895         BaseIndex,
896         NumOfMembers
897     };
898 
899     static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
900 
GetCurrentFramePointerAsmInterpretedFrame901     inline JSTaggedType* GetCurrentFramePointer()
902     {
903         return fp;
904     }
905 
GetPrevFrameFpAsmInterpretedFrame906     inline JSTaggedType* GetPrevFrameFp()
907     {
908         return base.prev;
909     }
910 
GetFrameFromSpAsmInterpretedFrame911     static AsmInterpretedFrame* GetFrameFromSp(const JSTaggedType *sp)
912     {
913         return reinterpret_cast<AsmInterpretedFrame *>(const_cast<JSTaggedType *>(sp)) - 1;
914     }
915 
GetFpOffsetAsmInterpretedFrame916     static size_t GetFpOffset(bool isArch32)
917     {
918         return GetOffset<static_cast<size_t>(Index::FpIndex)>(isArch32);
919     }
920 
GetCallSizeOffsetAsmInterpretedFrame921     static size_t GetCallSizeOffset(bool isArch32)
922     {
923         return GetOffset<static_cast<size_t>(Index::CallSizeIndex)>(isArch32);
924     }
925 
GetFunctionOffsetAsmInterpretedFrame926     static size_t GetFunctionOffset(bool isArch32)
927     {
928         return GetOffset<static_cast<size_t>(Index::FunctionIndex)>(isArch32);
929     }
930 
GetThisOffsetAsmInterpretedFrame931     static size_t GetThisOffset(bool isArch32)
932     {
933         return GetOffset<static_cast<size_t>(Index::ThisObjIndex)>(isArch32);
934     }
935 
GetAccOffsetAsmInterpretedFrame936     static size_t GetAccOffset(bool isArch32)
937     {
938         return GetOffset<static_cast<size_t>(Index::AccIndex)>(isArch32);
939     }
940 
GetEnvOffsetAsmInterpretedFrame941     static size_t GetEnvOffset(bool isArch32)
942     {
943         return GetOffset<static_cast<size_t>(Index::EnvIndex)>(isArch32);
944     }
945 
GetBaseOffsetAsmInterpretedFrame946     static size_t GetBaseOffset(bool isArch32)
947     {
948         return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32);
949     }
950 
GetPcOffsetAsmInterpretedFrame951     static size_t GetPcOffset(bool isArch32)
952     {
953         return GetOffset<static_cast<size_t>(Index::PcIndex)>(isArch32);
954     }
955 
GetSizeAsmInterpretedFrame956     static constexpr size_t GetSize(bool isArch32)
957     {
958         return isArch32 ? AsmInterpretedFrame::SizeArch32 : AsmInterpretedFrame::SizeArch64;
959     }
960 
NumOfMembersAsmInterpretedFrame961     static uint32_t NumOfMembers()
962     {
963         return sizeof(AsmInterpretedFrame) / JSTaggedValue::TaggedTypeSize();
964     }
965     void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor,
966         const RootBaseAndDerivedVisitor &derivedVisitor) const;
967 
GetEnvAsmInterpretedFrame968     JSTaggedValue GetEnv() const
969     {
970         return env;
971     }
972 
GetPcAsmInterpretedFrame973     const uint8_t *GetPc() const
974     {
975         return pc;
976     }
977 
GetTypeOffsetAsmInterpretedFrame978     static size_t GetTypeOffset()
979     {
980         return MEMBER_OFFSET(AsmInterpretedFrame, base) + MEMBER_OFFSET(InterpretedFrameBase, type);
981     }
982 
GetPrevOffsetAsmInterpretedFrame983     static size_t GetPrevOffset()
984     {
985         return MEMBER_OFFSET(AsmInterpretedFrame, base) + MEMBER_OFFSET(InterpretedFrameBase, prev);
986     }
987 
988     alignas(EAS) JSTaggedValue function {JSTaggedValue::Hole()};
989     alignas(EAS) JSTaggedValue thisObj {JSTaggedValue::Hole()};
990     alignas(EAS) JSTaggedValue acc {JSTaggedValue::Hole()};
991     alignas(EAS) JSTaggedValue env {JSTaggedValue::Hole()};
992     alignas(EAS) uintptr_t callSize {0};
993     alignas(EAS) JSTaggedType *fp {nullptr};
994     alignas(EAS) const uint8_t *pc {nullptr};
995     alignas(EAS) InterpretedFrameBase base;
996     // vregs, not exist in native
997     // args, may be truncated if not extra
998 };
999 STATIC_ASSERT_EQ_ARCH(sizeof(AsmInterpretedFrame), AsmInterpretedFrame::SizeArch32, AsmInterpretedFrame::SizeArch64);
1000 
1001 // InterpretedEntryFrame Layout as the following:
1002 //   +----------------------------------+---------------
1003 //   |        .  .  .   .               |              ^
1004 //   |     InterpretedFrameBase         |              |
1005 //   |        .  .  .   .               |    InterpretedEntryFrame
1006 //   |----------------------------------|              |
1007 //   |    pc(bytecode addr)             |              v
1008 //   |----------------------------------|---------------
1009 //
1010 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
1011 struct InterpretedEntryFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(),
1012                                                           base::AlignedPointer,
1013                                                           InterpretedFrameBase> {
1014     enum class Index : size_t {
1015         PcIndex = 0,
1016         BaseIndex,
1017         NumOfMembers
1018     };
1019     static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
1020 
GetPrevFrameFpInterpretedEntryFrame1021     inline JSTaggedType* GetPrevFrameFp()
1022     {
1023         return base.prev;
1024     }
1025 
GetFrameFromSpInterpretedEntryFrame1026     static InterpretedEntryFrame* GetFrameFromSp(const JSTaggedType *sp)
1027     {
1028         return reinterpret_cast<InterpretedEntryFrame *>(const_cast<JSTaggedType *>(sp)) - 1;
1029     }
1030 
NumOfMembersInterpretedEntryFrame1031     static uint32_t NumOfMembers()
1032     {
1033         return sizeof(InterpretedEntryFrame) / JSTaggedValue::TaggedTypeSize();
1034     }
1035 
1036     static size_t GetTypeOffset(bool isArch32 = false)
1037     {
1038         return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32) +
1039             InterpretedFrameBase::GetTypeOffset(isArch32);
1040     }
1041 
1042     static size_t GetPrevOffset(bool isArch32 = false)
1043     {
1044         return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32) +
1045             InterpretedFrameBase::GetPrevOffset(isArch32);
1046     }
1047 
1048     void GCIterate(const FrameIterator &it, const RootVisitor &visitor,
1049         const RootRangeVisitor &rangeVisitor) const;
1050     alignas(EAS) const uint8_t *pc {nullptr};
1051     alignas(EAS) InterpretedFrameBase base;
1052 };
1053 STATIC_ASSERT_EQ_ARCH(sizeof(InterpretedEntryFrame),
1054                       InterpretedEntryFrame::SizeArch32,
1055                       InterpretedEntryFrame::SizeArch64);
1056 
1057 
1058 // AsmInterpretedEntryFrame Layout as the following:
1059 //   +----------------------------------+---------------
1060 //   |        .  .  .   .               |              ^
1061 //   |     InterpretedFrameBase         |              |
1062 //   |        .  .  .   .               |    AsmInterpretedEntryFrame
1063 //   |----------------------------------|              |
1064 //   |    pc(bytecode addr)             |              v
1065 //   |----------------------------------|---------------
1066 //
1067 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
1068 struct AsmInterpretedEntryFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(),
1069                                                              base::AlignedPointer,
1070                                                              InterpretedFrameBase> {
1071     enum class Index : size_t {
1072         PcIndex = 0,
1073         BaseIndex,
1074         NumOfMembers
1075     };
1076     static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
1077 
GetPrevFrameFpAsmInterpretedEntryFrame1078     inline JSTaggedType* GetPrevFrameFp()
1079     {
1080         return base.prev;
1081     }
1082 
GetBaseOffsetAsmInterpretedEntryFrame1083     static size_t GetBaseOffset(bool isArch32)
1084     {
1085         return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32);
1086     }
1087 
GetFrameFromSpAsmInterpretedEntryFrame1088     static AsmInterpretedEntryFrame* GetFrameFromSp(const JSTaggedType *sp)
1089     {
1090         return reinterpret_cast<AsmInterpretedEntryFrame *>(const_cast<JSTaggedType *>(sp)) - 1;
1091     }
1092 
1093     static size_t GetTypeOffset(bool isArch32 = false)
1094     {
1095         return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32) +
1096             InterpretedFrameBase::GetTypeOffset(isArch32);
1097     }
1098 
1099     static size_t GetPrevOffset(bool isArch32 = false)
1100     {
1101         return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32) +
1102             InterpretedFrameBase::GetPrevOffset(isArch32);
1103     }
1104 
1105     alignas(EAS) const uint8_t *pc {nullptr};
1106     alignas(EAS) InterpretedFrameBase base;
1107 };
1108 
1109 // AsmInterpretedBridgeFrame Layout as the following:
1110 //   +----------------------------------+---------------
1111 //   |      ret-address                 |              ^
1112 //   |----------------------------------|              |
1113 //   |        .  .  .   .               |     AsmInterpretedBridgeFrame
1114 //   |     AsmInterpretedEntryFrame     |              |
1115 //   |        .  .  .   .               |              v
1116 //   |----------------------------------|---------------
1117 //
1118 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
1119 struct AsmInterpretedBridgeFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
1120                                                               AsmInterpretedEntryFrame,
1121                                                               base::AlignedPointer> {
1122     enum class Index : size_t {
1123         EntryIndex = 0,
1124         ReturnAddrIndex,
1125         NumOfMembers
1126     };
1127     static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
1128 
GetFrameFromSpAsmInterpretedBridgeFrame1129     static AsmInterpretedBridgeFrame* GetFrameFromSp(const JSTaggedType *sp)
1130     {
1131         return reinterpret_cast<AsmInterpretedBridgeFrame *>(reinterpret_cast<uintptr_t>(sp) -
1132             MEMBER_OFFSET(AsmInterpretedBridgeFrame, returnAddr));
1133     }
GetCallSiteSpAsmInterpretedBridgeFrame1134     uintptr_t GetCallSiteSp() const
1135     {
1136         return ToUintPtr(this) + sizeof(AsmInterpretedBridgeFrame);
1137     }
GetPrevFrameFpAsmInterpretedBridgeFrame1138     inline JSTaggedType* GetPrevFrameFp()
1139     {
1140         return entry.base.prev;
1141     }
1142 
GetReturnAddrOffsetAsmInterpretedBridgeFrame1143     static size_t GetReturnAddrOffset(bool isArch32)
1144     {
1145         return GetOffset<static_cast<size_t>(Index::ReturnAddrIndex)>(isArch32);
1146     }
1147 
GetSizeAsmInterpretedBridgeFrame1148     static constexpr size_t GetSize(bool isArch32)
1149     {
1150         return isArch32 ? AsmInterpretedBridgeFrame::SizeArch32 : AsmInterpretedBridgeFrame::SizeArch64;
1151     }
1152 
1153     static size_t GetTypeOffset(bool isArch32 = false)
1154     {
1155         return GetOffset<static_cast<size_t>(Index::EntryIndex)>(isArch32) +
1156             AsmInterpretedEntryFrame::GetBaseOffset(isArch32) +
1157             InterpretedFrameBase::GetTypeOffset(isArch32);
1158     }
1159     static size_t GetPrevOffset(bool isArch32 = false)
1160     {
1161         return GetOffset<static_cast<size_t>(Index::EntryIndex)>(isArch32) +
1162             AsmInterpretedEntryFrame::GetBaseOffset(isArch32) +
1163             InterpretedFrameBase::GetPrevOffset(isArch32);
1164     }
1165 
GetReturnAddrAsmInterpretedBridgeFrame1166     uintptr_t GetReturnAddr() const
1167     {
1168         return returnAddr;
1169     }
1170 
1171     AsmInterpretedEntryFrame entry;
1172     alignas(EAS) uintptr_t returnAddr;
1173 };
1174 
1175 // * Optimized-leaved-frame layout as the following:
1176 //         +--------------------------+
1177 //         |       argv[N-1]          |
1178 //         |--------------------------|
1179 //         |       . . . . .          |
1180 //         |--------------------------|
1181 //         |       argv[0]            |
1182 //         +--------------------------+-------------
1183 //         |       argc               |            ^
1184 //         |--------------------------|            |
1185 //         |       RuntimeId          |            |
1186 //  sp --> |--------------------------|   OptimizedLeaveFrame
1187 //         |       ret-addr           |            |
1188 //         |--------------------------|            |
1189 //         |       prevFp             |            |
1190 //         |--------------------------|            |
1191 //         |       frameType          |            v
1192 //         +--------------------------+-------------
1193 //
1194 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
1195 struct OptimizedLeaveFrame {
1196     FrameType type;
1197     uintptr_t callsiteFp; // thread sp set here
1198     uintptr_t returnAddr;
1199     uint64_t argRuntimeId;
1200     uint64_t argc;
1201 
1202     // argv[0]...argv[argc-1] dynamic according to agc
GetFrameFromSpOptimizedLeaveFrame1203     static OptimizedLeaveFrame* GetFrameFromSp(const JSTaggedType *sp)
1204     {
1205         return reinterpret_cast<OptimizedLeaveFrame *>(reinterpret_cast<uintptr_t>(sp) -
1206             MEMBER_OFFSET(OptimizedLeaveFrame, callsiteFp));
1207     }
1208 
GetCallSiteSpOptimizedLeaveFrame1209     uintptr_t GetCallSiteSp() const
1210     {
1211         return ToUintPtr(this) + MEMBER_OFFSET(OptimizedLeaveFrame, argRuntimeId);
1212     }
1213 
GetPrevFrameFpOptimizedLeaveFrame1214     inline JSTaggedType* GetPrevFrameFp() const
1215     {
1216         return reinterpret_cast<JSTaggedType*>(callsiteFp);
1217     }
1218 
GetReturnAddrOptimizedLeaveFrame1219     uintptr_t GetReturnAddr() const
1220     {
1221         return returnAddr;
1222     }
1223 
GetTypeOffsetOptimizedLeaveFrame1224     static size_t GetTypeOffset()
1225     {
1226         return MEMBER_OFFSET(OptimizedLeaveFrame, type);
1227     }
1228 
GetPrevOffsetOptimizedLeaveFrame1229     static size_t GetPrevOffset()
1230     {
1231         return MEMBER_OFFSET(OptimizedLeaveFrame, callsiteFp);
1232     }
1233 
1234     void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const;
1235 };
1236 
1237 // * Optimized-leaved-frame-with-argv layout as the following:
1238 //         +--------------------------+
1239 //         |       argv[]             |
1240 //         +--------------------------+-------------
1241 //         |       argc               |            ^
1242 //         |--------------------------|            |
1243 //         |       RuntimeId          |   OptimizedWithArgvLeaveFrame
1244 //  sp --> |--------------------------|            |
1245 //         |       returnAddr         |            |
1246 //         |--------------------------|            |
1247 //         |       callsiteFp         |            |
1248 //         |--------------------------|            |
1249 //         |       frameType          |            v
1250 //         +--------------------------+-------------
1251 
1252 struct OptimizedWithArgvLeaveFrame {
1253     FrameType type;
1254     uintptr_t callsiteFp; // thread sp set here
1255     uintptr_t returnAddr;
1256     uint64_t argRuntimeId;
1257     uint64_t argc;
1258 
GetFrameFromSpOptimizedWithArgvLeaveFrame1259     static OptimizedWithArgvLeaveFrame* GetFrameFromSp(const JSTaggedType *sp)
1260     {
1261         return reinterpret_cast<OptimizedWithArgvLeaveFrame *>(reinterpret_cast<uintptr_t>(sp) -
1262             MEMBER_OFFSET(OptimizedWithArgvLeaveFrame, callsiteFp));
1263     }
1264 
GetCallSiteSpOptimizedWithArgvLeaveFrame1265     uintptr_t GetCallSiteSp() const
1266     {
1267         return ToUintPtr(this) + MEMBER_OFFSET(OptimizedWithArgvLeaveFrame, argRuntimeId);
1268     }
1269 
GetPrevFrameFpOptimizedWithArgvLeaveFrame1270     inline JSTaggedType* GetPrevFrameFp()
1271     {
1272         return reinterpret_cast<JSTaggedType*>(callsiteFp);
1273     }
1274 
GetReturnAddrOptimizedWithArgvLeaveFrame1275     uintptr_t GetReturnAddr() const
1276     {
1277         return returnAddr;
1278     }
1279 
GetTypeOffsetOptimizedWithArgvLeaveFrame1280     static size_t GetTypeOffset()
1281     {
1282         return MEMBER_OFFSET(OptimizedWithArgvLeaveFrame, type);
1283     }
1284 
GetPrevOffsetOptimizedWithArgvLeaveFrame1285     static size_t GetPrevOffset()
1286     {
1287         return MEMBER_OFFSET(OptimizedWithArgvLeaveFrame, callsiteFp);
1288     }
1289 
1290     void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const;
1291 };
1292 
1293 // * OptimizedBuiltinLeaveFrame layout as the following:
1294 //         +--------------------------+
1295 //         |       argv[N-1]          |
1296 //         |--------------------------|
1297 //         |       . . . . .          |
1298 //         |--------------------------|
1299 //         |       argv[0]            |
1300 //         +--------------------------+-------------
1301 //         |       argc               |            ^
1302 //         |--------------------------|            |
1303 //         |       thread             |            |
1304 //         +--------------------------+            |
1305 //         |       ret-addr           |            |
1306 //  sp --> |--------------------------|   OptimizedBuiltinLeaveFrame
1307 //         |       prevFp             |            |
1308 //         |--------------------------|            |
1309 //         |       frameType          |            |
1310 //         |--------------------------|            |
1311 //         |       align byte         |            v
1312 //         +--------------------------+-------------
1313 //
1314 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
1315 struct OptimizedBuiltinLeaveFrame {
1316 public:
GetFrameFromSpOptimizedBuiltinLeaveFrame1317     static OptimizedBuiltinLeaveFrame* GetFrameFromSp(const JSTaggedType *sp)
1318     {
1319         return reinterpret_cast<OptimizedBuiltinLeaveFrame *>(reinterpret_cast<uintptr_t>(sp) -
1320             MEMBER_OFFSET(OptimizedBuiltinLeaveFrame, callsiteFp));
1321     }
1322 
GetCallSiteSpOptimizedBuiltinLeaveFrame1323     uintptr_t GetCallSiteSp() const
1324     {
1325         return ToUintPtr(this) + MEMBER_OFFSET(OptimizedBuiltinLeaveFrame, argc);
1326     }
1327 
GetPrevFrameFpOptimizedBuiltinLeaveFrame1328     inline JSTaggedType* GetPrevFrameFp() const
1329     {
1330         return reinterpret_cast<JSTaggedType*>(callsiteFp);
1331     }
1332 
GetReturnAddrOptimizedBuiltinLeaveFrame1333     uintptr_t GetReturnAddr() const
1334     {
1335         return returnAddr;
1336     }
1337 
1338     void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const;
1339 
GetTypeOffsetOptimizedBuiltinLeaveFrame1340     static size_t GetTypeOffset()
1341     {
1342         return MEMBER_OFFSET(OptimizedBuiltinLeaveFrame, type);
1343     }
1344 
GetPrevOffsetOptimizedBuiltinLeaveFrame1345     static size_t GetPrevOffset()
1346     {
1347         return MEMBER_OFFSET(OptimizedBuiltinLeaveFrame, callsiteFp);
1348     }
1349 
GetArgvOptimizedBuiltinLeaveFrame1350     const JSTaggedType* GetArgv() const
1351     {
1352         return reinterpret_cast<const JSTaggedType *>(&argc + 1);
1353     }
1354 
GetTypeOptimizedBuiltinLeaveFrame1355     FrameType GetType() const
1356     {
1357         return type;
1358     }
1359 
1360 private:
1361     FrameType type;
1362     uintptr_t callsiteFp; // thread sp set here
1363     uintptr_t returnAddr;
1364     JSTaggedValue thread;
1365     uint64_t argc;
1366     // argv[0]...argv[argc-1] dynamic according to agc
1367 };
1368 
1369 // * BuiltinFrame layout as the following:
1370 //               +--------------------------+
1371 //               |     argV[N - 1]          |
1372 //               |--------------------------|
1373 //               |       . . . .            |
1374 //               |--------------------------+
1375 //               |     argV[2]=this         |
1376 //               +--------------------------+
1377 //               |     argV[1]=new-target   |
1378 //               +--------------------------+
1379 //               |     argV[0]=call-target  |
1380 //               +--------------------------+ ---------
1381 //               |       argc               |         ^
1382 //               |--------------------------|         |
1383 //               |       thread             |         |
1384 //               |--------------------------|         |
1385 //               |       returnAddr         |     BuiltinFrame
1386 //               |--------------------------|         |
1387 //               |       callsiteFp         |         |
1388 //               |--------------------------|         |
1389 //               |       frameType          |         v
1390 //               +--------------------------+ ---------
1391 //
1392 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
1393 struct BuiltinFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
1394                                                  base::AlignedSize,
1395                                                  base::AlignedPointer,
1396                                                  base::AlignedPointer,
1397                                                  base::AlignedPointer,
1398                                                  base::AlignedPointer,
1399                                                  base::AlignedPointer> {
1400     enum class Index : size_t {
1401         TypeIndex = 0,
1402         PrevFpIndex,
1403         ReturnAddrIndex,
1404         ThreadIndex,
1405         NumArgsIndex,
1406         StackArgsIndex,
1407         NumOfMembers
1408     };
1409     static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
1410 
GetFrameFromSpBuiltinFrame1411     static BuiltinFrame* GetFrameFromSp(const JSTaggedType *sp)
1412     {
1413         return reinterpret_cast<BuiltinFrame *>(reinterpret_cast<uintptr_t>(sp) -
1414             MEMBER_OFFSET(BuiltinFrame, prevFp));
1415     }
1416 
GetPrevFrameFpBuiltinFrame1417     inline JSTaggedType* GetPrevFrameFp()
1418     {
1419         return prevFp;
1420     }
1421 
GetCallSiteSpBuiltinFrame1422     uintptr_t GetCallSiteSp() const
1423     {
1424         return ToUintPtr(this) + MEMBER_OFFSET(BuiltinFrame, thread);
1425     }
1426 
GetPreFpOffsetBuiltinFrame1427     static size_t GetPreFpOffset(bool isArch32)
1428     {
1429         return GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
1430     }
1431 
GetNumArgsToFpDeltaBuiltinFrame1432     static size_t GetNumArgsToFpDelta(bool isArch32)
1433     {
1434         auto offset = GetOffset<static_cast<size_t>(Index::NumArgsIndex)>(isArch32);
1435         return offset - GetPreFpOffset(isArch32);
1436     }
1437 
GetStackArgsToFpDeltaBuiltinFrame1438     static size_t GetStackArgsToFpDelta(bool isArch32)
1439     {
1440         auto offset = GetOffset<static_cast<size_t>(Index::StackArgsIndex)>(isArch32);
1441         return offset - GetPreFpOffset(isArch32);
1442     }
1443 
GetStackArgsAddressBuiltinFrame1444     uintptr_t GetStackArgsAddress()
1445     {
1446         return reinterpret_cast<uintptr_t>(&stackArgs);
1447     }
1448 
GetFunctionBuiltinFrame1449     JSTaggedValue GetFunction()
1450     {
1451         auto functionAddress = reinterpret_cast<JSTaggedType *>(GetStackArgsAddress());
1452         return JSTaggedValue(*functionAddress);
1453     }
1454 
GetNumArgsBuiltinFrame1455     uint32_t GetNumArgs()
1456     {
1457         return numArgs;
1458     }
1459 
GetReturnAddrBuiltinFrame1460     uintptr_t GetReturnAddr() const
1461     {
1462         return returnAddr;
1463     }
1464 
1465     static size_t GetTypeOffset(bool isArch32 = false)
1466     {
1467         return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
1468     }
1469 
1470     static size_t GetPrevOffset(bool isArch32 = false)
1471     {
1472         return GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
1473     }
1474 
1475     void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const;
1476 
1477     alignas(EAS) FrameType type;
1478     alignas(EAS) JSTaggedType *prevFp;
1479     alignas(EAS) uintptr_t returnAddr;
1480     alignas(EAS) uintptr_t thread;
1481     alignas(EAS) uint32_t numArgs;
1482     alignas(EAS) uintptr_t stackArgs;
1483 };
1484 
1485 // * BuiltinWithArgvFrame layout as the following:
1486 //               +--------------------------+ ---------
1487 //               |       . . . . .          |         ^
1488 //               |--------------------------|         |
1489 //               |       returnAddr         |         |
1490 //               |--------------------------|         |
1491 //               |       callsiteFp         |   BuiltinWithArgvFrame
1492 //               |--------------------------|         |
1493 //               |       frameType          |         |
1494 //               +--------------------------+         |
1495 //               |        argc              |         v
1496 //               +--------------------------+ ---------
1497 //               |        argV[0]           |
1498 //               +--------------------------+
1499 //               |        argV[1]           |
1500 //               +--------------------------+
1501 //               |        . . . .           |
1502 //               +--------------------------+
1503 //
1504 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
1505 struct BuiltinWithArgvFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
1506                                                          base::AlignedSize,
1507                                                          base::AlignedPointer,
1508                                                          base::AlignedPointer> {
1509     enum class Index : int {
1510         StackArgsTopIndex = -1,
1511         NumArgsIndex = -1,
1512         TypeIndex = 0,
1513         PrevFpIndex,
1514         ReturnAddrIndex,
1515         NumOfMembers
1516     };
1517     static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
1518 
GetFrameFromSpBuiltinWithArgvFrame1519     static BuiltinWithArgvFrame* GetFrameFromSp(const JSTaggedType *sp)
1520     {
1521         return reinterpret_cast<BuiltinWithArgvFrame *>(reinterpret_cast<uintptr_t>(sp) -
1522             MEMBER_OFFSET(BuiltinFrame, prevFp));
1523     }
1524 
GetPrevFrameFpBuiltinWithArgvFrame1525     inline JSTaggedType* GetPrevFrameFp()
1526     {
1527         return prevFp;
1528     }
1529 
GetCallSiteSpBuiltinWithArgvFrame1530     uintptr_t GetCallSiteSp() const
1531     {
1532         return ToUintPtr(this) + sizeof(BuiltinWithArgvFrame);
1533     }
1534 
GetStackArgsAddressBuiltinWithArgvFrame1535     uintptr_t GetStackArgsAddress()
1536     {
1537         auto topAddress = ToUintPtr(this) +
1538             (static_cast<int>(Index::StackArgsTopIndex) * sizeof(uintptr_t));
1539         auto numberArgs = GetNumArgs() + NUM_MANDATORY_JSFUNC_ARGS;
1540         return topAddress - static_cast<uint32_t>(numberArgs) * sizeof(uintptr_t);
1541     }
1542 
GetFunctionBuiltinWithArgvFrame1543     JSTaggedValue GetFunction()
1544     {
1545         auto functionAddress = reinterpret_cast<JSTaggedType *>(GetStackArgsAddress());
1546         return JSTaggedValue(*functionAddress);
1547     }
1548 
GetNumArgsBuiltinWithArgvFrame1549     int32_t GetNumArgs()
1550     {
1551         auto argcAddress = reinterpret_cast<int32_t *>(
1552             ToUintPtr(this) + (static_cast<int>(Index::NumArgsIndex) * sizeof(uintptr_t)));
1553         return *argcAddress;
1554     }
1555 
GetReturnAddrBuiltinWithArgvFrame1556     uintptr_t GetReturnAddr() const
1557     {
1558         return returnAddr;
1559     }
1560 
1561     static size_t GetTypeOffset(bool isArch32 = false)
1562     {
1563         return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
1564     }
1565 
1566     static size_t GetPrevOffset(bool isArch32 = false)
1567     {
1568         return GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
1569     }
1570 
1571     void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const;
1572     // argv(... this, new.target, function)
1573     // numargs
1574     alignas(EAS) FrameType type;
1575     alignas(EAS) JSTaggedType *prevFp;
1576     alignas(EAS) uintptr_t returnAddr;
1577 };
1578 
1579 enum class GCVisitedFlag : bool {
1580     VISITED = true,
1581     IGNORED = false,
1582     HYBRID_STACK = true,
1583 };
1584 
1585 class FrameIterator {
1586 public:
1587     using ConstInfo = kungfu::LLVMStackMapType::ConstInfo;
1588     explicit FrameIterator(JSTaggedType *sp, const JSThread *thread = nullptr);
GetFrameType()1589     FrameType GetFrameType() const
1590     {
1591         ASSERT(current_ != nullptr);
1592         FrameType *typeAddr = reinterpret_cast<FrameType *>(
1593             reinterpret_cast<uintptr_t>(current_) - sizeof(FrameType));
1594         return *typeAddr;
1595     }
1596 
1597     template<class T>
GetFrame()1598     T* GetFrame()
1599     {
1600         return T::GetFrameFromSp(current_);
1601     }
1602 
1603     template<class T>
GetFrame()1604     const T* GetFrame() const
1605     {
1606         return T::GetFrameFromSp(current_);
1607     }
1608 
Done()1609     bool Done() const
1610     {
1611         return current_ == nullptr;
1612     }
GetSp()1613     JSTaggedType *GetSp() const
1614     {
1615         return current_;
1616     }
GetSp()1617     JSTaggedType *GetSp()
1618     {
1619         return current_;
1620     }
GetCalleeRegAndOffsetVec(kungfu::CalleeRegAndOffsetVec & ret)1621     void GetCalleeRegAndOffsetVec(kungfu::CalleeRegAndOffsetVec &ret) const
1622     {
1623         ret = calleeRegInfo_;
1624     }
1625     int ComputeDelta() const;
1626     template <GCVisitedFlag GCVisit = GCVisitedFlag::IGNORED>
1627     void Advance();
1628     uint32_t GetBytecodeOffset() const;
1629     uintptr_t GetPrevFrameCallSiteSp() const;
1630     uintptr_t GetPrevFrame() const;
GetCallSiteSp()1631     uintptr_t GetCallSiteSp() const
1632     {
1633         return optimizedCallSiteSp_;
1634     }
GetOptimizedReturnAddr()1635     uintptr_t GetOptimizedReturnAddr() const
1636     {
1637         return optimizedReturnAddr_;
1638     }
GetThread()1639     const JSThread *GetThread() const
1640     {
1641         return thread_;
1642     }
1643     bool IteratorStackMap(const RootVisitor &visitor, const RootBaseAndDerivedVisitor &derivedVisitor) const;
1644     void CollectPcOffsetInfo(ConstInfo &info) const;
1645     void CollectArkDeopt(std::vector<kungfu::ARKDeopt>& deopts) const;
1646     std::tuple<uint64_t, uint8_t *, int, kungfu::CalleeRegAndOffsetVec> CalCallSiteInfo(uintptr_t retAddr) const;
1647     int GetCallSiteDelta(uintptr_t retAddr) const;
1648 
1649     Method *CheckAndGetMethod() const;
1650     JSTaggedValue GetFunction() const;
1651 
IsLeaveFrame()1652     bool IsLeaveFrame() const
1653     {
1654         FrameType type = GetFrameType();
1655         return (type == FrameType::LEAVE_FRAME) || (type == FrameType::LEAVE_FRAME_WITH_ARGV);
1656     }
1657 
IsOptimizedFrame()1658     bool IsOptimizedFrame() const
1659     {
1660         FrameType type = GetFrameType();
1661         return (type == FrameType::OPTIMIZED_FRAME);
1662     }
1663 
IsInterpretedFrame(FrameType type)1664     bool IsInterpretedFrame(FrameType type) const
1665     {
1666         return (type >= FrameType::INTERPRETER_FIRST) && (type <= FrameType::INTERPRETER_LAST);
1667     }
1668 
IsJSFrame()1669     bool IsJSFrame() const
1670     {
1671         FrameType type = GetFrameType();
1672         return IsInterpretedFrame(type) || IsOptimizedJSFunctionFrame(type);
1673     }
1674 
IsOptimizedJSFunctionFrame(FrameType type)1675     bool IsOptimizedJSFunctionFrame(FrameType type) const
1676     {
1677         return type == FrameType::OPTIMIZED_JS_FUNCTION_FRAME ||
1678             type == FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME;
1679     }
1680 
IsOptimizedJSFunctionFrame()1681     bool IsOptimizedJSFunctionFrame() const
1682     {
1683         FrameType type = GetFrameType();
1684         return IsOptimizedJSFunctionFrame(type);
1685     }
1686 
1687 private:
1688     JSTaggedType *current_ {nullptr};
1689     const JSThread *thread_ {nullptr};
1690     const kungfu::ArkStackMapParser *arkStackMapParser_ {nullptr};
1691     uintptr_t optimizedCallSiteSp_ {0};
1692     uintptr_t optimizedReturnAddr_ {0};
1693     uint8_t *stackMapAddr_ {nullptr};
1694     int fpDeltaPrevFrameSp_ {0};
1695     kungfu::CalleeRegAndOffsetVec calleeRegInfo_;
1696 };
1697 }  // namespace panda::ecmascript
1698 #endif // ECMASCRIPT_FRAMES_H
1699