• 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_INTERPRETER_FRAME_HANDLER_H
17 #define ECMASCRIPT_INTERPRETER_FRAME_HANDLER_H
18 
19 #include "ecmascript/interpreter/interpreter.h"
20 #include "ecmascript/js_method.h"
21 #include "ecmascript/js_tagged_value.h"
22 #include "ecmascript/mem/heap.h"
23 #include "ecmascript/mem/object_xray.h"
24 #include "ecmascript/frames.h"
25 
26 namespace panda {
27 namespace ecmascript {
28 class JSThread;
29 class JSFunction;
30 class ConstantPool;
31 
32 class FrameHandler {
33 public:
FrameHandler(const JSThread * thread)34     explicit FrameHandler(const JSThread *thread)
35         : sp_(const_cast<JSTaggedType *>(thread->GetCurrentSPFrame())) {}
FrameHandler(JSTaggedType * sp)36     explicit FrameHandler(JSTaggedType *sp) : sp_(sp) {}
37     ~FrameHandler() = default;
38     DEFAULT_COPY_SEMANTIC(FrameHandler);
39     DEFAULT_MOVE_SEMANTIC(FrameHandler);
40     static constexpr uintptr_t kFrameTypeOffset = -sizeof(FrameType);
41 
HasFrame()42     bool HasFrame() const
43     {
44         // Breakframe also is a frame
45         return sp_ != nullptr;
46     }
IsBreakFrame()47     bool IsBreakFrame() const
48     {
49         ASSERT(HasFrame());
50         // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
51         InterpretedFrame *state = InterpretedFrame::GetFrameFromSp(sp_);
52         return state->sp == nullptr;
53     }
54     void PrevFrame();
55 
GetFrameType()56     FrameType GetFrameType() const
57     {
58         ASSERT(HasFrame());
59         FrameType* typeAddr = reinterpret_cast<FrameType*>(reinterpret_cast<uintptr_t>(sp_) + kFrameTypeOffset);
60         return *typeAddr;
61     }
62 
IsInterpretedFrame()63     bool IsInterpretedFrame() const
64     {
65         FrameType type = GetFrameType();
66         return (type == FrameType::INTERPRETER_FRAME) || (type == FrameType::INTERPRETER_FAST_NEW_FRAME);
67     }
68 
IsOptimizedLeaveFrame()69     bool IsOptimizedLeaveFrame() const
70     {
71         return GetFrameType() == FrameType::OPTIMIZED_LEAVE_FRAME;
72     }
73 
GetOptimizedLeaveFrame()74     OptimizedLeaveFrame* GetOptimizedLeaveFrame() const
75     {
76         assert(IsOptimizedLeaveFrame());
77         return OptimizedLeaveFrame::GetFrameFromSp(sp_);
78     }
79 
80 protected:
81     JSTaggedType *sp_ {nullptr};
82 };
83 
84 class InterpretedFrameHandler : public FrameHandler {
85 public:
86     explicit InterpretedFrameHandler(JSThread *thread);
InterpretedFrameHandler(JSTaggedType * sp)87     explicit InterpretedFrameHandler(JSTaggedType *sp) : FrameHandler(sp) {}
88     DEFAULT_COPY_SEMANTIC(InterpretedFrameHandler);
89     DEFAULT_MOVE_SEMANTIC(InterpretedFrameHandler);
90 
91     void PrevFrame();
92     void PrevInterpretedFrame();
93     InterpretedFrameHandler GetPrevFrame() const;
94 
95     JSTaggedValue GetVRegValue(size_t index) const;
96     void SetVRegValue(size_t index, JSTaggedValue value);
97 
98     JSTaggedValue GetAcc() const;
99     uint32_t GetSize() const;
100     uint32_t GetBytecodeOffset() const;
101     JSMethod *GetMethod() const;
102     JSTaggedValue GetFunction() const;
103     const uint8_t *GetPc() const;
104     JSTaggedType *GetSp() const;
105     ConstantPool *GetConstpool() const;
106     JSTaggedValue GetEnv() const;
107 
108     void Iterate(const RootVisitor &v0, const RootRangeVisitor &v1);
109 
110     void DumpStack(std::ostream &os) const;
DumpStack()111     void DumpStack() const
112     {
113         DumpStack(std::cout);
114     }
115     void DumpPC(std::ostream &os, const uint8_t *pc) const;
DumpPC(const uint8_t * pc)116     void DumpPC(const uint8_t *pc) const
117     {
118         DumpPC(std::cout, pc);
119     }
120 };
121 
122 class OptimizedFrameHandler : public FrameHandler {
123 public:
OptimizedFrameHandler(uintptr_t * sp)124     explicit OptimizedFrameHandler(uintptr_t *sp)
125         : FrameHandler(reinterpret_cast<JSTaggedType *>(sp)) {}
126     explicit OptimizedFrameHandler(const JSThread *thread);
127     ~OptimizedFrameHandler() = default;
128     void PrevFrame();
129     void Iterate(const RootVisitor &v0, const RootRangeVisitor &v1,
130                 ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers,
131                  bool isVerifying) const;
132 };
133 
134 class OptimizedEntryFrameHandler : public FrameHandler {
135 public:
OptimizedEntryFrameHandler(uintptr_t * sp)136     explicit OptimizedEntryFrameHandler(uintptr_t *sp)
137         : FrameHandler(reinterpret_cast<JSTaggedType *>(sp)) {}
138     explicit OptimizedEntryFrameHandler(const JSThread *thread);
139     ~OptimizedEntryFrameHandler() = default;
140     void PrevFrame();
141     void Iterate(const RootVisitor &v0, const RootRangeVisitor &v1,
142                 ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers,
143                 bool isVerifying) const;
144 };
145 
146 class OptimizedLeaveFrameHandler : public FrameHandler {
147 public:
OptimizedLeaveFrameHandler(uintptr_t * sp)148     explicit OptimizedLeaveFrameHandler(uintptr_t *sp)
149         : FrameHandler(reinterpret_cast<JSTaggedType *>(sp)) {}
150     explicit OptimizedLeaveFrameHandler(const JSThread *thread);
151     ~OptimizedLeaveFrameHandler() = default;
152     void PrevFrame();
153     void Iterate(const RootVisitor &v0, const RootRangeVisitor &v1,
154                 ChunkMap<DerivedDataKey, uintptr_t> *derivedPointers,
155                 bool isVerifying) const;
156 };
157 
158 class FrameIterator {
159 public:
FrameIterator(JSTaggedType * sp,const JSThread * thread)160     explicit FrameIterator(JSTaggedType *sp, const JSThread *thread) : sp_(sp), thread_(thread) {}
161     ~FrameIterator() = default;
162     void Iterate(const RootVisitor &v0, const RootRangeVisitor &v1) const;
163     void IterateStackMapAfterGC() const;
164 private:
165     JSTaggedType *sp_ {nullptr};
166     const JSThread *thread_ {nullptr};
167 };
168 } // namespace ecmascript
169 }  // namespace panda
170 #endif  // ECMASCRIPT_INTERPRETER_FRAME_HANDLER_H
171