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