• 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_COMPILER_SLOWPATH_LOWERING_H
17 #define ECMASCRIPT_COMPILER_SLOWPATH_LOWERING_H
18 
19 #include "ecmascript/compiler/argument_accessor.h"
20 #include "ecmascript/compiler/circuit.h"
21 #include "ecmascript/compiler/circuit_builder.h"
22 #include "ecmascript/compiler/gate_accessor.h"
23 #include "ecmascript/compiler/new_object_stub_builder.h"
24 #include "ecmascript/compiler/pass_manager.h"
25 #include "ecmascript/compiler/share_gate_meta_data.h"
26 #include <cstddef>
27 
28 namespace panda::ecmascript::kungfu {
29 // slowPath Lowering Process
30 // SW: state wire, DW: depend wire, VW: value wire
31 // Before lowering:
32 //                         SW        DW         VW
33 //                         |         |          |
34 //                         |         |          |
35 //                         v         v          v
36 //                     +-----------------------------+
37 //                     |            (HIR)            |
38 //                     |         JS_BYTECODE         |DW--------------------------------------
39 //                     |                             |                                       |
40 //                     +-----------------------------+                                       |
41 //                         SW                   SW                                           |
42 //                         |                     |                                           |
43 //                         |                     |                                           |
44 //                         |                     |                                           |
45 //                         v                     v                                           |
46 //                 +--------------+        +--------------+                                  |
47 //                 |  IF_SUCCESS  |        | IF_EXCEPTION |SW---------                       |
48 //                 +--------------+        +--------------+          |                       |
49 //                         SW                    SW                  |                       |
50 //                         |                     |                   |                       |
51 //                         v                     v                   |                       |
52 //     --------------------------------------------------------------|-----------------------|-------------------
53 //     catch processing                                              |                       |
54 //                                                                   |                       |
55 //                                                                   v                       V
56 //                                                            +--------------+       +-----------------+
57 //                                                            |    MERGE     |SW---->| DEPEND_SELECTOR |
58 //                                                            +--------------+       +-----------------+
59 //                                                                                          DW
60 //                                                                                          |
61 //                                                                                          v
62 //                                                                                   +-----------------+
63 //                                                                                   |  GET_EXCEPTION  |
64 //                                                                                   +-----------------+
65 
66 
67 // After lowering:
68 //         SW                                          DW      VW
69 //         |                                           |       |
70 //         |                                           |       |
71 //         |                                           v       v
72 //         |        +---------------------+         +------------------+
73 //         |        | CONSTANT(Exception) |         |       CALL       |DW---------------
74 //         |        +---------------------+         +------------------+                |
75 //         |                           VW            VW                                 |
76 //         |                           |             |                                  |
77 //         |                           |             |                                  |
78 //         |                           v             v                                  |
79 //         |                        +------------------+                                |
80 //         |                        |        EQ        |                                |
81 //         |                        +------------------+                                |
82 //         |                                VW                                          |
83 //         |                                |                                           |
84 //         |                                |                                           |
85 //         |                                v                                           |
86 //         |                        +------------------+                                |
87 //         ------------------------>|    IF_BRANCH     |                                |
88 //                                  +------------------+                                |
89 //                                   SW             SW                                  |
90 //                                   |              |                                   |
91 //                                   v              v                                   |
92 //                           +--------------+  +--------------+                         |
93 //                           |   IF_FALSE   |  |   IF_TRUE    |                         |
94 //                           |  (success)   |  |  (exception) |                         |
95 //                           +--------------+  +--------------+                         |
96 //                                 SW                SW   SW                            |
97 //                                 |                 |    |                             |
98 //                                 v                 v    |                             |
99 //     ---------------------------------------------------|-----------------------------|----------------------
100 //     catch processing                                   |                             |
101 //                                                        |                             |
102 //                                                        v                             v
103 //                                                 +--------------+             +-----------------+
104 //                                                 |    MERGE     |SW---------->| DEPEND_SELECTOR |
105 //                                                 +--------------+             +-----------------+
106 //                                                                                      DW
107 //                                                                                      |
108 //                                                                                      v
109 //                                                                              +-----------------+
110 //                                                                              |  GET_EXCEPTION  |
111 //                                                                              +-----------------+
112 
113 class SlowPathLowering {
114 public:
SlowPathLowering(Circuit * circuit,CompilationConfig * cmpCfg,PassContext * ctx,const MethodLiteral * methodLiteral,bool enableLog,const std::string & name,const CString & recordName)115     SlowPathLowering(Circuit *circuit, CompilationConfig *cmpCfg,
116                      PassContext *ctx, const MethodLiteral *methodLiteral,
117                      bool enableLog, const std::string& name, const CString &recordName)
118         : compilationEnv_(ctx->GetCompilationEnv()), methodLiteral_(methodLiteral),
119           circuit_(circuit), acc_(circuit),
120           argAcc_(circuit->GetArgumentAccessor()), builder_(circuit, cmpCfg),
121           enableLog_(enableLog), methodName_(name), recordName_(recordName), glue_(acc_.GetGlueFromArgList())
122     {
123         traceBc_ = cmpCfg->IsTraceBC();
124         profiling_ = cmpCfg->IsProfiling();
125         stressDeopt_ = cmpCfg->IsStressDeopt();
126     }
127     ~SlowPathLowering() = default;
128     void CallRuntimeLowering();
129 
IsLogEnabled()130     bool IsLogEnabled() const
131     {
132         return enableLog_;
133     }
134 
IsTraceBC()135     bool IsTraceBC() const
136     {
137         return traceBc_;
138     }
139 
IsProfiling()140     bool IsProfiling() const
141     {
142         return profiling_;
143     }
144 
IsStressDeopt()145     bool IsStressDeopt() const
146     {
147         return stressDeopt_;
148     }
149 
150 private:
GetMethodName()151     const std::string& GetMethodName() const
152     {
153         return methodName_;
154     }
155     bool enableMegaIC(GateRef gate);
156     void ReplaceHirWithPendingException(GateRef hirGate, GateRef state, GateRef depend, GateRef value);
157     void ReplaceHirWithValue(GateRef hirGate, GateRef value);
158     void ReplaceHirToThrowCall(GateRef hirGate, GateRef callGate);
159     void LowerExceptionHandler(GateRef hirGate);
160     void Lower(GateRef gate);
161     void LowerAdd2(GateRef gate);
162     void LowerCreateIterResultObj(GateRef gate);
163     void SaveFrameToContext(GateRef gate);
164     void LowerSuspendGenerator(GateRef gate);
165     void LowerAsyncFunctionAwaitUncaught(GateRef gate);
166     void LowerAsyncFunctionResolve(GateRef gate);
167     void LowerAsyncFunctionReject(GateRef gate);
168     void LowerStGlobalVar(GateRef gate);
169     void LowerTryLdGlobalByName(GateRef gate);
170     void LowerGetIterator(GateRef gate);
171     void LowerGetAsyncIterator(GateRef gate);
172     void LowerToJSCall(GateRef hirGate, const std::vector<GateRef> &args, const std::vector<GateRef> &argsFastCall);
173     void LowerNewFastCall(GateRef gate, GateRef glue, GateRef func, bool needPushArgv, bool isFastCall,
174         const std::vector<GateRef> &args, const std::vector<GateRef> &fastCallArgs,
175         Variable *result, Label *exit);
176     void CallWithTimer(const CallSignature *cs, GateRef target, GateRef gate, GateRef func,
177                        const std::vector<GateRef> &args, Variable *result, Label *exit, const char *comment);
178     void SelectFastNew(GateRef selectCall, GateRef gate, GateRef func, const std::vector<GateRef> &args,
179                        const std::vector<GateRef> &argsFastCall, Variable *result, Label *exit);
180     void LowerCallArg0Stub(GateRef gate);
181     void LowerCallArg1Stub(GateRef gate);
182     void LowerCallArg2Stub(GateRef gate);
183     void LowerCallArg3Stub(GateRef gate);
184     void LowerCallThis0Stub(GateRef gate);
185     void LowerCallThis1Stub(GateRef gate);
186     void LowerCallThis2Stub(GateRef gate);
187     void LowerCallThis3Stub(GateRef gate);
188     void LowerCallthisrangeImm8Imm8V8(GateRef gate);
189     void LowerWideCallthisrangePrefImm16V8(GateRef gate);
190     void LowerCallSpread(GateRef gate);
191     void LowerCallrangeImm8Imm8V8(GateRef gate);
192     void LowerWideCallrangePrefImm16V8(GateRef gate);
193     void LowerNewObjApply(GateRef gate);
194     void LowerThrow(GateRef gate);
195     void LowerThrowConstAssignment(GateRef gate);
196     void LowerThrowThrowNotExists(GateRef gate);
197     void LowerThrowPatternNonCoercible(GateRef gate);
198     void LowerThrowIfNotObject(GateRef gate);
199     void LowerThrowUndefinedIfHole(GateRef gate);
200     void LowerThrowUndefinedIfHoleWithName(GateRef Getgate);
201     void LowerThrowIfSuperNotCorrectCall(GateRef gate);
202     void LowerThrowDeleteSuperProperty(GateRef gate);
203     void LowerLdSymbol(GateRef gate);
204     void LowerLdGlobal(GateRef gate);
205     void LowerSub2(GateRef gate);
206     void LowerMul2(GateRef gate);
207     void LowerDiv2(GateRef gate);
208     void LowerMod2(GateRef gate);
209     void LowerEq(GateRef gate);
210     void LowerNotEq(GateRef gate);
211     void LowerLess(GateRef gate);
212     void LowerLessEq(GateRef gate);
213     void LowerGreater(GateRef gate);
214     void LowerGreaterEq(GateRef gate);
215     void LowerGetPropIterator(GateRef gate);
216     void LowerCloseIterator(GateRef gate);
217     void LowerInc(GateRef gate);
218     void LowerDec(GateRef gate);
219     void LowerToNumber(GateRef gate);
220     void LowerNeg(GateRef gate);
221     void LowerNot(GateRef gate);
222     void LowerShl2(GateRef gate);
223     void LowerShr2(GateRef gate);
224     void LowerAshr2(GateRef gate);
225     void LowerAnd2(GateRef gate);
226     void LowerOr2(GateRef gate);
227     void LowerXor2(GateRef gate);
228     void LowerDelObjProp(GateRef gate);
229     void LowerExp(GateRef gate);
230     void LowerIsIn(GateRef gate);
231     void LowerInstanceof(GateRef gate);
232     void LowerFastStrictNotEqual(GateRef gate);
233     void LowerFastStrictEqual(GateRef gate);
234     void LowerCreateEmptyArray(GateRef gate);
235     void LowerCreateEmptyObject(GateRef gate);
236     void LowerCreateArrayWithBuffer(GateRef gate);
237     void LowerCreateObjectWithBuffer(GateRef gate);
238     void LowerStModuleVar(GateRef gate);
239     void LowerGetTemplateObject(GateRef gate);
240     void LowerSetObjectWithProto(GateRef gate);
241     void LowerLdBigInt(GateRef gate);
242     void LowerToNumeric(GateRef gate);
243     void LowerDynamicImport(GateRef gate);
244     void LowerLdLocalModuleVarByIndex(GateRef gate);
245     void LowerExternalModule(GateRef gate);
246     void LowerGetModuleNamespace(GateRef gate);
247     void LowerSendableExternalModule(GateRef gate);
248     void LowerSendableLocalModule(GateRef gate);
249     void LowerSuperCall(GateRef gate);
250     void LowerSuperCallForJIT(GateRef gate);
251     void LowerSuperCallArrow(GateRef gate);
252     void LowerSuperCallSpread(GateRef gate);
253     GateRef GetExpectedNumOfArgsFromFunc(GateRef func);
254     void LowerSuperCallForwardAllArgs(GateRef gate);
255     void LowerSuperCallForwardAllArgsForJIT(GateRef gate);
256     void CheckSuperAndNewTarget(NewObjectStubBuilder &objBuilder, GateRef super, Variable &newTarget,
257                                 Variable &thisObj, Label &fastPath, Label &slowPath);
258     GateRef CheckSuperAndNewTargetForJIT(GateRef gate, GateRef super, Variable &newTarget, Label &fastPath,
259                                       Label &slowPath);
260     GateRef IsAotOrFastCall(GateRef func, CircuitBuilder::JudgeMethodType type);
261     void LowerFastSuperCallWithArgArray(GateRef array, const std::vector<GateRef> &args, bool isSpread,
262                                         Variable &result, Label &exit);
263     void GenerateSuperCallForwardAllArgsWithoutArgv(const std::vector<GateRef> &args, Variable &result, Label &exit);
264     void LowerIsTrueOrFalse(GateRef gate, bool flag);
265     void LowerNewObjRange(GateRef gate);
266     bool IsDependIfStateMent(GateRef gate, size_t idx);
267     void LowerConditionJump(GateRef gate, bool isEqualJump);
268     void LowerGetNextPropName(GateRef gate);
269     void LowerCopyDataProperties(GateRef gate);
270     void LowerCreateObjectWithExcludedKeys(GateRef gate);
271     void LowerCreateRegExpWithLiteral(GateRef gate);
272     void LowerStOwnByValue(GateRef gate);
273     void LowerStOwnByIndex(GateRef gate);
274     void LowerStOwnByName(GateRef gate);
275     void LowerDefineFunc(GateRef gate);
276     void LowerNewLexicalEnv(GateRef gate);
277     void LowerNewLexicalEnvWithName(GateRef gate);
278     void LowerNewSendableEnv(GateRef gate);
279     void LowerPopLexicalEnv(GateRef gate);
280     void LowerLdSuperByValue(GateRef gate);
281     void LowerStSuperByValue(GateRef gate);
282     void LowerTryStGlobalByName(GateRef gate);
283     void LowerStConstToGlobalRecord(GateRef gate, bool isConst);
284     void LowerStOwnByValueWithNameSet(GateRef gate);
285     void LowerStOwnByNameWithNameSet(GateRef gate);
286     void LowerLdGlobalVar(GateRef gate);
287     void LowerLdObjByName(GateRef gate);
288     void LowerStObjByName(GateRef gate, bool isThis);
289     void LowerLdSuperByName(GateRef gate);
290     void LowerStSuperByName(GateRef gate);
291     void LowerDefineGetterSetterByValue(GateRef gate);
292     void LowerLdObjByIndex(GateRef gate);
293     void LowerStObjByIndex(GateRef gate);
294     void LowerLdObjByValue(GateRef gate, bool isThis);
295     void LowerStObjByValue(GateRef gate, bool isThis);
296     void LowerCreateGeneratorObj(GateRef gate);
297     void LowerStArraySpread(GateRef gate);
298     void LowerLdLexVar(GateRef gate);
299     void LowerLdSendableVar(GateRef gate);
300     void LowerStLexVar(GateRef gate);
301     void LowerStSendableVar(GateRef gate);
302     void LowerDefineClassWithBuffer(GateRef gate);
303     void LowerAsyncFunctionEnter(GateRef gate);
304     void LowerTypeof(GateRef gate);
305     void LowerResumeGenerator(GateRef gate);
306     void LowerStoreRegister(GateRef gate, GateRef arrayGate);
307     void LowerGetResumeMode(GateRef gate);
308     void LowerDefineMethod(GateRef gate);
309     void LowerGetUnmappedArgs(GateRef gate);
310     void LowerCopyRestArgs(GateRef gate);
311     void LowerCallStubWithIC(GateRef gate, int sign, const std::vector<GateRef> &args);
312     GateRef LowerCallRuntime(GateRef gate, int index, const std::vector<GateRef> &args, bool useLabel = false);
313     GateRef LowerCallNGCRuntime(GateRef gate, int index, const std::vector<GateRef> &args, bool useLabel = false);
314     void LowerCreateAsyncGeneratorObj(GateRef gate);
315     void LowerAsyncGeneratorResolve(GateRef gate);
316     void LowerAsyncGeneratorReject(GateRef gate);
317     void LowerSetGeneratorState(GateRef gate);
318     GateRef GetValueFromTaggedArray(GateRef arrayGate, GateRef indexOffset);
319     GateRef GetTaggedArrayFromValueIn(Environment *env, GateRef gate, size_t length);
320     GateRef LowerUpdateArrayHClassAtDefine(GateRef gate, GateRef array);
321     void AddProfiling(GateRef gate, bool skipGenerator = true);
322     GateRef FastStrictEqual(GateRef left, GateRef right);
323     void LowerWideLdPatchVar(GateRef gate);
324     void LowerWideStPatchVar(GateRef gate);
325     void LowerLdThisByName(GateRef gate);
326     bool IsFastCallArgs(size_t index);
327     void LowerConstruct(GateRef gate);
328     void LowerCallInternal(GateRef gate);
329     void LowerCallNew(GateRef gate);
330     void LowerCallNewBuiltin(GateRef gate);
331     void LowerTypedCall(GateRef gate);
332     void LowerTypedFastCall(GateRef gate);
333     void LowerCheckSafePointAndStackOver(GateRef gate);
334     void LowerLdPrivateProperty(GateRef gate);
335     void LowerStPrivateProperty(GateRef gate);
336     void LowerTestIn(GateRef gate);
337     void LowerNotifyConcurrentResult(GateRef gate);
338     void LowerDefineFieldByName(GateRef gate);
339     void LowerDefineFieldByValue(GateRef gate);
340     void LowerDefineFieldByIndex(GateRef gate);
341     void LowerToPropertyKey(GateRef gate);
342     void LowerCreatePrivateProperty(GateRef gate);
343     void LowerDefinePrivateProperty(GateRef gate);
344     void LowerDefineSendableClass(GateRef gate);
345     void LowerLdSendableClass(GateRef gate);
346     void LowerGetEnv(GateRef gate);
347     void DeleteLoopExit(GateRef gate);
348     void DeleteLoopExitValue(GateRef gate);
349     void LowerLdStr(GateRef gate);
350     void LowerGetSharedConstPool(GateRef gate);
351     void LowerGetUnsharedConstPool(GateRef gate);
352     bool TryLowerGetGlobalEnvCache(GateRef gate);
353     void LowerLdLazyExternalModuleVar(GateRef gate);
354     void LowerLdLazySendableExternalModuleVar(GateRef gate);
355     GateRef GetStringFromConstPool(GateRef gate, GateRef stringId, uint32_t stringIdIdx);
356     bool OptimizeDefineFuncForJit(GateRef gate, GateRef jsFunc, GateRef length, GateRef methodId, GateRef lexEnv,
357                                   GateRef slotId);
358 
359     CompilationEnv *compilationEnv_;
360     const MethodLiteral *methodLiteral_ {nullptr};
361     Circuit *circuit_;
362     GateAccessor acc_;
363     ArgumentAccessor *argAcc_;
364     CircuitBuilder builder_;
365     bool enableLog_ {false};
366     bool traceBc_ {false};
367     bool profiling_ {false};
368     bool stressDeopt_ {false};
369     std::string methodName_;
370     const CString &recordName_;
371     GateRef glue_ {Circuit::NullGate()};
372     CVector<GateRef> unsharedCP_;
373 };
374 }  // panda::ecmascript::kungfu
375 #endif  // ECMASCRIPT_COMPILER_SLOWPATH_LOWERING_H
376