• 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/aot_compiler_preprocessor.h"
22 #include "ecmascript/compiler/builtins/builtins_call_signature.h"
23 #include "ecmascript/compiler/bytecode_circuit_builder.h"
24 #include "ecmascript/compiler/circuit_builder-inl.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,const CallMethodFlagMap * callMethodFlagMap,PGOProfilerDecoder * decoder,const std::string optBCRange,const MethodLiteral * currentMethod)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                          const CallMethodFlagMap* callMethodFlagMap,
42                          PGOProfilerDecoder *decoder,
43                          const std::string optBCRange,
44                          const MethodLiteral *currentMethod)
45         : circuit_(circuit),
46           acc_(circuit),
47           ctx_(ctx),
48           builder_(circuit, ctx->GetCompilerConfig()),
49           dependEntry_(circuit->GetDependRoot()),
50           chunk_(chunk),
51           enableLog_(enableLog),
52           enableTypeLog_(enableTypeLog),
53           profiling_(ctx->GetCompilerConfig()->IsProfiling()),
54           verifyVTable_(ctx->GetCompilerConfig()->IsVerifyVTbale()),
55           traceBc_(ctx->GetCompilerConfig()->IsTraceBC()),
56           methodName_(name),
57           glue_(acc_.GetGlueFromArgList()),
58           argAcc_(circuit),
59           pgoTypeLog_(circuit),
60           noCheck_(ctx->GetCompilationEnv()->GetJSOptions().IsCompilerNoCheck()),
61           compilationEnv_(ctx->GetCompilationEnv()),
62           enableLoweringBuiltin_(enableLoweringBuiltin),
63           recordName_(recordName),
64           callMethodFlagMap_(callMethodFlagMap),
65           decoder_(decoder),
66           optBCRange_(optBCRange),
67           currentMethod_(currentMethod)
68     {
69         auto currentMethodId = currentMethod_->GetMethodId();
70         panda_file::IndexAccessor indexAccessor(*(ctx_->GetJSPandaFile()->GetPandaFile()),
71                                                 panda_file::File::EntityId(currentMethodId));
72         constPoolId_ = static_cast<uint32_t>(indexAccessor.GetHeaderIndex());
73     }
74 
75     ~TypedBytecodeLowering() = default;
76 
77     void RunTypedBytecodeLowering();
78 
79 private:
IsLogEnabled()80     bool IsLogEnabled() const
81     {
82         return enableLog_;
83     }
84 
IsTypeLogEnabled()85     bool IsTypeLogEnabled() const
86     {
87         return enableTypeLog_;
88     }
89 
IsProfiling()90     bool IsProfiling() const
91     {
92         return profiling_;
93     }
94 
IsVerifyVTbale()95     bool IsVerifyVTbale() const
96     {
97         return verifyVTable_;
98     }
99 
IsTraceBC()100     bool IsTraceBC() const
101     {
102         return traceBc_;
103     }
104 
GetMethodName()105     const std::string& GetMethodName() const
106     {
107         return methodName_;
108     }
109 
110     void Lower(GateRef gate);
111     template<TypedBinOp Op>
112     void LowerTypedBinOp(GateRef gate);
113     template<TypedUnOp Op>
114     void LowerTypedUnOp(GateRef gate);
115     template<TypedBinOp Op>
116     void LowerTypedEqOrNotEq(GateRef gate);
117     void LowerTypeToNumeric(GateRef gate);
118     void LowerPrimitiveTypeToNumber(const UnOpTypeInfoAccessor &tacc);
119     void LowerConditionJump(GateRef gate, bool flag);
120 
121     void LowerTypedTryLdGlobalByName(GateRef gate);
122 
123     void LowerTypedStPrivateProperty(GateRef gate);
124     void LowerTypedLdPrivateProperty(GateRef gate);
125     void LowerTypedLdObjByName(GateRef gate);
126     void LowerTypedStObjByName(GateRef gate);
127     void TypedStObjByNameTransition(GateRef gate, GateRef receiverHC, GateRef frameState,
128                                     Label &exit, StoreObjByNameTypeInfoAccessor &tacc, size_t i);
129     void LowerTypedStOwnByName(GateRef gate);
130     GateRef BuildNamedPropertyAccess(GateRef hir, GateRef receiver, GateRef holder, PropertyLookupResult plr);
131     GateRef BuildNamedPropertyAccess(GateRef hir, GateRef receiver, GateRef holder,
132                                      GateRef value, PropertyLookupResult plr, uint32_t receiverHClassIndex = 0);
133     bool TryLowerTypedLdObjByNameForBuiltin(GateRef gate);
134     bool TryLowerTypedLdObjByNameForBuiltinsId(const LoadBulitinObjTypeInfoAccessor &tacc, BuiltinTypeId type);
135     bool TryLowerTypedLdObjByNameForBuiltin(const LoadBulitinObjTypeInfoAccessor &tacc);
136     bool TryLowerTypedLdObjByNameForGlobalsId(const LoadBulitinObjTypeInfoAccessor &tacc, GlobalIndex globalsId);
137     void LowerTypedLdArrayLength(const LoadBulitinObjTypeInfoAccessor &tacc);
138     void LowerTypedLdTypedArrayLength(const LoadBulitinObjTypeInfoAccessor &tacc);
139     void LowerTypedLdStringLength(const LoadBulitinObjTypeInfoAccessor &tacc);
140     void LowerTypedLdMapSize(const LoadBulitinObjTypeInfoAccessor &tacc);
141     bool TryLowerTypedLdObjByNameForBuiltinMethod(const LoadBulitinObjTypeInfoAccessor &tacc, BuiltinTypeId type);
142 
143     void LowerTypedLdObjByIndex(GateRef gate);
144     bool TryLowerTypedLdObjByIndexForBuiltin(GateRef gate);
145     void LowerTypedStObjByIndex(GateRef gate);
146     bool TryLowerTypedStObjByIndexForBuiltin(GateRef gate);
147 
148     void LowerTypedLdObjByValue(GateRef gate);
149     bool TryLowerTypedLdObjByValueForBuiltin(GateRef gate);
150     void LowerTypedStObjByValue(GateRef gate);
151     void LowerTypedStOwnByValue(GateRef gate);
152     bool TryLowerTypedStObjByValueForBuiltin(GateRef gate);
153 
154     void LowerTypedIsTrueOrFalse(GateRef gate, bool flag);
155 
156     void LowerTypedNewObjRange(GateRef gate);
157     void LowerCreateEmptyObject(GateRef gate);
158     void LowerCreateObjectWithBuffer(GateRef gate);
159     void LowerTypedSuperCall(GateRef gate);
160 
161     void LowerTypedCallArg0(GateRef gate);
162     void LowerTypedCallArg1(GateRef gate);
163     void LowerTypedCallArg2(GateRef gate);
164     void LowerTypedCallArg3(GateRef gate);
165     void LowerTypedCallrange(GateRef gate);
166     void LowerTypedCallthis0(GateRef gate);
167     void LowerTypedCallthis1(GateRef gate);
168     void LowerTypedCallthis2(GateRef gate);
169     void LowerTypedCallthis3(GateRef gate);
170     void LowerTypedCallthisrange(GateRef gate);
171     void LowerTypedCallInit(GateRef gate);
172 
173     template<class TypeAccessor>
174     bool InSameConstPool(const TypeAccessor &tacc) const;
175 
176     template<class TypeAccessor>
177     void CheckFastCallThisCallTarget(const TypeAccessor &tacc);
178 
179     template<class TypeAccessor>
180     void CheckCallThisCallTarget(const TypeAccessor &tacc);
181 
182     template<class TypeAccessor>
183     void CheckThisCallTargetAndLowerCall(const TypeAccessor &tacc,
184         const std::vector<GateRef> &args, const std::vector<GateRef> &argsFastCall);
185 
186     template<class TypeAccessor>
187     void CheckCallTargetFromDefineFuncAndLowerCall(const TypeAccessor &tacc,
188         const std::vector<GateRef> &args, const std::vector<GateRef> &argsFastCall, bool isNoGC);
189 
190     template<class TypeAccessor>
191     void CheckCallTargetAndLowerCall(const TypeAccessor &tacc,
192         const std::vector<GateRef> &args, const std::vector<GateRef> &argsFastCall);
193 
194     template<EcmaOpcode Op, class TypeAccessor>
195     void LowerTypedCall(const TypeAccessor &tacc);
196 
197     template<EcmaOpcode Op, class TypeAccessor>
198     void LowerTypedThisCall(const TypeAccessor &tacc);
199 
200     bool IsLoadVtable(GateRef func);
201     void LowerFastCall(GateRef gate, GateRef func, const std::vector<GateRef> &argsFastCall, bool isNoGC);
202     void LowerCall(GateRef gate, GateRef func, const std::vector<GateRef> &args, bool isNoGC);
203     void LowerTypedTypeOf(GateRef gate);
204     void LowerInstanceOf(GateRef gate);
205     void LowerGetIterator(GateRef gate);
206     GateRef LoadStringByIndex(const LoadBulitinObjTypeInfoAccessor &tacc);
207     GateRef LoadJSArrayByIndex(const LoadBulitinObjTypeInfoAccessor &tacc);
208     GateRef LoadTypedArrayByIndex(const LoadBulitinObjTypeInfoAccessor &tacc);
209     GateRef LoadElmentFromFloat64Array(const LoadBulitinObjTypeInfoAccessor &tacc);
210     void StoreJSArrayByIndex(const StoreBulitinObjTypeInfoAccessor &tacc);
211     void StoreTypedArrayByIndex(const StoreBulitinObjTypeInfoAccessor &tacc);
212 
213     void AddBytecodeCount(EcmaOpcode op);
214     void DeleteBytecodeCount(EcmaOpcode op);
215     void AddHitBytecodeCount();
216 
217     GateRef InternStringCheck(GateRef gate);
218     template<TypedBinOp Op>
219     void SpeculateInternStrings(const BinOpTypeInfoAccessor& tacc);
220     template<TypedBinOp Op>
221     void SpeculateStrings(const BinOpTypeInfoAccessor& tacc);
222     template<TypedBinOp Op>
223     void SpeculateNumbers(const BinOpTypeInfoAccessor& tacc);
224     template<TypedBinOp Op>
225     void SpeculateNumbersOrString(const BinOpTypeInfoAccessor& tacc);
226     template<TypedUnOp Op>
227     void SpeculateNumber(const UnOpTypeInfoAccessor& tacc);
228     void SpeculateConditionJump(const ConditionJumpTypeInfoAccessor &tacc, bool flag);
229     void SpeculateCallBuiltin(GateRef gate, GateRef func, const std::vector<GateRef> &args,
230                               BuiltinsStubCSigns::ID id, bool isThrow);
231     void SpeculateCallBuiltinFromGlobal(GateRef gate, const std::vector<GateRef> &args,
232                                         BuiltinsStubCSigns::ID id, bool isThrow, bool isSideEffect = false);
233     void DeleteConstDataIfNoUser(GateRef gate);
234     bool TryLowerNewBuiltinConstructor(GateRef gate);
235     bool TryLowerTypedLdobjBynameFromGloablBuiltin(GateRef gate);
236     bool CheckIsInOptBCIgnoreRange(int32_t index, EcmaOpcode ecmaOpcode);
237     bool IsTrueOrFalseHasProfileType(GateRef gate) const;
238     int32_t GetEcmaOpCodeListIndex(EcmaOpcode ecmaOpCode);
239     void ParseOptBytecodeRange();
240     void ReplaceGateWithPendingException(GateRef glue, GateRef gate, GateRef state, GateRef depend, GateRef value);
241 
242     const JSPandaFile* GetCalleePandaFile(GateRef gate);
243 
244     void AddProfiling(GateRef gate);
245 
IsFuncFromGlobal(GateRef gate)246     bool IsFuncFromGlobal(GateRef gate) const
247     {
248         return acc_.GetOpCode(gate) == OpCode::LOAD_BUILTIN_OBJECT;
249     }
250 
Uncheck()251     bool Uncheck() const
252     {
253         return noCheck_;
254     }
255 
256     Circuit *circuit_ {nullptr};
257     GateAccessor acc_;
258     PassContext *ctx_ {nullptr};
259     CircuitBuilder builder_;
260     GateRef dependEntry_ {Gate::InvalidGateRef};
261     Chunk *chunk_ {nullptr};
262     bool enableLog_ {false};
263     bool enableTypeLog_ {false};
264     bool profiling_ {false};
265     bool verifyVTable_ {false};
266     bool traceBc_ {false};
267     size_t allJSBcCount_ {0};
268     size_t allNonTypedOpCount_ {0};
269     size_t hitTypedOpCount_ {0};
270     std::string methodName_;
271     GateRef glue_ {Circuit::NullGate()};
272     ArgumentAccessor argAcc_;
273     EcmaOpcode currentOp_ {static_cast<EcmaOpcode>(0xff)};
274     PGOTypeLogList pgoTypeLog_;
275     std::unordered_map<EcmaOpcode, uint32_t> bytecodeMap_;
276     std::unordered_map<EcmaOpcode, uint32_t> bytecodeHitTimeMap_;
277     bool noCheck_ {false};
278     const CompilationEnv *compilationEnv_ {nullptr};
279     bool enableLoweringBuiltin_ {false};
280     const CString &recordName_;
281     const CallMethodFlagMap *callMethodFlagMap_;
282     PGOProfilerDecoder *decoder_ {nullptr};
283     std::string optBCRange_;
284     std::vector<std::vector<int32_t>> optBCRangeList_;
285     const MethodLiteral *currentMethod_ {nullptr};
286     uint32_t constPoolId_ {0};
287 };
288 }  // panda::ecmascript::kungfu
289 #endif  // ECMASCRIPT_COMPILER_TYPED_BYTECODE_LOWERING_H
290