• 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 LowerTypedStOwnByName(GateRef gate);
128     GateRef BuildNamedPropertyAccess(GateRef hir, GateRef receiver, GateRef holder, PropertyLookupResult plr);
129     GateRef BuildNamedPropertyAccess(GateRef hir, GateRef receiver, GateRef holder,
130                                      GateRef value, PropertyLookupResult plr, uint32_t receiverHClassIndex = 0);
131     bool TryLowerTypedLdObjByNameForBuiltin(GateRef gate);
132     bool TryLowerTypedLdObjByNameForBuiltinsId(const LoadBulitinObjTypeInfoAccessor &tacc, BuiltinTypeId type);
133     bool TryLowerTypedLdObjByNameForBuiltin(const LoadBulitinObjTypeInfoAccessor &tacc);
134     bool TryLowerTypedLdObjByNameForGlobalsId(const LoadBulitinObjTypeInfoAccessor &tacc, GlobalIndex globalsId);
135     void LowerTypedLdArrayLength(const LoadBulitinObjTypeInfoAccessor &tacc);
136     void LowerTypedLdTypedArrayLength(const LoadBulitinObjTypeInfoAccessor &tacc);
137     void LowerTypedLdStringLength(const LoadBulitinObjTypeInfoAccessor &tacc);
138     void LowerTypedLdMapSize(const LoadBulitinObjTypeInfoAccessor &tacc);
139     bool TryLowerTypedLdObjByNameForBuiltinMethod(const LoadBulitinObjTypeInfoAccessor &tacc, BuiltinTypeId type);
140 
141     void LowerTypedLdObjByIndex(GateRef gate);
142     bool TryLowerTypedLdObjByIndexForBuiltin(GateRef gate);
143     void LowerTypedStObjByIndex(GateRef gate);
144     bool TryLowerTypedStObjByIndexForBuiltin(GateRef gate);
145 
146     void LowerTypedLdObjByValue(GateRef gate);
147     bool TryLowerTypedLdObjByValueForBuiltin(GateRef gate);
148     void LowerTypedStObjByValue(GateRef gate);
149     void LowerTypedStOwnByValue(GateRef gate);
150     bool TryLowerTypedStObjByValueForBuiltin(GateRef gate);
151 
152     void LowerTypedIsTrueOrFalse(GateRef gate, bool flag);
153 
154     void LowerTypedNewObjRange(GateRef gate);
155     void LowerCreateEmptyObject(GateRef gate);
156     void LowerCreateObjectWithBuffer(GateRef gate);
157     void LowerTypedSuperCall(GateRef gate);
158 
159     void LowerTypedCallArg0(GateRef gate);
160     void LowerTypedCallArg1(GateRef gate);
161     void LowerTypedCallArg2(GateRef gate);
162     void LowerTypedCallArg3(GateRef gate);
163     void LowerTypedCallrange(GateRef gate);
164     void LowerTypedCallthis0(GateRef gate);
165     void LowerTypedCallthis1(GateRef gate);
166     void LowerTypedCallthis2(GateRef gate);
167     void LowerTypedCallthis3(GateRef gate);
168     void LowerTypedCallthisrange(GateRef gate);
169     void LowerTypedCallInit(GateRef gate);
170 
171     template<class TypeAccessor>
172     bool InSameConstPool(const TypeAccessor &tacc) const;
173 
174     template<class TypeAccessor>
175     void CheckFastCallThisCallTarget(const TypeAccessor &tacc);
176 
177     template<class TypeAccessor>
178     void CheckCallThisCallTarget(const TypeAccessor &tacc);
179 
180     template<class TypeAccessor>
181     void CheckThisCallTargetAndLowerCall(const TypeAccessor &tacc,
182         const std::vector<GateRef> &args, const std::vector<GateRef> &argsFastCall);
183 
184     template<class TypeAccessor>
185     void CheckCallTargetFromDefineFuncAndLowerCall(const TypeAccessor &tacc,
186         const std::vector<GateRef> &args, const std::vector<GateRef> &argsFastCall, bool isNoGC);
187 
188     template<class TypeAccessor>
189     void CheckCallTargetAndLowerCall(const TypeAccessor &tacc,
190         const std::vector<GateRef> &args, const std::vector<GateRef> &argsFastCall);
191 
192     template<EcmaOpcode Op, class TypeAccessor>
193     void LowerTypedCall(const TypeAccessor &tacc);
194 
195     template<EcmaOpcode Op, class TypeAccessor>
196     void LowerTypedThisCall(const TypeAccessor &tacc);
197 
198     bool IsLoadVtable(GateRef func);
199     void LowerFastCall(GateRef gate, GateRef func, const std::vector<GateRef> &argsFastCall, bool isNoGC);
200     void LowerCall(GateRef gate, GateRef func, const std::vector<GateRef> &args, bool isNoGC);
201     void LowerTypedTypeOf(GateRef gate);
202     void LowerInstanceOf(GateRef gate);
203     void LowerGetIterator(GateRef gate);
204     GateRef LoadStringByIndex(const LoadBulitinObjTypeInfoAccessor &tacc);
205     GateRef LoadJSArrayByIndex(const LoadBulitinObjTypeInfoAccessor &tacc);
206     GateRef LoadTypedArrayByIndex(const LoadBulitinObjTypeInfoAccessor &tacc);
207     void StoreJSArrayByIndex(const StoreBulitinObjTypeInfoAccessor &tacc);
208     void StoreTypedArrayByIndex(const StoreBulitinObjTypeInfoAccessor &tacc);
209 
210     void AddBytecodeCount(EcmaOpcode op);
211     void DeleteBytecodeCount(EcmaOpcode op);
212     void AddHitBytecodeCount();
213 
214     template<TypedBinOp Op>
215     void SpeculateStrings(const BinOpTypeInfoAccessor& tacc);
216     template<TypedBinOp Op>
217     void SpeculateNumbers(const BinOpTypeInfoAccessor& tacc);
218     template<TypedBinOp Op>
219     void SpeculateNumbersOrString(const BinOpTypeInfoAccessor& tacc);
220     template<TypedUnOp Op>
221     void SpeculateNumber(const UnOpTypeInfoAccessor& tacc);
222     void SpeculateConditionJump(const ConditionJumpTypeInfoAccessor &tacc, bool flag);
223     void SpeculateCallBuiltin(GateRef gate, GateRef func, const std::vector<GateRef> &args,
224                               BuiltinsStubCSigns::ID id, bool isThrow, bool isSideEffect = false);
225     void DeleteConstDataIfNoUser(GateRef gate);
226     bool TryLowerNewBuiltinConstructor(GateRef gate);
227     bool TryLowerTypedLdobjBynameFromGloablBuiltin(GateRef gate);
228     bool CheckIsInOptBCIgnoreRange(int32_t index, EcmaOpcode ecmaOpcode);
229     bool IsTrueOrFalseHasProfileType(GateRef gate) const;
230     int32_t GetEcmaOpCodeListIndex(EcmaOpcode ecmaOpCode);
231     void ParseOptBytecodeRange();
232 
233     const JSPandaFile* GetCalleePandaFile(GateRef gate);
234 
235     void AddProfiling(GateRef gate);
236 
Uncheck()237     bool Uncheck() const
238     {
239         return noCheck_;
240     }
241 
242     Circuit *circuit_ {nullptr};
243     GateAccessor acc_;
244     PassContext *ctx_ {nullptr};
245     CircuitBuilder builder_;
246     GateRef dependEntry_ {Gate::InvalidGateRef};
247     Chunk *chunk_ {nullptr};
248     bool enableLog_ {false};
249     bool enableTypeLog_ {false};
250     bool profiling_ {false};
251     bool verifyVTable_ {false};
252     bool traceBc_ {false};
253     size_t allJSBcCount_ {0};
254     size_t allNonTypedOpCount_ {0};
255     size_t hitTypedOpCount_ {0};
256     std::string methodName_;
257     GateRef glue_ {Circuit::NullGate()};
258     ArgumentAccessor argAcc_;
259     EcmaOpcode currentOp_ {static_cast<EcmaOpcode>(0xff)};
260     PGOTypeLogList pgoTypeLog_;
261     std::unordered_map<EcmaOpcode, uint32_t> bytecodeMap_;
262     std::unordered_map<EcmaOpcode, uint32_t> bytecodeHitTimeMap_;
263     bool noCheck_ {false};
264     const CompilationEnv *compilationEnv_ {nullptr};
265     bool enableLoweringBuiltin_ {false};
266     const CString &recordName_;
267     const CallMethodFlagMap *callMethodFlagMap_;
268     PGOProfilerDecoder *decoder_ {nullptr};
269     std::string optBCRange_;
270     std::vector<std::vector<int32_t>> optBCRangeList_;
271     const MethodLiteral *currentMethod_ {nullptr};
272     uint32_t constPoolId_ {0};
273 };
274 }  // panda::ecmascript::kungfu
275 #endif  // ECMASCRIPT_COMPILER_TYPED_BYTECODE_LOWERING_H
276