/
githubmirror
/
node
Обзор
Документация
Войти
/
githubmirror
/
node
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
deps/v8/src/objects/name-inl.h
302 строки
10 KB
Michaël Zasso
deps: update V8 to 14.6.202.33
24 апр 2026, 19:01
Не верифицирован
24 апр 2026, 19:01
f1e0b83
Код
Авторство
О чём код?
// Copyright 2017 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_OBJECTS_NAME_INL_H_ #define V8_OBJECTS_NAME_INL_H_ #include "src/objects/name.h" // Include the non-inl header before the rest of the headers. #include "src/base/logging.h" #include "src/heap/heap-write-barrier-inl.h" #include "src/objects/instance-type-inl.h" #include "src/objects/map-inl.h" #include "src/objects/primitive-heap-object-inl.h" #include "src/objects/string-forwarding-table.h" #include "src/objects/string-inl.h" // Has to be the last include (doesn't have include guards): #include "src/objects/object-macros.h" namespace v8 { namespace internal { Tagged<PrimitiveHeapObject> Symbol::description() const { return description_.load(); } void Symbol::set_description(Tagged<PrimitiveHeapObject> value, WriteBarrierMode mode) { SLOW_DCHECK(IsString(value) || IsUndefined(value)); description_.store(this, value, mode); } BIT_FIELD_ACCESSORS(Symbol, flags, is_well_known_symbol, Symbol::IsWellKnownSymbolBit) BIT_FIELD_ACCESSORS(Symbol, flags, is_in_public_symbol_table, Symbol::IsInPublicSymbolTableBit) BIT_FIELD_ACCESSORS(Symbol, flags, is_interesting_symbol, Symbol::IsInterestingSymbolBit) bool Symbol::is_any_private() const { return Symbol::PrivateSymbolKindBits::decode(flags()) != PrivateSymbolKind::kPublic; } void Symbol::set_private_symbol_kind(PrivateSymbolKind kind) { set_flags(Symbol::PrivateSymbolKindBits::update(flags(), kind)); } bool Symbol::is_private_internal() const { return Symbol::PrivateSymbolKindBits::decode(flags()) == PrivateSymbolKind::kInternal; } bool Symbol::is_private_brand() const { return Symbol::PrivateSymbolKindBits::decode(flags()) == PrivateSymbolKind::kBrand; } PrivateSymbolKind Symbol::private_symbol_kind() const { return Symbol::PrivateSymbolKindBits::decode(flags()); } bool Symbol::is_any_private_name() const { return Symbol::PrivateSymbolKindBits::decode(flags()) >= PrivateSymbolKind::kFieldName; } DEF_HEAP_OBJECT_PREDICATE(Name, IsUniqueName) { uint32_t type = obj->map()->instance_type(); bool result = (type & (kIsNotStringMask | kIsNotInternalizedMask)) != (kStringTag | kNotInternalizedTag); SLOW_DCHECK(result == IsUniqueName(Cast<HeapObject>(obj))); DCHECK_IMPLIES(result, obj->HasHashCode()); return result; } bool Name::Equals(Tagged<Name> other) { if (other == this) return true; if ((IsInternalizedString(this) && IsInternalizedString(other)) || IsSymbol(this) || IsSymbol(other)) { return false; } return Cast<String>(this)->SlowEquals(Cast<String>(other)); } bool Name::Equals(Isolate* isolate, DirectHandle<Name> one, DirectHandle<Name> two) { if (one.is_identical_to(two)) return true; if ((IsInternalizedString(*one) && IsInternalizedString(*two)) || IsSymbol(*one) || IsSymbol(*two)) { return false; } return String::SlowEquals(isolate, Cast<String>(one), Cast<String>(two)); } // static bool Name::IsHashFieldComputed(uint32_t raw_hash_field) { return (raw_hash_field & kHashNotComputedMask) == 0; } // static bool Name::IsHash(uint32_t raw_hash_field) { return HashFieldTypeBits::decode(raw_hash_field) == HashFieldType::kHash; } // static bool Name::IsIntegerIndex(uint32_t raw_hash_field) { return HashFieldTypeBits::decode(raw_hash_field) == HashFieldType::kIntegerIndex; } // static bool Name::IsForwardingIndex(uint32_t raw_hash_field) { return HashFieldTypeBits::decode(raw_hash_field) == HashFieldType::kForwardingIndex; } // static bool Name::IsInternalizedForwardingIndex(uint32_t raw_hash_field) { return HashFieldTypeBits::decode(raw_hash_field) == HashFieldType::kForwardingIndex && IsInternalizedForwardingIndexBit::decode(raw_hash_field); } // static bool Name::IsExternalForwardingIndex(uint32_t raw_hash_field) { return HashFieldTypeBits::decode(raw_hash_field) == HashFieldType::kForwardingIndex && IsExternalForwardingIndexBit::decode(raw_hash_field); } // static uint32_t Name::CreateHashFieldValue(uint32_t hash, HashFieldType type) { DCHECK_NE(type, HashFieldType::kForwardingIndex); return HashBits::encode(hash & HashBits::kMax) | HashFieldTypeBits::encode(type); } // static uint32_t Name::CreateInternalizedForwardingIndex(uint32_t index) { return ForwardingIndexValueBits::encode(index) | IsExternalForwardingIndexBit::encode(false) | IsInternalizedForwardingIndexBit::encode(true) | HashFieldTypeBits::encode(HashFieldType::kForwardingIndex); } // static uint32_t Name::CreateExternalForwardingIndex(uint32_t index) { return ForwardingIndexValueBits::encode(index) | IsExternalForwardingIndexBit::encode(true) | IsInternalizedForwardingIndexBit::encode(false) | HashFieldTypeBits::encode(HashFieldType::kForwardingIndex); } bool Name::HasHashCode() const { uint32_t field = raw_hash_field(); return IsHashFieldComputed(field) || IsForwardingIndex(field); } bool Name::HasForwardingIndex(AcquireLoadTag) const { return IsForwardingIndex(raw_hash_field(kAcquireLoad)); } bool Name::HasInternalizedForwardingIndex(AcquireLoadTag) const { return IsInternalizedForwardingIndex(raw_hash_field(kAcquireLoad)); } bool Name::HasExternalForwardingIndex(AcquireLoadTag) const { return IsExternalForwardingIndex(raw_hash_field(kAcquireLoad)); } uint32_t Name::GetRawHashFromForwardingTable(uint32_t raw_hash) const { DCHECK(IsForwardingIndex(raw_hash)); // TODO(pthier): Add parameter for isolate so we don't need to calculate it. Isolate* isolate = Isolate::Current(); const int index = ForwardingIndexValueBits::decode(raw_hash); return isolate->string_forwarding_table()->GetRawHash(isolate, index); } uint32_t Name::EnsureRawHash() { // Fast case: has hash code already been computed? uint32_t field = raw_hash_field(kAcquireLoad); if (IsHashFieldComputed(field)) return field; // The computed hash might be stored in the forwarding table. if (V8_UNLIKELY(IsForwardingIndex(field))) { return GetRawHashFromForwardingTable(field); } // Slow case: compute hash code and set it. Has to be a string. return Cast<String>(this)->ComputeAndSetRawHash(); } uint32_t Name::EnsureRawHash( const SharedStringAccessGuardIfNeeded& access_guard) { // Fast case: has hash code already been computed? uint32_t field = raw_hash_field(kAcquireLoad); if (IsHashFieldComputed(field)) return field; // The computed hash might be stored in the forwarding table. if (V8_UNLIKELY(IsForwardingIndex(field))) { return GetRawHashFromForwardingTable(field); } // Slow case: compute hash code and set it. Has to be a string. return Cast<String>(this)->ComputeAndSetRawHash(access_guard); } uint32_t Name::RawHash() { uint32_t field = raw_hash_field(kAcquireLoad); if (V8_UNLIKELY(IsForwardingIndex(field))) { return GetRawHashFromForwardingTable(field); } return field; } uint32_t Name::EnsureHash() { return HashBits::decode(EnsureRawHash()); } uint32_t Name::EnsureHash(const SharedStringAccessGuardIfNeeded& access_guard) { return HashBits::decode(EnsureRawHash(access_guard)); } void Name::set_raw_hash_field_if_empty(uint32_t hash) { uint32_t field_value = kEmptyHashField; bool result = raw_hash_field_.compare_exchange_strong(field_value, hash); USE(result); // CAS can only fail if the string is shared or we use the forwarding table // for all strings and the hash was already set (by another thread) or it is // a forwarding index (that overwrites the previous hash). // In all cases we don't want overwrite the old value, so we don't handle the // failure case. DCHECK_IMPLIES(!result, (Cast<String>(this)->IsShared() || v8_flags.always_use_string_forwarding_table) && (field_value == hash || IsForwardingIndex(hash))); } uint32_t Name::hash() const { uint32_t field = raw_hash_field(kAcquireLoad); if (V8_UNLIKELY(!IsHashFieldComputed(field))) { DCHECK(IsForwardingIndex(field)); return HashBits::decode(GetRawHashFromForwardingTable(field)); } return HashBits::decode(field); } bool Name::TryGetHash(uint32_t* hash) const { uint32_t field = raw_hash_field(kAcquireLoad); if (IsHashFieldComputed(field)) { *hash = HashBits::decode(field); return true; } if (V8_UNLIKELY(IsForwardingIndex(field))) { *hash = HashBits::decode(GetRawHashFromForwardingTable(field)); return true; } return false; } bool Name::IsInteresting(Isolate* isolate) { // TODO(ishell): consider using ReadOnlyRoots::IsNameForProtector() trick for // these strings and interesting symbols. return (IsSymbol(this) && Cast<Symbol>(this)->is_interesting_symbol()) || this == *isolate->factory()->toJSON_string() || this == *isolate->factory()->get_string(); } bool Name::IsAnyPrivate() { return IsSymbol(this) && Cast<Symbol>(this)->is_any_private(); } bool Name::IsPrivateInternal() { return IsSymbol(this) && Cast<Symbol>(this)->is_private_internal(); } bool Name::IsAnyPrivateName() { return IsSymbol(this) && Cast<Symbol>(this)->is_any_private_name(); } bool Name::IsPrivateBrand() { bool is_private_brand = IsSymbol(this) && Cast<Symbol>(this)->is_private_brand(); DCHECK_IMPLIES(is_private_brand, IsAnyPrivateName()); return is_private_brand; } bool Name::IsArrayIndex() { uint32_t index; return AsArrayIndex(&index); } bool Name::AsArrayIndex(uint32_t* index) { return IsString(this) && Cast<String>(this)->AsArrayIndex(index); } bool Name::AsIntegerIndex(size_t* index) { return IsString(this) && Cast<String>(this)->AsIntegerIndex(index); } // static bool Name::ContainsCachedArrayIndex(uint32_t raw_hash_field) { return (raw_hash_field & Name::kDoesNotContainCachedArrayIndexMask) == 0; } } // namespace internal } // namespace v8 #include "src/objects/object-macros-undef.h" #endif // V8_OBJECTS_NAME_INL_H_