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