• 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_TYPED_HCR_LOWERING_H
17 #define ECMASCRIPT_COMPILER_TYPED_HCR_LOWERING_H
18 
19 #include "ecmascript/compiler/argument_accessor.h"
20 #include "ecmascript/compiler/bytecode_circuit_builder.h"
21 #include "ecmascript/compiler/circuit_builder-inl.h"
22 #include "ecmascript/compiler/combined_pass_visitor.h"
23 #include "ecmascript/compiler/type_info_accessors.h"
24 #include "ecmascript/compiler/pass_manager.h"
25 
26 namespace panda::ecmascript::kungfu {
27 // TypeHCRLowering Process
28 // SW: state wire, DW: depend wire, VW: value wire
29 // Before Type Lowering:
30 //                                    SW   DW   VW
31 //                                    |    |    |
32 //                                    |    |    |
33 //                                    v    v    v
34 //                                +-------------------+
35 //                                |       (HIR)       |    SW     +--------------+
36 //                            --DW|    JS_BYTECODE    |---------->| IF_EXCEPTION |
37 //                            |   +-------------------+           +--------------+
38 //                            |            SW       VW
39 //                            |            |        |
40 //                            |            v        |
41 //                            |    +--------------+ |
42 //                            |    |  IF_SUCCESS  | |
43 //                            |    +--------------+ |
44 //                            |            SW       |
45 //                            |            |        |
46 //                            |            v        v
47 //                            |   +-------------------+
48 //                            |   |       (HIR)       |
49 //                            --->|    JS_BYTECODE    |
50 //                                +-------------------+
51 //
52 // After Type Lowering:
53 //                                           SW
54 //                                           |
55 //                                           v
56 //                                 +-------------------+
57 //                                 |     IF_BRANCH     |
58 //                                 |    (Type Check)   |
59 //                                 +-------------------+
60 //                                    SW            SW
61 //                                    |             |
62 //                                    V             V
63 //                            +--------------+  +--------------+
64 //                            |    IF_TRUE   |  |   IF_FALSE   |
65 //                            +--------------+  +--------------+
66 //                 VW   DW          SW               SW                   DW   VW
67 //                 |    |           |                |                    |    |
68 //                 |    |           V                V                    |    |
69 //                 |    |  +---------------+     +---------------------+  |    |
70 //                 ------->|   FAST PATH   |     |        (HIR)        |<-------
71 //                         +---------------+     |     JS_BYTECODE     |
72 //                            VW  DW   SW        +---------------------+
73 //                            |   |    |               SW         VW  DW
74 //                            |   |    |               |          |   |
75 //                            |   |    |               v          |   |
76 //                            |   |    |         +--------------+ |   |
77 //                            |   |    |         |  IF_SUCCESS  | |   |
78 //                            |   |    |         +--------------+ |   |
79 //                            |   |    |                SW        |   |
80 //                            |   |    |                |         |   |
81 //                            |   |    v                v         |   |
82 //                            |   |  +---------------------+      |   |
83 //                            |   |  |        MERGE        |      |   |
84 //                            |   |  +---------------------+      |   |
85 //                            |   |    SW         SW    SW        |   |
86 //                            ----|----|----------|-----|--       |   |
87 //                             ---|----|----------|-----|-|-------|----
88 //                             |  |    |          |     | |       |
89 //                             v  v    v          |     v v       v
90 //                            +-----------------+ | +----------------+
91 //                            | DEPEND_SELECTOR | | | VALUE_SELECTOR |
92 //                            +-----------------+ | +----------------+
93 //                                    DW          |        VW
94 //                                    |           |        |
95 //                                    v           v        v
96 //                                  +------------------------+
97 //                                  |         (HIR)          |
98 //                                  |      JS_BYTECODE       |
99 //                                  +------------------------+
100 
101 class TypedHCRLowering : public PassVisitor {
102 public:
TypedHCRLowering(Circuit * circuit,CompilationEnv * env,RPOVisitor * visitor,CompilationConfig * cmpCfg,Chunk * chunk,bool enableLoweringBuiltin)103     TypedHCRLowering(Circuit* circuit,
104                      CompilationEnv *env,
105                      RPOVisitor* visitor,
106                      CompilationConfig* cmpCfg,
107                      Chunk* chunk,
108                      bool enableLoweringBuiltin)
109         : PassVisitor(circuit, chunk, visitor),
110           circuit_(circuit),
111           compilationEnv_(env),
112           acc_(circuit),
113           builder_(circuit, cmpCfg),
114           dependEntry_(circuit->GetDependRoot()),
115           enableLoweringBuiltin_(enableLoweringBuiltin),
116           traceBuiltins_(env != nullptr ? env->GetJSOptions().GetTraceBuiltins() : false),
117           glue_(acc_.GetGlueFromArgList())
118     {
119     }
120 
121     ~TypedHCRLowering() = default;
122 
123     GateRef VisitGate(GateRef gate) override;
124 
125 private:
126     void Lower(GateRef gate);
127     void LowerType(GateRef gate);
128     void LowerPrimitiveTypeCheck(GateRef gate);
129     void LowerTypeConvert(GateRef gate);
130     void LowerPrimitiveToNumber(GateRef dst, GateRef src, ParamType srcType);
131     void LowerIntCheck(GateRef gate);
132     void LowerDoubleCheck(GateRef gate);
133     void LowerNumberCheck(GateRef gate);
134     void LowerBooleanCheck(GateRef gate);
135     void LowerIndexCheck(GateRef gate);
136     void LowerObjectTypeCheck(GateRef glue, GateRef gate);
137     void LowerSimpleHClassCheck(GateRef glue, GateRef gate);
138     GateRef BuildCompareHClass(GateRef glue, GateRef gate, GateRef frameState);
139     void LowerStableArrayCheck(GateRef glue, GateRef gate);
140     void LowerTypedArrayCheck(GateRef glue, GateRef gate);
141     void LowerEcmaStringCheck(GateRef gate, GateRef glue);
142     void LowerInternStringCheck(GateRef gate, GateRef glue);
143     void LowerStringKeyCheck(GateRef gate, GateRef glue);
144     void LowerInternStringKeyCheck(GateRef gate, GateRef glue);
145     void LowerEcmaMapCheck(GateRef glue, GateRef gate);
146     void LowerFlattenTreeStringCheck(GateRef gate, GateRef glue);
147     void LowerLoadTypedArrayLength(GateRef gate);
148     void LowerStringLength(GateRef gate);
149     void LowerMapSize(GateRef gate);
150     void LowerCallPrivateGetter(GateRef gate, GateRef glue);
151     void LowerCallPrivateSetter(GateRef gate, GateRef glue);
152     void LowerLoadProperty(GateRef gate);
153     void LowerCallGetter(GateRef gate, GateRef glue);
154     void LowerStoreProperty(GateRef gate);
155     void LowerCallSetter(GateRef gate, GateRef glue);
156     void LowerLoadArrayLength(GateRef gate);
157     void LowerStoreElement(GateRef gate, GateRef glue);
158     void LowerLoadElement(GateRef gate, GateRef glue);
159     void LowerLoadFromTaggedArray(GateRef gate);
160     void LowerStoreToTaggedArray(GateRef gate, GateRef glue);
161     void LowerRangeCheckPredicate(GateRef gate);
162     void LowerBuiltinInstanceHClassCheck(GateRef gate);
163     void LowerBuiltinPrototypeHClassCheck(GateRef gate);
164     void BuiltinInstanceStringTypeCheck(GateRef gate);
165     void LowerLoadBuiltinObject(GateRef gate);
166     void LowerTypedCreateObjWithBuffer(GateRef gate, GateRef glue);
167     void LowerNumberToString(GateRef gate, GateRef glue);
168 
169     enum class ArrayState : uint8_t {
170         PACKED = 0,
171         HOLEY,
172     };
173 
174     struct ProtoTypeHolderInfo {
175         GateRef receiver;
176         GateRef holderHClassIndex;
177         GateRef unsharedConstPool;
178         GateRef frameState;
179     };
180     void LowerArrayLoadElement(GateRef gate, ArrayState arrayState, TypedLoadOp op);
181     void LowerCowArrayCheck(GateRef gate, GateRef glue);
182     void LowerTypedArrayLoadElement(GateRef gate, BuiltinTypeId id);
183     void LowerStringLoadElement(GateRef gate, GateRef glue);
184     GateRef BuildOnHeapTypedArrayLoadElement(GateRef glue, GateRef receiver, GateRef offset, VariableType type);
185     GateRef BuildNotOnHeapTypedArrayLoadElement(GateRef glue, GateRef receiver, GateRef offset, VariableType type);
186     GateRef BuildTypedArrayLoadElement(GateRef glue, GateRef receiver, GateRef offset, VariableType type,
187                                        Label *isByteArray, Label *isArrayBuffer, Label *exit);
188     void LowerArrayStoreElement(GateRef gate, GateRef glue, TypedStoreOp kind);
189     void LowerTypedArrayStoreElement(GateRef gate, BuiltinTypeId id);
190     void OptStoreElementByOnHeapMode(GateRef gate, GateRef glue, GateRef receiver, GateRef offset, GateRef value,
191                                      Label *isByteArray, Label *isArrayBuffer, Label *exit);
192     void BuildOnHeapTypedArrayStoreElement(GateRef receiver, GateRef offset, GateRef value);
193     void BuildNotOnHeapTypedArrayStoreElement(GateRef glue, GateRef receiver, GateRef offset, GateRef value);
194     void BuildTypedArrayStoreElement(GateRef glue, GateRef receiver, GateRef offset, GateRef value, Label *isByteArray,
195                                      Label *isArrayBuffer, Label *exit);
196     void LowerUInt8ClampedArrayStoreElement(GateRef gate);
197     void LowerTypedCallBuitin(GateRef gate);
198     void LowerCallTargetCheck(GateRef gate);
199     void LowerJSCallTargetCheck(GateRef gate, GateRef glue);
200     void LowerCallTargetIsCompiledCheck(GateRef gate);
201     void CallTargetIsCompiledCheck(GateRef func, GateRef frameState, Label *checkAlreadyDeopt, Label *exit);
202     void LowerJSCallTargetFromDefineFuncCheck(GateRef gate);
203     void LowerJSCallTargetTypeCheck(GateRef gate, GateRef glue);
204     void LowerJSFastCallTargetTypeCheck(GateRef gate, GateRef glue);
205     void LowerJSCallThisTargetTypeCheck(GateRef gate, GateRef glue);
206     void LowerJSFastCallThisTargetTypeCheck(GateRef gate, GateRef glue);
207     void LowerJSNoGCCallThisTargetTypeCheck(GateRef gate, GateRef glue);
208     void LowerJSNoGCFastCallThisTargetTypeCheck(GateRef gate, GateRef glue);
209     void LowerJSNewObjRangeCallTargetCheck(GateRef gate, GateRef glue);
210     void LowerTypedNewAllocateThis(GateRef gate, GateRef glue);
211     void LowerTypedSuperAllocateThis(GateRef gate, GateRef glue);
212     void LowerGetSuperConstructor(GateRef glue, GateRef gate);
213     void LowerJSInlineTargetTypeCheck(GateRef gate, GateRef glue);
214     void LowerJSInlineTargetHeapConstantCheck(GateRef gate);
215     void SetDeoptTypeInfo(JSType jstype, DeoptType &type, size_t &typedArrayRootHclassIndex,
216         size_t &typedArrayRootHclassOnHeapIndex);
217     void LowerLookupHolder(GateRef glue, GateRef gate);
218     void LowerLoadGetter(GateRef gate, GateRef glue);
219     void LowerLoadSetter(GateRef gate, GateRef glue);
220     void LowerPrototypeCheck(GateRef glue, GateRef gate);
221     void LowerStringEqual(GateRef gate, GateRef glue);
222     void LowerTypeOfCheck(GateRef gate);
223     void LowerTypeOf(GateRef gate, GateRef glue);
224     void LowerTypedConstructorCheck(GateRef gate, GateRef glue);
225     void LowerArrayConstructorCheck(GateRef gate, GateRef glue);
226     void NewArrayConstructorWithNoArgs(GateRef gate, GateRef glue);
227     void LowerArrayConstructor(GateRef gate, GateRef glue);
228     void LowerFloat32ArrayConstructorCheck(GateRef gate, GateRef glue);
229     void NewFloat32ArrayConstructorWithNoArgs(GateRef gate, GateRef glue);
230     void ConvertFloat32ArrayConstructorLength(GateRef len, Variable *arrayLength,
231                                               Label *arrayCreate, Label *slowPath);
232     void LowerFloat32ArrayConstructor(GateRef gate, GateRef glue);
233     void LowerObjectConstructorCheck(GateRef gate, GateRef glue);
234     void LowerObjectConstructor(GateRef gate, GateRef glue);
235     void LowerBooleanConstructorCheck(GateRef gate, GateRef glue);
236     void LowerBooleanConstructor(GateRef gate, GateRef glue);
237     GateRef NewJSPrimitiveRef(PrimitiveType type, GateRef glue, GateRef value);
238     void ReplaceGateWithPendingException(GateRef glue, GateRef gate, GateRef state, GateRef depend, GateRef value);
239     void LowerOrdinaryHasInstance(GateRef gate, GateRef glue);
240     void LowerOrdinaryHasInstanceForJIT(GateRef gate, GateRef glue);
241     void LowerProtoChangeMarkerCheck(GateRef glue, GateRef gate);
242     void LowerPrimitiveTypeProtoChangeMarkerCheck(GateRef glue, GateRef gate);
243     void GetPropertyHolderFromProtoChain(GateRef glue, ProtoTypeHolderInfo holderInfo, Label *loadHolder,
244                                          Variable *current, DeoptType deoptType);
245     void LowerMonoCallGetterOnProto(GateRef gate, GateRef glue);
246     void LowerMonoLoadPropertyOnProto(GateRef glue, GateRef gate);
247     void LowerMonoStorePropertyLookUpProto(GateRef gate, GateRef glue);
248     void LowerMonoStoreProperty(GateRef gate, GateRef glue);
249     void LowerStringFromSingleCharCode(GateRef gate, GateRef glue);
250     void LowerMigrateArrayWithKind(GateRef gate, GateRef glue);
251     void LowerEcmaObjectCheck(GateRef gate);
252     void LowerElementskindCheck(GateRef glue, GateRef gate);
253     void LowerInlineSuperCtorCheck(GateRef glue, GateRef gate);
254     void LowerCheckConstructor(GateRef gate, GateRef glue);
255 
256     GateRef LowerCallRuntime(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args,
257                              bool useLabel = false);
258 
259     enum AccessorMode {
260         GETTER,
261         SETTER,
262     };
263 
264     GateRef CallAccessor(GateRef glue, GateRef gate, GateRef function, GateRef receiver, AccessorMode mode,
265                          GateRef value = Circuit::NullGate());
266     void BuiltinInstanceHClassCheck(Environment *env, GateRef gate);
267     void BuiltinPrototypeHClassCheck(Environment *env, GateRef gate);
268     void ReplaceHirWithPendingException(GateRef hirGate, GateRef glue, GateRef state, GateRef depend, GateRef value);
269 
270     GateRef DoubleToTaggedDoublePtr(GateRef gate);
271     GateRef ChangeInt32ToFloat64(GateRef gate);
272     GateRef TruncDoubleToInt(GateRef gate);
273     GateRef IntToTaggedIntPtr(GateRef x);
274     GateType GetLeftType(GateRef gate);
275     GateType GetRightType(GateRef gate);
276     GateRef GetElementSize(BuiltinTypeId id);
277     VariableType GetVariableType(BuiltinTypeId id);
278 
GetFrameState(GateRef gate)279     GateRef GetFrameState(GateRef gate) const
280     {
281         return acc_.GetFrameState(gate);
282     }
283 
284     VariableType GetVarType(PropertyLookupResult plr);
285     GateRef GetLengthFromSupers(GateRef supers);
286     GateRef GetValueFromSupers(GateRef supers, size_t index);
287     GateRef LoadFromTaggedArray(GateRef array, size_t index);
288     GateRef LoadFromConstPool(GateRef glue, GateRef unsharedConstPool, size_t index, size_t valVecType);
289     GateRef GetLengthFromString(GateRef gate);
290     GateRef LoadPropertyFromHolder(GateRef holder, PropertyLookupResult plr);
291     void StorePropertyOnHolder(GateRef holder, GateRef value, PropertyLookupResult plr, bool needBarrier);
292 
293     Circuit *circuit_;
294     CompilationEnv *compilationEnv_ {nullptr};
295     GateAccessor acc_;
296     CircuitBuilder builder_;
297     GateRef dependEntry_;
298     bool enableLoweringBuiltin_ {false};
299     bool traceBuiltins_ {false};
300     GateRef glue_ {Circuit::NullGate()};
301 };
302 }  // panda::ecmascript::kungfu
303 #endif  // ECMASCRIPT_COMPILER_TYPED_HCR_LOWERING_H
304