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_SLOWPATH_LOWERING_H 17 #define ECMASCRIPT_COMPILER_SLOWPATH_LOWERING_H 18 19 #include "ecmascript/compiler/argument_accessor.h" 20 #include "ecmascript/compiler/circuit.h" 21 #include "ecmascript/compiler/circuit_builder.h" 22 #include "ecmascript/compiler/gate_accessor.h" 23 #include "ecmascript/compiler/new_object_stub_builder.h" 24 #include "ecmascript/compiler/pass_manager.h" 25 #include "ecmascript/compiler/share_gate_meta_data.h" 26 #include <cstddef> 27 28 namespace panda::ecmascript::kungfu { 29 // slowPath Lowering Process 30 // SW: state wire, DW: depend wire, VW: value wire 31 // Before lowering: 32 // SW DW VW 33 // | | | 34 // | | | 35 // v v v 36 // +-----------------------------+ 37 // | (HIR) | 38 // | JS_BYTECODE |DW-------------------------------------- 39 // | | | 40 // +-----------------------------+ | 41 // SW SW | 42 // | | | 43 // | | | 44 // | | | 45 // v v | 46 // +--------------+ +--------------+ | 47 // | IF_SUCCESS | | IF_EXCEPTION |SW--------- | 48 // +--------------+ +--------------+ | | 49 // SW SW | | 50 // | | | | 51 // v v | | 52 // --------------------------------------------------------------|-----------------------|------------------- 53 // catch processing | | 54 // | | 55 // v V 56 // +--------------+ +-----------------+ 57 // | MERGE |SW---->| DEPEND_SELECTOR | 58 // +--------------+ +-----------------+ 59 // DW 60 // | 61 // v 62 // +-----------------+ 63 // | GET_EXCEPTION | 64 // +-----------------+ 65 66 67 // After lowering: 68 // SW DW VW 69 // | | | 70 // | | | 71 // | v v 72 // | +---------------------+ +------------------+ 73 // | | CONSTANT(Exception) | | CALL |DW--------------- 74 // | +---------------------+ +------------------+ | 75 // | VW VW | 76 // | | | | 77 // | | | | 78 // | v v | 79 // | +------------------+ | 80 // | | EQ | | 81 // | +------------------+ | 82 // | VW | 83 // | | | 84 // | | | 85 // | v | 86 // | +------------------+ | 87 // ------------------------>| IF_BRANCH | | 88 // +------------------+ | 89 // SW SW | 90 // | | | 91 // v v | 92 // +--------------+ +--------------+ | 93 // | IF_FALSE | | IF_TRUE | | 94 // | (success) | | (exception) | | 95 // +--------------+ +--------------+ | 96 // SW SW SW | 97 // | | | | 98 // v v | | 99 // ---------------------------------------------------|-----------------------------|---------------------- 100 // catch processing | | 101 // | | 102 // v v 103 // +--------------+ +-----------------+ 104 // | MERGE |SW---------->| DEPEND_SELECTOR | 105 // +--------------+ +-----------------+ 106 // DW 107 // | 108 // v 109 // +-----------------+ 110 // | GET_EXCEPTION | 111 // +-----------------+ 112 113 class SlowPathLowering { 114 public: SlowPathLowering(Circuit * circuit,CompilationConfig * cmpCfg,PassContext * ctx,const MethodLiteral * methodLiteral,bool enableLog,const std::string & name,const CString & recordName)115 SlowPathLowering(Circuit *circuit, CompilationConfig *cmpCfg, 116 PassContext *ctx, const MethodLiteral *methodLiteral, 117 bool enableLog, const std::string& name, const CString &recordName) 118 : compilationEnv_(ctx->GetCompilationEnv()), methodLiteral_(methodLiteral), 119 circuit_(circuit), acc_(circuit), 120 argAcc_(circuit->GetArgumentAccessor()), builder_(circuit, cmpCfg), 121 enableLog_(enableLog), methodName_(name), recordName_(recordName), glue_(acc_.GetGlueFromArgList()) 122 { 123 traceBc_ = cmpCfg->IsTraceBC(); 124 profiling_ = cmpCfg->IsProfiling(); 125 stressDeopt_ = cmpCfg->IsStressDeopt(); 126 } 127 ~SlowPathLowering() = default; 128 void CallRuntimeLowering(); 129 IsLogEnabled()130 bool IsLogEnabled() const 131 { 132 return enableLog_; 133 } 134 IsTraceBC()135 bool IsTraceBC() const 136 { 137 return traceBc_; 138 } 139 IsProfiling()140 bool IsProfiling() const 141 { 142 return profiling_; 143 } 144 IsStressDeopt()145 bool IsStressDeopt() const 146 { 147 return stressDeopt_; 148 } 149 150 private: GetMethodName()151 const std::string& GetMethodName() const 152 { 153 return methodName_; 154 } 155 bool enableMegaIC(GateRef gate); 156 void ReplaceHirWithPendingException(GateRef hirGate, GateRef state, GateRef depend, GateRef value); 157 void ReplaceHirWithValue(GateRef hirGate, GateRef value); 158 void ReplaceHirToThrowCall(GateRef hirGate, GateRef callGate); 159 void LowerExceptionHandler(GateRef hirGate); 160 void Lower(GateRef gate); 161 void LowerAdd2(GateRef gate); 162 void LowerCreateIterResultObj(GateRef gate); 163 void SaveFrameToContext(GateRef gate); 164 void LowerSuspendGenerator(GateRef gate); 165 void LowerAsyncFunctionAwaitUncaught(GateRef gate); 166 void LowerAsyncFunctionResolve(GateRef gate); 167 void LowerAsyncFunctionReject(GateRef gate); 168 void LowerStGlobalVar(GateRef gate); 169 void LowerTryLdGlobalByName(GateRef gate); 170 void LowerGetIterator(GateRef gate); 171 void LowerGetAsyncIterator(GateRef gate); 172 void LowerToJSCall(GateRef hirGate, const std::vector<GateRef> &args, const std::vector<GateRef> &argsFastCall); 173 void LowerNewFastCall(GateRef gate, GateRef glue, GateRef func, bool needPushArgv, bool isFastCall, 174 const std::vector<GateRef> &args, const std::vector<GateRef> &fastCallArgs, 175 Variable *result, Label *exit); 176 void CallWithTimer(const CallSignature *cs, GateRef target, GateRef gate, GateRef func, 177 const std::vector<GateRef> &args, Variable *result, Label *exit, const char *comment); 178 void SelectFastNew(GateRef selectCall, GateRef gate, GateRef func, const std::vector<GateRef> &args, 179 const std::vector<GateRef> &argsFastCall, Variable *result, Label *exit); 180 void LowerCallArg0Stub(GateRef gate); 181 void LowerCallArg1Stub(GateRef gate); 182 void LowerCallArg2Stub(GateRef gate); 183 void LowerCallArg3Stub(GateRef gate); 184 void LowerCallThis0Stub(GateRef gate); 185 void LowerCallThis1Stub(GateRef gate); 186 void LowerCallThis2Stub(GateRef gate); 187 void LowerCallThis3Stub(GateRef gate); 188 void LowerCallthisrangeImm8Imm8V8(GateRef gate); 189 void LowerWideCallthisrangePrefImm16V8(GateRef gate); 190 void LowerCallSpread(GateRef gate); 191 void LowerCallrangeImm8Imm8V8(GateRef gate); 192 void LowerWideCallrangePrefImm16V8(GateRef gate); 193 void LowerNewObjApply(GateRef gate); 194 void LowerThrow(GateRef gate); 195 void LowerThrowConstAssignment(GateRef gate); 196 void LowerThrowThrowNotExists(GateRef gate); 197 void LowerThrowPatternNonCoercible(GateRef gate); 198 void LowerThrowIfNotObject(GateRef gate); 199 void LowerThrowUndefinedIfHole(GateRef gate); 200 void LowerThrowUndefinedIfHoleWithName(GateRef Getgate); 201 void LowerThrowIfSuperNotCorrectCall(GateRef gate); 202 void LowerThrowDeleteSuperProperty(GateRef gate); 203 void LowerLdSymbol(GateRef gate); 204 void LowerLdGlobal(GateRef gate); 205 void LowerSub2(GateRef gate); 206 void LowerMul2(GateRef gate); 207 void LowerDiv2(GateRef gate); 208 void LowerMod2(GateRef gate); 209 void LowerEq(GateRef gate); 210 void LowerNotEq(GateRef gate); 211 void LowerLess(GateRef gate); 212 void LowerLessEq(GateRef gate); 213 void LowerGreater(GateRef gate); 214 void LowerGreaterEq(GateRef gate); 215 void LowerGetPropIterator(GateRef gate); 216 void LowerCloseIterator(GateRef gate); 217 void LowerInc(GateRef gate); 218 void LowerDec(GateRef gate); 219 void LowerToNumber(GateRef gate); 220 void LowerNeg(GateRef gate); 221 void LowerNot(GateRef gate); 222 void LowerShl2(GateRef gate); 223 void LowerShr2(GateRef gate); 224 void LowerAshr2(GateRef gate); 225 void LowerAnd2(GateRef gate); 226 void LowerOr2(GateRef gate); 227 void LowerXor2(GateRef gate); 228 void LowerDelObjProp(GateRef gate); 229 void LowerExp(GateRef gate); 230 void LowerIsIn(GateRef gate); 231 void LowerInstanceof(GateRef gate); 232 void LowerFastStrictNotEqual(GateRef gate); 233 void LowerFastStrictEqual(GateRef gate); 234 void LowerCreateEmptyArray(GateRef gate); 235 void LowerCreateEmptyObject(GateRef gate); 236 void LowerCreateArrayWithBuffer(GateRef gate); 237 void LowerCreateObjectWithBuffer(GateRef gate); 238 void LowerStModuleVar(GateRef gate); 239 void LowerGetTemplateObject(GateRef gate); 240 void LowerSetObjectWithProto(GateRef gate); 241 void LowerLdBigInt(GateRef gate); 242 void LowerToNumeric(GateRef gate); 243 void LowerDynamicImport(GateRef gate); 244 void LowerLdLocalModuleVarByIndex(GateRef gate); 245 void LowerExternalModule(GateRef gate); 246 void LowerGetModuleNamespace(GateRef gate); 247 void LowerSendableExternalModule(GateRef gate); 248 void LowerSendableLocalModule(GateRef gate); 249 void LowerSuperCall(GateRef gate); 250 void LowerSuperCallForJIT(GateRef gate); 251 void LowerSuperCallArrow(GateRef gate); 252 void LowerSuperCallSpread(GateRef gate); 253 GateRef GetExpectedNumOfArgsFromFunc(GateRef func); 254 void LowerSuperCallForwardAllArgs(GateRef gate); 255 void LowerSuperCallForwardAllArgsForJIT(GateRef gate); 256 void CheckSuperAndNewTarget(NewObjectStubBuilder &objBuilder, GateRef super, Variable &newTarget, 257 Variable &thisObj, Label &fastPath, Label &slowPath); 258 GateRef CheckSuperAndNewTargetForJIT(GateRef gate, GateRef super, Variable &newTarget, Label &fastPath, 259 Label &slowPath); 260 GateRef IsAotOrFastCall(GateRef func, CircuitBuilder::JudgeMethodType type); 261 void LowerFastSuperCallWithArgArray(GateRef array, const std::vector<GateRef> &args, bool isSpread, 262 Variable &result, Label &exit); 263 void GenerateSuperCallForwardAllArgsWithoutArgv(const std::vector<GateRef> &args, Variable &result, Label &exit); 264 void LowerIsTrueOrFalse(GateRef gate, bool flag); 265 void LowerNewObjRange(GateRef gate); 266 bool IsDependIfStateMent(GateRef gate, size_t idx); 267 void LowerConditionJump(GateRef gate, bool isEqualJump); 268 void LowerGetNextPropName(GateRef gate); 269 void LowerCopyDataProperties(GateRef gate); 270 void LowerCreateObjectWithExcludedKeys(GateRef gate); 271 void LowerCreateRegExpWithLiteral(GateRef gate); 272 void LowerStOwnByValue(GateRef gate); 273 void LowerStOwnByIndex(GateRef gate); 274 void LowerStOwnByName(GateRef gate); 275 void LowerDefineFunc(GateRef gate); 276 void LowerNewLexicalEnv(GateRef gate); 277 void LowerNewLexicalEnvWithName(GateRef gate); 278 void LowerNewSendableEnv(GateRef gate); 279 void LowerPopLexicalEnv(GateRef gate); 280 void LowerLdSuperByValue(GateRef gate); 281 void LowerStSuperByValue(GateRef gate); 282 void LowerTryStGlobalByName(GateRef gate); 283 void LowerStConstToGlobalRecord(GateRef gate, bool isConst); 284 void LowerStOwnByValueWithNameSet(GateRef gate); 285 void LowerStOwnByNameWithNameSet(GateRef gate); 286 void LowerLdGlobalVar(GateRef gate); 287 void LowerLdObjByName(GateRef gate); 288 void LowerStObjByName(GateRef gate, bool isThis); 289 void LowerLdSuperByName(GateRef gate); 290 void LowerStSuperByName(GateRef gate); 291 void LowerDefineGetterSetterByValue(GateRef gate); 292 void LowerLdObjByIndex(GateRef gate); 293 void LowerStObjByIndex(GateRef gate); 294 void LowerLdObjByValue(GateRef gate, bool isThis); 295 void LowerStObjByValue(GateRef gate, bool isThis); 296 void LowerCreateGeneratorObj(GateRef gate); 297 void LowerStArraySpread(GateRef gate); 298 void LowerLdLexVar(GateRef gate); 299 void LowerLdSendableVar(GateRef gate); 300 void LowerStLexVar(GateRef gate); 301 void LowerStSendableVar(GateRef gate); 302 void LowerDefineClassWithBuffer(GateRef gate); 303 void LowerAsyncFunctionEnter(GateRef gate); 304 void LowerTypeof(GateRef gate); 305 void LowerResumeGenerator(GateRef gate); 306 void LowerStoreRegister(GateRef gate, GateRef arrayGate); 307 void LowerGetResumeMode(GateRef gate); 308 void LowerDefineMethod(GateRef gate); 309 void LowerGetUnmappedArgs(GateRef gate); 310 void LowerCopyRestArgs(GateRef gate); 311 void LowerCallStubWithIC(GateRef gate, int sign, const std::vector<GateRef> &args); 312 GateRef LowerCallRuntime(GateRef gate, int index, const std::vector<GateRef> &args, bool useLabel = false); 313 GateRef LowerCallNGCRuntime(GateRef gate, int index, const std::vector<GateRef> &args, bool useLabel = false); 314 void LowerCreateAsyncGeneratorObj(GateRef gate); 315 void LowerAsyncGeneratorResolve(GateRef gate); 316 void LowerAsyncGeneratorReject(GateRef gate); 317 void LowerSetGeneratorState(GateRef gate); 318 GateRef GetValueFromTaggedArray(GateRef arrayGate, GateRef indexOffset); 319 GateRef GetTaggedArrayFromValueIn(Environment *env, GateRef gate, size_t length); 320 GateRef LowerUpdateArrayHClassAtDefine(GateRef gate, GateRef array); 321 void AddProfiling(GateRef gate, bool skipGenerator = true); 322 GateRef FastStrictEqual(GateRef left, GateRef right); 323 void LowerWideLdPatchVar(GateRef gate); 324 void LowerWideStPatchVar(GateRef gate); 325 void LowerLdThisByName(GateRef gate); 326 bool IsFastCallArgs(size_t index); 327 void LowerConstruct(GateRef gate); 328 void LowerCallInternal(GateRef gate); 329 void LowerCallNew(GateRef gate); 330 void LowerCallNewBuiltin(GateRef gate); 331 void LowerTypedCall(GateRef gate); 332 void LowerTypedFastCall(GateRef gate); 333 void LowerCheckSafePointAndStackOver(GateRef gate); 334 void LowerLdPrivateProperty(GateRef gate); 335 void LowerStPrivateProperty(GateRef gate); 336 void LowerTestIn(GateRef gate); 337 void LowerNotifyConcurrentResult(GateRef gate); 338 void LowerDefineFieldByName(GateRef gate); 339 void LowerDefineFieldByValue(GateRef gate); 340 void LowerDefineFieldByIndex(GateRef gate); 341 void LowerToPropertyKey(GateRef gate); 342 void LowerCreatePrivateProperty(GateRef gate); 343 void LowerDefinePrivateProperty(GateRef gate); 344 void LowerDefineSendableClass(GateRef gate); 345 void LowerLdSendableClass(GateRef gate); 346 void LowerGetEnv(GateRef gate); 347 void DeleteLoopExit(GateRef gate); 348 void DeleteLoopExitValue(GateRef gate); 349 void LowerLdStr(GateRef gate); 350 void LowerGetSharedConstPool(GateRef gate); 351 void LowerGetUnsharedConstPool(GateRef gate); 352 bool TryLowerGetGlobalEnvCache(GateRef gate); 353 void LowerLdLazyExternalModuleVar(GateRef gate); 354 void LowerLdLazySendableExternalModuleVar(GateRef gate); 355 GateRef GetStringFromConstPool(GateRef gate, GateRef stringId, uint32_t stringIdIdx); 356 bool OptimizeDefineFuncForJit(GateRef gate, GateRef jsFunc, GateRef length, GateRef methodId, GateRef lexEnv, 357 GateRef slotId); 358 359 CompilationEnv *compilationEnv_; 360 const MethodLiteral *methodLiteral_ {nullptr}; 361 Circuit *circuit_; 362 GateAccessor acc_; 363 ArgumentAccessor *argAcc_; 364 CircuitBuilder builder_; 365 bool enableLog_ {false}; 366 bool traceBc_ {false}; 367 bool profiling_ {false}; 368 bool stressDeopt_ {false}; 369 std::string methodName_; 370 const CString &recordName_; 371 GateRef glue_ {Circuit::NullGate()}; 372 CVector<GateRef> unsharedCP_; 373 }; 374 } // panda::ecmascript::kungfu 375 #endif // ECMASCRIPT_COMPILER_SLOWPATH_LOWERING_H 376