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