1 // Copyright 2017 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_OBJECTS_NAME_INL_H_
6 #define V8_OBJECTS_NAME_INL_H_
7
8 #include "src/base/logging.h"
9 #include "src/heap/heap-write-barrier-inl.h"
10 #include "src/objects/map-inl.h"
11 #include "src/objects/name.h"
12 #include "src/objects/primitive-heap-object-inl.h"
13 #include "src/objects/string-inl.h"
14
15 // Has to be the last include (doesn't have include guards):
16 #include "src/objects/object-macros.h"
17
18 namespace v8 {
19 namespace internal {
20
21 #include "torque-generated/src/objects/name-tq-inl.inc"
22
23 TQ_OBJECT_CONSTRUCTORS_IMPL(Name)
TQ_OBJECT_CONSTRUCTORS_IMPL(Symbol)24 TQ_OBJECT_CONSTRUCTORS_IMPL(Symbol)
25
26 BIT_FIELD_ACCESSORS(Symbol, flags, is_private, Symbol::IsPrivateBit)
27 BIT_FIELD_ACCESSORS(Symbol, flags, is_well_known_symbol,
28 Symbol::IsWellKnownSymbolBit)
29 BIT_FIELD_ACCESSORS(Symbol, flags, is_in_public_symbol_table,
30 Symbol::IsInPublicSymbolTableBit)
31 BIT_FIELD_ACCESSORS(Symbol, flags, is_interesting_symbol,
32 Symbol::IsInterestingSymbolBit)
33
34 bool Symbol::is_private_brand() const {
35 bool value = Symbol::IsPrivateBrandBit::decode(flags());
36 DCHECK_IMPLIES(value, is_private());
37 return value;
38 }
39
set_is_private_brand()40 void Symbol::set_is_private_brand() {
41 set_flags(Symbol::IsPrivateBit::update(flags(), true));
42 set_flags(Symbol::IsPrivateNameBit::update(flags(), true));
43 set_flags(Symbol::IsPrivateBrandBit::update(flags(), true));
44 }
45
is_private_name()46 bool Symbol::is_private_name() const {
47 bool value = Symbol::IsPrivateNameBit::decode(flags());
48 DCHECK_IMPLIES(value, is_private());
49 return value;
50 }
51
set_is_private_name()52 void Symbol::set_is_private_name() {
53 // TODO(gsathya): Re-order the bits to have these next to each other
54 // and just do the bit shifts once.
55 set_flags(Symbol::IsPrivateBit::update(flags(), true));
56 set_flags(Symbol::IsPrivateNameBit::update(flags(), true));
57 }
58
DEF_GETTER(Name,IsUniqueName,bool)59 DEF_GETTER(Name, IsUniqueName, bool) {
60 uint32_t type = map(cage_base).instance_type();
61 bool result = (type & (kIsNotStringMask | kIsNotInternalizedMask)) !=
62 (kStringTag | kNotInternalizedTag);
63 SLOW_DCHECK(result == HeapObject::IsUniqueName());
64 DCHECK_IMPLIES(result, HasHashCode());
65 return result;
66 }
67
Equals(Name other)68 bool Name::Equals(Name other) {
69 if (other == *this) return true;
70 if ((this->IsInternalizedString() && other.IsInternalizedString()) ||
71 this->IsSymbol() || other.IsSymbol()) {
72 return false;
73 }
74 return String::cast(*this).SlowEquals(String::cast(other));
75 }
76
Equals(Isolate * isolate,Handle<Name> one,Handle<Name> two)77 bool Name::Equals(Isolate* isolate, Handle<Name> one, Handle<Name> two) {
78 if (one.is_identical_to(two)) return true;
79 if ((one->IsInternalizedString() && two->IsInternalizedString()) ||
80 one->IsSymbol() || two->IsSymbol()) {
81 return false;
82 }
83 return String::SlowEquals(isolate, Handle<String>::cast(one),
84 Handle<String>::cast(two));
85 }
86
IsHashFieldComputed(uint32_t raw_hash_field)87 bool Name::IsHashFieldComputed(uint32_t raw_hash_field) {
88 return (raw_hash_field & kHashNotComputedMask) == 0;
89 }
90
IsHash(uint32_t raw_hash_field)91 bool Name::IsHash(uint32_t raw_hash_field) {
92 return HashFieldTypeBits::decode(raw_hash_field) == HashFieldType::kHash;
93 }
94
IsIntegerIndex(uint32_t raw_hash_field)95 bool Name::IsIntegerIndex(uint32_t raw_hash_field) {
96 return HashFieldTypeBits::decode(raw_hash_field) ==
97 HashFieldType::kIntegerIndex;
98 }
99
IsForwardingIndex(uint32_t raw_hash_field)100 bool Name::IsForwardingIndex(uint32_t raw_hash_field) {
101 return HashFieldTypeBits::decode(raw_hash_field) ==
102 HashFieldType::kForwardingIndex;
103 }
104
CreateHashFieldValue(uint32_t hash,HashFieldType type)105 uint32_t Name::CreateHashFieldValue(uint32_t hash, HashFieldType type) {
106 return HashBits::encode(hash & HashBits::kMax) |
107 HashFieldTypeBits::encode(type);
108 }
109
HasHashCode()110 bool Name::HasHashCode() const { return IsHashFieldComputed(raw_hash_field()); }
111
EnsureHash()112 uint32_t Name::EnsureHash() {
113 // Fast case: has hash code already been computed?
114 uint32_t field = raw_hash_field();
115 if (IsHashFieldComputed(field)) return HashBits::decode(field);
116 // Slow case: compute hash code and set it. Has to be a string.
117 return String::cast(*this).ComputeAndSetHash();
118 }
119
EnsureHash(const SharedStringAccessGuardIfNeeded & access_guard)120 uint32_t Name::EnsureHash(const SharedStringAccessGuardIfNeeded& access_guard) {
121 // Fast case: has hash code already been computed?
122 uint32_t field = raw_hash_field();
123 if (IsHashFieldComputed(field)) return HashBits::decode(field);
124 // Slow case: compute hash code and set it. Has to be a string.
125 return String::cast(*this).ComputeAndSetHash(access_guard);
126 }
127
hash()128 uint32_t Name::hash() const {
129 uint32_t field = raw_hash_field();
130 DCHECK(IsHashFieldComputed(field));
131 return HashBits::decode(field);
132 }
133
DEF_GETTER(Name,IsInterestingSymbol,bool)134 DEF_GETTER(Name, IsInterestingSymbol, bool) {
135 return IsSymbol(cage_base) && Symbol::cast(*this).is_interesting_symbol();
136 }
137
DEF_GETTER(Name,IsPrivate,bool)138 DEF_GETTER(Name, IsPrivate, bool) {
139 return this->IsSymbol(cage_base) && Symbol::cast(*this).is_private();
140 }
141
DEF_GETTER(Name,IsPrivateName,bool)142 DEF_GETTER(Name, IsPrivateName, bool) {
143 bool is_private_name =
144 this->IsSymbol(cage_base) && Symbol::cast(*this).is_private_name();
145 DCHECK_IMPLIES(is_private_name, IsPrivate());
146 return is_private_name;
147 }
148
DEF_GETTER(Name,IsPrivateBrand,bool)149 DEF_GETTER(Name, IsPrivateBrand, bool) {
150 bool is_private_brand =
151 this->IsSymbol(cage_base) && Symbol::cast(*this).is_private_brand();
152 DCHECK_IMPLIES(is_private_brand, IsPrivateName());
153 return is_private_brand;
154 }
155
AsArrayIndex(uint32_t * index)156 bool Name::AsArrayIndex(uint32_t* index) {
157 return IsString() && String::cast(*this).AsArrayIndex(index);
158 }
159
AsIntegerIndex(size_t * index)160 bool Name::AsIntegerIndex(size_t* index) {
161 return IsString() && String::cast(*this).AsIntegerIndex(index);
162 }
163
164 // static
ContainsCachedArrayIndex(uint32_t raw_hash_field)165 bool Name::ContainsCachedArrayIndex(uint32_t raw_hash_field) {
166 return (raw_hash_field & Name::kDoesNotContainCachedArrayIndexMask) == 0;
167 }
168
169 } // namespace internal
170 } // namespace v8
171
172 #include "src/objects/object-macros-undef.h"
173
174 #endif // V8_OBJECTS_NAME_INL_H_
175