• 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     {
118     }
119 
120     ~TypedHCRLowering() = default;
121 
122     GateRef VisitGate(GateRef gate) override;
123 
124 private:
125     void Lower(GateRef gate);
126     void LowerType(GateRef gate);
127     void LowerPrimitiveTypeCheck(GateRef gate);
128     void LowerTypeConvert(GateRef gate);
129     void LowerPrimitiveToNumber(GateRef dst, GateRef src, ParamType srcType);
130     void LowerIntCheck(GateRef gate);
131     void LowerDoubleCheck(GateRef gate);
132     void LowerNumberCheck(GateRef gate);
133     void LowerBooleanCheck(GateRef gate);
134     void LowerIndexCheck(GateRef gate);
135     void LowerObjectTypeCheck(GateRef gate);
136     void LowerSimpleHClassCheck(GateRef gate);
137     GateRef BuildCompareHClass(GateRef gate, GateRef frameState);
138     void LowerStableArrayCheck(GateRef gate);
139     void LowerTypedArrayCheck(GateRef gate);
140     void LowerEcmaStringCheck(GateRef gate);
141     void LowerInternStringCheck(GateRef gate);
142     void LowerEcmaMapCheck(GateRef gate);
143     void LowerFlattenTreeStringCheck(GateRef gate, GateRef glue);
144     void LowerLoadTypedArrayLength(GateRef gate);
145     void LowerStringLength(GateRef gate);
146     void LowerMapSize(GateRef gate);
147     void LowerCallPrivateGetter(GateRef gate, GateRef glue);
148     void LowerCallPrivateSetter(GateRef gate, GateRef glue);
149     void LowerLoadProperty(GateRef gate);
150     void LowerCallGetter(GateRef gate, GateRef glue);
151     void LowerStoreProperty(GateRef gate);
152     void LowerCallSetter(GateRef gate, GateRef glue);
153     void LowerLoadArrayLength(GateRef gate);
154     void LowerStoreElement(GateRef gate, GateRef glue);
155     void LowerLoadElement(GateRef gate);
156     void LowerLoadFromTaggedArray(GateRef gate);
157     void LowerStoreToTaggedArray(GateRef gate, GateRef glue);
158     void LowerRangeCheckPredicate(GateRef gate);
159     void LowerBuiltinPrototypeHClassCheck(GateRef gate);
160     void BuiltinInstanceStringTypeCheck(GateRef gate);
161     void LowerLoadBuiltinObject(GateRef gate);
162     void LowerTypedCreateObjWithBuffer(GateRef gate, GateRef glue);
163     void LowerNumberToString(GateRef gate, GateRef glue);
164 
165     enum class ArrayState : uint8_t {
166         PACKED = 0,
167         HOLEY,
168     };
169     void LowerArrayLoadElement(GateRef gate, ArrayState arrayState, TypedLoadOp op);
170     void LowerCowArrayCheck(GateRef gate, GateRef glue);
171     void LowerTypedArrayLoadElement(GateRef gate, BuiltinTypeId id);
172     void LowerStringLoadElement(GateRef gate);
173     GateRef BuildOnHeapTypedArrayLoadElement(GateRef receiver, GateRef offset, VariableType type);
174     GateRef BuildNotOnHeapTypedArrayLoadElement(GateRef receiver, GateRef offset, VariableType type);
175     GateRef BuildTypedArrayLoadElement(GateRef receiver, GateRef offset, VariableType type, Label *isByteArray,
176                                        Label *isArrayBuffer, Label *exit);
177     void LowerArrayStoreElement(GateRef gate, GateRef glue, TypedStoreOp kind);
178     void LowerTypedArrayStoreElement(GateRef gate, BuiltinTypeId id);
179     void OptStoreElementByOnHeapMode(GateRef gate, GateRef receiver, GateRef offset, GateRef value, Label *isByteArray,
180                                      Label *isArrayBuffer, Label *exit);
181     void BuildOnHeapTypedArrayStoreElement(GateRef receiver, GateRef offset, GateRef value);
182     void BuildNotOnHeapTypedArrayStoreElement(GateRef receiver, GateRef offset, GateRef value);
183     void BuildTypedArrayStoreElement(GateRef receiver, GateRef offset, GateRef value, Label *isByteArray,
184                                      Label *isArrayBuffer, Label *exit);
185     void LowerUInt8ClampedArrayStoreElement(GateRef gate);
186     void LowerTypedCallBuitin(GateRef gate);
187     void LowerCallTargetCheck(GateRef gate);
188     void LowerJSCallTargetCheck(GateRef gate);
189     void LowerCallTargetIsCompiledCheck(GateRef gate);
190     void CallTargetIsCompiledCheck(GateRef func, GateRef frameState, Label *checkAlreadyDeopt, Label *exit);
191     void LowerJSCallTargetFromDefineFuncCheck(GateRef gate);
192     void LowerJSCallTargetTypeCheck(GateRef gate);
193     void LowerJSFastCallTargetTypeCheck(GateRef gate);
194     void LowerJSCallThisTargetTypeCheck(GateRef gate);
195     void LowerJSFastCallThisTargetTypeCheck(GateRef gate);
196     void LowerJSNoGCCallThisTargetTypeCheck(GateRef gate);
197     void LowerJSNoGCFastCallThisTargetTypeCheck(GateRef gate);
198     void LowerJSNewObjRangeCallTargetCheck(GateRef gate);
199     void LowerTypedNewAllocateThis(GateRef gate, GateRef glue);
200     void LowerTypedSuperAllocateThis(GateRef gate, GateRef glue);
201     void LowerGetSuperConstructor(GateRef gate);
202     void LowerJSInlineTargetTypeCheck(GateRef gate);
203     void SetDeoptTypeInfo(JSType jstype, DeoptType &type, size_t &typedArrayRootHclassIndex,
204         size_t &typedArrayRootHclassOnHeapIndex);
205     void LowerLookupHolder(GateRef gate);
206     void LowerLoadGetter(GateRef gate);
207     void LowerLoadSetter(GateRef gate);
208     void LowerPrototypeCheck(GateRef gate);
209     void LowerStringEqual(GateRef gate, GateRef glue);
210     void LowerTypeOfCheck(GateRef gate);
211     void LowerTypeOf(GateRef gate, GateRef glue);
212     void LowerArrayConstructorCheck(GateRef gate, GateRef glue);
213     void NewArrayConstructorWithNoArgs(GateRef gate, GateRef glue);
214     void LowerArrayConstructor(GateRef gate, GateRef glue);
215     void LowerFloat32ArrayConstructorCheck(GateRef gate, GateRef glue);
216     void NewFloat32ArrayConstructorWithNoArgs(GateRef gate, GateRef glue);
217     void ConvertFloat32ArrayConstructorLength(GateRef len, Variable *arrayLength,
218                                               Label *arrayCreate, Label *slowPath);
219     void LowerFloat32ArrayConstructor(GateRef gate, GateRef glue);
220     void LowerObjectConstructorCheck(GateRef gate, GateRef glue);
221     void LowerObjectConstructor(GateRef gate, GateRef glue);
222     void LowerBooleanConstructorCheck(GateRef gate, GateRef glue);
223     void LowerBooleanConstructor(GateRef gate, GateRef glue);
224     GateRef NewJSPrimitiveRef(PrimitiveType type, GateRef glue, GateRef value);
225     void ReplaceGateWithPendingException(GateRef glue, GateRef gate, GateRef state, GateRef depend, GateRef value);
226     void LowerOrdinaryHasInstance(GateRef gate, GateRef glue);
227     void LowerProtoChangeMarkerCheck(GateRef gate);
228     void LowerMonoCallGetterOnProto(GateRef gate, GateRef glue);
229     void LowerMonoLoadPropertyOnProto(GateRef gate);
230     void LowerMonoStorePropertyLookUpProto(GateRef gate, GateRef glue);
231     void LowerMonoStoreProperty(GateRef gate, GateRef glue);
232     void LowerStringFromSingleCharCode(GateRef gate, GateRef glue);
233     void LowerMigrateArrayWithKind(GateRef gate);
234     void LowerEcmaObjectCheck(GateRef gate);
235     void LowerElementskindCheck(GateRef gate);
236 
237     GateRef LowerCallRuntime(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args,
238                              bool useLabel = false);
239 
240     enum AccessorMode {
241         GETTER,
242         SETTER,
243     };
244 
245     GateRef CallAccessor(GateRef glue, GateRef gate, GateRef function, GateRef receiver, AccessorMode mode,
246                          GateRef value = Circuit::NullGate());
247     void BuiltinInstanceHClassCheck(Environment *env, GateRef gate);
248     void BuiltinPrototypeHClassCheck(Environment *env, GateRef gate);
249     void ReplaceHirWithPendingException(GateRef hirGate, GateRef glue, GateRef state, GateRef depend, GateRef value);
250 
251     GateRef DoubleToTaggedDoublePtr(GateRef gate);
252     GateRef ChangeInt32ToFloat64(GateRef gate);
253     GateRef TruncDoubleToInt(GateRef gate);
254     GateRef IntToTaggedIntPtr(GateRef x);
255     GateType GetLeftType(GateRef gate);
256     GateType GetRightType(GateRef gate);
257     GateRef GetElementSize(BuiltinTypeId id);
258     VariableType GetVariableType(BuiltinTypeId id);
259 
GetFrameState(GateRef gate)260     GateRef GetFrameState(GateRef gate) const
261     {
262         return acc_.GetFrameState(gate);
263     }
264 
265     VariableType GetVarType(PropertyLookupResult plr);
266     GateRef GetLengthFromSupers(GateRef supers);
267     GateRef GetValueFromSupers(GateRef supers, size_t index);
268     GateRef LoadFromTaggedArray(GateRef array, size_t index);
269     GateRef LoadFromConstPool(GateRef unsharedConstPool, size_t index, size_t valVecType);
270     GateRef GetLengthFromString(GateRef gate);
271     GateRef LoadPropertyFromHolder(GateRef holder, PropertyLookupResult plr);
272     void StorePropertyOnHolder(GateRef holder, GateRef value, PropertyLookupResult plr, bool needBarrier);
273 
274     Circuit *circuit_;
275     CompilationEnv *compilationEnv_ {nullptr};
276     GateAccessor acc_;
277     CircuitBuilder builder_;
278     GateRef dependEntry_;
279     bool enableLoweringBuiltin_ {false};
280     bool traceBuiltins_ {false};
281 };
282 }  // panda::ecmascript::kungfu
283 #endif  // ECMASCRIPT_COMPILER_TYPED_HCR_LOWERING_H
284