1 /* 2 * Copyright (c) 2022-2024 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_SHARE_GATE_META_DATA_H 17 #define ECMASCRIPT_COMPILER_SHARE_GATE_META_DATA_H 18 19 #include <string> 20 21 #include "ecmascript/base/hash_combine.h" 22 #include "ecmascript/compiler/bytecodes.h" 23 #include "ecmascript/compiler/share_opcodes.h" 24 #include "ecmascript/compiler/type.h" 25 #include "ecmascript/elements.h" 26 #include "ecmascript/js_thread_hclass_entries.h" 27 #include "ecmascript/mem/chunk.h" 28 #include "ecmascript/mem/chunk_containers.h" 29 #include "ecmascript/mem/region.h" 30 #include "ecmascript/pgo_profiler/types/pgo_profiler_type.h" 31 #include "libpandabase/macros.h" 32 33 namespace panda::ecmascript::kungfu { 34 using ProfileType = pgo::ProfileType; 35 using GateRef = int32_t; 36 using PGOTypeRef = pgo::PGOTypeRef; 37 using PGODefineOpType = pgo::PGODefineOpType; 38 using PGOSampleType = pgo::PGOSampleType; 39 using PGORWOpType = pgo::PGORWOpType; 40 enum class TypedBinOp : uint8_t; 41 enum class TypedUnOp : uint8_t; 42 enum class TypedJumpOp : uint8_t; 43 enum class TypedLoadOp : uint8_t; 44 enum class TypedStoreOp : uint8_t; 45 enum class TypedCallTargetCheckOp : uint8_t; 46 47 enum GateFlags : uint8_t { 48 NONE_FLAG = 0, 49 NO_WRITE = 1 << 0, 50 HAS_ROOT = 1 << 1, 51 HAS_FRAME_STATE = 1 << 2, 52 CONTROL = NO_WRITE, 53 CONTROL_ROOT = NO_WRITE | HAS_ROOT, 54 CHECKABLE = NO_WRITE | HAS_FRAME_STATE, 55 ROOT = NO_WRITE | HAS_ROOT, 56 FIXED = NO_WRITE, 57 }; 58 59 class GateMetaData : public ChunkObject { 60 public: 61 enum class Kind : uint8_t { 62 IMMUTABLE = 0, 63 MUTABLE_WITH_SIZE, 64 IMMUTABLE_ONE_PARAMETER, 65 MUTABLE_ONE_PARAMETER, 66 IMMUTABLE_BOOL, 67 MUTABLE_STRING, 68 JSBYTECODE, 69 TYPED_BINARY_OP, 70 TYPED_CALLTARGETCHECK_OP, 71 TYPED_CALL, 72 CALL_NEW, 73 }; 74 GateMetaData() = default; GateMetaData(OpCode opcode,GateFlags flags,uint32_t statesIn,uint16_t dependsIn,uint32_t valuesIn)75 GateMetaData(OpCode opcode, GateFlags flags, 76 uint32_t statesIn, uint16_t dependsIn, uint32_t valuesIn) 77 : opcode_(opcode), flags_(flags), 78 statesIn_(statesIn), dependsIn_(dependsIn), valuesIn_(valuesIn) {} 79 equal(const GateMetaData & other)80 virtual bool equal(const GateMetaData &other) const 81 { 82 if (opcode_ == other.opcode_ && kind_ == other.kind_ && flags_ == other.flags_ && 83 statesIn_ == other.statesIn_ && dependsIn_ == other.dependsIn_ && valuesIn_ == other.valuesIn_) { 84 return true; 85 } 86 return false; 87 } 88 GetHashCode()89 virtual uint64_t GetHashCode() const 90 { 91 const uint64_t OPCODE_SHIFT = 48; 92 const uint64_t KIND_SHIFT = 40; 93 const uint64_t FLAGS_SHIFT = 32; 94 return static_cast<uint64_t>(opcode_) << OPCODE_SHIFT | (static_cast<uint64_t>(kind_) << KIND_SHIFT) | 95 (static_cast<uint64_t>(flags_) << FLAGS_SHIFT); 96 } 97 GetStateCount()98 size_t GetStateCount() const 99 { 100 return statesIn_; 101 } 102 GetDependCount()103 size_t GetDependCount() const 104 { 105 return dependsIn_; 106 } 107 GetInValueCount()108 size_t GetInValueCount() const 109 { 110 return valuesIn_; 111 } 112 GetRootCount()113 size_t GetRootCount() const 114 { 115 return HasRoot() ? 1 : 0; 116 } 117 GetInFrameStateCount()118 size_t GetInFrameStateCount() const 119 { 120 return HasFrameState() ? 1 : 0; 121 } 122 GetNumIns()123 size_t GetNumIns() const 124 { 125 return GetStateCount() + GetDependCount() + GetInValueCount() 126 + GetInFrameStateCount() + GetRootCount(); 127 } 128 GetInValueStarts()129 size_t GetInValueStarts() const 130 { 131 return GetStateCount() + GetDependCount(); 132 } 133 GetInFrameStateStarts()134 size_t GetInFrameStateStarts() const 135 { 136 return GetInValueStarts() + GetInValueCount(); 137 } 138 GetOpCode()139 OpCode GetOpCode() const 140 { 141 return opcode_; 142 } 143 GetKind()144 Kind GetKind() const 145 { 146 return kind_; 147 } 148 AssertKind(Kind kind)149 void AssertKind([[maybe_unused]] Kind kind) const 150 { 151 ASSERT(GetKind() == kind); 152 } 153 IsOneParameterKind()154 bool IsOneParameterKind() const 155 { 156 return GetKind() == Kind::IMMUTABLE_ONE_PARAMETER || GetKind() == Kind::MUTABLE_ONE_PARAMETER || 157 GetKind() == Kind::TYPED_BINARY_OP || GetKind() == Kind::TYPED_CALLTARGETCHECK_OP || 158 GetKind() == Kind::CALL_NEW; 159 } 160 IsStringType()161 bool IsStringType() const 162 { 163 return GetKind() == Kind::MUTABLE_STRING; 164 } 165 166 bool IsRoot() const; 167 bool IsProlog() const; 168 bool IsFixed() const; 169 bool IsSchedulable() const; 170 bool IsState() const; // note: IsState(STATE_ENTRY) == false 171 bool IsGeneralState() const; 172 bool IsTerminalState() const; 173 bool IsVirtualState() const; 174 bool IsCFGMerge() const; 175 bool IsControlCase() const; 176 bool IsIfOrSwitchRelated() const; 177 bool IsLoopHead() const; 178 bool IsNop() const; 179 bool IsDead() const; 180 bool IsConstant() const; 181 bool IsDependSelector() const; 182 bool IsTypedOperator() const; 183 bool IsCheckWithOneIn() const; 184 bool IsCheckWithTwoIns() const; HasFrameState()185 bool HasFrameState() const 186 { 187 return HasFlag(GateFlags::HAS_FRAME_STATE); 188 } 189 IsNotWrite()190 bool IsNotWrite() const 191 { 192 return HasFlag(GateFlags::NO_WRITE); 193 } 194 195 ~GateMetaData() = default; 196 197 static std::string Str(OpCode opcode); 198 static std::string Str(TypedBinOp op); 199 static std::string Str(TypedUnOp op); 200 static std::string Str(TypedJumpOp op); 201 static std::string Str(TypedLoadOp op); 202 static std::string Str(TypedStoreOp op); 203 static std::string Str(TypedCallTargetCheckOp op); 204 static std::string Str(ValueType type); Str()205 std::string Str() const 206 { 207 return Str(opcode_); 208 } 209 protected: SetKind(Kind kind)210 void SetKind(Kind kind) 211 { 212 kind_ = kind; 213 } 214 SetFlags(GateFlags flags)215 void SetFlags(GateFlags flags) 216 { 217 flags_ = flags; 218 } 219 DecreaseIn(size_t idx)220 void DecreaseIn(size_t idx) 221 { 222 ASSERT(GetKind() == Kind::MUTABLE_WITH_SIZE); 223 if (idx < statesIn_) { 224 statesIn_--; 225 } else if (idx < statesIn_ + dependsIn_) { 226 dependsIn_--; 227 } else { 228 valuesIn_--; 229 } 230 } 231 HasRoot()232 bool HasRoot() const 233 { 234 return HasFlag(GateFlags::HAS_ROOT); 235 } 236 HasFlag(GateFlags flag)237 bool HasFlag(GateFlags flag) const 238 { 239 return (GetFlags() & flag) == flag; 240 } 241 GetFlags()242 GateFlags GetFlags() const 243 { 244 return flags_; 245 } 246 247 private: 248 friend class Gate; 249 friend class Circuit; 250 friend class GateMetaBuilder; 251 252 OpCode opcode_ { OpCode::NOP }; 253 Kind kind_ { Kind::IMMUTABLE }; 254 GateFlags flags_ { GateFlags::NONE_FLAG }; 255 uint32_t statesIn_ { 0 }; 256 uint32_t dependsIn_ { 0 }; 257 uint32_t valuesIn_ { 0 }; 258 }; 259 260 inline std::ostream& operator<<(std::ostream& os, OpCode opcode) 261 { 262 return os << GateMetaData::Str(opcode); 263 } 264 265 class BoolMetaData : public GateMetaData { 266 public: BoolMetaData(OpCode opcode,GateFlags flags,uint32_t statesIn,uint16_t dependsIn,uint32_t valuesIn,bool value)267 BoolMetaData(OpCode opcode, GateFlags flags, uint32_t statesIn, 268 uint16_t dependsIn, uint32_t valuesIn, bool value) 269 : GateMetaData(opcode, flags, statesIn, dependsIn, valuesIn), value_(value) 270 { 271 SetKind(GateMetaData::Kind::IMMUTABLE_BOOL); 272 } 273 equal(const GateMetaData & other)274 bool equal(const GateMetaData &other) const override 275 { 276 if (!GateMetaData::equal(other)) { 277 return false; 278 } 279 auto cast_other = static_cast<const BoolMetaData *>(&other); 280 if (value_ == cast_other->value_) { 281 return true; 282 } 283 return false; 284 } 285 Cast(const GateMetaData * meta)286 static const BoolMetaData* Cast(const GateMetaData* meta) 287 { 288 meta->AssertKind(GateMetaData::Kind::IMMUTABLE_BOOL); 289 return static_cast<const BoolMetaData*>(meta); 290 } 291 GetBool()292 bool GetBool() const 293 { 294 return value_; 295 } 296 SetBool(bool value)297 void SetBool(bool value) 298 { 299 value_ = value; 300 } 301 302 private: 303 bool value_ { false }; 304 }; 305 306 class OneParameterMetaData : public GateMetaData { 307 public: OneParameterMetaData(OpCode opcode,GateFlags flags,uint32_t statesIn,uint16_t dependsIn,uint32_t valuesIn,uint64_t value)308 OneParameterMetaData(OpCode opcode, GateFlags flags, uint32_t statesIn, 309 uint16_t dependsIn, uint32_t valuesIn, uint64_t value) 310 : GateMetaData(opcode, flags, statesIn, dependsIn, valuesIn), value_(value) 311 { 312 SetKind(GateMetaData::Kind::IMMUTABLE_ONE_PARAMETER); 313 } 314 equal(const GateMetaData & other)315 bool equal(const GateMetaData &other) const override 316 { 317 if (!GateMetaData::equal(other)) { 318 return false; 319 } 320 auto cast_other = static_cast<const OneParameterMetaData *>(&other); 321 if (value_ == cast_other->value_) { 322 return true; 323 } 324 return false; 325 } 326 GetHashCode()327 uint64_t GetHashCode() const override 328 { 329 uint64_t hash = GateMetaData::GetHashCode(); 330 return base::HashCombiner::HashCombine(hash, value_); 331 } 332 Cast(const GateMetaData * meta)333 static const OneParameterMetaData* Cast(const GateMetaData* meta) 334 { 335 ASSERT(meta->IsOneParameterKind()); 336 return static_cast<const OneParameterMetaData*>(meta); 337 } 338 GetValue()339 uint64_t GetValue() const 340 { 341 return value_; 342 } 343 SetValue(uint64_t value)344 void SetValue(uint64_t value) 345 { 346 value_ = value; 347 } 348 349 private: 350 uint64_t value_ { 0 }; 351 }; 352 353 class StringMetaData : public GateMetaData { 354 public: StringMetaData(Chunk * chunk,std::string_view str)355 StringMetaData(Chunk* chunk, std::string_view str) 356 : GateMetaData(OpCode::CONSTSTRING, GateFlags::NONE_FLAG, 0, 0, 0), 357 stringData_(str.size() + 1, chunk) 358 { 359 auto srcLength = str.size(); 360 auto destlength = stringData_.size(); 361 auto dest = stringData_.data(); 362 auto src = str.data(); 363 if (destlength <= static_cast<size_t>(srcLength) || strcpy_s(dest, destlength, src) != EOK) { 364 LOG_COMPILER(FATAL) << "StringMetaData strcpy_s failed"; 365 } 366 SetKind(GateMetaData::Kind::MUTABLE_STRING); 367 } equal(const GateMetaData & other)368 bool equal(const GateMetaData &other) const override 369 { 370 if (!GateMetaData::equal(other)) { 371 return false; 372 } 373 auto cast_other = static_cast<const StringMetaData *>(&other); 374 if (stringData_.size() != cast_other->GetString().size()) { 375 return false; 376 } 377 378 if (strncmp(stringData_.data(), cast_other->GetString().data(), stringData_.size()) != 0) { 379 return false; 380 } 381 382 return true; 383 } 384 GetString()385 const ChunkVector<char> &GetString() const 386 { 387 return stringData_; 388 } 389 390 private: 391 ChunkVector<char> stringData_; 392 }; 393 394 class GateTypeAccessor { 395 public: GateTypeAccessor(uint64_t value)396 explicit GateTypeAccessor(uint64_t value) 397 : type_(static_cast<uint32_t>(value)) {} 398 GetGateType()399 GateType GetGateType() const 400 { 401 return GateType(type_); 402 } 403 GetParamType()404 ParamType GetParamType() const 405 { 406 return ParamType(type_); 407 } 408 private: 409 uint32_t type_; 410 }; 411 412 class ValuePairTypeAccessor { 413 public: 414 // type bits shift 415 static constexpr int OPRAND_TYPE_BITS = 8; ValuePairTypeAccessor(uint64_t value)416 explicit ValuePairTypeAccessor(uint64_t value) : bitField_(value) {} 417 GetSrcType()418 ValueType GetSrcType() const 419 { 420 return static_cast<ValueType>(LeftBits::Get(bitField_)); 421 } 422 GetDstType()423 ValueType GetDstType() const 424 { 425 return static_cast<ValueType>(RightBits::Get(bitField_)); 426 } 427 IsConvertSupport()428 bool IsConvertSupport() const 429 { 430 return ConvertSupportBits::Get(bitField_) == ConvertSupport::ENABLE; 431 } 432 433 static uint64_t ToValue(ValueType srcType, ValueType dstType, ConvertSupport support = ConvertSupport::ENABLE) 434 { 435 uint8_t srcVlaue = static_cast<uint8_t>(srcType); 436 uint8_t dstVlaue = static_cast<uint8_t>(dstType); 437 return LeftBits::Encode(srcVlaue) | RightBits::Encode(dstVlaue) | ConvertSupportBits::Encode(support); 438 } 439 440 private: 441 using LeftBits = panda::BitField<uint8_t, 0, OPRAND_TYPE_BITS>; 442 using RightBits = LeftBits::NextField<uint8_t, OPRAND_TYPE_BITS>; 443 using ConvertSupportBits = RightBits::NextField<ConvertSupport, OPRAND_TYPE_BITS>; 444 445 uint64_t bitField_; 446 }; 447 448 class TypeConvertAccessor { 449 public: 450 // type bits shift 451 static constexpr int OPRAND_TYPE_BITS = 32; TypeConvertAccessor(uint64_t value)452 explicit TypeConvertAccessor(uint64_t value) : bitField_(value) {} 453 GetLeftType()454 ParamType GetLeftType() const 455 { 456 return ParamType(LeftBits::Get(bitField_)); 457 } 458 GetRightType()459 GateType GetRightType() const 460 { 461 return GateType(RightBits::Get(bitField_)); 462 } 463 ToValue(ParamType leftType,GateType rightType)464 static uint64_t ToValue(ParamType leftType, GateType rightType) 465 { 466 return LeftBits::Encode(leftType.Value()) | RightBits::Encode(rightType.Value()); 467 } 468 469 private: 470 using LeftBits = panda::BitField<uint32_t, 0, OPRAND_TYPE_BITS>; 471 using RightBits = LeftBits::NextField<uint32_t, OPRAND_TYPE_BITS>; 472 473 uint64_t bitField_; 474 }; 475 476 class UInt32PairAccessor { 477 public: 478 // type bits shift 479 static constexpr int OPRAND_TYPE_BITS = 32; UInt32PairAccessor(uint64_t value)480 explicit UInt32PairAccessor(uint64_t value) : bitField_(value) {} UInt32PairAccessor(uint32_t first,uint32_t second)481 explicit UInt32PairAccessor(uint32_t first, uint32_t second) 482 { 483 bitField_ = FirstBits::Encode(first) | SecondBits::Encode(second); 484 } 485 GetFirstValue()486 uint32_t GetFirstValue() const 487 { 488 return FirstBits::Get(bitField_); 489 } 490 GetSecondValue()491 uint32_t GetSecondValue() const 492 { 493 return SecondBits::Get(bitField_); 494 } 495 ToValue()496 uint64_t ToValue() const 497 { 498 return bitField_; 499 } 500 501 private: 502 using FirstBits = panda::BitField<uint32_t, 0, OPRAND_TYPE_BITS>; 503 using SecondBits = FirstBits::NextField<uint32_t, OPRAND_TYPE_BITS>; 504 505 uint64_t bitField_; 506 }; 507 508 class ArrayMetaDataAccessor { 509 public: 510 enum Mode : uint8_t { 511 CREATE = 0, 512 LOAD_ELEMENT, 513 STORE_ELEMENT, 514 LOAD_LENGTH, 515 CALL_BUILTIN_METHOD 516 }; 517 518 static constexpr int BITS_SIZE = 8; 519 static constexpr int ARRAY_LENGTH_BITS_SIZE = 32; ArrayMetaDataAccessor(uint64_t value)520 explicit ArrayMetaDataAccessor(uint64_t value) : bitField_(value) {} 521 explicit ArrayMetaDataAccessor(ElementsKind kind, Mode mode, 522 uint32_t length = 0, RegionSpaceFlag flag = RegionSpaceFlag::IN_YOUNG_SPACE) 523 { 524 bitField_ = ElementsKindBits::Encode(kind) | ModeBits::Encode(mode) | 525 ArrayLengthBits::Encode(length) | RegionSpaceFlagBits::Encode(flag); 526 } 527 GetRegionSpaceFlag()528 RegionSpaceFlag GetRegionSpaceFlag() const 529 { 530 return RegionSpaceFlagBits::Get(bitField_); 531 } 532 GetElementsKind()533 ElementsKind GetElementsKind() const 534 { 535 return ElementsKindBits::Get(bitField_); 536 } 537 GetMode()538 Mode GetMode() const 539 { 540 return ModeBits::Get(bitField_); 541 } 542 SetElementsKind(ElementsKind kind)543 void SetElementsKind(ElementsKind kind) 544 { 545 bitField_ = ElementsKindBits::Update(bitField_, kind); 546 } 547 SetArrayLength(uint32_t length)548 void SetArrayLength(uint32_t length) 549 { 550 bitField_ = ArrayLengthBits::Update(bitField_, length); 551 } 552 SetRegionSpaceFlag(RegionSpaceFlag flag)553 void SetRegionSpaceFlag(RegionSpaceFlag flag) 554 { 555 bitField_ = RegionSpaceFlagBits::Update(bitField_, flag); 556 } 557 GetArrayLength()558 uint32_t GetArrayLength() const 559 { 560 return ArrayLengthBits::Get(bitField_); 561 } 562 IsLoadElement()563 bool IsLoadElement() const 564 { 565 return GetMode() == Mode::LOAD_ELEMENT; 566 } 567 IsStoreElement()568 bool IsStoreElement() const 569 { 570 return GetMode() == Mode::STORE_ELEMENT; 571 } 572 ToValue()573 uint64_t ToValue() const 574 { 575 return bitField_; 576 } 577 578 private: 579 using ElementsKindBits = panda::BitField<ElementsKind, 0, BITS_SIZE>; 580 using ModeBits = ElementsKindBits::NextField<Mode, BITS_SIZE>; 581 using ArrayLengthBits = ModeBits::NextField<uint32_t, ARRAY_LENGTH_BITS_SIZE>; 582 using RegionSpaceFlagBits = ArrayLengthBits::NextField<RegionSpaceFlag, BITS_SIZE>; 583 584 uint64_t bitField_; 585 }; 586 587 class CreateArgumentsAccessor { 588 public: 589 enum Mode : uint8_t { 590 REST_ARGUMENTS, 591 UNMAPPED_ARGUMENTS, 592 INVALID, 593 }; 594 595 static constexpr int BITS_SIZE = 8; CreateArgumentsAccessor(uint64_t value)596 explicit CreateArgumentsAccessor(uint64_t value) : bitField_(value) {} CreateArgumentsAccessor(ElementsKind kind,Mode mode)597 explicit CreateArgumentsAccessor(ElementsKind kind, Mode mode) 598 { 599 bitField_ = ElementsKindBits::Encode(kind) | ModeBits::Encode(mode); 600 } GetMode()601 Mode GetMode() const 602 { 603 return ModeBits::Get(bitField_); 604 } ToValue()605 uint64_t ToValue() const 606 { 607 return bitField_; 608 } 609 private: 610 using ElementsKindBits = panda::BitField<ElementsKind, 0, BITS_SIZE>; 611 using ModeBits = ElementsKindBits::NextField<Mode, BITS_SIZE>; 612 613 uint64_t bitField_; 614 }; 615 616 class ObjectTypeAccessor { 617 public: 618 static constexpr int IS_HEAP_OBJECT_BIT_SIZE = 1; 619 ObjectTypeAccessor(uint64_t value)620 explicit ObjectTypeAccessor(uint64_t value) : bitField_(value) {} 621 explicit ObjectTypeAccessor(bool isHeapObject = false) 622 { 623 bitField_ = IsHeapObjectBit::Encode(isHeapObject); 624 } 625 IsHeapObject()626 bool IsHeapObject() const 627 { 628 return IsHeapObjectBit::Get(bitField_); 629 } 630 ToValue()631 uint64_t ToValue() const 632 { 633 return bitField_; 634 } 635 636 private: 637 using IsHeapObjectBit = panda::BitField<bool, 0, IS_HEAP_OBJECT_BIT_SIZE>; 638 639 uint64_t bitField_; 640 }; 641 642 class BuiltinPrototypeHClassAccessor { 643 public: 644 static constexpr int WORD_BITS_SIZE = 8; 645 static constexpr int IS_PROTOTYPE_OF_PROTOTYPE_BITS_SIZE = 1; 646 BuiltinPrototypeHClassAccessor(uint64_t value)647 explicit BuiltinPrototypeHClassAccessor(uint64_t value): type_(value) {} 648 // Only valid indices accepted BuiltinPrototypeHClassAccessor(BuiltinTypeId type,ElementsKind kind,bool isPrototypeOfPrototype)649 explicit BuiltinPrototypeHClassAccessor(BuiltinTypeId type, ElementsKind kind, 650 bool isPrototypeOfPrototype): type_(0) 651 { 652 type_ = BuiltinTypeIdBits::Encode(type) | ElementsKindBits::Encode(kind) | 653 IsPrototypeOfPrototypeBits::Encode(isPrototypeOfPrototype); 654 type_ = BuiltinTypeIdBits::Encode(type) | ElementsKindBits::Encode(kind); 655 ASSERT(BuiltinHClassEntries::GetEntryIndex(type) < BuiltinHClassEntries::N_ENTRIES); 656 } 657 GetElementsKind()658 ElementsKind GetElementsKind() const 659 { 660 return ElementsKindBits::Get(type_); 661 } 662 GetBuiltinTypeId()663 BuiltinTypeId GetBuiltinTypeId() const 664 { 665 return BuiltinTypeIdBits::Get(type_); 666 } 667 IsPrototypeOfPrototype()668 bool IsPrototypeOfPrototype() const 669 { 670 return IsPrototypeOfPrototypeBits::Get(type_); 671 } 672 ToValue()673 uint64_t ToValue() const 674 { 675 return type_; 676 } 677 678 private: 679 using BuiltinTypeIdBits = panda::BitField<BuiltinTypeId, 0, WORD_BITS_SIZE>; 680 using ElementsKindBits = BuiltinTypeIdBits::NextField<ElementsKind, WORD_BITS_SIZE>; 681 using IsPrototypeOfPrototypeBits = ElementsKindBits::NextField<bool, IS_PROTOTYPE_OF_PROTOTYPE_BITS_SIZE>; 682 683 uint64_t type_; 684 }; 685 686 class TypedArrayMetaDataAccessor { 687 public: 688 enum Mode : uint8_t { 689 ACCESS_ELEMENT = 0, 690 LOAD_LENGTH, 691 }; 692 693 static constexpr int TYPE_BITS_SIZE = 32; 694 static constexpr int MODE_BITS_SIZE = 2; 695 static constexpr int ON_HEAP_MODE_BITS_SIZE = 2; 696 TypedArrayMetaDataAccessor(uint64_t value)697 explicit TypedArrayMetaDataAccessor(uint64_t value) : bitField_(value) {} 698 GetParamType()699 ParamType GetParamType() const 700 { 701 return ParamType(TypeBits::Get(bitField_)); 702 } 703 GetOnHeapMode()704 OnHeapMode GetOnHeapMode() const 705 { 706 return OnHeapModeBits::Get(bitField_); 707 } 708 UpdateOnHeapMode(OnHeapMode mode)709 uint64_t UpdateOnHeapMode(OnHeapMode mode) 710 { 711 return OnHeapModeBits::Update(bitField_, mode); 712 } 713 IsAccessElement()714 bool IsAccessElement() const 715 { 716 return ModeBits::Get(bitField_) == Mode::ACCESS_ELEMENT; 717 } 718 ToValue()719 uint64_t ToValue() 720 { 721 return bitField_; 722 } 723 ToValue(ParamType paramType,Mode mode,OnHeapMode onHeap)724 static uint64_t ToValue(ParamType paramType, Mode mode, OnHeapMode onHeap) 725 { 726 return TypeBits::Encode(paramType.Value()) | ModeBits::Encode(mode) | OnHeapModeBits::Encode(onHeap); 727 } 728 729 private: 730 using TypeBits = panda::BitField<uint32_t, 0, TYPE_BITS_SIZE>; 731 using ModeBits = TypeBits::NextField<Mode, MODE_BITS_SIZE>; 732 using OnHeapModeBits = ModeBits::NextField<OnHeapMode, ON_HEAP_MODE_BITS_SIZE>; 733 734 uint64_t bitField_; 735 }; 736 737 class LoadElementAccessor { 738 public: 739 static constexpr int TYPED_LOAD_OP_BITS_SIZE = 8; 740 static constexpr int ON_HEAP_MODE_BITS_SIZE = 8; 741 LoadElementAccessor(uint64_t value)742 explicit LoadElementAccessor(uint64_t value): bitField_(value) {} LoadElementAccessor(TypedLoadOp op,OnHeapMode onHeap)743 explicit LoadElementAccessor(TypedLoadOp op, OnHeapMode onHeap) 744 { 745 bitField_ = TypedLoadOpBits::Encode(op) | OnHeapModeBits::Encode(onHeap); 746 } 747 GetTypedLoadOp()748 TypedLoadOp GetTypedLoadOp() const 749 { 750 return TypedLoadOpBits::Get(bitField_); 751 } 752 GetOnHeapMode()753 OnHeapMode GetOnHeapMode() const 754 { 755 return OnHeapModeBits::Get(bitField_); 756 } 757 ToValue()758 uint64_t ToValue() const 759 { 760 return bitField_; 761 } 762 763 private: 764 using TypedLoadOpBits = panda::BitField<TypedLoadOp, 0, TYPED_LOAD_OP_BITS_SIZE>; 765 using OnHeapModeBits = TypedLoadOpBits::NextField<OnHeapMode, ON_HEAP_MODE_BITS_SIZE>; 766 767 uint64_t bitField_; 768 }; 769 770 class StoreElementAccessor { 771 public: 772 static constexpr int TYPED_STORE_OP_BITS_SIZE = 8; 773 static constexpr int ON_HEAP_MODE_BITS_SIZE = 8; 774 StoreElementAccessor(uint64_t value)775 explicit StoreElementAccessor(uint64_t value): bitField_(value) {} StoreElementAccessor(TypedStoreOp op,OnHeapMode onHeap)776 explicit StoreElementAccessor(TypedStoreOp op, OnHeapMode onHeap) 777 { 778 bitField_ = TypedStoreOpBits::Encode(op) | OnHeapModeBits::Encode(onHeap); 779 } 780 GetTypedStoreOp()781 TypedStoreOp GetTypedStoreOp() const 782 { 783 return TypedStoreOpBits::Get(bitField_); 784 } 785 GetOnHeapMode()786 OnHeapMode GetOnHeapMode() const 787 { 788 return OnHeapModeBits::Get(bitField_); 789 } 790 ToValue()791 uint64_t ToValue() const 792 { 793 return bitField_; 794 } 795 796 private: 797 using TypedStoreOpBits = panda::BitField<TypedStoreOp, 0, TYPED_STORE_OP_BITS_SIZE>; 798 using OnHeapModeBits = TypedStoreOpBits::NextField<OnHeapMode, ON_HEAP_MODE_BITS_SIZE>; 799 800 uint64_t bitField_; 801 }; 802 803 class StringStatusAccessor { 804 public: type_(value)805 explicit StringStatusAccessor(uint64_t value = 0) : type_(value) {} 806 GetStringStatus()807 uint32_t GetStringStatus() const 808 { 809 return static_cast<uint32_t>(type_); 810 } 811 ToValue()812 uint64_t ToValue() const 813 { 814 return type_; 815 } 816 817 private: 818 uint64_t type_ {0}; 819 }; 820 } // namespace panda::ecmascript::kungfu 821 822 #endif // ECMASCRIPT_COMPILER_SHARE_GATE_META_DATA_H 823