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 #include "ecmascript/compiler/type_info_accessors.h" 24 #include "ecmascript/compiler/pass_manager.h" 25 26 namespace panda::ecmascript::kungfu { 27 // TypeHCRLowering Process 28 // SW: state wire, DW: depend wire, VW: value wire 29 // Before Type Lowering: 30 // SW DW VW 31 // | | | 32 // | | | 33 // v v v 34 // +-------------------+ 35 // | (HIR) | SW +--------------+ 36 // --DW| JS_BYTECODE |---------->| IF_EXCEPTION | 37 // | +-------------------+ +--------------+ 38 // | SW VW 39 // | | | 40 // | v | 41 // | +--------------+ | 42 // | | IF_SUCCESS | | 43 // | +--------------+ | 44 // | SW | 45 // | | | 46 // | v v 47 // | +-------------------+ 48 // | | (HIR) | 49 // --->| JS_BYTECODE | 50 // +-------------------+ 51 // 52 // After Type Lowering: 53 // SW 54 // | 55 // v 56 // +-------------------+ 57 // | IF_BRANCH | 58 // | (Type Check) | 59 // +-------------------+ 60 // SW SW 61 // | | 62 // V V 63 // +--------------+ +--------------+ 64 // | IF_TRUE | | IF_FALSE | 65 // +--------------+ +--------------+ 66 // VW DW SW SW DW VW 67 // | | | | | | 68 // | | V V | | 69 // | | +---------------+ +---------------------+ | | 70 // ------->| FAST PATH | | (HIR) |<------- 71 // +---------------+ | JS_BYTECODE | 72 // VW DW SW +---------------------+ 73 // | | | SW VW DW 74 // | | | | | | 75 // | | | v | | 76 // | | | +--------------+ | | 77 // | | | | IF_SUCCESS | | | 78 // | | | +--------------+ | | 79 // | | | SW | | 80 // | | | | | | 81 // | | v v | | 82 // | | +---------------------+ | | 83 // | | | MERGE | | | 84 // | | +---------------------+ | | 85 // | | SW SW SW | | 86 // ----|----|----------|-----|-- | | 87 // ---|----|----------|-----|-|-------|---- 88 // | | | | | | | 89 // v v v | v v v 90 // +-----------------+ | +----------------+ 91 // | DEPEND_SELECTOR | | | VALUE_SELECTOR | 92 // +-----------------+ | +----------------+ 93 // DW | VW 94 // | | | 95 // v v v 96 // +------------------------+ 97 // | (HIR) | 98 // | JS_BYTECODE | 99 // +------------------------+ 100 101 class TypedHCRLowering : public PassVisitor { 102 public: TypedHCRLowering(Circuit * circuit,CompilationEnv * env,RPOVisitor * visitor,CompilationConfig * cmpCfg,Chunk * chunk,bool enableLoweringBuiltin)103 TypedHCRLowering(Circuit* circuit, 104 CompilationEnv *env, 105 RPOVisitor* visitor, 106 CompilationConfig* cmpCfg, 107 Chunk* chunk, 108 bool enableLoweringBuiltin) 109 : PassVisitor(circuit, chunk, visitor), 110 circuit_(circuit), 111 compilationEnv_(env), 112 acc_(circuit), 113 builder_(circuit, cmpCfg), 114 dependEntry_(circuit->GetDependRoot()), 115 enableLoweringBuiltin_(enableLoweringBuiltin), 116 traceBuiltins_(env != nullptr ? env->GetJSOptions().GetTraceBuiltins() : false), 117 glue_(acc_.GetGlueFromArgList()) 118 { 119 } 120 121 ~TypedHCRLowering() = default; 122 123 GateRef VisitGate(GateRef gate) override; 124 125 private: 126 void Lower(GateRef gate); 127 void LowerType(GateRef gate); 128 void LowerPrimitiveTypeCheck(GateRef gate); 129 void LowerTypeConvert(GateRef gate); 130 void LowerPrimitiveToNumber(GateRef dst, GateRef src, ParamType srcType); 131 void LowerIntCheck(GateRef gate); 132 void LowerDoubleCheck(GateRef gate); 133 void LowerNumberCheck(GateRef gate); 134 void LowerBooleanCheck(GateRef gate); 135 void LowerIndexCheck(GateRef gate); 136 void LowerObjectTypeCheck(GateRef glue, GateRef gate); 137 void LowerSimpleHClassCheck(GateRef glue, GateRef gate); 138 GateRef BuildCompareHClass(GateRef glue, GateRef gate, GateRef frameState); 139 void LowerStableArrayCheck(GateRef glue, GateRef gate); 140 void LowerTypedArrayCheck(GateRef glue, GateRef gate); 141 void LowerEcmaStringCheck(GateRef gate, GateRef glue); 142 void LowerInternStringCheck(GateRef gate, GateRef glue); 143 void LowerStringKeyCheck(GateRef gate, GateRef glue); 144 void LowerInternStringKeyCheck(GateRef gate, GateRef glue); 145 void LowerEcmaMapCheck(GateRef glue, GateRef gate); 146 void LowerFlattenTreeStringCheck(GateRef gate, GateRef glue); 147 void LowerLoadTypedArrayLength(GateRef gate); 148 void LowerStringLength(GateRef gate); 149 void LowerMapSize(GateRef gate); 150 void LowerCallPrivateGetter(GateRef gate, GateRef glue); 151 void LowerCallPrivateSetter(GateRef gate, GateRef glue); 152 void LowerLoadProperty(GateRef gate); 153 void LowerCallGetter(GateRef gate, GateRef glue); 154 void LowerStoreProperty(GateRef gate); 155 void LowerCallSetter(GateRef gate, GateRef glue); 156 void LowerLoadArrayLength(GateRef gate); 157 void LowerStoreElement(GateRef gate, GateRef glue); 158 void LowerLoadElement(GateRef gate, GateRef glue); 159 void LowerLoadFromTaggedArray(GateRef gate); 160 void LowerStoreToTaggedArray(GateRef gate, GateRef glue); 161 void LowerRangeCheckPredicate(GateRef gate); 162 void LowerBuiltinInstanceHClassCheck(GateRef gate); 163 void LowerBuiltinPrototypeHClassCheck(GateRef gate); 164 void BuiltinInstanceStringTypeCheck(GateRef gate); 165 void LowerLoadBuiltinObject(GateRef gate); 166 void LowerTypedCreateObjWithBuffer(GateRef gate, GateRef glue); 167 void LowerNumberToString(GateRef gate, GateRef glue); 168 169 enum class ArrayState : uint8_t { 170 PACKED = 0, 171 HOLEY, 172 }; 173 174 struct ProtoTypeHolderInfo { 175 GateRef receiver; 176 GateRef holderHClassIndex; 177 GateRef unsharedConstPool; 178 GateRef frameState; 179 }; 180 void LowerArrayLoadElement(GateRef gate, ArrayState arrayState, TypedLoadOp op); 181 void LowerCowArrayCheck(GateRef gate, GateRef glue); 182 void LowerTypedArrayLoadElement(GateRef gate, BuiltinTypeId id); 183 void LowerStringLoadElement(GateRef gate, GateRef glue); 184 GateRef BuildOnHeapTypedArrayLoadElement(GateRef glue, GateRef receiver, GateRef offset, VariableType type); 185 GateRef BuildNotOnHeapTypedArrayLoadElement(GateRef glue, GateRef receiver, GateRef offset, VariableType type); 186 GateRef BuildTypedArrayLoadElement(GateRef glue, GateRef receiver, GateRef offset, VariableType type, 187 Label *isByteArray, Label *isArrayBuffer, Label *exit); 188 void LowerArrayStoreElement(GateRef gate, GateRef glue, TypedStoreOp kind); 189 void LowerTypedArrayStoreElement(GateRef gate, BuiltinTypeId id); 190 void OptStoreElementByOnHeapMode(GateRef gate, GateRef glue, GateRef receiver, GateRef offset, GateRef value, 191 Label *isByteArray, Label *isArrayBuffer, Label *exit); 192 void BuildOnHeapTypedArrayStoreElement(GateRef receiver, GateRef offset, GateRef value); 193 void BuildNotOnHeapTypedArrayStoreElement(GateRef glue, GateRef receiver, GateRef offset, GateRef value); 194 void BuildTypedArrayStoreElement(GateRef glue, GateRef receiver, GateRef offset, GateRef value, Label *isByteArray, 195 Label *isArrayBuffer, Label *exit); 196 void LowerUInt8ClampedArrayStoreElement(GateRef gate); 197 void LowerTypedCallBuitin(GateRef gate); 198 void LowerCallTargetCheck(GateRef gate); 199 void LowerJSCallTargetCheck(GateRef gate, GateRef glue); 200 void LowerCallTargetIsCompiledCheck(GateRef gate); 201 void CallTargetIsCompiledCheck(GateRef func, GateRef frameState, Label *checkAlreadyDeopt, Label *exit); 202 void LowerJSCallTargetFromDefineFuncCheck(GateRef gate); 203 void LowerJSCallTargetTypeCheck(GateRef gate, GateRef glue); 204 void LowerJSFastCallTargetTypeCheck(GateRef gate, GateRef glue); 205 void LowerJSCallThisTargetTypeCheck(GateRef gate, GateRef glue); 206 void LowerJSFastCallThisTargetTypeCheck(GateRef gate, GateRef glue); 207 void LowerJSNoGCCallThisTargetTypeCheck(GateRef gate, GateRef glue); 208 void LowerJSNoGCFastCallThisTargetTypeCheck(GateRef gate, GateRef glue); 209 void LowerJSNewObjRangeCallTargetCheck(GateRef gate, GateRef glue); 210 void LowerTypedNewAllocateThis(GateRef gate, GateRef glue); 211 void LowerTypedSuperAllocateThis(GateRef gate, GateRef glue); 212 void LowerGetSuperConstructor(GateRef glue, GateRef gate); 213 void LowerJSInlineTargetTypeCheck(GateRef gate, GateRef glue); 214 void LowerJSInlineTargetHeapConstantCheck(GateRef gate); 215 void SetDeoptTypeInfo(JSType jstype, DeoptType &type, size_t &typedArrayRootHclassIndex, 216 size_t &typedArrayRootHclassOnHeapIndex); 217 void LowerLookupHolder(GateRef glue, GateRef gate); 218 void LowerLoadGetter(GateRef gate, GateRef glue); 219 void LowerLoadSetter(GateRef gate, GateRef glue); 220 void LowerPrototypeCheck(GateRef glue, GateRef gate); 221 void LowerStringEqual(GateRef gate, GateRef glue); 222 void LowerTypeOfCheck(GateRef gate); 223 void LowerTypeOf(GateRef gate, GateRef glue); 224 void LowerTypedConstructorCheck(GateRef gate, GateRef glue); 225 void LowerArrayConstructorCheck(GateRef gate, GateRef glue); 226 void NewArrayConstructorWithNoArgs(GateRef gate, GateRef glue); 227 void LowerArrayConstructor(GateRef gate, GateRef glue); 228 void LowerFloat32ArrayConstructorCheck(GateRef gate, GateRef glue); 229 void NewFloat32ArrayConstructorWithNoArgs(GateRef gate, GateRef glue); 230 void ConvertFloat32ArrayConstructorLength(GateRef len, Variable *arrayLength, 231 Label *arrayCreate, Label *slowPath); 232 void LowerFloat32ArrayConstructor(GateRef gate, GateRef glue); 233 void LowerObjectConstructorCheck(GateRef gate, GateRef glue); 234 void LowerObjectConstructor(GateRef gate, GateRef glue); 235 void LowerBooleanConstructorCheck(GateRef gate, GateRef glue); 236 void LowerBooleanConstructor(GateRef gate, GateRef glue); 237 GateRef NewJSPrimitiveRef(PrimitiveType type, GateRef glue, GateRef value); 238 void ReplaceGateWithPendingException(GateRef glue, GateRef gate, GateRef state, GateRef depend, GateRef value); 239 void LowerOrdinaryHasInstance(GateRef gate, GateRef glue); 240 void LowerOrdinaryHasInstanceForJIT(GateRef gate, GateRef glue); 241 void LowerProtoChangeMarkerCheck(GateRef glue, GateRef gate); 242 void LowerPrimitiveTypeProtoChangeMarkerCheck(GateRef glue, GateRef gate); 243 void GetPropertyHolderFromProtoChain(GateRef glue, ProtoTypeHolderInfo holderInfo, Label *loadHolder, 244 Variable *current, DeoptType deoptType); 245 void LowerMonoCallGetterOnProto(GateRef gate, GateRef glue); 246 void LowerMonoLoadPropertyOnProto(GateRef glue, GateRef gate); 247 void LowerMonoStorePropertyLookUpProto(GateRef gate, GateRef glue); 248 void LowerMonoStoreProperty(GateRef gate, GateRef glue); 249 void LowerStringFromSingleCharCode(GateRef gate, GateRef glue); 250 void LowerMigrateArrayWithKind(GateRef gate, GateRef glue); 251 void LowerEcmaObjectCheck(GateRef gate); 252 void LowerElementskindCheck(GateRef glue, GateRef gate); 253 void LowerInlineSuperCtorCheck(GateRef glue, GateRef gate); 254 void LowerCheckConstructor(GateRef gate, GateRef glue); 255 256 GateRef LowerCallRuntime(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args, 257 bool useLabel = false); 258 259 enum AccessorMode { 260 GETTER, 261 SETTER, 262 }; 263 264 GateRef CallAccessor(GateRef glue, GateRef gate, GateRef function, GateRef receiver, AccessorMode mode, 265 GateRef value = Circuit::NullGate()); 266 void BuiltinInstanceHClassCheck(Environment *env, GateRef gate); 267 void BuiltinPrototypeHClassCheck(Environment *env, GateRef gate); 268 void ReplaceHirWithPendingException(GateRef hirGate, GateRef glue, GateRef state, GateRef depend, GateRef value); 269 270 GateRef DoubleToTaggedDoublePtr(GateRef gate); 271 GateRef ChangeInt32ToFloat64(GateRef gate); 272 GateRef TruncDoubleToInt(GateRef gate); 273 GateRef IntToTaggedIntPtr(GateRef x); 274 GateType GetLeftType(GateRef gate); 275 GateType GetRightType(GateRef gate); 276 GateRef GetElementSize(BuiltinTypeId id); 277 VariableType GetVariableType(BuiltinTypeId id); 278 GetFrameState(GateRef gate)279 GateRef GetFrameState(GateRef gate) const 280 { 281 return acc_.GetFrameState(gate); 282 } 283 284 VariableType GetVarType(PropertyLookupResult plr); 285 GateRef GetLengthFromSupers(GateRef supers); 286 GateRef GetValueFromSupers(GateRef supers, size_t index); 287 GateRef LoadFromTaggedArray(GateRef array, size_t index); 288 GateRef LoadFromConstPool(GateRef glue, GateRef unsharedConstPool, size_t index, size_t valVecType); 289 GateRef GetLengthFromString(GateRef gate); 290 GateRef LoadPropertyFromHolder(GateRef holder, PropertyLookupResult plr); 291 void StorePropertyOnHolder(GateRef holder, GateRef value, PropertyLookupResult plr, bool needBarrier); 292 293 Circuit *circuit_; 294 CompilationEnv *compilationEnv_ {nullptr}; 295 GateAccessor acc_; 296 CircuitBuilder builder_; 297 GateRef dependEntry_; 298 bool enableLoweringBuiltin_ {false}; 299 bool traceBuiltins_ {false}; 300 GateRef glue_ {Circuit::NullGate()}; 301 }; 302 } // panda::ecmascript::kungfu 303 #endif // ECMASCRIPT_COMPILER_TYPED_HCR_LOWERING_H 304