• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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_BYTECODE_LOWERING_H
17 #define ECMASCRIPT_COMPILER_TYPED_BYTECODE_LOWERING_H
18 
19 #include "ecmascript/builtin_entries.h"
20 #include "ecmascript/compiler/argument_accessor.h"
21 #include "ecmascript/compiler/builtins/builtins_call_signature.h"
22 #include "ecmascript/compiler/bytecode_circuit_builder.h"
23 #include "ecmascript/compiler/circuit_builder-inl.h"
24 #include "ecmascript/compiler/object_access_helper.h"
25 #include "ecmascript/compiler/pass_manager.h"
26 #include "ecmascript/compiler/pgo_type/pgo_type_manager.h"
27 #include "ecmascript/compiler/type_info_accessors.h"
28 #include "ecmascript/enum_conversion.h"
29 
30 namespace panda::ecmascript::kungfu {
31 class TypedBytecodeLowering {
32 public:
TypedBytecodeLowering(Circuit * circuit,PassContext * ctx,Chunk * chunk,bool enableLog,bool enableTypeLog,const std::string & name,bool enableLoweringBuiltin,const CString & recordName)33     TypedBytecodeLowering(Circuit* circuit,
34                          PassContext* ctx,
35                          Chunk* chunk,
36                          bool enableLog,
37                          bool enableTypeLog,
38                          const std::string& name,
39                          bool enableLoweringBuiltin,
40                          const CString& recordName)
41         : circuit_(circuit),
42           acc_(circuit),
43           builder_(circuit, ctx->GetCompilerConfig()),
44           dependEntry_(circuit->GetDependRoot()),
45           tsManager_(ctx->GetTSManager()),
46           chunk_(chunk),
47           enableLog_(enableLog),
48           enableTypeLog_(enableTypeLog),
49           profiling_(ctx->GetCompilerConfig()->IsProfiling()),
50           verifyVTable_(ctx->GetCompilerConfig()->IsVerifyVTbale()),
51           traceBc_(ctx->GetCompilerConfig()->IsTraceBC()),
52           methodName_(name),
53           glue_(acc_.GetGlueFromArgList()),
54           argAcc_(circuit),
55           pgoTypeLog_(circuit),
56           noCheck_(ctx->GetEcmaVM()->GetJSOptions().IsCompilerNoCheck()),
57           thread_(ctx->GetEcmaVM()->GetJSThread()),
58           enableLoweringBuiltin_(enableLoweringBuiltin),
59           recordName_(recordName)
60     {
61     }
62 
63     ~TypedBytecodeLowering() = default;
64 
65     bool RunTypedBytecodeLowering();
66 
67 private:
IsLogEnabled()68     bool IsLogEnabled() const
69     {
70         return enableLog_;
71     }
72 
IsTypeLogEnabled()73     bool IsTypeLogEnabled() const
74     {
75         return enableTypeLog_;
76     }
77 
IsProfiling()78     bool IsProfiling() const
79     {
80         return profiling_;
81     }
82 
IsVerifyVTbale()83     bool IsVerifyVTbale() const
84     {
85         return verifyVTable_;
86     }
87 
IsTraceBC()88     bool IsTraceBC() const
89     {
90         return traceBc_;
91     }
92 
GetMethodName()93     const std::string& GetMethodName() const
94     {
95         return methodName_;
96     }
97 
98     void Lower(GateRef gate);
99     template<TypedBinOp Op>
100     void LowerTypedBinOp(GateRef gate, bool convertNumberType = true);
101     template<TypedUnOp Op>
102     void LowerTypedUnOp(GateRef gate);
103     template<TypedBinOp Op>
104     void LowerTypedEqOrNotEq(GateRef gate);
105     void LowerTypeToNumeric(GateRef gate);
106     void LowerPrimitiveTypeToNumber(const UnOpTypeInfoAccessor &tacc);
107     void LowerConditionJump(GateRef gate, bool flag);
108 
109     void LowerTypedTryLdGlobalByName(GateRef gate);
110 
111     void LowerTypedLdObjByName(GateRef gate);
112     void LowerTypedStObjByName(GateRef gate);
113     void LowerTypedStOwnByName(GateRef gate);
114     GateRef BuildNamedPropertyAccess(GateRef hir, GateRef receiver, GateRef holder, PropertyLookupResult plr);
115     GateRef BuildNamedPropertyAccess(GateRef hir, GateRef receiver, GateRef holder,
116                                      GateRef value, PropertyLookupResult plr, uint32_t receiverHClassIndex = 0);
117     using AccessMode = PGOObjectAccessHelper::AccessMode;
118     bool TryLowerTypedLdObjByNameForBuiltin(GateRef gate);
119     bool TryLowerTypedLdObjByNameForBuiltin(const LoadBulitinObjTypeInfoAccessor &tacc, BuiltinTypeId type);
120     void LowerTypedLdArrayLength(const LoadBulitinObjTypeInfoAccessor &tacc);
121     void LowerTypedLdTypedArrayLength(const LoadBulitinObjTypeInfoAccessor &tacc);
122     void LowerTypedLdStringLength(const LoadBulitinObjTypeInfoAccessor &tacc);
123     bool TryLowerTypedLdObjByNameForBuiltinMethod(GateRef gate, JSTaggedValue key, BuiltinTypeId type);
124 
125     void LowerTypedLdObjByIndex(GateRef gate);
126     bool TryLowerTypedLdObjByIndexForBuiltin(GateRef gate);
127     void LowerTypedStObjByIndex(GateRef gate);
128     bool TryLowerTypedStObjByIndexForBuiltin(GateRef gate);
129 
130     void LowerTypedLdObjByValue(GateRef gate);
131     bool TryLowerTypedLdObjByValueForBuiltin(GateRef gate);
132     void LowerTypedStObjByValue(GateRef gate);
133     void LowerTypedStOwnByValue(GateRef gate);
134     bool TryLowerTypedStObjByValueForBuiltin(GateRef gate);
135 
136     void LowerTypedIsTrueOrFalse(GateRef gate, bool flag);
137 
138     void LowerTypedNewObjRange(GateRef gate);
139     void LowerCreateEmptyObject(GateRef gate);
140     void LowerCreateObjectWithBuffer(GateRef gate);
141     void LowerTypedSuperCall(GateRef gate);
142 
143     void LowerTypedCallArg0(GateRef gate);
144     void LowerTypedCallArg1(GateRef gate);
145     void LowerTypedCallArg2(GateRef gate);
146     void LowerTypedCallArg3(GateRef gate);
147     void LowerTypedCallrange(GateRef gate);
148     void LowerTypedCallthis0(GateRef gate);
149     void LowerTypedCallthis1(GateRef gate);
150     void LowerTypedCallthis2(GateRef gate);
151     void LowerTypedCallthis3(GateRef gate);
152     void LowerTypedCallthisrange(GateRef gate);
153     void LowerTypedCallInit(GateRef gate);
154 
155     template<class TypeAccessor>
156     void CheckFastCallThisCallTarget(const TypeAccessor &tacc);
157 
158     template<class TypeAccessor>
159     void CheckCallThisCallTarget(const TypeAccessor &tacc);
160 
161     template<class TypeAccessor>
162     void CheckThisCallTargetAndLowerCall(const TypeAccessor &tacc,
163         const std::vector<GateRef> &args, const std::vector<GateRef> &argsFastCall);
164 
165     template<class TypeAccessor>
166     void CheckCallTargetFromDefineFuncAndLowerCall(const TypeAccessor &tacc,
167         const std::vector<GateRef> &args, const std::vector<GateRef> &argsFastCall, bool isNoGC);
168 
169     template<class TypeAccessor>
170     void CheckCallTargetAndLowerCall(const TypeAccessor &tacc,
171         const std::vector<GateRef> &args, const std::vector<GateRef> &argsFastCall);
172 
173     template<EcmaOpcode Op, class TypeAccessor>
174     void LowerTypedCall(const TypeAccessor &tacc);
175 
176     template<EcmaOpcode Op, class TypeAccessor>
177     void LowerTypedThisCall(const TypeAccessor &tacc);
178 
179     bool IsLoadVtable(GateRef func);
180     void LowerFastCall(GateRef gate, GateRef func, const std::vector<GateRef> &argsFastCall, bool isNoGC);
181     void LowerCall(GateRef gate, GateRef func, const std::vector<GateRef> &args, bool isNoGC);
182     void LowerTypedTypeOf(GateRef gate);
183     void LowerInstanceOf(GateRef gate);
184     void LowerGetIterator(GateRef gate);
185     GateRef LoadStringByIndex(const LoadBulitinObjTypeInfoAccessor &tacc);
186     GateRef LoadJSArrayByIndex(const LoadBulitinObjTypeInfoAccessor &tacc);
187     GateRef LoadTypedArrayByIndex(const LoadBulitinObjTypeInfoAccessor &tacc);
188     void StoreJSArrayByIndex(const StoreBulitinObjTypeInfoAccessor &tacc);
189     void StoreTypedArrayByIndex(const StoreBulitinObjTypeInfoAccessor &tacc);
190 
191     void AddBytecodeCount(EcmaOpcode op);
192     void DeleteBytecodeCount(EcmaOpcode op);
193     void AddHitBytecodeCount();
194 
195     template<TypedBinOp Op>
196     void SpeculateStrings(GateRef gate);
197     template<TypedBinOp Op>
198     void SpeculateNumbers(GateRef gate);
199     template<TypedUnOp Op>
200     void SpeculateNumber(GateRef gate);
201     void SpeculateConditionJump(const ConditionJumpTypeInfoAccessor &tacc, bool flag);
202     void SpeculateCallBuiltin(GateRef gate, GateRef func, const std::vector<GateRef> &args,
203                               BuiltinsStubCSigns::ID id, bool isThrow);
204     void DeleteConstDataIfNoUser(GateRef gate);
205     bool TryLowerNewBuiltinConstructor(GateRef gate);
206     bool TryLowerTypedLdobjBynameFromGloablBuiltin(GateRef gate);
207 
208     void AddProfiling(GateRef gate);
209 
Uncheck()210     bool Uncheck() const
211     {
212         return noCheck_;
213     }
214 
215     Circuit *circuit_ {nullptr};
216     GateAccessor acc_;
217     CircuitBuilder builder_;
218     GateRef dependEntry_ {Gate::InvalidGateRef};
219     TSManager *tsManager_ {nullptr};
220     Chunk *chunk_ {nullptr};
221     bool enableLog_ {false};
222     bool enableTypeLog_ {false};
223     bool profiling_ {false};
224     bool verifyVTable_ {false};
225     bool traceBc_ {false};
226     size_t allJSBcCount_ {0};
227     size_t allNonTypedOpCount_ {0};
228     size_t hitTypedOpCount_ {0};
229     std::string methodName_;
230     GateRef glue_ {Circuit::NullGate()};
231     ArgumentAccessor argAcc_;
232     EcmaOpcode currentOp_ {static_cast<EcmaOpcode>(0xff)};
233     PGOTypeLogList pgoTypeLog_;
234     std::unordered_map<EcmaOpcode, uint32_t> bytecodeMap_;
235     std::unordered_map<EcmaOpcode, uint32_t> bytecodeHitTimeMap_;
236     bool noCheck_ {false};
237     const JSThread *thread_ {nullptr};
238     bool enableLoweringBuiltin_ {false};
239     const CString &recordName_;
240 };
241 }  // panda::ecmascript::kungfu
242 #endif  // ECMASCRIPT_COMPILER_TYPED_BYTECODE_LOWERING_H
243