1 /* 2 * Copyright (c) 2021 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_HCR_LOWERING_H 17 #define ECMASCRIPT_COMPILER_TYPED_HCR_LOWERING_H 18 19 #include "ecmascript/compiler/argument_accessor.h" 20 #include "ecmascript/compiler/bytecode_circuit_builder.h" 21 #include "ecmascript/compiler/circuit_builder-inl.h" 22 #include "ecmascript/compiler/combined_pass_visitor.h" 23 24 namespace panda::ecmascript::kungfu { 25 // TypeHCRLowering Process 26 // SW: state wire, DW: depend wire, VW: value wire 27 // Before Type Lowering: 28 // SW DW VW 29 // | | | 30 // | | | 31 // v v v 32 // +-------------------+ 33 // | (HIR) | SW +--------------+ 34 // --DW| JS_BYTECODE |---------->| IF_EXCEPTION | 35 // | +-------------------+ +--------------+ 36 // | SW VW 37 // | | | 38 // | v | 39 // | +--------------+ | 40 // | | IF_SUCCESS | | 41 // | +--------------+ | 42 // | SW | 43 // | | | 44 // | v v 45 // | +-------------------+ 46 // | | (HIR) | 47 // --->| JS_BYTECODE | 48 // +-------------------+ 49 // 50 // After Type Lowering: 51 // SW 52 // | 53 // v 54 // +-------------------+ 55 // | IF_BRANCH | 56 // | (Type Check) | 57 // +-------------------+ 58 // SW SW 59 // | | 60 // V V 61 // +--------------+ +--------------+ 62 // | IF_TRUE | | IF_FALSE | 63 // +--------------+ +--------------+ 64 // VW DW SW SW DW VW 65 // | | | | | | 66 // | | V V | | 67 // | | +---------------+ +---------------------+ | | 68 // ------->| FAST PATH | | (HIR) |<------- 69 // +---------------+ | JS_BYTECODE | 70 // VW DW SW +---------------------+ 71 // | | | SW VW DW 72 // | | | | | | 73 // | | | v | | 74 // | | | +--------------+ | | 75 // | | | | IF_SUCCESS | | | 76 // | | | +--------------+ | | 77 // | | | SW | | 78 // | | | | | | 79 // | | v v | | 80 // | | +---------------------+ | | 81 // | | | MERGE | | | 82 // | | +---------------------+ | | 83 // | | SW SW SW | | 84 // ----|----|----------|-----|-- | | 85 // ---|----|----------|-----|-|-------|---- 86 // | | | | | | | 87 // v v v | v v v 88 // +-----------------+ | +----------------+ 89 // | DEPEND_SELECTOR | | | VALUE_SELECTOR | 90 // +-----------------+ | +----------------+ 91 // DW | VW 92 // | | | 93 // v v v 94 // +------------------------+ 95 // | (HIR) | 96 // | JS_BYTECODE | 97 // +------------------------+ 98 99 class TypedHCRLowering : public PassVisitor { 100 public: TypedHCRLowering(Circuit * circuit,RPOVisitor * visitor,CompilationConfig * cmpCfg,TSManager * tsManager,Chunk * chunk,bool enableLoweringBuiltin)101 TypedHCRLowering(Circuit* circuit, 102 RPOVisitor* visitor, 103 CompilationConfig* cmpCfg, 104 TSManager* tsManager, 105 Chunk* chunk, 106 bool enableLoweringBuiltin) 107 : PassVisitor(circuit, chunk, visitor), 108 circuit_(circuit), 109 acc_(circuit), 110 builder_(circuit, cmpCfg), 111 dependEntry_(circuit->GetDependRoot()), 112 tsManager_(tsManager), 113 enableLoweringBuiltin_(enableLoweringBuiltin) 114 { 115 if (cmpCfg != nullptr) { 116 typedOpProfiling_ = cmpCfg->IsTypedOpProfiling(); 117 } 118 } 119 120 ~TypedHCRLowering() = default; 121 122 GateRef VisitGate(GateRef gate) override; 123 124 private: 125 void Lower(GateRef gate); 126 void LowerType(GateRef gate); 127 void LowerPrimitiveTypeCheck(GateRef gate); 128 void LowerTypeConvert(GateRef gate); 129 void LowerPrimitiveToNumber(GateRef dst, GateRef src, GateType srcType); 130 void LowerIntCheck(GateRef gate); 131 void LowerDoubleCheck(GateRef gate); 132 void LowerNumberCheck(GateRef gate); 133 void LowerBooleanCheck(GateRef gate); 134 void LowerIndexCheck(GateRef gate); 135 void LowerObjectTypeCheck(GateRef gate); 136 void LowerSimpleHClassCheck(GateRef gate); 137 void LowerTSSubtypingCheck(GateRef gate); 138 void LowerObjectTypeCompare(GateRef gate); 139 void LowerSimpleHClassCompare(GateRef gate); 140 void LowerTSSubtypingCompare(GateRef gate); 141 GateRef BuildCompareSubTyping(GateRef gate, GateRef frameState, Label *levelValid, Label *exit); 142 GateRef BuildCompareHClass(GateRef gate, GateRef frameState); 143 void BuildCompareSubTyping(GateRef gate); 144 void LowerStableArrayCheck(GateRef gate); 145 void LowerTypedArrayCheck(GateRef gate); 146 void LowerEcmaStringCheck(GateRef gate); 147 void LowerFlattenTreeStringCheck(GateRef gate, GateRef glue); 148 void LowerLoadTypedArrayLength(GateRef gate); 149 void LowerStringLength(GateRef gate); 150 void LowerLoadProperty(GateRef gate); 151 void LowerCallGetter(GateRef gate, GateRef glue); 152 void LowerStoreProperty(GateRef gate); 153 void LowerCallSetter(GateRef gate, GateRef glue); 154 void LowerLoadArrayLength(GateRef gate); 155 void LowerStoreElement(GateRef gate, GateRef glue); 156 void LowerLoadElement(GateRef gate); 157 void LowerLoadFromTaggedArray(GateRef gate); 158 void LowerStoreToTaggedArray(GateRef gate, GateRef glue); 159 void LowerRangeCheckPredicate(GateRef gate); 160 void LowerBuiltinPrototypeHClassCheck(GateRef gate); 161 void LowerLoadBuiltinObject(GateRef gate); 162 void LowerTypedCreateObjWithBuffer(GateRef gate, GateRef glue); 163 164 enum class ArrayState : uint8_t { 165 PACKED = 0, 166 HOLEY, 167 }; 168 void LowerArrayLoadElement(GateRef gate, ArrayState arrayState); 169 void LowerCowArrayCheck(GateRef gate, GateRef glue); 170 void LowerTypedArrayLoadElement(GateRef gate, BuiltinTypeId id); 171 void LowerStringLoadElement(GateRef gate); 172 GateRef BuildOnHeapTypedArrayLoadElement(GateRef receiver, GateRef offset, VariableType type); 173 GateRef BuildNotOnHeapTypedArrayLoadElement(GateRef receiver, GateRef offset, VariableType type); 174 GateRef BuildTypedArrayLoadElement(GateRef receiver, GateRef offset, VariableType type, Label *isByteArray, 175 Label *isArrayBuffer, Label *exit); 176 void LowerArrayStoreElement(GateRef gate, GateRef glue); 177 void LowerTypedArrayStoreElement(GateRef gate, BuiltinTypeId id); 178 void BuildOnHeapTypedArrayStoreElement(GateRef receiver, GateRef offset, GateRef value); 179 void BuildNotOnHeapTypedArrayStoreElement(GateRef receiver, GateRef offset, GateRef value); 180 void BuildTypedArrayStoreElement(GateRef receiver, GateRef offset, GateRef value, Label *isByteArray, 181 Label *isArrayBuffer, Label *exit); 182 void LowerUInt8ClampedArrayStoreElement(GateRef gate); 183 void LowerTypedCallBuitin(GateRef gate); 184 void LowerCallTargetCheck(GateRef gate); 185 void LowerJSCallTargetCheck(GateRef gate); 186 void LowerJSCallTargetFromDefineFuncCheck(GateRef gate); 187 void LowerJSCallTargetTypeCheck(GateRef gate); 188 void LowerJSFastCallTargetTypeCheck(GateRef gate); 189 void LowerJSCallThisTargetTypeCheck(GateRef gate); 190 void LowerJSFastCallThisTargetTypeCheck(GateRef gate); 191 void LowerJSNoGCCallThisTargetTypeCheck(GateRef gate); 192 void LowerJSNoGCFastCallThisTargetTypeCheck(GateRef gate); 193 void LowerTypedNewAllocateThis(GateRef gate, GateRef glue); 194 void LowerTypedSuperAllocateThis(GateRef gate, GateRef glue); 195 void LowerGetSuperConstructor(GateRef gate); 196 void LowerJSInlineTargetTypeCheck(GateRef gate); 197 void SetDeoptTypeInfo(BuiltinTypeId id, DeoptType &type, size_t &typedArrayRootHclassIndex, 198 size_t &typedArrayRootHclassOnHeapIndex); 199 void LowerLookupHolder(GateRef gate); 200 void LowerLoadGetter(GateRef gate); 201 void LowerLoadSetter(GateRef gate); 202 void LowerPrototypeCheck(GateRef gate); 203 void LowerStringEqual(GateRef gate, GateRef glue); 204 void LowerStringAdd(GateRef gate, GateRef glue); 205 void LowerTypeOfCheck(GateRef gate); 206 void LowerTypeOf(GateRef gate, GateRef glue); 207 void LowerArrayConstructorCheck(GateRef gate, GateRef glue); 208 void NewArrayConstructorWithNoArgs(GateRef gate, GateRef glue); 209 void LowerArrayConstructor(GateRef gate, GateRef glue); 210 void LowerObjectConstructorCheck(GateRef gate, GateRef glue); 211 void LowerObjectConstructor(GateRef gate, GateRef glue); 212 GateRef NewJSPrimitiveRef(PrimitiveType type, GateRef glue, GateRef value); 213 void ReplaceGateWithPendingException(GateRef glue, GateRef gate, GateRef state, GateRef depend, GateRef value); 214 void LowerOrdinaryHasInstance(GateRef gate, GateRef glue); 215 void LowerProtoChangeMarkerCheck(GateRef gate); 216 void LowerMonoCallGetterOnProto(GateRef gate, GateRef glue); 217 void LowerMonoLoadPropertyOnProto(GateRef gate); 218 void LowerMonoStorePropertyLookUpProto(GateRef gate, GateRef glue); 219 void LowerMonoStoreProperty(GateRef gate, GateRef glue); 220 void LowerStringFromSingleCharCode(GateRef gate, GateRef glue); 221 222 GateRef LowerCallRuntime(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args, 223 bool useLabel = false); 224 225 enum AccessorMode { 226 GETTER, 227 SETTER, 228 }; 229 230 GateRef CallAccessor(GateRef glue, GateRef gate, GateRef function, GateRef receiver, AccessorMode mode, 231 GateRef value = Circuit::NullGate()); 232 void ReplaceHirWithPendingException(GateRef hirGate, GateRef glue, GateRef state, GateRef depend, GateRef value); 233 234 GateRef DoubleToTaggedDoublePtr(GateRef gate); 235 GateRef ChangeInt32ToFloat64(GateRef gate); 236 GateRef TruncDoubleToInt(GateRef gate); 237 GateRef IntToTaggedIntPtr(GateRef x); 238 GateType GetLeftType(GateRef gate); 239 GateType GetRightType(GateRef gate); 240 GateRef GetObjectFromConstPool(GateRef jsFunc, GateRef index); 241 GateRef GetElementSize(BuiltinTypeId id); 242 VariableType GetVariableType(BuiltinTypeId id); 243 GateRef AllocateLineString(GateRef length, GateRef canBeCompressed); 244 GateRef AllocateSlicedString(GateRef flatString, GateRef length, GateRef canBeCompressed); 245 bool IsFirstConcatInStringAdd(GateRef gate) const; 246 bool ConcatIsInStringAdd(GateRef gate) const; 247 GetFrameState(GateRef gate)248 GateRef GetFrameState(GateRef gate) const 249 { 250 return acc_.GetFrameState(gate); 251 } 252 253 VariableType GetVarType(PropertyLookupResult plr); 254 GateRef LoadSupers(GateRef hclass); 255 GateRef GetLengthFromSupers(GateRef supers); 256 GateRef GetValueFromSupers(GateRef supers, size_t index); 257 GateRef LoadFromTaggedArray(GateRef array, size_t index); 258 GateRef LoadFromConstPool(GateRef jsFunc, size_t index, size_t valVecType); 259 GateRef LoadFromVTable(GateRef receiver, size_t index); 260 GateRef GetLengthFromString(GateRef gate); 261 GateRef LoadPropertyFromHolder(GateRef holder, PropertyLookupResult plr); 262 void StorePropertyOnHolder(GateRef holder, GateRef value, PropertyLookupResult plr, bool needBarrier); 263 264 void AddProfiling(GateRef gate); 265 IsTypedOpProfiling()266 bool IsTypedOpProfiling() const 267 { 268 return typedOpProfiling_; 269 } 270 271 Circuit *circuit_; 272 GateAccessor acc_; 273 CircuitBuilder builder_; 274 GateRef dependEntry_; 275 [[maybe_unused]] TSManager *tsManager_ {nullptr}; 276 bool enableLoweringBuiltin_ {false}; 277 bool typedOpProfiling_ {false}; 278 }; 279 } // panda::ecmascript::kungfu 280 #endif // ECMASCRIPT_COMPILER_TYPED_HCR_LOWERING_H 281