• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-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 #ifndef PANDA_SLOW_PATH_H
17 #define PANDA_SLOW_PATH_H
18 
19 #include "optimizer/ir/graph.h"
20 #include "optimizer/code_generator/encode.h"
21 
22 namespace ark::compiler {
23 class Codegen;
24 
25 class SlowPathBase {
26 public:
27     using EntrypointId = RuntimeInterface::EntrypointId;
28 
SlowPathBase(LabelHolder::LabelId label)29     explicit SlowPathBase(LabelHolder::LabelId label) : SlowPathBase(label, nullptr) {}
SlowPathBase(LabelHolder::LabelId label,Inst * inst)30     SlowPathBase(LabelHolder::LabelId label, Inst *inst)
31         : label_(label), labelBack_(LabelHolder::INVALID_LABEL), inst_(inst)
32     {
33     }
34     virtual ~SlowPathBase() = default;
35 
36     NO_COPY_SEMANTIC(SlowPathBase);
37     NO_MOVE_SEMANTIC(SlowPathBase);
38 
GetInst()39     Inst *GetInst() const
40     {
41         return inst_;
42     }
43 
GetLabel()44     auto &GetLabel() const
45     {
46         return label_;
47     }
48 
BindBackLabel(Encoder * encoder)49     void BindBackLabel(Encoder *encoder)
50     {
51         if (!encoder->IsLabelValid(labelBack_)) {
52             labelBack_ = encoder->CreateLabel();
53         }
54         encoder->BindLabel(labelBack_);
55     }
56 
CreateBackLabel(Encoder * encoder)57     void CreateBackLabel(Encoder *encoder)
58     {
59         labelBack_ = encoder->CreateLabel();
60     }
61 
GetBackLabel()62     LabelHolder::LabelId GetBackLabel()
63     {
64         return labelBack_;
65     }
66 
67     void Generate(Codegen *codegen);
68 
69     virtual void GenerateImpl(Codegen *codegen) = 0;
70 
71 private:
72     LabelHolder::LabelId label_ {LabelHolder::INVALID_LABEL};
73     LabelHolder::LabelId labelBack_ {LabelHolder::INVALID_LABEL};
74     Inst *inst_ {nullptr};
75 
76 #ifndef NDEBUG
77     // Intended to check that slow path is generated only once.
78     bool generated_ {false};
79 #endif
80 };
81 
82 class SlowPathIntrinsic : public SlowPathBase {
83 public:
84     using SlowPathBase::SlowPathBase;
85 
SlowPathIntrinsic(LabelHolder::LabelId label,Inst * inst)86     SlowPathIntrinsic(LabelHolder::LabelId label, Inst *inst) : SlowPathBase(label, inst) {}
87     ~SlowPathIntrinsic() override = default;
88 
89     NO_COPY_SEMANTIC(SlowPathIntrinsic);
90     NO_MOVE_SEMANTIC(SlowPathIntrinsic);
91 
92     void GenerateImpl(Codegen *codegen) override;
93 };
94 
95 class SlowPathEntrypoint : public SlowPathBase {
96 public:
SlowPathEntrypoint(LabelHolder::LabelId label)97     explicit SlowPathEntrypoint(LabelHolder::LabelId label) : SlowPathBase(label) {}
SlowPathEntrypoint(LabelHolder::LabelId label,Inst * inst,EntrypointId eid)98     SlowPathEntrypoint(LabelHolder::LabelId label, Inst *inst, EntrypointId eid)
99         : SlowPathBase(label, inst), entrypoint_(eid)
100     {
101     }
102     ~SlowPathEntrypoint() override = default;
103 
104     void GenerateImpl(Codegen *codegen) override;
105 
GetEntrypoint()106     EntrypointId GetEntrypoint()
107     {
108         return entrypoint_;
109     }
110 
111     NO_COPY_SEMANTIC(SlowPathEntrypoint);
112     NO_MOVE_SEMANTIC(SlowPathEntrypoint);
113 
114 private:
115     bool GenerateThrowOutOfBoundsException(Codegen *codegen);
116     bool GenerateInitializeClass(Codegen *codegen);
117     bool GenerateIsInstance(Codegen *codegen);
118     bool GenerateCheckCast(Codegen *codegen);
119     bool GenerateByEntry(Codegen *codegen);
120     bool GenerateCreateObject(Codegen *codegen);
121 
122 private:
123     EntrypointId entrypoint_ {EntrypointId::COUNT};
124 };
125 
126 class SlowPathDeoptimize : public SlowPathEntrypoint {
127 public:
128     ~SlowPathDeoptimize() override = default;
129     NO_COPY_SEMANTIC(SlowPathDeoptimize);
130     NO_MOVE_SEMANTIC(SlowPathDeoptimize);
131 
SlowPathDeoptimize(LabelHolder::LabelId label,Inst * inst,DeoptimizeType deoptimizeType)132     SlowPathDeoptimize(LabelHolder::LabelId label, Inst *inst, DeoptimizeType deoptimizeType)
133         : SlowPathEntrypoint(label, inst, EntrypointId::DEOPTIMIZE), deoptimizeType_ {deoptimizeType}
134     {
135     }
136 
137     void GenerateImpl(Codegen *codegen) override;
138 
139 private:
140     DeoptimizeType deoptimizeType_;
141 };
142 
143 class SlowPathImplicitNullCheck : public SlowPathEntrypoint {
144 public:
145     using SlowPathEntrypoint::SlowPathEntrypoint;
146 
147     void GenerateImpl(Codegen *codegen) override;
148 };
149 
150 class SlowPathShared : public SlowPathEntrypoint {
151 public:
152     using SlowPathEntrypoint::SlowPathEntrypoint;
153 
154     void GenerateImpl(Codegen *codegen) override;
SetTmpReg(Reg reg)155     void SetTmpReg(Reg reg)
156     {
157         tmpReg_ = reg;
158     }
GetTmpReg()159     Reg GetTmpReg() const
160     {
161         return tmpReg_;
162     }
163 
164 private:
165     Reg tmpReg_ {INVALID_REGISTER};
166 };
167 
168 class SlowPathResolveStringAot : public SlowPathEntrypoint {
169 public:
170     using SlowPathEntrypoint::SlowPathEntrypoint;
171 
172     void GenerateImpl(Codegen *codegen) override;
173 
SetDstReg(Reg reg)174     void SetDstReg(Reg reg)
175     {
176         dstReg_ = reg;
177     }
178 
SetAddrReg(Reg reg)179     void SetAddrReg(Reg reg)
180     {
181         addrReg_ = reg;
182     }
183 
SetStringId(uint32_t stringId)184     void SetStringId(uint32_t stringId)
185     {
186         stringId_ = stringId;
187     }
188 
SetMethod(void * method)189     void SetMethod(void *method)
190     {
191         method_ = method;
192     }
193 
194 private:
195     Reg dstReg_ {INVALID_REGISTER};
196     Reg addrReg_ {INVALID_REGISTER};
197     uint32_t stringId_ {0};
198     void *method_ {nullptr};
199 };
200 
201 class SlowPathCheck : public SlowPathEntrypoint {
202 public:
203     using SlowPathEntrypoint::SlowPathEntrypoint;
204 };
205 
206 class SlowPathCheckCast : public SlowPathEntrypoint {
207 public:
208     using SlowPathEntrypoint::SlowPathEntrypoint;
209     void GenerateImpl(Codegen *codegen) override;
SetClassReg(Reg reg)210     void SetClassReg(Reg reg)
211     {
212         classReg_ = reg;
213     }
214 
215 private:
216     Reg classReg_ {INVALID_REGISTER};
217 };
218 
219 class SlowPathAbstract : public SlowPathEntrypoint {
220 public:
221     using SlowPathEntrypoint::SlowPathEntrypoint;
222     void GenerateImpl(Codegen *codegen) override;
SetMethodReg(Reg reg)223     void SetMethodReg(Reg reg)
224     {
225         methodReg_ = reg;
226     }
227 
228 private:
229     Reg methodReg_ {INVALID_REGISTER};
230 };
231 
232 class SlowPathRefCheck : public SlowPathEntrypoint {
233 public:
234     using SlowPathEntrypoint::SlowPathEntrypoint;
235 
236     void GenerateImpl(Codegen *codegen) override;
237 
SetRegs(Reg arrayReg,Reg refReg)238     void SetRegs(Reg arrayReg, Reg refReg)
239     {
240         arrayReg_ = arrayReg;
241         refReg_ = refReg;
242     }
243 
244 private:
245     Reg arrayReg_ {INVALID_REGISTER};
246     Reg refReg_ {INVALID_REGISTER};
247 };
248 
249 class SlowPathUnresolved : public SlowPathEntrypoint {
250 public:
251     using SlowPathEntrypoint::SlowPathEntrypoint;
252 
253     void GenerateImpl(Codegen *codegen) override;
254 
SetUnresolvedType(void * method,uint32_t typeId)255     void SetUnresolvedType(void *method, uint32_t typeId)
256     {
257         method_ = method;
258         typeId_ = typeId;
259     }
260 
SetSlotAddr(uintptr_t addr)261     void SetSlotAddr(uintptr_t addr)
262     {
263         slotAddr_ = addr;
264     }
265 
SetDstReg(Reg dstReg)266     void SetDstReg(Reg dstReg)
267     {
268         dstReg_ = dstReg;
269     }
270 
SetArgReg(Reg argReg)271     void SetArgReg(Reg argReg)
272     {
273         argReg_ = argReg;
274     }
275 
276 private:
277     Reg dstReg_ {INVALID_REGISTER};
278     Reg argReg_ {INVALID_REGISTER};
279     void *method_ {nullptr};
280     uint32_t typeId_ {0};
281     uintptr_t slotAddr_ {0};
282 };
283 
284 class SlowPathJsCastDoubleToInt32 : public SlowPathBase {
285 public:
286     using SlowPathBase::SlowPathBase;
287 
288     ~SlowPathJsCastDoubleToInt32() override = default;
289 
290     NO_COPY_SEMANTIC(SlowPathJsCastDoubleToInt32);
291     NO_MOVE_SEMANTIC(SlowPathJsCastDoubleToInt32);
292 
SetSrcReg(Reg srcReg)293     void SetSrcReg(Reg srcReg)
294     {
295         srcReg_ = srcReg;
296     }
297 
SetDstReg(Reg dstReg)298     void SetDstReg(Reg dstReg)
299     {
300         dstReg_ = dstReg;
301     }
302 
303     void GenerateImpl(Codegen *codegen) override;
304 
305 private:
306     Reg srcReg_ {INVALID_REGISTER};
307     Reg dstReg_ {INVALID_REGISTER};
308 };
309 
310 class SlowPathStringHashCode : public SlowPathEntrypoint {
311 public:
312     using SlowPathEntrypoint::SlowPathEntrypoint;
313 
314     ~SlowPathStringHashCode() override = default;
315 
316     NO_COPY_SEMANTIC(SlowPathStringHashCode);
317     NO_MOVE_SEMANTIC(SlowPathStringHashCode);
318 
SetDstReg(Reg dstReg)319     void SetDstReg(Reg dstReg)
320     {
321         dstReg_ = dstReg;
322     }
323 
SetSrcReg(Reg srcReg)324     void SetSrcReg(Reg srcReg)
325     {
326         srcReg_ = srcReg;
327     }
328 
329     void GenerateImpl(Codegen *codegen) override;
330 
331 private:
332     Reg dstReg_ {INVALID_REGISTER};
333     Reg srcReg_ {INVALID_REGISTER};
334 };
335 
336 }  // namespace ark::compiler
337 
338 #endif  // PANDA_SLOW_PATH_H
339