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