• 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 
24 namespace panda::ecmascript::kungfu {
25 // TypeHCRLowering Process
26 // SW: state wire, DW: depend wire, VW: value wire
27 // Before Type Lowering:
28 //                                    SW   DW   VW
29 //                                    |    |    |
30 //                                    |    |    |
31 //                                    v    v    v
32 //                                +-------------------+
33 //                                |       (HIR)       |    SW     +--------------+
34 //                            --DW|    JS_BYTECODE    |---------->| IF_EXCEPTION |
35 //                            |   +-------------------+           +--------------+
36 //                            |            SW       VW
37 //                            |            |        |
38 //                            |            v        |
39 //                            |    +--------------+ |
40 //                            |    |  IF_SUCCESS  | |
41 //                            |    +--------------+ |
42 //                            |            SW       |
43 //                            |            |        |
44 //                            |            v        v
45 //                            |   +-------------------+
46 //                            |   |       (HIR)       |
47 //                            --->|    JS_BYTECODE    |
48 //                                +-------------------+
49 //
50 // After Type Lowering:
51 //                                           SW
52 //                                           |
53 //                                           v
54 //                                 +-------------------+
55 //                                 |     IF_BRANCH     |
56 //                                 |    (Type Check)   |
57 //                                 +-------------------+
58 //                                    SW            SW
59 //                                    |             |
60 //                                    V             V
61 //                            +--------------+  +--------------+
62 //                            |    IF_TRUE   |  |   IF_FALSE   |
63 //                            +--------------+  +--------------+
64 //                 VW   DW          SW               SW                   DW   VW
65 //                 |    |           |                |                    |    |
66 //                 |    |           V                V                    |    |
67 //                 |    |  +---------------+     +---------------------+  |    |
68 //                 ------->|   FAST PATH   |     |        (HIR)        |<-------
69 //                         +---------------+     |     JS_BYTECODE     |
70 //                            VW  DW   SW        +---------------------+
71 //                            |   |    |               SW         VW  DW
72 //                            |   |    |               |          |   |
73 //                            |   |    |               v          |   |
74 //                            |   |    |         +--------------+ |   |
75 //                            |   |    |         |  IF_SUCCESS  | |   |
76 //                            |   |    |         +--------------+ |   |
77 //                            |   |    |                SW        |   |
78 //                            |   |    |                |         |   |
79 //                            |   |    v                v         |   |
80 //                            |   |  +---------------------+      |   |
81 //                            |   |  |        MERGE        |      |   |
82 //                            |   |  +---------------------+      |   |
83 //                            |   |    SW         SW    SW        |   |
84 //                            ----|----|----------|-----|--       |   |
85 //                             ---|----|----------|-----|-|-------|----
86 //                             |  |    |          |     | |       |
87 //                             v  v    v          |     v v       v
88 //                            +-----------------+ | +----------------+
89 //                            | DEPEND_SELECTOR | | | VALUE_SELECTOR |
90 //                            +-----------------+ | +----------------+
91 //                                    DW          |        VW
92 //                                    |           |        |
93 //                                    v           v        v
94 //                                  +------------------------+
95 //                                  |         (HIR)          |
96 //                                  |      JS_BYTECODE       |
97 //                                  +------------------------+
98 
99 class TypedHCRLowering : public PassVisitor {
100 public:
TypedHCRLowering(Circuit * circuit,RPOVisitor * visitor,CompilationConfig * cmpCfg,TSManager * tsManager,Chunk * chunk,bool enableLoweringBuiltin)101     TypedHCRLowering(Circuit* circuit,
102                     RPOVisitor* visitor,
103                     CompilationConfig* cmpCfg,
104                     TSManager* tsManager,
105                     Chunk* chunk,
106                     bool enableLoweringBuiltin)
107         : PassVisitor(circuit, chunk, visitor),
108           circuit_(circuit),
109           acc_(circuit),
110           builder_(circuit, cmpCfg),
111           dependEntry_(circuit->GetDependRoot()),
112           tsManager_(tsManager),
113           enableLoweringBuiltin_(enableLoweringBuiltin)
114     {
115         if (cmpCfg != nullptr) {
116             typedOpProfiling_ = cmpCfg->IsTypedOpProfiling();
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, GateType 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     void LowerTSSubtypingCheck(GateRef gate);
138     void LowerObjectTypeCompare(GateRef gate);
139     void LowerSimpleHClassCompare(GateRef gate);
140     void LowerTSSubtypingCompare(GateRef gate);
141     GateRef BuildCompareSubTyping(GateRef gate, GateRef frameState, Label *levelValid, Label *exit);
142     GateRef BuildCompareHClass(GateRef gate, GateRef frameState);
143     void BuildCompareSubTyping(GateRef gate);
144     void LowerStableArrayCheck(GateRef gate);
145     void LowerTypedArrayCheck(GateRef gate);
146     void LowerEcmaStringCheck(GateRef gate);
147     void LowerFlattenTreeStringCheck(GateRef gate, GateRef glue);
148     void LowerLoadTypedArrayLength(GateRef gate);
149     void LowerStringLength(GateRef gate);
150     void LowerLoadProperty(GateRef gate);
151     void LowerCallGetter(GateRef gate, GateRef glue);
152     void LowerStoreProperty(GateRef gate);
153     void LowerCallSetter(GateRef gate, GateRef glue);
154     void LowerLoadArrayLength(GateRef gate);
155     void LowerStoreElement(GateRef gate, GateRef glue);
156     void LowerLoadElement(GateRef gate);
157     void LowerLoadFromTaggedArray(GateRef gate);
158     void LowerStoreToTaggedArray(GateRef gate, GateRef glue);
159     void LowerRangeCheckPredicate(GateRef gate);
160     void LowerBuiltinPrototypeHClassCheck(GateRef gate);
161     void LowerLoadBuiltinObject(GateRef gate);
162     void LowerTypedCreateObjWithBuffer(GateRef gate, GateRef glue);
163 
164     enum class ArrayState : uint8_t {
165         PACKED = 0,
166         HOLEY,
167     };
168     void LowerArrayLoadElement(GateRef gate, ArrayState arrayState);
169     void LowerCowArrayCheck(GateRef gate, GateRef glue);
170     void LowerTypedArrayLoadElement(GateRef gate, BuiltinTypeId id);
171     void LowerStringLoadElement(GateRef gate);
172     GateRef BuildOnHeapTypedArrayLoadElement(GateRef receiver, GateRef offset, VariableType type);
173     GateRef BuildNotOnHeapTypedArrayLoadElement(GateRef receiver, GateRef offset, VariableType type);
174     GateRef BuildTypedArrayLoadElement(GateRef receiver, GateRef offset, VariableType type, Label *isByteArray,
175                                        Label *isArrayBuffer, Label *exit);
176     void LowerArrayStoreElement(GateRef gate, GateRef glue);
177     void LowerTypedArrayStoreElement(GateRef gate, BuiltinTypeId id);
178     void BuildOnHeapTypedArrayStoreElement(GateRef receiver, GateRef offset, GateRef value);
179     void BuildNotOnHeapTypedArrayStoreElement(GateRef receiver, GateRef offset, GateRef value);
180     void BuildTypedArrayStoreElement(GateRef receiver, GateRef offset, GateRef value, Label *isByteArray,
181                                      Label *isArrayBuffer, Label *exit);
182     void LowerUInt8ClampedArrayStoreElement(GateRef gate);
183     void LowerTypedCallBuitin(GateRef gate);
184     void LowerCallTargetCheck(GateRef gate);
185     void LowerJSCallTargetCheck(GateRef gate);
186     void LowerJSCallTargetFromDefineFuncCheck(GateRef gate);
187     void LowerJSCallTargetTypeCheck(GateRef gate);
188     void LowerJSFastCallTargetTypeCheck(GateRef gate);
189     void LowerJSCallThisTargetTypeCheck(GateRef gate);
190     void LowerJSFastCallThisTargetTypeCheck(GateRef gate);
191     void LowerJSNoGCCallThisTargetTypeCheck(GateRef gate);
192     void LowerJSNoGCFastCallThisTargetTypeCheck(GateRef gate);
193     void LowerTypedNewAllocateThis(GateRef gate, GateRef glue);
194     void LowerTypedSuperAllocateThis(GateRef gate, GateRef glue);
195     void LowerGetSuperConstructor(GateRef gate);
196     void LowerJSInlineTargetTypeCheck(GateRef gate);
197     void SetDeoptTypeInfo(BuiltinTypeId id, DeoptType &type, size_t &typedArrayRootHclassIndex,
198         size_t &typedArrayRootHclassOnHeapIndex);
199     void LowerLookupHolder(GateRef gate);
200     void LowerLoadGetter(GateRef gate);
201     void LowerLoadSetter(GateRef gate);
202     void LowerPrototypeCheck(GateRef gate);
203     void LowerStringEqual(GateRef gate, GateRef glue);
204     void LowerStringAdd(GateRef gate, GateRef glue);
205     void LowerTypeOfCheck(GateRef gate);
206     void LowerTypeOf(GateRef gate, GateRef glue);
207     void LowerArrayConstructorCheck(GateRef gate, GateRef glue);
208     void NewArrayConstructorWithNoArgs(GateRef gate, GateRef glue);
209     void LowerArrayConstructor(GateRef gate, GateRef glue);
210     void LowerObjectConstructorCheck(GateRef gate, GateRef glue);
211     void LowerObjectConstructor(GateRef gate, GateRef glue);
212     GateRef NewJSPrimitiveRef(PrimitiveType type, GateRef glue, GateRef value);
213     void ReplaceGateWithPendingException(GateRef glue, GateRef gate, GateRef state, GateRef depend, GateRef value);
214     void LowerOrdinaryHasInstance(GateRef gate, GateRef glue);
215     void LowerProtoChangeMarkerCheck(GateRef gate);
216     void LowerMonoCallGetterOnProto(GateRef gate, GateRef glue);
217     void LowerMonoLoadPropertyOnProto(GateRef gate);
218     void LowerMonoStorePropertyLookUpProto(GateRef gate, GateRef glue);
219     void LowerMonoStoreProperty(GateRef gate, GateRef glue);
220     void LowerStringFromSingleCharCode(GateRef gate, GateRef glue);
221 
222     GateRef LowerCallRuntime(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args,
223                              bool useLabel = false);
224 
225     enum AccessorMode {
226         GETTER,
227         SETTER,
228     };
229 
230     GateRef CallAccessor(GateRef glue, GateRef gate, GateRef function, GateRef receiver, AccessorMode mode,
231                          GateRef value = Circuit::NullGate());
232     void ReplaceHirWithPendingException(GateRef hirGate, GateRef glue, GateRef state, GateRef depend, GateRef value);
233 
234     GateRef DoubleToTaggedDoublePtr(GateRef gate);
235     GateRef ChangeInt32ToFloat64(GateRef gate);
236     GateRef TruncDoubleToInt(GateRef gate);
237     GateRef IntToTaggedIntPtr(GateRef x);
238     GateType GetLeftType(GateRef gate);
239     GateType GetRightType(GateRef gate);
240     GateRef GetObjectFromConstPool(GateRef jsFunc, GateRef index);
241     GateRef GetElementSize(BuiltinTypeId id);
242     VariableType GetVariableType(BuiltinTypeId id);
243     GateRef AllocateLineString(GateRef length, GateRef canBeCompressed);
244     GateRef AllocateSlicedString(GateRef flatString, GateRef length, GateRef canBeCompressed);
245     bool IsFirstConcatInStringAdd(GateRef gate) const;
246     bool ConcatIsInStringAdd(GateRef gate) const;
247 
GetFrameState(GateRef gate)248     GateRef GetFrameState(GateRef gate) const
249     {
250         return acc_.GetFrameState(gate);
251     }
252 
253     VariableType GetVarType(PropertyLookupResult plr);
254     GateRef LoadSupers(GateRef hclass);
255     GateRef GetLengthFromSupers(GateRef supers);
256     GateRef GetValueFromSupers(GateRef supers, size_t index);
257     GateRef LoadFromTaggedArray(GateRef array, size_t index);
258     GateRef LoadFromConstPool(GateRef jsFunc, size_t index, size_t valVecType);
259     GateRef LoadFromVTable(GateRef receiver, size_t index);
260     GateRef GetLengthFromString(GateRef gate);
261     GateRef LoadPropertyFromHolder(GateRef holder, PropertyLookupResult plr);
262     void StorePropertyOnHolder(GateRef holder, GateRef value, PropertyLookupResult plr, bool needBarrier);
263 
264     void AddProfiling(GateRef gate);
265 
IsTypedOpProfiling()266     bool IsTypedOpProfiling() const
267     {
268         return typedOpProfiling_;
269     }
270 
271     Circuit *circuit_;
272     GateAccessor acc_;
273     CircuitBuilder builder_;
274     GateRef dependEntry_;
275     [[maybe_unused]] TSManager *tsManager_ {nullptr};
276     bool enableLoweringBuiltin_ {false};
277     bool typedOpProfiling_ {false};
278 };
279 }  // panda::ecmascript::kungfu
280 #endif  // ECMASCRIPT_COMPILER_TYPED_HCR_LOWERING_H
281