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