1 /* 2 * Copyright (c) 2023 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_TYPE_INFO_ACCESSORS_H 17 #define ECMASCRIPT_COMPILER_TYPE_INFO_ACCESSORS_H 18 19 #include "ecmascript/compiler/aot_compiler_preprocessor.h" 20 #include "ecmascript/compiler/argument_accessor.h" 21 #include "ecmascript/compiler/pgo_type/pgo_type_manager.h" 22 #include "ecmascript/enum_conversion.h" 23 #include "ecmascript/global_index.h" 24 #include "ecmascript/jspandafile/program_object.h" 25 #include "ecmascript/mem/chunk.h" 26 #include "libpandafile/index_accessor.h" 27 28 namespace panda::ecmascript::kungfu { 29 class TypeInfoAccessor { 30 public: TypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate)31 TypeInfoAccessor(const CompilationEnv *env, Circuit* circuit, GateRef gate) 32 : compilationEnv_(env), 33 acc_(circuit), 34 argAcc_(circuit), 35 gate_(gate) 36 { 37 pgoType_ = acc_.TryGetPGOType(gate); 38 // NOTICE-PGO: wx delete in part3 39 ptManager_ = compilationEnv_->GetPTManager(); 40 isAot_ = compilationEnv_->IsAotCompiler(); 41 } 42 GetGate()43 inline GateRef GetGate() const 44 { 45 return gate_; 46 } 47 48 static bool IsTrustedBooleanType(GateAccessor acc, GateRef gate); 49 50 static bool IsTrustedNumberType(GateAccessor acc, GateRef gate); 51 52 static bool IsTrustedStringType( 53 const CompilationEnv *env, Circuit *circuit, Chunk *chunk, GateAccessor acc, GateRef gate); 54 IsTrustedBooleanOrNumberOrStringType(const CompilationEnv * env,Circuit * circuit,Chunk * chunk,GateAccessor acc,GateRef gate)55 static inline bool IsTrustedBooleanOrNumberOrStringType(const CompilationEnv *env, Circuit *circuit, 56 Chunk *chunk, GateAccessor acc, GateRef gate) 57 { 58 return IsTrustedBooleanType(acc, gate) || IsTrustedNumberType(acc, gate) || 59 IsTrustedStringType(env, circuit, chunk, acc, gate); 60 } 61 IsAot()62 inline bool IsAot() const 63 { 64 return isAot_; 65 } 66 67 static bool IsTrustedNotSameType(const CompilationEnv *env, Circuit *circuit, Chunk *chunk, 68 GateAccessor acc, GateRef left, GateRef right); 69 70 BuiltinsStubCSigns::ID TryGetPGOBuiltinMethodId() const; 71 72 static constexpr uint32_t INVALID_LEN = std::numeric_limits<uint32_t>::max(); 73 74 protected: 75 ParamType PGOSampleTypeToParamType() const; 76 static ParamType PGOBuiltinTypeToParamType(ProfileType pgoType); 77 bool IsMegaType() const; 78 79 const CompilationEnv *compilationEnv_ {nullptr}; 80 GateAccessor acc_; 81 ArgumentAccessor argAcc_; 82 GateRef gate_; 83 PGOTypeRef pgoType_; 84 // NOTICE-PGO: wx delete in part3 85 PGOTypeManager *ptManager_ {nullptr}; 86 bool isAot_; 87 }; 88 89 class BinOpTypeInfoAccessor final : public TypeInfoAccessor { 90 public: BinOpTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate)91 BinOpTypeInfoAccessor(const CompilationEnv *env, 92 Circuit *circuit, 93 GateRef gate) 94 : TypeInfoAccessor(env, circuit, gate) 95 { 96 left_ = acc_.GetValueIn(gate, 0); // 0: left 97 right_ = acc_.GetValueIn(gate, 1); // 1: right 98 } 99 NO_COPY_SEMANTIC(BinOpTypeInfoAccessor); 100 NO_MOVE_SEMANTIC(BinOpTypeInfoAccessor); 101 GetLeftGate()102 inline GateRef GetLeftGate() const 103 { 104 return left_; 105 } 106 GetReightGate()107 inline GateRef GetReightGate() const 108 { 109 return right_; 110 } 111 HasNumberType()112 inline bool HasNumberType() const 113 { 114 if (LeftOrRightIsUndefinedOrNull()) { 115 return false; 116 } 117 return pgoType_.HasNumber(); 118 } 119 IsStringType()120 inline bool IsStringType() const 121 { 122 if (LeftOrRightIsUndefinedOrNull()) { 123 return false; 124 } 125 return pgoType_.IsString(); 126 } 127 IsInternStringType()128 inline bool IsInternStringType() const 129 { 130 if (LeftOrRightIsUndefinedOrNull()) { 131 return false; 132 } 133 return pgoType_.IsInternString(); 134 } 135 IsNumberOrStringType()136 inline bool IsNumberOrStringType() const 137 { 138 if (LeftOrRightIsUndefinedOrNull()) { 139 return false; 140 } 141 return pgoType_.IsNumberOrString(); 142 } 143 LeftOrRightIsUndefinedOrNull()144 inline bool LeftOrRightIsUndefinedOrNull() const 145 { 146 return acc_.IsUndefinedOrNullOrHole(left_) || acc_.IsUndefinedOrNullOrHole(right_); 147 } 148 GetParamType()149 inline ParamType GetParamType() const 150 { 151 if (LeftOrRightIsUndefinedOrNull()) { 152 return ParamType::AnyType(); 153 } 154 return PGOSampleTypeToParamType(); 155 } 156 157 private: 158 GateRef left_; 159 GateRef right_; 160 }; 161 162 class UnOpTypeInfoAccessor : public TypeInfoAccessor { 163 public: UnOpTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate)164 UnOpTypeInfoAccessor(const CompilationEnv *env, 165 Circuit *circuit, 166 GateRef gate) 167 : TypeInfoAccessor(env, circuit, gate) 168 { 169 value_ = acc_.GetValueIn(gate, 0); // 0: value 170 } 171 NO_COPY_SEMANTIC(UnOpTypeInfoAccessor); 172 NO_MOVE_SEMANTIC(UnOpTypeInfoAccessor); 173 GetValue()174 inline GateRef GetValue() const 175 { 176 return value_; 177 } 178 HasNumberType()179 inline bool HasNumberType() const 180 { 181 return pgoType_.HasNumber(); 182 } 183 IsBooleanType()184 inline bool IsBooleanType() const 185 { 186 return pgoType_.IsBoolean(); 187 } 188 IsUndefinedOrNullType()189 inline bool IsUndefinedOrNullType() const 190 { 191 return pgoType_.IsUndefinedOrNull(); 192 } 193 GetParamType()194 inline ParamType GetParamType() const 195 { 196 return PGOSampleTypeToParamType(); 197 } 198 GetValueGateType()199 GateType GetValueGateType() const 200 { 201 return acc_.GetGateType(value_); 202 } 203 204 protected: 205 GateRef value_ {Circuit::NullGate()}; 206 }; 207 208 class ConditionJumpTypeInfoAccessor final : public UnOpTypeInfoAccessor { 209 public: ConditionJumpTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate)210 ConditionJumpTypeInfoAccessor(const CompilationEnv *env, 211 Circuit *circuit, 212 GateRef gate) 213 : UnOpTypeInfoAccessor(env, circuit, gate) {} 214 NO_COPY_SEMANTIC(ConditionJumpTypeInfoAccessor); 215 NO_MOVE_SEMANTIC(ConditionJumpTypeInfoAccessor); 216 GetBranchWeight()217 uint32_t GetBranchWeight() const 218 { 219 return acc_.TryGetPGOType(value_).GetPGOSampleType()->GetWeight(); 220 } 221 }; 222 223 class NewObjRangeTypeInfoAccessor final : public UnOpTypeInfoAccessor { 224 public: 225 class AccessorStrategy { 226 public: 227 virtual ~AccessorStrategy() = default; 228 virtual bool IsValidCallMethodId() const = 0; 229 virtual uint32_t GetCallMethodId() const = 0; 230 virtual bool FindHClass() const = 0; 231 virtual JSTaggedValue GetHClass() const = 0; 232 }; 233 234 class AotAccessorStrategy : public AccessorStrategy { 235 public: AotAccessorStrategy(NewObjRangeTypeInfoAccessor & parent)236 explicit AotAccessorStrategy(NewObjRangeTypeInfoAccessor &parent) : parent_(parent) 237 { 238 } 239 IsValidCallMethodId()240 bool IsValidCallMethodId() const override 241 { 242 return parent_.pgoType_.IsValidCallMethodId(); 243 } 244 GetCallMethodId()245 uint32_t GetCallMethodId() const override 246 { 247 ASSERT(IsValidCallMethodId()); 248 return parent_.pgoType_.GetCallMethodId(); 249 } 250 bool FindHClass() const override; 251 JSTaggedValue GetHClass() const override; 252 253 private: 254 NewObjRangeTypeInfoAccessor &parent_; 255 }; 256 257 class JitAccessorStrategy : public AccessorStrategy { 258 public: JitAccessorStrategy(NewObjRangeTypeInfoAccessor & parent)259 explicit JitAccessorStrategy(NewObjRangeTypeInfoAccessor &parent) : parent_(parent) 260 { 261 } 262 IsValidCallMethodId()263 bool IsValidCallMethodId() const override 264 { 265 return parent_.pgoType_.IsDefOpValidCallMethodId(); 266 } 267 GetCallMethodId()268 uint32_t GetCallMethodId() const override 269 { 270 ASSERT(IsValidCallMethodId()); 271 return parent_.pgoType_.GetDefOpCallMethodId(); 272 } 273 bool FindHClass() const override; 274 JSTaggedValue GetHClass() const override; 275 276 private: 277 NewObjRangeTypeInfoAccessor &parent_; 278 }; 279 NewObjRangeTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate,Chunk * chunk)280 NewObjRangeTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate, Chunk* chunk) 281 : UnOpTypeInfoAccessor(env, circuit, gate), hclassIndex_(-1), traHClassIndex_(-1) 282 { 283 if (IsAot()) { 284 strategy_ = chunk->New<AotAccessorStrategy>(*this); 285 } else { 286 strategy_ = chunk->New<JitAccessorStrategy>(*this); 287 } 288 } 289 NO_COPY_SEMANTIC(NewObjRangeTypeInfoAccessor); 290 NO_MOVE_SEMANTIC(NewObjRangeTypeInfoAccessor); 291 FindHClass()292 bool FindHClass() 293 { 294 return strategy_->FindHClass(); 295 } GetHClass()296 JSTaggedValue GetHClass() 297 { 298 return strategy_->GetHClass(); 299 } 300 IsValidCallMethodId()301 bool IsValidCallMethodId() const 302 { 303 return strategy_->IsValidCallMethodId(); 304 } 305 GetCallMethodId()306 uint32_t GetCallMethodId() const 307 { 308 ASSERT(IsValidCallMethodId()); 309 return strategy_->GetCallMethodId(); 310 } 311 GetHClassIndex()312 int GetHClassIndex() const 313 { 314 if (traHClassIndex_ != -1) { 315 return traHClassIndex_; 316 } 317 return hclassIndex_; 318 } 319 320 private: 321 int hclassIndex_; 322 int traHClassIndex_ {-1}; 323 AccessorStrategy* strategy_; 324 325 friend class AotAccessorStrategy; 326 friend class JitAccessorStrategy; 327 }; 328 329 class NewBuiltinCtorTypeInfoAccessor final : public UnOpTypeInfoAccessor { 330 public: NewBuiltinCtorTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate)331 NewBuiltinCtorTypeInfoAccessor(const CompilationEnv *env, 332 Circuit *circuit, 333 GateRef gate) 334 : UnOpTypeInfoAccessor(env, circuit, gate) {} 335 NO_COPY_SEMANTIC(NewBuiltinCtorTypeInfoAccessor); 336 NO_MOVE_SEMANTIC(NewBuiltinCtorTypeInfoAccessor); 337 IsBuiltinId(BuiltinsStubCSigns::ID id)338 bool IsBuiltinId(BuiltinsStubCSigns::ID id) 339 { 340 if (pgoType_.IsPGOSampleType()) { 341 return TryGetPGOBuiltinMethodId() == id; 342 } else { 343 return false; 344 } 345 } 346 347 private: GetCtorGT()348 GlobalTSTypeRef GetCtorGT() const 349 { 350 return GetValueGateType().GetGTRef(); 351 } 352 }; 353 354 class TypeOfTypeInfoAccessor final : public UnOpTypeInfoAccessor { 355 public: TypeOfTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate)356 TypeOfTypeInfoAccessor(const CompilationEnv *env, 357 Circuit *circuit, 358 GateRef gate) 359 : UnOpTypeInfoAccessor(env, circuit, gate) {} 360 NO_COPY_SEMANTIC(TypeOfTypeInfoAccessor); 361 NO_MOVE_SEMANTIC(TypeOfTypeInfoAccessor); 362 363 bool IsIllegalType() const; 364 }; 365 366 class SuperCallTypeInfoAccessor final : public TypeInfoAccessor { 367 public: 368 SuperCallTypeInfoAccessor(const CompilationEnv *env, 369 Circuit *circuit, 370 GateRef gate, 371 const JSPandaFile *jsPandaFile = nullptr, 372 const CallMethodFlagMap *callMethodFlagMap = nullptr); 373 NO_COPY_SEMANTIC(SuperCallTypeInfoAccessor); 374 NO_MOVE_SEMANTIC(SuperCallTypeInfoAccessor); 375 IsValidCallMethodId()376 bool IsValidCallMethodId() const 377 { 378 return pgoType_.IsValidCallMethodId(); 379 } 380 GetMethodId()381 uint32_t GetMethodId() const 382 { 383 if (jsPandaFile_ == nullptr || callMethodFlagMap_ == nullptr) { 384 return 0; 385 } 386 auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); 387 if (!profileType->IsNone()) { 388 return profileType->GetProfileType().GetId(); 389 } 390 return 0; 391 } 392 GetCtor()393 GateRef GetCtor() const 394 { 395 return ctor_; 396 } 397 398 protected: 399 const JSPandaFile *jsPandaFile_; 400 const CallMethodFlagMap *callMethodFlagMap_; 401 402 private: 403 GateRef ctor_; 404 }; 405 406 class CallTypeInfoAccessor : public TypeInfoAccessor { 407 public: 408 CallTypeInfoAccessor(const CompilationEnv *env, 409 Circuit *circuit, 410 GateRef gate, 411 const JSPandaFile *jsPandaFile = nullptr, 412 const CallMethodFlagMap *callMethodFlagMap = nullptr) TypeInfoAccessor(env,circuit,gate)413 : TypeInfoAccessor(env, circuit, gate), 414 argc_(0), 415 func_(Circuit::NullGate()), 416 jsPandaFile_(jsPandaFile), 417 callMethodFlagMap_(callMethodFlagMap) 418 {} 419 GetArgc()420 size_t GetArgc() const 421 { 422 return argc_; 423 } 424 GetFunc()425 GateRef GetFunc() const 426 { 427 return func_; 428 } 429 GetFuncGateType()430 GateType GetFuncGateType() const 431 { 432 return acc_.GetGateType(func_); 433 } 434 IsValidCallMethodId()435 bool IsValidCallMethodId() const 436 { 437 return pgoType_.IsValidCallMethodId(); 438 } 439 IsHotnessFunc()440 bool IsHotnessFunc() const 441 { 442 if (jsPandaFile_ == nullptr || callMethodFlagMap_ == nullptr) { 443 return false; 444 } 445 auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); 446 bool haveProfileType = !profileType->IsNone(); 447 if (haveProfileType) { 448 CString fileDesc = jsPandaFile_->GetNormalizedFileDesc(); 449 uint32_t methodId = profileType->GetProfileType().GetId(); 450 return callMethodFlagMap_->IsAotCompile(fileDesc, methodId); 451 } 452 return false; 453 } 454 GetFunctionTypeLength()455 uint32_t GetFunctionTypeLength() const 456 { 457 if (jsPandaFile_ == nullptr || callMethodFlagMap_ == nullptr) { 458 return INVALID_LEN; 459 } 460 auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); 461 bool haveProfileType = !profileType->IsNone(); 462 if (haveProfileType) { 463 uint32_t methodId = profileType->GetProfileType().GetId(); 464 MethodLiteral *targetMethodLiteral = jsPandaFile_->FindMethodLiteral(methodId); 465 if (UNLIKELY(targetMethodLiteral == nullptr)) { 466 return INVALID_LEN; 467 } 468 469 return targetMethodLiteral->GetNumArgsWithCallField(); 470 } 471 return INVALID_LEN; 472 } 473 IsNoGC()474 bool IsNoGC() const 475 { 476 if (jsPandaFile_ == nullptr || callMethodFlagMap_ == nullptr) { 477 return false; 478 } 479 auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); 480 bool haveProfileType = !profileType->IsNone(); 481 if (haveProfileType) { 482 uint32_t methodId = profileType->GetProfileType().GetId(); 483 MethodLiteral *targetMethodLiteral = jsPandaFile_->FindMethodLiteral(methodId); 484 if (UNLIKELY(targetMethodLiteral == nullptr)) { 485 return false; 486 } 487 return targetMethodLiteral->IsNoGC(); 488 } 489 return false; 490 } 491 GetMethodIndex()492 int GetMethodIndex() const 493 { 494 if (jsPandaFile_ == nullptr || callMethodFlagMap_ == nullptr) { 495 return -1; 496 } 497 auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); 498 bool haveProfileType = !profileType->IsNone(); 499 if (haveProfileType) { 500 uint32_t methodId = profileType->GetProfileType().GetId(); 501 panda_file::IndexAccessor indexAccessor(*(jsPandaFile_->GetPandaFile()), 502 panda_file::File::EntityId(methodId)); 503 uint32_t cpId = static_cast<uint32_t>(indexAccessor.GetHeaderIndex()); 504 ConstantPool *constpoolHandle = 505 ConstantPool::Cast(compilationEnv_->FindConstpool(jsPandaFile_, cpId).GetTaggedObject()); 506 return constpoolHandle->GetMethodIndexByEntityId(panda_file::File::EntityId(methodId)); 507 } 508 return -1; 509 } 510 GetPandaFile()511 const JSPandaFile *GetPandaFile() const 512 { 513 return jsPandaFile_; 514 } 515 GetMethodId()516 uint32_t GetMethodId() const 517 { 518 if (jsPandaFile_ == nullptr || callMethodFlagMap_ == nullptr) { 519 return 0; 520 } 521 auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); 522 if (!profileType->IsNone()) { 523 return profileType->GetProfileType().GetId(); 524 } 525 return 0; 526 } 527 MethodOffsetIsVaild()528 bool MethodOffsetIsVaild() const 529 { 530 auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); 531 return !profileType->IsNone(); 532 } 533 CanFastCall()534 bool CanFastCall() const 535 { 536 if (jsPandaFile_ == nullptr || callMethodFlagMap_ == nullptr) { 537 return false; 538 } 539 auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); 540 bool haveProfileType = !profileType->IsNone(); 541 if (haveProfileType) { 542 CString fileDesc = jsPandaFile_->GetNormalizedFileDesc(); 543 uint32_t methodId = profileType->GetProfileType().GetId(); 544 return (callMethodFlagMap_->IsAotCompile(fileDesc, methodId) || 545 callMethodFlagMap_->IsJitCompile(fileDesc, methodId)) && 546 callMethodFlagMap_->IsFastCall(fileDesc, methodId); 547 } 548 return false; 549 } 550 GetFuncMethodOffset()551 uint32_t GetFuncMethodOffset() const 552 { 553 if (jsPandaFile_ == nullptr || callMethodFlagMap_ == nullptr) { 554 return false; 555 } 556 auto profileType = acc_.TryGetPGOType(gate_).GetPGOSampleType(); 557 bool haveProfileType = !profileType->IsNone(); 558 if (haveProfileType) { 559 uint32_t methodId = profileType->GetProfileType().GetId(); 560 MethodLiteral *targetMethodLiteral = jsPandaFile_->FindMethodLiteral(methodId); 561 if (UNLIKELY(targetMethodLiteral == nullptr)) { 562 return false; 563 } 564 return targetMethodLiteral->GetMethodId().GetOffset(); 565 } 566 return 0; 567 } 568 569 protected: 570 size_t argc_; 571 GateRef func_; 572 const JSPandaFile *jsPandaFile_; 573 const CallMethodFlagMap *callMethodFlagMap_; 574 }; 575 576 class GetIteratorTypeInfoAccessor final : public CallTypeInfoAccessor { 577 public: 578 GetIteratorTypeInfoAccessor(const CompilationEnv *env, 579 Circuit *circuit, 580 GateRef gate, 581 const JSPandaFile *jsPandaFile = nullptr, 582 const CallMethodFlagMap *callMethodFlagMap = nullptr); 583 NO_COPY_SEMANTIC(GetIteratorTypeInfoAccessor); 584 NO_MOVE_SEMANTIC(GetIteratorTypeInfoAccessor); 585 GetCallee()586 GateRef GetCallee() 587 { 588 return func_; 589 } 590 }; 591 592 class CallArg0TypeInfoAccessor final : public CallTypeInfoAccessor { 593 public: 594 CallArg0TypeInfoAccessor(const CompilationEnv *env, 595 Circuit *circuit, 596 GateRef gate, 597 const JSPandaFile *jsPandaFile = nullptr, 598 const CallMethodFlagMap *callMethodFlagMap = nullptr); 599 NO_COPY_SEMANTIC(CallArg0TypeInfoAccessor); 600 NO_MOVE_SEMANTIC(CallArg0TypeInfoAccessor); 601 }; 602 603 class CallArg1TypeInfoAccessor final : public CallTypeInfoAccessor { 604 public: 605 CallArg1TypeInfoAccessor(const CompilationEnv *env, 606 Circuit *circuit, 607 GateRef gate, 608 const JSPandaFile *jsPandaFile = nullptr, 609 const CallMethodFlagMap *callMethodFlagMap = nullptr); 610 NO_COPY_SEMANTIC(CallArg1TypeInfoAccessor); 611 NO_MOVE_SEMANTIC(CallArg1TypeInfoAccessor); 612 GetValue()613 GateRef GetValue() 614 { 615 return value_; 616 } 617 GetValueGateType()618 GateType GetValueGateType() 619 { 620 return acc_.GetGateType(value_); 621 } 622 623 private: 624 GateRef value_; 625 }; 626 627 class CallArg2TypeInfoAccessor final : public CallTypeInfoAccessor { 628 public: 629 CallArg2TypeInfoAccessor(const CompilationEnv *env, 630 Circuit *circuit, 631 GateRef gate, 632 const JSPandaFile *jsPandaFile = nullptr, 633 const CallMethodFlagMap *callMethodFlagMap = nullptr); 634 NO_COPY_SEMANTIC(CallArg2TypeInfoAccessor); 635 NO_MOVE_SEMANTIC(CallArg2TypeInfoAccessor); 636 }; 637 638 class CallArg3TypeInfoAccessor final : public CallTypeInfoAccessor { 639 public: 640 CallArg3TypeInfoAccessor(const CompilationEnv *env, 641 Circuit *circuit, 642 GateRef gate, 643 const JSPandaFile *jsPandaFile = nullptr, 644 const CallMethodFlagMap *callMethodFlagMap = nullptr); 645 NO_COPY_SEMANTIC(CallArg3TypeInfoAccessor); 646 NO_MOVE_SEMANTIC(CallArg3TypeInfoAccessor); 647 }; 648 649 class CallRangeTypeInfoAccessor final : public CallTypeInfoAccessor { 650 public: 651 CallRangeTypeInfoAccessor(const CompilationEnv *env, 652 Circuit *circuit, 653 GateRef gate, 654 const JSPandaFile *jsPandaFile = nullptr, 655 const CallMethodFlagMap *callMethodFlagMap = nullptr); 656 NO_COPY_SEMANTIC(CallRangeTypeInfoAccessor); 657 NO_MOVE_SEMANTIC(CallRangeTypeInfoAccessor); 658 }; 659 660 class CallThisTypeInfoAccessor : public CallTypeInfoAccessor { 661 public: 662 CallThisTypeInfoAccessor(const CompilationEnv *env, 663 Circuit *circuit, 664 GateRef gate, 665 const JSPandaFile *jsPandaFile = nullptr, 666 const CallMethodFlagMap *callMethodFlagMap = nullptr) CallTypeInfoAccessor(env,circuit,gate,jsPandaFile,callMethodFlagMap)667 : CallTypeInfoAccessor(env, circuit, gate, jsPandaFile, callMethodFlagMap) 668 { 669 thisObj_ = acc_.GetValueIn(gate, 0); 670 } 671 NO_COPY_SEMANTIC(CallThisTypeInfoAccessor); 672 NO_MOVE_SEMANTIC(CallThisTypeInfoAccessor); 673 674 bool CanOptimizeAsFastCall(); 675 GetThisObj()676 GateRef GetThisObj() const 677 { 678 return thisObj_; 679 } 680 protected: 681 GateRef thisObj_; 682 }; 683 684 class CallThis0TypeInfoAccessor final : public CallThisTypeInfoAccessor { 685 public: 686 CallThis0TypeInfoAccessor(const CompilationEnv *env, 687 Circuit *circuit, 688 GateRef gate, 689 const JSPandaFile *jsPandaFile = nullptr, 690 const CallMethodFlagMap *callMethodFlagMap = nullptr); 691 NO_COPY_SEMANTIC(CallThis0TypeInfoAccessor); 692 NO_MOVE_SEMANTIC(CallThis0TypeInfoAccessor); 693 }; 694 695 class CallThis1TypeInfoAccessor final : public CallThisTypeInfoAccessor { 696 public: 697 CallThis1TypeInfoAccessor(const CompilationEnv *env, 698 Circuit *circuit, 699 GateRef gate, 700 const JSPandaFile *jsPandaFile = nullptr, 701 const CallMethodFlagMap *callMethodFlagMap = nullptr); 702 NO_COPY_SEMANTIC(CallThis1TypeInfoAccessor); 703 NO_MOVE_SEMANTIC(CallThis1TypeInfoAccessor); 704 GetArg0()705 GateRef GetArg0() const 706 { 707 return a0_; 708 } 709 GetArgs()710 std::vector<GateRef> GetArgs() 711 { 712 return { thisObj_, a0_ }; 713 } 714 Arg0IsNumberType()715 bool Arg0IsNumberType() const 716 { 717 return acc_.GetGateType(a0_).IsNumberType(); 718 } 719 720 private: 721 GateRef a0_; 722 }; 723 724 class CallThis2TypeInfoAccessor final : public CallThisTypeInfoAccessor { 725 public: 726 CallThis2TypeInfoAccessor(const CompilationEnv *env, 727 Circuit *circuit, 728 GateRef gate, 729 const JSPandaFile *jsPandaFile = nullptr, 730 const CallMethodFlagMap *callMethodFlagMap = nullptr); 731 NO_COPY_SEMANTIC(CallThis2TypeInfoAccessor); 732 NO_MOVE_SEMANTIC(CallThis2TypeInfoAccessor); 733 GetArgs()734 std::vector<GateRef> GetArgs() 735 { 736 return { thisObj_, a0_, a1_ }; 737 } 738 private: 739 GateRef a0_; 740 GateRef a1_; 741 }; 742 743 class CallThis3TypeInfoAccessor final : public CallThisTypeInfoAccessor { 744 public: 745 CallThis3TypeInfoAccessor(const CompilationEnv *env, 746 Circuit *circuit, 747 GateRef gate, 748 const JSPandaFile *jsPandaFile = nullptr, 749 const CallMethodFlagMap *callMethodFlagMap = nullptr); 750 NO_COPY_SEMANTIC(CallThis3TypeInfoAccessor); 751 NO_MOVE_SEMANTIC(CallThis3TypeInfoAccessor); 752 GetArgs()753 std::vector<GateRef> GetArgs() 754 { 755 return { thisObj_, a0_, a1_, a2_ }; 756 } 757 758 private: 759 GateRef a0_; 760 GateRef a1_; 761 GateRef a2_; 762 }; 763 764 class CallThisRangeTypeInfoAccessor final : public CallThisTypeInfoAccessor { 765 public: 766 CallThisRangeTypeInfoAccessor(const CompilationEnv *env, 767 Circuit *circuit, 768 GateRef gate, 769 const JSPandaFile *jsPandaFile = nullptr, 770 const CallMethodFlagMap *callMethodFlagMap = nullptr); 771 NO_COPY_SEMANTIC(CallThisRangeTypeInfoAccessor); 772 NO_MOVE_SEMANTIC(CallThisRangeTypeInfoAccessor); 773 }; 774 775 enum CallKind : uint8_t { 776 CALL, 777 CALL_THIS, 778 CALL_INIT, 779 CALL_SETTER, 780 CALL_GETTER, 781 INVALID 782 }; 783 784 class InlineTypeInfoAccessor final : public TypeInfoAccessor { 785 public: 786 InlineTypeInfoAccessor(const CompilationEnv *env, 787 Circuit *circuit, 788 GateRef gate, 789 GateRef receiver, 790 CallKind kind); 791 IsEnableNormalInline()792 bool IsEnableNormalInline() const 793 { 794 return IsValidCallMethodId(); 795 } 796 IsEnableAccessorInline()797 bool IsEnableAccessorInline() const 798 { 799 if (plr_.IsAccessor()) { 800 const PGORWOpType *pgoTypes = acc_.TryGetPGOType(gate_).GetPGORWOpType(); 801 auto pgoType = pgoTypes->GetObjectInfo(0); 802 if (pgoType.GetAccessorMethod().GetProfileType().IsValidCallMethodId()) { 803 return true; 804 } 805 } 806 return false; 807 } 808 IsValidCallMethodId()809 bool IsValidCallMethodId() const 810 { 811 return pgoType_.IsValidCallMethodId(); 812 } 813 GetFuncMethodOffsetFromPGO()814 uint32_t GetFuncMethodOffsetFromPGO() const 815 { 816 if (IsValidCallMethodId()) { 817 return pgoType_.GetCallMethodId(); 818 } 819 return 0; 820 } 821 GetReceiverGT()822 GateType GetReceiverGT() const 823 { 824 return acc_.GetGateType(receiver_); 825 } 826 827 uint32_t GetCallMethodId() const; 828 GetCallGate()829 GateRef GetCallGate() const 830 { 831 return GetGate(); 832 } 833 IsCallInit()834 bool IsCallInit() const 835 { 836 return kind_ == CallKind::CALL_INIT; 837 } 838 IsCallThis()839 bool IsCallThis() const 840 { 841 return kind_ == CallKind::CALL_THIS || kind_ == CallKind::CALL_INIT; 842 } 843 IsNormalCall()844 bool IsNormalCall() const 845 { 846 return kind_ == CallKind::CALL || kind_ == CallKind::CALL_THIS || kind_ == CallKind::CALL_INIT; 847 } 848 IsCallAccessor()849 bool IsCallAccessor() const 850 { 851 return kind_ == CallKind::CALL_SETTER || kind_ == CallKind::CALL_GETTER; 852 } 853 IsCallGetter()854 bool IsCallGetter() const 855 { 856 return kind_ == CallKind::CALL_GETTER; 857 } 858 IsCallSetter()859 bool IsCallSetter() const 860 { 861 return kind_ == CallKind::CALL_SETTER; 862 } 863 GetType()864 uint32_t GetType() const 865 { 866 return GetFuncMethodOffsetFromPGO(); 867 } 868 GetPlr()869 PropertyLookupResult GetPlr() const 870 { 871 return plr_; 872 } 873 874 private: 875 PropertyLookupResult GetAccessorPlr() const; 876 PropertyLookupResult GetAccessorPlrInJIT() const; 877 bool InitPropAndCheck(JSTaggedValue &prop) const; 878 879 GateRef receiver_; 880 CallKind kind_ {CallKind::INVALID}; 881 PropertyLookupResult plr_ { PropertyLookupResult() }; 882 }; 883 884 class ObjectAccessTypeInfoAccessor : public TypeInfoAccessor { 885 public: 886 class ObjectAccessInfo final { 887 public: 888 explicit ObjectAccessInfo(int hclassIndex = -1, PropertyLookupResult plr = PropertyLookupResult()) hclassIndex_(hclassIndex)889 : hclassIndex_(hclassIndex), plr_(plr), hclass_(nullptr) {} 890 Set(int hclassIndex,PropertyLookupResult plr)891 void Set(int hclassIndex, PropertyLookupResult plr) 892 { 893 hclassIndex_ = hclassIndex; 894 plr_ = plr; 895 } 896 Set(JSHClass * hclass,PropertyLookupResult plr)897 void Set(JSHClass* hclass, PropertyLookupResult plr) 898 { 899 hclass_ = hclass; 900 plr_ = plr; 901 } 902 HClassIndex()903 int HClassIndex() const 904 { 905 return hclassIndex_; 906 } 907 Plr()908 PropertyLookupResult Plr() const 909 { 910 return plr_; 911 } 912 913 private: 914 int hclassIndex_; 915 PropertyLookupResult plr_; 916 JSHClass* hclass_; 917 }; 918 919 enum AccessMode : uint8_t { 920 LOAD = 0, 921 STORE 922 }; 923 ObjectAccessTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate,Chunk * chunk,AccessMode mode)924 ObjectAccessTypeInfoAccessor(const CompilationEnv *env, 925 Circuit *circuit, 926 GateRef gate, 927 Chunk *chunk, 928 AccessMode mode) 929 : TypeInfoAccessor(env, circuit, gate), 930 chunk_(chunk), 931 mode_(mode), 932 key_(Circuit::NullGate()), 933 receiver_(Circuit::NullGate()) 934 {} 935 NO_COPY_SEMANTIC(ObjectAccessTypeInfoAccessor); 936 NO_MOVE_SEMANTIC(ObjectAccessTypeInfoAccessor); 937 938 JSTaggedValue GetKeyTaggedValue() const; 939 GetKey()940 GateRef GetKey() const 941 { 942 return key_; 943 } 944 GetReceiver()945 GateRef GetReceiver() const 946 { 947 return receiver_; 948 } 949 IsMegaType(const PGORWOpType * pgoTypes)950 static bool IsMegaType(const PGORWOpType *pgoTypes) 951 { 952 for (uint32_t i = 0; i < pgoTypes->GetCount(); ++i) { 953 auto temp = pgoTypes->GetObjectInfo(i); 954 if (temp.GetReceiverType().IsMegaStateType()) { 955 return true; 956 } 957 } 958 return false; 959 } 960 961 protected: 962 Chunk *chunk_; 963 AccessMode mode_; 964 GateRef key_; 965 GateRef receiver_; 966 }; 967 968 class ObjAccByNameTypeInfoAccessor : public ObjectAccessTypeInfoAccessor { 969 public: ObjAccByNameTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate,Chunk * chunk,AccessMode mode)970 ObjAccByNameTypeInfoAccessor(const CompilationEnv *env, 971 Circuit *circuit, 972 GateRef gate, 973 Chunk *chunk, 974 AccessMode mode) 975 : ObjectAccessTypeInfoAccessor(env, circuit, gate, chunk, mode), 976 hasIllegalType_(false), 977 accessInfos_(chunk), 978 checkerInfos_(chunk) 979 {} 980 981 NO_COPY_SEMANTIC(ObjAccByNameTypeInfoAccessor); 982 NO_MOVE_SEMANTIC(ObjAccByNameTypeInfoAccessor); 983 HasIllegalType()984 bool HasIllegalType() const 985 { 986 return hasIllegalType_; 987 } 988 GetExpectedHClassIndex(size_t index)989 int GetExpectedHClassIndex(size_t index) const 990 { 991 ASSERT(index < checkerInfos_.size()); 992 return checkerInfos_[index].HClassIndex(); 993 } 994 GetAccessInfo(size_t index)995 ObjectAccessInfo GetAccessInfo(size_t index) const 996 { 997 ASSERT(index < accessInfos_.size()); 998 return accessInfos_[index]; 999 } 1000 1001 protected: 1002 bool GeneratePlr(ProfileTyper type, ObjectAccessInfo &info, JSTaggedValue key) const; 1003 bool GeneratePlrInJIT(JSHClass* hclass, ObjectAccessInfo &info, JSTaggedValue key) const; 1004 1005 bool hasIllegalType_; 1006 ChunkVector<ObjectAccessInfo> accessInfos_; 1007 ChunkVector<ObjectAccessInfo> checkerInfos_; 1008 }; 1009 1010 class LoadPrivatePropertyTypeInfoAccessor final : public ObjAccByNameTypeInfoAccessor { 1011 public: 1012 class AccessorStrategy { 1013 public: 1014 virtual ~AccessorStrategy() = default; 1015 virtual bool TypesIsEmpty() const = 0; 1016 virtual bool IsMono() const = 0; 1017 virtual void FetchPGORWTypesDual() = 0; 1018 virtual bool GenerateObjectAccessInfo() = 0; 1019 }; 1020 1021 class AotAccessorStrategy : public AccessorStrategy { 1022 public: AotAccessorStrategy(LoadPrivatePropertyTypeInfoAccessor & parent)1023 explicit AotAccessorStrategy(LoadPrivatePropertyTypeInfoAccessor &parent) : parent_(parent) 1024 { 1025 } 1026 TypesIsEmpty()1027 bool TypesIsEmpty() const override 1028 { 1029 return parent_.types_.empty(); 1030 } 1031 IsMono()1032 bool IsMono() const override 1033 { 1034 return parent_.types_.size() == 1; 1035 } 1036 1037 void FetchPGORWTypesDual() override; 1038 bool GenerateObjectAccessInfo() override; 1039 1040 private: 1041 LoadPrivatePropertyTypeInfoAccessor &parent_; 1042 }; 1043 1044 class JitAccessorStrategy : public AccessorStrategy { 1045 public: JitAccessorStrategy(LoadPrivatePropertyTypeInfoAccessor & parent)1046 explicit JitAccessorStrategy(LoadPrivatePropertyTypeInfoAccessor &parent) : parent_(parent) 1047 { 1048 } 1049 TypesIsEmpty()1050 bool TypesIsEmpty() const override 1051 { 1052 return parent_.jitTypes_.empty(); 1053 } 1054 IsMono()1055 bool IsMono() const override 1056 { 1057 return parent_.jitTypes_.size() == 1; 1058 } 1059 1060 void FetchPGORWTypesDual() override; 1061 bool GenerateObjectAccessInfo() override; 1062 1063 private: 1064 LoadPrivatePropertyTypeInfoAccessor &parent_; 1065 }; 1066 LoadPrivatePropertyTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate,Chunk * chunk)1067 LoadPrivatePropertyTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate, Chunk *chunk) 1068 : ObjAccByNameTypeInfoAccessor(env, circuit, gate, chunk, AccessMode::STORE), types_(chunk_), jitTypes_(chunk_) 1069 { 1070 levelIndex_ = acc_.GetValueIn(gate, 1); // 1: levelIndex 1071 slotIndex_ = acc_.GetValueIn(gate, 2); // 2: slotIndex 1072 lexicalEnv_ = acc_.GetValueIn(gate, 3); // 3: lexicalEnv 1073 receiver_ = acc_.GetValueIn(gate, 4); // 4: acc as receiver 1074 if (IsAot()) { 1075 strategy_ = chunk_->New<AotAccessorStrategy>(*this); 1076 } else { 1077 strategy_ = chunk_->New<JitAccessorStrategy>(*this); 1078 } 1079 strategy_->FetchPGORWTypesDual(); 1080 hasIllegalType_ = !strategy_->GenerateObjectAccessInfo(); 1081 } 1082 NO_COPY_SEMANTIC(LoadPrivatePropertyTypeInfoAccessor); 1083 NO_MOVE_SEMANTIC(LoadPrivatePropertyTypeInfoAccessor); 1084 IsMono()1085 bool IsMono() const 1086 { 1087 return strategy_->IsMono(); 1088 } 1089 TypesIsEmpty()1090 bool TypesIsEmpty() const 1091 { 1092 return strategy_->TypesIsEmpty(); 1093 } 1094 GetLevelIndex()1095 GateRef GetLevelIndex() const 1096 { 1097 return levelIndex_; 1098 } 1099 GetSlotIndex()1100 GateRef GetSlotIndex() const 1101 { 1102 return slotIndex_; 1103 } 1104 GetLexicalEnv()1105 GateRef GetLexicalEnv() const 1106 { 1107 return lexicalEnv_; 1108 } 1109 IsAccessor()1110 bool IsAccessor() const 1111 { 1112 return isAccessor_; 1113 } 1114 1115 private: 1116 void FetchPGORWTypesDual(); 1117 bool GenerateObjectAccessInfo(); 1118 1119 void FetchPGORWTypesDualInJIT(); 1120 bool GenerateObjectAccessInfoInJIT(); 1121 JSTaggedValue GetKeyTaggedValue() const; 1122 1123 ChunkVector<std::pair<ProfileTyper, ProfileTyper>> types_; 1124 ChunkVector<pgo::PGOObjectInfo> jitTypes_; 1125 GateRef levelIndex_; 1126 GateRef slotIndex_; 1127 GateRef lexicalEnv_; 1128 bool isAccessor_{false}; 1129 AccessorStrategy* strategy_; 1130 friend class AotAccessorStrategy; 1131 friend class JitAccessorStrategy; 1132 }; 1133 1134 class StorePrivatePropertyTypeInfoAccessor final : public ObjAccByNameTypeInfoAccessor { 1135 public: 1136 class AccessorStrategy { 1137 public: 1138 virtual ~AccessorStrategy() = default; 1139 virtual bool TypesIsEmpty() const = 0; 1140 virtual bool IsMono() const = 0; 1141 virtual void FetchPGORWTypesDual() = 0; 1142 virtual bool GenerateObjectAccessInfo() = 0; 1143 }; 1144 1145 class AotAccessorStrategy : public AccessorStrategy { 1146 public: AotAccessorStrategy(StorePrivatePropertyTypeInfoAccessor & parent)1147 explicit AotAccessorStrategy(StorePrivatePropertyTypeInfoAccessor &parent) : parent_(parent) 1148 { 1149 } 1150 TypesIsEmpty()1151 bool TypesIsEmpty() const override 1152 { 1153 return parent_.types_.empty(); 1154 } 1155 IsMono()1156 bool IsMono() const override 1157 { 1158 return parent_.types_.size() == 1; 1159 } 1160 1161 void FetchPGORWTypesDual() override; 1162 bool GenerateObjectAccessInfo() override; 1163 1164 private: 1165 StorePrivatePropertyTypeInfoAccessor &parent_; 1166 }; 1167 1168 class JitAccessorStrategy : public AccessorStrategy { 1169 public: JitAccessorStrategy(StorePrivatePropertyTypeInfoAccessor & parent)1170 explicit JitAccessorStrategy(StorePrivatePropertyTypeInfoAccessor &parent) : parent_(parent) 1171 { 1172 } 1173 TypesIsEmpty()1174 bool TypesIsEmpty() const override 1175 { 1176 return parent_.jitTypes_.empty(); 1177 } 1178 IsMono()1179 bool IsMono() const override 1180 { 1181 return parent_.jitTypes_.size() == 1; 1182 } 1183 1184 void FetchPGORWTypesDual() override; 1185 bool GenerateObjectAccessInfo() override; 1186 1187 private: 1188 StorePrivatePropertyTypeInfoAccessor &parent_; 1189 }; 1190 StorePrivatePropertyTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate,Chunk * chunk)1191 StorePrivatePropertyTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate, Chunk *chunk) 1192 : ObjAccByNameTypeInfoAccessor(env, circuit, gate, chunk, AccessMode::STORE), types_(chunk_), jitTypes_(chunk) 1193 { 1194 levelIndex_ = acc_.GetValueIn(gate, 1); // 1: levelIndex 1195 slotIndex_ = acc_.GetValueIn(gate, 2); // 2: slotIndex 1196 receiver_ = acc_.GetValueIn(gate, 3); // 3: receiver 1197 lexicalEnv_ = acc_.GetValueIn(gate, 4); // 4: lexicalEnv 1198 value_ = acc_.GetValueIn(gate, 5); // 5: acc as value 1199 if (IsAot()) { 1200 strategy_ = chunk_->New<AotAccessorStrategy>(*this); 1201 } else { 1202 strategy_ = chunk_->New<JitAccessorStrategy>(*this); 1203 } 1204 strategy_->FetchPGORWTypesDual(); 1205 hasIllegalType_ = !strategy_->GenerateObjectAccessInfo(); 1206 } 1207 NO_COPY_SEMANTIC(StorePrivatePropertyTypeInfoAccessor); 1208 NO_MOVE_SEMANTIC(StorePrivatePropertyTypeInfoAccessor); 1209 IsMono()1210 bool IsMono() const 1211 { 1212 return strategy_->IsMono(); 1213 } 1214 TypesIsEmpty()1215 bool TypesIsEmpty() const 1216 { 1217 return strategy_->TypesIsEmpty(); 1218 } 1219 GetValue()1220 GateRef GetValue() const 1221 { 1222 return value_; 1223 } 1224 GetLevelIndex()1225 GateRef GetLevelIndex() const 1226 { 1227 return levelIndex_; 1228 } 1229 GetSlotIndex()1230 GateRef GetSlotIndex() const 1231 { 1232 return slotIndex_; 1233 } 1234 GetLexicalEnv()1235 GateRef GetLexicalEnv() const 1236 { 1237 return lexicalEnv_; 1238 } 1239 IsAccessor()1240 bool IsAccessor() const 1241 { 1242 return isAccessor_; 1243 } 1244 1245 private: 1246 JSTaggedValue GetKeyTaggedValue() const; 1247 1248 ChunkVector<std::tuple<ProfileTyper, ProfileTyper, ProfileTyper>> types_; 1249 ChunkVector<pgo::PGOObjectInfo> jitTypes_; 1250 GateRef value_; 1251 GateRef levelIndex_; 1252 GateRef slotIndex_; 1253 GateRef lexicalEnv_; 1254 bool isAccessor_{false}; 1255 AccessorStrategy* strategy_; 1256 friend class AotAccessorStrategy; 1257 friend class JitAccessorStrategy; 1258 }; 1259 1260 class LoadObjByNameTypeInfoAccessor final : public ObjAccByNameTypeInfoAccessor { 1261 public: 1262 class AccessorStrategy { 1263 public: 1264 virtual ~AccessorStrategy() = default; 1265 virtual size_t GetTypeCount() const = 0; 1266 virtual bool TypesIsEmpty() const = 0; 1267 virtual bool IsMono() const = 0; 1268 virtual bool IsReceiverEqHolder(size_t index) const = 0; 1269 virtual void FetchPGORWTypesDual() = 0; 1270 virtual bool GenerateObjectAccessInfo() = 0; 1271 }; 1272 1273 class AotAccessorStrategy : public AccessorStrategy { 1274 public: AotAccessorStrategy(LoadObjByNameTypeInfoAccessor & parent)1275 explicit AotAccessorStrategy(LoadObjByNameTypeInfoAccessor &parent) : parent_(parent) 1276 { 1277 } 1278 GetTypeCount()1279 size_t GetTypeCount() const override 1280 { 1281 return parent_.types_.size(); 1282 } 1283 TypesIsEmpty()1284 bool TypesIsEmpty() const override 1285 { 1286 return parent_.types_.empty(); 1287 } 1288 IsMono()1289 bool IsMono() const override 1290 { 1291 return parent_.types_.size() == 1; 1292 } 1293 IsReceiverEqHolder(size_t index)1294 bool IsReceiverEqHolder(size_t index) const override 1295 { 1296 ASSERT(index < parent_.types_.size()); 1297 return parent_.types_[index].first == parent_.types_[index].second; 1298 } 1299 1300 void FetchPGORWTypesDual() override; 1301 bool GenerateObjectAccessInfo() override; 1302 1303 private: 1304 LoadObjByNameTypeInfoAccessor &parent_; 1305 }; 1306 1307 class JitAccessorStrategy : public AccessorStrategy { 1308 public: JitAccessorStrategy(LoadObjByNameTypeInfoAccessor & parent)1309 explicit JitAccessorStrategy(LoadObjByNameTypeInfoAccessor &parent) : parent_(parent) 1310 { 1311 } 1312 GetTypeCount()1313 size_t GetTypeCount() const override 1314 { 1315 return parent_.jitTypes_.size(); 1316 } 1317 TypesIsEmpty()1318 bool TypesIsEmpty() const override 1319 { 1320 return parent_.jitTypes_.empty(); 1321 } 1322 IsMono()1323 bool IsMono() const override 1324 { 1325 return parent_.jitTypes_.size() == 1; 1326 } 1327 IsReceiverEqHolder(size_t index)1328 bool IsReceiverEqHolder(size_t index) const override 1329 { 1330 return parent_.jitTypes_[index].GetReceiverHclass() == parent_.jitTypes_[index].GetHolderHclass(); 1331 } 1332 1333 void FetchPGORWTypesDual() override; 1334 bool GenerateObjectAccessInfo() override; 1335 1336 private: 1337 LoadObjByNameTypeInfoAccessor &parent_; 1338 }; 1339 LoadObjByNameTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate, Chunk *chunk); 1340 NO_COPY_SEMANTIC(LoadObjByNameTypeInfoAccessor); 1341 NO_MOVE_SEMANTIC(LoadObjByNameTypeInfoAccessor); 1342 GetTypeCount()1343 size_t GetTypeCount() 1344 { 1345 return strategy_->GetTypeCount(); 1346 } 1347 TypesIsEmpty()1348 bool TypesIsEmpty() 1349 { 1350 return strategy_->TypesIsEmpty(); 1351 } 1352 IsMono()1353 bool IsMono() 1354 { 1355 return strategy_->IsMono(); 1356 } 1357 IsReceiverEqHolder(size_t index)1358 bool IsReceiverEqHolder(size_t index) 1359 { 1360 return strategy_->IsReceiverEqHolder(index); 1361 } 1362 1363 private: 1364 ChunkVector<std::pair<ProfileTyper, ProfileTyper>> types_; 1365 ChunkVector<pgo::PGOObjectInfo> jitTypes_; 1366 1367 AccessorStrategy* strategy_; 1368 friend class AotAccessorStrategy; 1369 friend class JitAccessorStrategy; 1370 }; 1371 1372 class StoreObjByNameTypeInfoAccessor final : public ObjAccByNameTypeInfoAccessor { 1373 public: 1374 class AccessorStrategy { 1375 public: 1376 virtual ~AccessorStrategy() = default; 1377 virtual size_t GetTypeCount() const = 0; 1378 virtual bool TypesIsEmpty() const = 0; 1379 virtual bool IsMono() const = 0; 1380 virtual bool IsReceiverEqHolder(size_t index) const = 0; 1381 virtual bool IsReceiverNoEqNewHolder(size_t index) const = 0; 1382 virtual bool IsHolderEqNewHolder(size_t index) const = 0; 1383 virtual void FetchPGORWTypesDual() = 0; 1384 virtual bool GenerateObjectAccessInfo() = 0; 1385 virtual bool IsPrototypeHclass(size_t index) const = 0; 1386 }; 1387 1388 class AotAccessorStrategy : public AccessorStrategy { 1389 public: AotAccessorStrategy(StoreObjByNameTypeInfoAccessor & parent)1390 explicit AotAccessorStrategy(StoreObjByNameTypeInfoAccessor &parent) : parent_(parent) 1391 { 1392 } 1393 GetTypeCount()1394 size_t GetTypeCount() const override 1395 { 1396 return parent_.types_.size(); 1397 } 1398 TypesIsEmpty()1399 bool TypesIsEmpty() const override 1400 { 1401 return parent_.types_.empty(); 1402 } 1403 IsMono()1404 bool IsMono() const override 1405 { 1406 return parent_.types_.size() == 1; 1407 } 1408 IsReceiverEqHolder(size_t index)1409 bool IsReceiverEqHolder(size_t index) const override 1410 { 1411 return std::get<HclassIndex::Reciver>(parent_.types_[index]) == 1412 std::get<HclassIndex::Holder>(parent_.types_[index]); 1413 } 1414 IsReceiverNoEqNewHolder(size_t index)1415 bool IsReceiverNoEqNewHolder(size_t index) const override 1416 { 1417 return std::get<HclassIndex::Reciver>(parent_.types_[index]) != 1418 std::get<HclassIndex::HolderTra>(parent_.types_[index]); 1419 } 1420 IsHolderEqNewHolder(size_t index)1421 bool IsHolderEqNewHolder(size_t index) const override 1422 { 1423 return std::get<HclassIndex::Holder>(parent_.types_[index]) == 1424 std::get<HclassIndex::HolderTra>(parent_.types_[index]); 1425 } 1426 IsPrototypeHclass(size_t index)1427 bool IsPrototypeHclass(size_t index) const override 1428 { 1429 ProfileTyper recv = std::get<HclassIndex::Reciver>(parent_.types_[index]); 1430 JSTaggedValue hclass = parent_.ptManager_->QueryHClass(recv.first, recv.second); 1431 if (!hclass.IsJSHClass()) { 1432 return false; 1433 } 1434 return JSHClass::Cast(hclass.GetTaggedObject())->IsPrototype(); 1435 } 1436 1437 void FetchPGORWTypesDual() override; 1438 bool GenerateObjectAccessInfo() override; 1439 1440 private: 1441 StoreObjByNameTypeInfoAccessor &parent_; 1442 }; 1443 1444 class JitAccessorStrategy : public AccessorStrategy { 1445 public: JitAccessorStrategy(StoreObjByNameTypeInfoAccessor & parent)1446 explicit JitAccessorStrategy(StoreObjByNameTypeInfoAccessor &parent) : parent_(parent) 1447 { 1448 } 1449 GetTypeCount()1450 size_t GetTypeCount() const override 1451 { 1452 return parent_.jitTypes_.size(); 1453 } 1454 TypesIsEmpty()1455 bool TypesIsEmpty() const override 1456 { 1457 return parent_.jitTypes_.empty(); 1458 } 1459 IsMono()1460 bool IsMono() const override 1461 { 1462 return parent_.jitTypes_.size() == 1; 1463 } 1464 IsReceiverEqHolder(size_t index)1465 bool IsReceiverEqHolder(size_t index) const override 1466 { 1467 return parent_.jitTypes_[index].GetReceiverHclass() == parent_.jitTypes_[index].GetHolderHclass(); 1468 } 1469 IsReceiverNoEqNewHolder(size_t index)1470 bool IsReceiverNoEqNewHolder(size_t index) const override 1471 { 1472 return parent_.jitTypes_[index].GetReceiverHclass() != parent_.jitTypes_[index].GetHolderTraHclass(); 1473 } 1474 IsHolderEqNewHolder(size_t index)1475 bool IsHolderEqNewHolder(size_t index) const override 1476 { 1477 return parent_.jitTypes_[index].GetHolderHclass() == parent_.jitTypes_[index].GetHolderTraHclass(); 1478 } 1479 IsPrototypeHclass(size_t index)1480 bool IsPrototypeHclass(size_t index) const override 1481 { 1482 return parent_.jitTypes_[index].GetReceiverHclass()->IsPrototype(); 1483 } 1484 1485 void FetchPGORWTypesDual() override; 1486 bool GenerateObjectAccessInfo() override; 1487 1488 private: 1489 StoreObjByNameTypeInfoAccessor &parent_; 1490 }; 1491 1492 StoreObjByNameTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate, Chunk *chunk); 1493 NO_COPY_SEMANTIC(StoreObjByNameTypeInfoAccessor); 1494 NO_MOVE_SEMANTIC(StoreObjByNameTypeInfoAccessor); 1495 GetTypeCount()1496 size_t GetTypeCount() 1497 { 1498 return strategy_->GetTypeCount(); 1499 } 1500 TypesIsEmpty()1501 bool TypesIsEmpty() 1502 { 1503 return strategy_->TypesIsEmpty(); 1504 } 1505 IsMono()1506 bool IsMono() 1507 { 1508 return strategy_->IsMono(); 1509 } 1510 IsReceiverEqHolder(size_t index)1511 bool IsReceiverEqHolder(size_t index) const 1512 { 1513 return strategy_->IsReceiverEqHolder(index); 1514 } 1515 IsReceiverNoEqNewHolder(size_t index)1516 bool IsReceiverNoEqNewHolder(size_t index) const 1517 { 1518 return strategy_->IsReceiverNoEqNewHolder(index); 1519 } 1520 IsHolderEqNewHolder(size_t index)1521 bool IsHolderEqNewHolder(size_t index) const 1522 { 1523 return strategy_->IsHolderEqNewHolder(index); 1524 } 1525 IsPrototypeHclass(size_t index)1526 bool IsPrototypeHclass(size_t index) const 1527 { 1528 return strategy_->IsPrototypeHclass(index); 1529 } 1530 GetValue()1531 GateRef GetValue() const 1532 { 1533 return value_; 1534 } 1535 1536 private: 1537 enum HclassIndex { 1538 Reciver = 0, 1539 Holder, 1540 HolderTra 1541 }; 1542 ChunkVector<std::tuple<ProfileTyper, ProfileTyper, ProfileTyper>> types_; 1543 ChunkVector<pgo::PGOObjectInfo> jitTypes_; 1544 GateRef value_; 1545 AccessorStrategy* strategy_; 1546 friend class AotAccessorStrategy; 1547 friend class JitAccessorStrategy; 1548 }; 1549 1550 class InstanceOfTypeInfoAccessor final : public ObjAccByNameTypeInfoAccessor { 1551 public: 1552 class AccessorStrategy { 1553 public: 1554 virtual ~AccessorStrategy() = default; 1555 virtual size_t GetTypeCount() const = 0; 1556 virtual bool TypesIsEmpty() const = 0; 1557 virtual bool IsMono() const = 0; 1558 virtual void FetchPGORWTypesDual() = 0; 1559 virtual bool GenerateObjectAccessInfo() = 0; 1560 virtual bool ClassInstanceIsCallable(ProfileTyper type) const = 0; 1561 virtual bool ClassInstanceIsCallable(JSHClass *hclass) const = 0; 1562 }; 1563 1564 class AotAccessorStrategy : public AccessorStrategy { 1565 public: AotAccessorStrategy(InstanceOfTypeInfoAccessor & parent)1566 explicit AotAccessorStrategy(InstanceOfTypeInfoAccessor &parent) : parent_(parent) 1567 { 1568 } 1569 GetTypeCount()1570 size_t GetTypeCount() const override 1571 { 1572 return parent_.types_.size(); 1573 } 1574 TypesIsEmpty()1575 bool TypesIsEmpty() const override 1576 { 1577 return parent_.types_.empty(); 1578 } 1579 IsMono()1580 bool IsMono() const override 1581 { 1582 return parent_.types_.size() == 1; 1583 } 1584 1585 void FetchPGORWTypesDual() override; 1586 bool GenerateObjectAccessInfo() override; 1587 bool ClassInstanceIsCallable(ProfileTyper type) const override; ClassInstanceIsCallable(JSHClass * hclass)1588 bool ClassInstanceIsCallable([[maybe_unused]] JSHClass *hclass) const override 1589 { 1590 ASSERT(0); 1591 return false; 1592 } 1593 1594 private: 1595 InstanceOfTypeInfoAccessor &parent_; 1596 }; 1597 1598 class JitAccessorStrategy : public AccessorStrategy { 1599 public: JitAccessorStrategy(InstanceOfTypeInfoAccessor & parent)1600 explicit JitAccessorStrategy(InstanceOfTypeInfoAccessor &parent) : parent_(parent) 1601 { 1602 } 1603 GetTypeCount()1604 size_t GetTypeCount() const override 1605 { 1606 return parent_.jitTypes_.size(); 1607 } 1608 TypesIsEmpty()1609 bool TypesIsEmpty() const override 1610 { 1611 return parent_.jitTypes_.empty(); 1612 } 1613 IsMono()1614 bool IsMono() const override 1615 { 1616 return parent_.jitTypes_.size() == 1; 1617 } 1618 void FetchPGORWTypesDual() override; 1619 bool GenerateObjectAccessInfo() override; 1620 bool ClassInstanceIsCallable(JSHClass *hclass) const override; ClassInstanceIsCallable(ProfileTyper type)1621 bool ClassInstanceIsCallable([[maybe_unused]] ProfileTyper type) const override 1622 { 1623 ASSERT(0); 1624 return false; 1625 } 1626 1627 private: 1628 InstanceOfTypeInfoAccessor &parent_; 1629 }; 1630 1631 InstanceOfTypeInfoAccessor(const CompilationEnv *env, Circuit *circuit, GateRef gate, Chunk *chunk); 1632 NO_COPY_SEMANTIC(InstanceOfTypeInfoAccessor); 1633 NO_MOVE_SEMANTIC(InstanceOfTypeInfoAccessor); 1634 GetTypeCount()1635 size_t GetTypeCount() 1636 { 1637 return strategy_->GetTypeCount(); 1638 } 1639 TypesIsEmpty()1640 bool TypesIsEmpty() 1641 { 1642 return strategy_->TypesIsEmpty(); 1643 } 1644 IsMono()1645 bool IsMono() 1646 { 1647 return strategy_->IsMono(); 1648 } 1649 1650 JSTaggedValue GetKeyTaggedValue() const; 1651 GetTarget()1652 GateRef GetTarget() const 1653 { 1654 return target_; 1655 } 1656 1657 private: 1658 ChunkVector<std::pair<ProfileTyper, ProfileTyper>> types_; 1659 ChunkVector<pgo::PGOObjectInfo> jitTypes_; 1660 GateRef target_; 1661 AccessorStrategy* strategy_; 1662 1663 friend class AotAccessorStrategy; 1664 friend class JitAccessorStrategy; 1665 }; 1666 1667 class AccBuiltinObjTypeInfoAccessor : public ObjectAccessTypeInfoAccessor { 1668 public: AccBuiltinObjTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate,Chunk * chunk,AccessMode mode)1669 AccBuiltinObjTypeInfoAccessor(const CompilationEnv *env, 1670 Circuit *circuit, 1671 GateRef gate, 1672 Chunk *chunk, 1673 AccessMode mode) 1674 : ObjectAccessTypeInfoAccessor(env, circuit, gate, chunk, mode), types_(chunk_) 1675 {} 1676 NO_COPY_SEMANTIC(AccBuiltinObjTypeInfoAccessor); 1677 NO_MOVE_SEMANTIC(AccBuiltinObjTypeInfoAccessor); 1678 IsMono()1679 bool IsMono() const 1680 { 1681 return types_.size() == 1 || IsMonoBuiltins(); 1682 } 1683 GetTypeCount()1684 size_t GetTypeCount() 1685 { 1686 return types_.size(); 1687 } 1688 IsBuiltinsMap()1689 bool IsBuiltinsMap() const 1690 { 1691 return types_[0].IsBuiltinsMap(); 1692 } 1693 IsBuiltinsString()1694 bool IsBuiltinsString() const 1695 { 1696 return types_[0].IsBuiltinsString(); 1697 } 1698 IsBuiltinsArray()1699 bool IsBuiltinsArray() const 1700 { 1701 return types_[0].IsBuiltinsArray(); 1702 } 1703 IsBuiltinsTypeArray()1704 bool IsBuiltinsTypeArray() const 1705 { 1706 return types_[0].IsBuiltinsTypeArray(); 1707 } 1708 IsStoreOutOfBounds()1709 bool IsStoreOutOfBounds() const 1710 { 1711 ASSERT(types_.size() > 0); 1712 return types_[0].IsEverOutOfBounds(); 1713 } 1714 HasNoType()1715 bool HasNoType() const 1716 { 1717 return types_.empty(); 1718 } 1719 GetBuiltinsJSType()1720 JSType GetBuiltinsJSType() const 1721 { 1722 if (types_[0].IsBuiltinsType()) { 1723 return types_[0].GetBuiltinsType(); 1724 } 1725 return JSType::INVALID; 1726 } 1727 GetParamType()1728 ParamType GetParamType() const 1729 { 1730 ASSERT(IsMono()); 1731 return TypeInfoAccessor::PGOBuiltinTypeToParamType(types_[0]); 1732 } 1733 IsPolyBuiltinsArray()1734 bool IsPolyBuiltinsArray() const 1735 { 1736 if (types_.size() == 0) { 1737 return false; 1738 } 1739 for (size_t i = 0; i < types_.size(); ++i) { 1740 if (!types_[i].IsBuiltinsArray()) { 1741 return false; 1742 } 1743 } 1744 return true; 1745 } 1746 GetElementsKindBeforeTransition(size_t index)1747 ElementsKind GetElementsKindBeforeTransition(size_t index) 1748 { 1749 ProfileType currType = types_[index]; 1750 return currType.GetElementsKindBeforeTransition(); 1751 } 1752 GetElementsKindAfterTransition(size_t index)1753 ElementsKind GetElementsKindAfterTransition(size_t index) 1754 { 1755 ProfileType currType = types_[index]; 1756 return currType.GetElementsKindAfterTransition(); 1757 } 1758 IsBuiltinsType()1759 bool IsBuiltinsType() const 1760 { 1761 return IsMono() && types_[0].IsBuiltinsType(); 1762 } 1763 IsGlobalsType()1764 bool IsGlobalsType() const 1765 { 1766 return IsMono() && types_[0].IsGlobalsType(); 1767 } 1768 GetBuiltinsTypeId()1769 std::optional<BuiltinTypeId> GetBuiltinsTypeId() const 1770 { 1771 if (!IsMono()) { 1772 return std::nullopt; 1773 } 1774 auto type = types_[0].GetBuiltinsType(); 1775 return ToBuiltinsTypeId(type); 1776 } 1777 GetGlobalsId()1778 std::optional<GlobalIndex> GetGlobalsId() const 1779 { 1780 return types_[0].GetGlobalsId(); 1781 } 1782 TryGetHeapMode()1783 OnHeapMode TryGetHeapMode() const 1784 { 1785 return acc_.TryGetOnHeapMode(gate_); 1786 } 1787 TryConvertKeyToInt()1788 uint32_t TryConvertKeyToInt() const 1789 { 1790 return static_cast<uint32_t>(acc_.GetConstantValue(GetKey())); 1791 } 1792 1793 // Default get is elementsKind before possible transition TryGetArrayElementsKind()1794 ElementsKind TryGetArrayElementsKind() const 1795 { 1796 [[maybe_unused]] bool condition = (IsMono() && IsBuiltinsArray()); 1797 ASSERT(condition); 1798 return acc_.TryGetArrayElementsKind(gate_); 1799 } 1800 TryGetArrayElementsKindAfterTransition()1801 ElementsKind TryGetArrayElementsKindAfterTransition() const 1802 { 1803 [[maybe_unused]] bool condition = (IsMono() && IsBuiltinsArray()); 1804 ASSERT(condition); 1805 return acc_.TryGetArrayElementsKindAfterTransition(gate_); 1806 } 1807 1808 protected: 1809 bool IsMonoBuiltins() const; 1810 bool IsStringMonoBuiltins() const; 1811 void FetchBuiltinsTypes(); 1812 bool CheckDuplicatedBuiltinType(ProfileType newType) const; 1813 1814 ChunkVector<ProfileType> types_; 1815 }; 1816 1817 class LoadBulitinObjTypeInfoAccessor final : public AccBuiltinObjTypeInfoAccessor { 1818 public: 1819 LoadBulitinObjTypeInfoAccessor(const CompilationEnv *env, 1820 Circuit *circuit, 1821 GateRef gate, 1822 Chunk *chunk); 1823 NO_COPY_SEMANTIC(LoadBulitinObjTypeInfoAccessor); 1824 NO_MOVE_SEMANTIC(LoadBulitinObjTypeInfoAccessor); 1825 }; 1826 1827 class StoreBulitinObjTypeInfoAccessor final : public AccBuiltinObjTypeInfoAccessor { 1828 public: 1829 StoreBulitinObjTypeInfoAccessor(const CompilationEnv *env, 1830 Circuit *circuit, 1831 GateRef gate, 1832 Chunk *chunk); 1833 NO_COPY_SEMANTIC(StoreBulitinObjTypeInfoAccessor); 1834 NO_MOVE_SEMANTIC(StoreBulitinObjTypeInfoAccessor); 1835 ValueIsNumberType()1836 bool ValueIsNumberType() const 1837 { 1838 return acc_.GetGateType(value_).IsNumberType(); 1839 } 1840 GetValue()1841 GateRef GetValue() const 1842 { 1843 return value_; 1844 } 1845 1846 private: 1847 GateRef value_ {Circuit::NullGate()}; 1848 }; 1849 1850 class GlobalObjAccTypeInfoAccessor : public ObjectAccessTypeInfoAccessor { 1851 public: GlobalObjAccTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate,AccessMode mode)1852 GlobalObjAccTypeInfoAccessor(const CompilationEnv *env, 1853 Circuit *circuit, 1854 GateRef gate, 1855 AccessMode mode) 1856 : ObjectAccessTypeInfoAccessor(env, circuit, gate, nullptr, mode) {} 1857 1858 NO_COPY_SEMANTIC(GlobalObjAccTypeInfoAccessor); 1859 NO_MOVE_SEMANTIC(GlobalObjAccTypeInfoAccessor); 1860 }; 1861 1862 class LoadGlobalObjByNameTypeInfoAccessor final : public GlobalObjAccTypeInfoAccessor { 1863 public: LoadGlobalObjByNameTypeInfoAccessor(const CompilationEnv * env,Circuit * circuit,GateRef gate)1864 LoadGlobalObjByNameTypeInfoAccessor(const CompilationEnv *env, 1865 Circuit *circuit, 1866 GateRef gate) 1867 : GlobalObjAccTypeInfoAccessor(env, circuit, gate, AccessMode::LOAD) 1868 { 1869 key_ = acc_.GetValueIn(gate, 1); 1870 } 1871 NO_COPY_SEMANTIC(LoadGlobalObjByNameTypeInfoAccessor); 1872 NO_MOVE_SEMANTIC(LoadGlobalObjByNameTypeInfoAccessor); 1873 }; 1874 1875 class CreateObjWithBufferTypeInfoAccessor : public TypeInfoAccessor { 1876 public: 1877 CreateObjWithBufferTypeInfoAccessor(const CompilationEnv *env, 1878 Circuit *circuit, 1879 GateRef gate, 1880 const CString &recordName, 1881 Chunk* chunk); 1882 1883 NO_COPY_SEMANTIC(CreateObjWithBufferTypeInfoAccessor); 1884 NO_MOVE_SEMANTIC(CreateObjWithBufferTypeInfoAccessor); 1885 1886 class AccessorStrategy { 1887 public: 1888 virtual ~AccessorStrategy() = default; 1889 virtual JSTaggedValue GetHClass() const = 0; 1890 }; 1891 1892 class AotAccessorStrategy : public AccessorStrategy { 1893 public: AotAccessorStrategy(CreateObjWithBufferTypeInfoAccessor & parent)1894 explicit AotAccessorStrategy(CreateObjWithBufferTypeInfoAccessor &parent) : parent_(parent) 1895 { 1896 } 1897 1898 JSTaggedValue GetHClass() const override; 1899 1900 private: 1901 CreateObjWithBufferTypeInfoAccessor &parent_; 1902 }; 1903 1904 class JitAccessorStrategy : public AccessorStrategy { 1905 public: JitAccessorStrategy(CreateObjWithBufferTypeInfoAccessor & parent)1906 explicit JitAccessorStrategy(CreateObjWithBufferTypeInfoAccessor &parent) : parent_(parent) 1907 { 1908 } 1909 1910 JSTaggedValue GetHClass() const override; 1911 1912 private: 1913 CreateObjWithBufferTypeInfoAccessor &parent_; 1914 }; 1915 GetHClass()1916 JSTaggedValue GetHClass() const 1917 { 1918 return strategy_->GetHClass(); 1919 } 1920 1921 JSTaggedValue GetObject() const; 1922 GetIndex()1923 GateRef GetIndex() const 1924 { 1925 return index_; 1926 } 1927 CanOptimize()1928 bool CanOptimize() const 1929 { 1930 JSTaggedValue obj = GetObject(); 1931 if (obj.IsUndefined()) { 1932 return false; 1933 } 1934 JSObject *jsObj = JSObject::Cast(obj); 1935 TaggedArray *properties = TaggedArray::Cast(jsObj->GetProperties()); 1936 TaggedArray *elements = TaggedArray::Cast(jsObj->GetElements()); 1937 return properties->GetLength() == 0 && elements->GetLength() == 0; 1938 } 1939 1940 private: 1941 void Init(); 1942 1943 const CString &recordName_; 1944 GateRef index_; 1945 AccessorStrategy* strategy_; 1946 1947 friend class AotAccessorStrategy; 1948 friend class JitAccessorStrategy; 1949 }; 1950 } // panda::ecmascript::kungfu 1951 #endif // ECMASCRIPT_COMPILER_TYPE_INFO_ACCESSORS_H 1952