1 /* 2 * Copyright (c) 2021-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_JSSYMBOL_H 17 #define ECMASCRIPT_JSSYMBOL_H 18 19 #include "ecmascript/ecma_string.h" 20 #include "ecmascript/js_object.h" 21 #include "ecmascript/pgo_profiler/types/pgo_profile_type.h" 22 23 namespace panda { 24 namespace ecmascript { 25 using ProfileType = pgo::ProfileType; 26 27 class JSSymbol : public TaggedObject { 28 public: 29 static constexpr uint32_t IS_PRIVATE = 1U << 0U; 30 static constexpr uint32_t IS_WELL_KNOWN_SYMBOL = 1U << 1U; 31 static constexpr uint32_t IS_IN_PUBLIC_SYMBOL_TABLE = 1U << 2U; 32 static constexpr uint32_t IS_INTERESTING_SYMBOL = 1U << 3U; 33 static constexpr uint32_t IS_PRIVATE_NAME = 1U << 4U; 34 static constexpr uint32_t IS_PRIVATE_BRAND = 1U << 5U; 35 static constexpr uint32_t HAS_ID = 1U << 6U; 36 37 static constexpr int SYMBOL_HAS_INSTANCE_TYPE = 0; 38 static constexpr int SYMBOL_TO_PRIMITIVE_TYPE = 1; 39 static constexpr int SYMBOL_DEFAULT_TYPE = 2; 40 41 static constexpr const uint32_t LINEAR_X = 1103515245U; 42 static constexpr const uint32_t LINEAR_Y = 12345U; 43 static constexpr const uint32_t LINEAR_SEED = 987654321U; 44 45 // 48: high 16 bits need to be double encoded as a valid number tagged value 46 static constexpr size_t SYMBOL_ID_BITFIELD_NUM = 48; 47 static constexpr size_t ABC_ID_OFFSET_BIT = SYMBOL_ID_BITFIELD_NUM - ProfileType::ABC_ID_BITFIELD_NUM; 48 static constexpr size_t LITERAL_ID_BITFIELD_NUM = 16; 49 static constexpr size_t LITERAL_ID_OFFSET_BIT = ABC_ID_OFFSET_BIT - LITERAL_ID_BITFIELD_NUM; 50 51 public: 52 CAST_CHECK(JSSymbol, IsSymbol); 53 ComputeHash()54 static inline uint32_t ComputeHash() 55 { 56 uint32_t hashSeed = static_cast<uint32_t>(LINEAR_SEED + std::time(nullptr)); 57 uint32_t hash = hashSeed * LINEAR_X + LINEAR_Y; 58 return hash; 59 } 60 HasId() const61 bool HasId() const 62 { 63 return (GetFlags() & HAS_ID) != 0U; 64 } 65 SetHasId()66 void SetHasId() 67 { 68 SetFlags(GetFlags() | HAS_ID); 69 } 70 IsPrivate() const71 bool IsPrivate() const 72 { 73 return (GetFlags() & IS_PRIVATE) != 0U; 74 } 75 SetPrivate()76 void SetPrivate() 77 { 78 SetFlags(GetFlags() | IS_PRIVATE); 79 } 80 IsWellKnownSymbol() const81 bool IsWellKnownSymbol() const 82 { 83 return (GetFlags() & IS_WELL_KNOWN_SYMBOL) != 0U; 84 } 85 SetWellKnownSymbol()86 void SetWellKnownSymbol() 87 { 88 SetFlags(GetFlags() | IS_WELL_KNOWN_SYMBOL); 89 } 90 IsInPublicSymbolTable() const91 bool IsInPublicSymbolTable() const 92 { 93 return (GetFlags() & IS_IN_PUBLIC_SYMBOL_TABLE) != 0U; 94 } 95 SetInPublicSymbolTable()96 void SetInPublicSymbolTable() 97 { 98 SetFlags(GetFlags() | IS_IN_PUBLIC_SYMBOL_TABLE); 99 } 100 IsInterestingSymbol() const101 bool IsInterestingSymbol() const 102 { 103 return (GetFlags() & IS_INTERESTING_SYMBOL) != 0U; 104 } 105 SetInterestingSymbol()106 void SetInterestingSymbol() 107 { 108 SetFlags(GetFlags() | IS_INTERESTING_SYMBOL); 109 } 110 IsPrivateNameSymbol() const111 bool IsPrivateNameSymbol() const 112 { 113 return (GetFlags() & IS_PRIVATE_NAME) != 0U; 114 } 115 SetPrivateNameSymbol()116 void SetPrivateNameSymbol() 117 { 118 SetFlags(GetFlags() | IS_PRIVATE_NAME); 119 } 120 Equal(const JSSymbol &src, const JSSymbol &dst)121 static bool Equal(const JSSymbol &src, const JSSymbol &dst) 122 { 123 if (src.GetFlags() != dst.GetFlags()) { 124 return false; 125 } 126 EcmaString *srcString = EcmaString::Cast(src.GetDescription().GetTaggedObject()); 127 EcmaString *dstString = EcmaString::Cast(dst.GetDescription().GetTaggedObject()); 128 return EcmaStringAccessor::StringsAreEqual(srcString, dstString); 129 } 130 GetPrivateId()131 uint64_t GetPrivateId() 132 { 133 return GetId(); 134 } 135 SetPrivateId(uint64_t id)136 void SetPrivateId(uint64_t id) 137 { 138 SetHasId(); 139 SetId(id); 140 } 141 GeneratePrivateId(uint64_t abcId, uint64_t literalId, uint64_t slotIndex)142 static uint64_t GeneratePrivateId(uint64_t abcId, uint64_t literalId, uint64_t slotIndex) 143 { 144 return JSTaggedValueInternals::DOUBLE_ENCODE_OFFSET | (abcId << ABC_ID_OFFSET_BIT) | 145 (literalId << LITERAL_ID_OFFSET_BIT) | slotIndex; 146 } 147 GetSlotIndex(uint64_t id)148 static uint64_t GetSlotIndex(uint64_t id) 149 { 150 uint64_t mask = (1ULL << LITERAL_ID_OFFSET_BIT) - 1; 151 return id & mask; 152 } 153 GetLiteralId(uint64_t id)154 static uint64_t GetLiteralId(uint64_t id) 155 { 156 uint64_t mask = (1ULL << LITERAL_ID_BITFIELD_NUM) - 1; 157 return (id >> LITERAL_ID_OFFSET_BIT) & mask; 158 } 159 GetAbcId(uint64_t id)160 static uint64_t GetAbcId(uint64_t id) 161 { 162 uint64_t mask = (1ULL << ProfileType::ABC_ID_BITFIELD_NUM) - 1; 163 return (id >> ABC_ID_OFFSET_BIT) & mask; 164 } 165 166 public: 167 static constexpr size_t DESCRIPTION_OFFSET = TaggedObjectSize(); 168 ACCESSORS(Description, DESCRIPTION_OFFSET, HASHFIELD_OFFSET) 169 ACCESSORS_PRIMITIVE_FIELD(HashField, uint32_t, HASHFIELD_OFFSET, FLAGS_OFFSET) 170 ACCESSORS_PRIMITIVE_FIELD(Flags, uint32_t, FLAGS_OFFSET, ID_OFFSET) 171 ACCESSORS_PRIMITIVE_FIELD(Id, uint64_t, ID_OFFSET, LAST_OFFSET) 172 DEFINE_ALIGN_SIZE(LAST_OFFSET); 173 174 DECL_DUMP() 175 176 DECL_VISIT_OBJECT(DESCRIPTION_OFFSET, HASHFIELD_OFFSET) 177 }; 178 } // namespace ecmascript 179 } // namespace panda 180 #endif // ECMASCRIPT_NAME_H 181