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_TS_HCR_LOWERING_H 17 #define ECMASCRIPT_COMPILER_TS_HCR_LOWERING_H 18 19 #include "ecmascript/compiler/argument_accessor.h" 20 #include "ecmascript/compiler/builtins/builtins_call_signature.h" 21 #include "ecmascript/compiler/bytecode_circuit_builder.h" 22 #include "ecmascript/compiler/circuit_builder-inl.h" 23 #include "ecmascript/compiler/object_access_helper.h" 24 #include "ecmascript/compiler/pass_manager.h" 25 26 namespace panda::ecmascript::kungfu { 27 class TSHCRLowering { 28 public: TSHCRLowering(Circuit * circuit,PassContext * ctx,bool enableLog,bool enableTypeLog,const std::string & name)29 TSHCRLowering(Circuit *circuit, PassContext *ctx, 30 bool enableLog, bool enableTypeLog, 31 const std::string& name) 32 : circuit_(circuit), 33 acc_(circuit), 34 builder_(circuit, ctx->GetCompilerConfig()), 35 dependEntry_(circuit->GetDependRoot()), 36 tsManager_(ctx->GetTSManager()), 37 enableLog_(enableLog), 38 enableTypeLog_(enableTypeLog), 39 profiling_(ctx->GetCompilerConfig()->IsProfiling()), 40 verifyVTable_(ctx->GetCompilerConfig()->IsVerifyVTbale()), 41 traceBc_(ctx->GetCompilerConfig()->IsTraceBC()), 42 methodName_(name), 43 glue_(acc_.GetGlueFromArgList()), 44 argAcc_(circuit), 45 pgoTypeLog_(circuit), 46 noCheck_(ctx->GetEcmaVM()->GetJSOptions().IsCompilerNoCheck()), 47 thread_(ctx->GetEcmaVM()->GetJSThread()) {} 48 49 ~TSHCRLowering() = default; 50 51 bool RunTSHCRLowering(); 52 53 private: IsLogEnabled()54 bool IsLogEnabled() const 55 { 56 return enableLog_; 57 } 58 IsTypeLogEnabled()59 bool IsTypeLogEnabled() const 60 { 61 return enableTypeLog_; 62 } 63 IsProfiling()64 bool IsProfiling() const 65 { 66 return profiling_; 67 } 68 IsVerifyVTbale()69 bool IsVerifyVTbale() const 70 { 71 return verifyVTable_; 72 } 73 IsTraceBC()74 bool IsTraceBC() const 75 { 76 return traceBc_; 77 } 78 GetMethodName()79 const std::string& GetMethodName() const 80 { 81 return methodName_; 82 } 83 84 void Lower(GateRef gate); 85 template<TypedBinOp Op> 86 void LowerTypedBinOp(GateRef gate); 87 void LowerTypedMod(GateRef gate); 88 void LowerTypedDiv(GateRef gate); 89 void LowerTypedStrictEq(GateRef gate); 90 void LowerTypedShl(GateRef gate); 91 void LowerTypedShr(GateRef gate); 92 void LowerTypedAshr(GateRef gate); 93 void LowerTypedAnd(GateRef gate); 94 void LowerTypedOr(GateRef gate); 95 void LowerTypedXor(GateRef gate); 96 void LowerTypedInc(GateRef gate); 97 void LowerTypedDec(GateRef gate); 98 void LowerTypeToNumeric(GateRef gate); 99 void LowerPrimitiveTypeToNumber(GateRef gate); 100 void LowerConditionJump(GateRef gate, bool flag); 101 void LowerTypedNeg(GateRef gate); 102 void LowerTypedNot(GateRef gate); 103 104 void LowerTypedLdObjByName(GateRef gate); 105 void LowerTypedStObjByName(GateRef gate, bool isThis); 106 using AccessMode = ObjectAccessHelper::AccessMode; 107 void LowerNamedAccess(GateRef gate, GateRef receiver, AccessMode accessMode, JSTaggedValue key, GateRef value); 108 GateRef BuildNamedPropertyAccess(GateRef hir, ObjectAccessHelper accessHelper, PropertyLookupResult plr); 109 void BuildNamedPropertyAccessVerifier(GateRef gate, GateRef receiver, AccessMode mode, GateRef value); 110 bool TryLowerTypedLdObjByNameForArray(GateRef gate, GateType receiverType, JSTaggedValue key); 111 void LowerTypedLdArrayLength(GateRef gate); 112 void LowerTypedLdTypedArrayLength(GateRef gate); 113 114 void LowerTypedLdObjByIndex(GateRef gate); 115 void LowerTypedStObjByIndex(GateRef gate); 116 void LowerTypedLdObjByValue(GateRef gate, bool isThis); 117 void LowerTypedStObjByValue(GateRef gate); 118 void LowerTypedIsTrueOrFalse(GateRef gate, bool flag); 119 void LowerTypedNewObjRange(GateRef gate); 120 void LowerTypedSuperCall(GateRef gate); 121 122 void LowerTypedCallArg0(GateRef gate); 123 void LowerTypedCallArg1(GateRef gate); 124 void LowerTypedCallArg2(GateRef gate); 125 void LowerTypedCallArg3(GateRef gate); 126 void LowerTypedCallrange(GateRef gate); 127 void LowerTypedCallthis0(GateRef gate); 128 void LowerTypedCallthis1(GateRef gate); 129 void LowerTypedCallthis2(GateRef gate); 130 void LowerTypedCallthis3(GateRef gate); 131 void LowerTypedCallthisrange(GateRef gate); 132 void LowerTypedCall(GateRef gate, GateRef func, GateRef actualArgc, GateType funcType, uint32_t argc); 133 void LowerTypedThisCall(GateRef gate, GateRef func, GateRef actualArgc, uint32_t argc); 134 bool IsLoadVtable(GateRef func); 135 bool CanOptimizeAsFastCall(GateRef func); 136 void CheckCallTargetAndLowerCall(GateRef gate, GateRef func, GlobalTSTypeRef funcGt, 137 GateType funcType, const std::vector<GateRef> &args, const std::vector<GateRef> &argsFastCall); 138 void CheckCallTargetFromDefineFuncAndLowerCall(GateRef gate, GateRef func, GlobalTSTypeRef funcGt, 139 GateType funcType, const std::vector<GateRef> &args, const std::vector<GateRef> &argsFastCall, bool isNoGC); 140 void CheckThisCallTargetAndLowerCall(GateRef gate, GateRef func, GlobalTSTypeRef funcGt, 141 GateType funcType, const std::vector<GateRef> &args, const std::vector<GateRef> &argsFastCall); 142 void CheckCallThisCallTarget(GateRef gate, GateRef func, GlobalTSTypeRef funcGt, 143 GateType funcType, bool isNoGC); 144 void CheckFastCallThisCallTarget(GateRef gate, GateRef func, GlobalTSTypeRef funcGt, 145 GateType funcType, bool isNoGC); 146 void LowerFastCall(GateRef gate, GateRef func, const std::vector<GateRef> &argsFastCall, bool isNoGC); 147 void LowerCall(GateRef gate, GateRef func, const std::vector<GateRef> &args, bool isNoGC); 148 GateRef LoadJSArrayByIndex(GateRef receiver, GateRef propKey, ElementsKind kind); 149 GateRef LoadTypedArrayByIndex(GateRef receiver, GateRef propKey); 150 void StoreJSArrayByIndex(GateRef receiver, GateRef propKey, GateRef value, ElementsKind kind); 151 void StoreTypedArrayByIndex(GateRef receiver, GateRef propKey, GateRef value); 152 153 // TypeTrusted means the type of gate is already PrimitiveTypeCheck-passed, 154 // or the gate is constant and no need to check. 155 bool IsTrustedType(GateRef gate) const; 156 bool HasNumberType(GateRef gate, GateRef value) const; 157 bool HasNumberType(GateRef gate, GateRef left, GateRef right) const; 158 159 void AddBytecodeCount(EcmaOpcode op); 160 void DeleteBytecodeCount(EcmaOpcode op); 161 void AddHitBytecodeCount(); 162 163 template<TypedBinOp Op> 164 void SpeculateNumbers(GateRef gate); 165 template<TypedUnOp Op> 166 void SpeculateNumber(GateRef gate); 167 void SpeculateConditionJump(GateRef gate, bool flag); 168 void SpeculateCallBuiltin(GateRef gate, GateRef func, GateRef a0, BuiltinsStubCSigns::ID Op); 169 void SpeculateCallThis3Builtin(GateRef gate, BuiltinsStubCSigns::ID id); 170 BuiltinsStubCSigns::ID GetBuiltinId(BuiltinTypeId id, GateRef func); 171 void DeleteConstDataIfNoUser(GateRef gate); 172 173 void AddProfiling(GateRef gate); 174 Uncheck()175 bool Uncheck() const 176 { 177 return noCheck_; 178 } 179 180 Circuit *circuit_ {nullptr}; 181 GateAccessor acc_; 182 CircuitBuilder builder_; 183 GateRef dependEntry_ {Gate::InvalidGateRef}; 184 TSManager *tsManager_ {nullptr}; 185 bool enableLog_ {false}; 186 bool enableTypeLog_ {false}; 187 bool profiling_ {false}; 188 bool verifyVTable_ {false}; 189 bool traceBc_ {false}; 190 size_t allJSBcCount_ {0}; 191 size_t allNonTypedOpCount_ {0}; 192 size_t hitTypedOpCount_ {0}; 193 std::string methodName_; 194 GateRef glue_ {Circuit::NullGate()}; 195 ArgumentAccessor argAcc_; 196 EcmaOpcode currentOp_ {static_cast<EcmaOpcode>(0xff)}; 197 PGOTypeLogList pgoTypeLog_; 198 std::unordered_map<EcmaOpcode, uint32_t> bytecodeMap_; 199 std::unordered_map<EcmaOpcode, uint32_t> bytecodeHitTimeMap_; 200 bool noCheck_ {false}; 201 const JSThread *thread_ {nullptr}; 202 }; 203 } // panda::ecmascript::kungfu 204 #endif // ECMASCRIPT_COMPILER_TS_HCR_LOWERING_H 205