v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
name.h
Go to the documentation of this file.
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_H_
6#define V8_OBJECTS_NAME_H_
7
8#include <atomic>
9
10#include "src/base/bit-field.h"
11#include "src/common/globals.h"
12#include "src/objects/objects.h"
14#include "src/utils/utils.h"
15#include "torque-generated/bit-fields.h"
16
17// Has to be the last include (doesn't have include guards):
19
20namespace v8 {
21namespace internal {
22
23namespace compiler {
24class WasmGraphBuilder;
25}
26
27namespace maglev {
28class MaglevGraphBuilder;
29}
30
31class SharedStringAccessGuardIfNeeded;
32
33// The Name abstract class captures anything that can be used as a property
34// name, i.e., strings and symbols. All names store a hash value.
36 public:
37 // Tells whether the hash code has been computed.
38 // Note: Use TryGetHash() whenever you want to use the hash, instead of a
39 // combination of HashHashCode() and hash() for thread-safety.
40 inline bool HasHashCode() const;
41 // Tells whether the name contains a forwarding index pointing to a row
42 // in the string forwarding table.
43 inline bool HasForwardingIndex(AcquireLoadTag) const;
46
47 inline uint32_t raw_hash_field() const {
48 return raw_hash_field_.load(std::memory_order_relaxed);
49 }
50
51 inline uint32_t raw_hash_field(AcquireLoadTag) const {
52 return raw_hash_field_.load(std::memory_order_acquire);
53 }
54
55 inline void set_raw_hash_field(uint32_t hash) {
56 raw_hash_field_.store(hash, std::memory_order_relaxed);
57 }
58
59 inline void set_raw_hash_field(uint32_t hash, ReleaseStoreTag) {
60 raw_hash_field_.store(hash, std::memory_order_release);
61 }
62
63 // Sets the hash field only if it is empty. Otherwise does nothing.
64 inline void set_raw_hash_field_if_empty(uint32_t hash);
65
66 // Returns a hash value used for the property table (same as Hash()), assumes
67 // the hash is already computed.
68 inline uint32_t hash() const;
69
70 // Returns true if the hash has been computed, and sets the computed hash
71 // as out-parameter.
72 inline bool TryGetHash(uint32_t* hash) const;
73
74 // Equality operations.
75 inline bool Equals(Tagged<Name> other);
76 inline static bool Equals(Isolate* isolate, DirectHandle<Name> one,
78
79 // Conversion.
80 inline bool IsArrayIndex();
81 inline bool AsArrayIndex(uint32_t* index);
82 inline bool AsIntegerIndex(size_t* index);
83
84 // An "interesting" is a well-known symbol or string, like @@toStringTag,
85 // @@toJSON, that's often looked up on random objects but is usually not
86 // present. We optimize this by setting a flag on the object's map when such
87 // symbol properties are added, so we can optimize lookups on objects
88 // that don't have the flag.
89 inline bool IsInteresting(Isolate* isolate);
90
91 // If the name is private, it can only name own properties.
92 inline bool IsPrivate();
93
94 // If the name is a private name, it should behave like a private
95 // symbol but also throw on property access miss.
96 inline bool IsPrivateName();
97
98 // If the name is a private brand, it should behave like a private name
99 // symbol but is filtered out when generating list of private fields.
100 inline bool IsPrivateBrand();
101
102 static inline bool ContainsCachedArrayIndex(uint32_t hash);
103
104 // Return a string version of this name that is converted according to the
105 // rules described in ES6 section 9.2.11.
107 Isolate* isolate, DirectHandle<Name> name);
109 Isolate* isolate, DirectHandle<Name> name, DirectHandle<String> prefix);
110
113 void NameShortPrint();
115
116 // Mask constant for checking if a name has a computed hash code and the type
117 // of information stored in the hash field. The least significant bit
118 // indicates whether the value can be used as a hash (i.e. different values
119 // imply different strings).
120 enum class HashFieldType : uint32_t {
121 kHash = 0b10,
122 kIntegerIndex = 0b00,
123 kForwardingIndex = 0b01,
124 kEmpty = 0b11
125 };
126
128 using HashBits =
130
131 static constexpr int kHashNotComputedMask = 1;
132 // Value of empty hash field indicating that the hash is not computed.
133 static constexpr int kEmptyHashField =
135
136 // Empty hash and forwarding indices can not be used as hash.
137 static_assert((kEmptyHashField & kHashNotComputedMask) != 0);
140
145 unsigned int, kBitsPerInt - HashFieldTypeBits::kSize -
148
149 // Array index strings this short can keep their index in the hash field.
150 static const int kMaxCachedArrayIndexLength = 7;
151
152 static const uint32_t kMaxArrayIndex = kMaxUInt32 - 1;
153 // Maximum number of characters to consider when trying to convert a string
154 // value into an array index.
155 static const int kMaxArrayIndexSize = 10;
156 static_assert(TenToThe(kMaxArrayIndexSize) >= kMaxArrayIndex);
157 static_assert(TenToThe(kMaxArrayIndexSize - 1) < kMaxArrayIndex);
158 // Maximum number of characters in a string that can possibly be an
159 // "integer index" in the spec sense, i.e. a canonical representation of a
160 // number in the range up to MAX_SAFE_INTEGER. We parse these into a size_t,
161 // so the size of that type also factors in as a limit: 10 characters per
162 // 32 bits of size_t width.
163 static const int kMaxIntegerIndexSize =
164 std::min(16, int{10 * (sizeof(size_t) / 4)});
165
166 // For strings which are array indexes the hash value has the string length
167 // mixed into the hash, mainly to avoid a hash value of zero which would be
168 // the case for the string '0'. 24 bits are used for the array index value.
169 static const int kArrayIndexValueBits = 24;
170 static const int kArrayIndexLengthBits =
172
173 static_assert(kArrayIndexLengthBits > 0);
174 static_assert(kMaxArrayIndexSize < (1 << kArrayIndexLengthBits));
175
180
181 // Check that kMaxCachedArrayIndexLength + 1 is a power of two so we
182 // could use a mask to test if the length of string is less than or equal to
183 // kMaxCachedArrayIndexLength.
185 "(kMaxCachedArrayIndexLength + 1) must be power of two");
186
187 // When any of these bits is set then the hash field does not contain a cached
188 // array index.
190 static const unsigned int kDoesNotContainCachedArrayIndexMask =
191 (~static_cast<unsigned>(kMaxCachedArrayIndexLength)
194
195 // When any of these bits is set then the hash field does not contain an
196 // integer or forwarding index.
197 static const unsigned int kDoesNotContainIntegerOrForwardingIndexMask = 0b10;
202
203 // Returns a hash value used for the property table. Ensures that the hash
204 // value is computed.
205 //
206 // The overload without SharedStringAccessGuardIfNeeded can only be called on
207 // the main thread.
208 inline uint32_t EnsureHash();
209 inline uint32_t EnsureHash(const SharedStringAccessGuardIfNeeded&);
210 // The value returned is always a computed hash, even if the value stored is
211 // a forwarding index.
212 inline uint32_t EnsureRawHash();
213 inline uint32_t EnsureRawHash(const SharedStringAccessGuardIfNeeded&);
214 inline uint32_t RawHash();
215
216 static inline bool IsHashFieldComputed(uint32_t raw_hash_field);
217 static inline bool IsHash(uint32_t raw_hash_field);
218 static inline bool IsIntegerIndex(uint32_t raw_hash_field);
219 static inline bool IsForwardingIndex(uint32_t raw_hash_field);
220 static inline bool IsInternalizedForwardingIndex(uint32_t raw_hash_field);
221 static inline bool IsExternalForwardingIndex(uint32_t raw_hash_field);
222
223 static inline uint32_t CreateHashFieldValue(uint32_t hash,
224 HashFieldType type);
225 static inline uint32_t CreateInternalizedForwardingIndex(uint32_t index);
226 static inline uint32_t CreateExternalForwardingIndex(uint32_t index);
227
228 private:
229 friend class V8HeapExplorer;
230 friend class CodeStubAssembler;
232 friend class SandboxTesting;
238
239 inline uint32_t GetRawHashFromForwardingTable(uint32_t raw_hash) const;
240
241 std::atomic_uint32_t raw_hash_field_;
243
244inline bool IsUniqueName(Tagged<Name> obj);
245inline bool IsUniqueName(Tagged<Name> obj, PtrComprCageBase cage_base);
246
247// ES6 symbols.
248V8_OBJECT class Symbol : public Name {
249 public:
256
260
261 // [is_private]: Whether this is a private symbol. Private symbols can only
262 // be used to designate own properties of objects.
263 inline bool is_private() const;
264 inline void set_is_private(bool value);
265
266 // [is_well_known_symbol]: Whether this is a spec-defined well-known symbol,
267 // or not. Well-known symbols do not throw when an access check fails during
268 // a load.
269 inline bool is_well_known_symbol() const;
270 inline void set_is_well_known_symbol(bool value);
271
272 // [is_interesting_symbol]: Whether this is an "interesting symbol", which
273 // is a well-known symbol like @@toStringTag that's often looked up on
274 // random objects but is usually not present. See Name::IsInterestingSymbol()
275 // for a detailed description.
276 inline bool is_interesting_symbol() const;
277 inline void set_is_interesting_symbol(bool value);
278
279 // [is_in_public_symbol_table]: Whether this is a symbol created by
280 // Symbol.for. Calling Symbol.keyFor on such a symbol simply needs
281 // to return the attached name.
282 inline bool is_in_public_symbol_table() const;
283 inline void set_is_in_public_symbol_table(bool value);
284
285 // [is_private_name]: Whether this is a private name. Private names
286 // are the same as private symbols except they throw on missing
287 // property access.
288 //
289 // This also sets the is_private bit.
290 inline bool is_private_name() const;
291 inline void set_is_private_name();
292
293 // [is_private_name]: Whether this is a brand symbol. Brand symbols are
294 // private name symbols that are used for validating access to
295 // private methods and storing information about the private methods.
296 //
297 // This also sets the is_private bit.
298 inline bool is_private_brand() const;
299 inline void set_is_private_brand();
300
301 // Dispatched behavior.
304
305 void SymbolShortPrint(std::ostream& os);
306
307 private:
308 friend class Factory;
309 friend struct ObjectTraits<Symbol>;
310 friend struct OffsetsForDebug;
311 friend class V8HeapExplorer;
312 friend class CodeStubAssembler;
315
316 // TODO(cbruni): remove once the new maptracer is in place.
317 friend class Name; // For PrivateSymbolToName.
318
319 uint32_t flags() const { return flags_; }
320 void set_flags(uint32_t value) { flags_ = value; }
321
322 const char* PrivateSymbolToName() const;
323
324 uint32_t flags_;
325 // String|Undefined
326 // TODO(leszeks): Introduce a union type for this.
329
330template <>
332 using BodyDescriptor = FixedBodyDescriptor<offsetof(Symbol, description_),
333 sizeof(Symbol), sizeof(Symbol)>;
334};
335
336} // namespace internal
337} // namespace v8
338
340
341#endif // V8_OBJECTS_NAME_H_
#define one
static constexpr U encode(T value)
Definition bit-field.h:55
static constexpr int kSize
Definition bit-field.h:40
static constexpr U kMask
Definition bit-field.h:41
static constexpr int kShift
Definition bit-field.h:39
bool HasForwardingIndex(AcquireLoadTag) const
Definition name-inl.h:157
static const uint32_t kMaxArrayIndex
Definition name.h:152
std::atomic_uint32_t raw_hash_field_
Definition name.h:241
static const int kMaxCachedArrayIndexLength
Definition name.h:150
void set_raw_hash_field(uint32_t hash, ReleaseStoreTag)
Definition name.h:59
static bool IsIntegerIndex(uint32_t raw_hash_field)
Definition name-inl.h:106
bool IsInteresting(Isolate *isolate)
Definition name-inl.h:250
static bool IsForwardingIndex(uint32_t raw_hash_field)
Definition name-inl.h:112
friend class TorqueGeneratedNameAsserts
Definition name.h:237
static const int kArrayIndexLengthBits
Definition name.h:170
uint32_t EnsureHash()
Definition name-inl.h:208
static V8_WARN_UNUSED_RESULT MaybeDirectHandle< String > ToFunctionName(Isolate *isolate, DirectHandle< Name > name)
Definition objects.cc:4049
static bool IsHash(uint32_t raw_hash_field)
Definition name-inl.h:101
static uint32_t CreateHashFieldValue(uint32_t hash, HashFieldType type)
Definition name-inl.h:132
bool TryGetHash(uint32_t *hash) const
Definition name-inl.h:237
static bool ContainsCachedArrayIndex(uint32_t hash)
Definition name-inl.h:290
void set_raw_hash_field_if_empty(uint32_t hash)
Definition name-inl.h:214
static const int kMaxArrayIndexSize
Definition name.h:155
static constexpr int kEmptyHashField
Definition name.h:133
bool Equals(Tagged< Name > other)
Definition name-inl.h:76
uint32_t raw_hash_field() const
Definition name.h:47
static constexpr int kHashNotComputedMask
Definition name.h:131
static const unsigned int kDoesNotContainCachedArrayIndexMask
Definition name.h:190
bool IsPrivateBrand()
Definition name-inl.h:269
friend class SandboxTesting
Definition name.h:232
uint32_t raw_hash_field(AcquireLoadTag) const
Definition name.h:51
bool HasHashCode() const
Definition name-inl.h:153
static uint32_t CreateExternalForwardingIndex(uint32_t index)
Definition name-inl.h:146
static const unsigned int kDoesNotContainIntegerOrForwardingIndexMask
Definition name.h:197
bool HasExternalForwardingIndex(AcquireLoadTag) const
Definition name-inl.h:163
static uint32_t CreateInternalizedForwardingIndex(uint32_t index)
Definition name-inl.h:138
uint32_t EnsureRawHash()
Definition name-inl.h:175
uint32_t RawHash()
Definition name-inl.h:200
bool AsArrayIndex(uint32_t *index)
Definition name-inl.h:281
void set_raw_hash_field(uint32_t hash)
Definition name.h:55
static bool IsInternalizedForwardingIndex(uint32_t raw_hash_field)
Definition name-inl.h:118
static const int kArrayIndexValueBits
Definition name.h:169
bool AsIntegerIndex(size_t *index)
Definition name-inl.h:285
static bool IsExternalForwardingIndex(uint32_t raw_hash_field)
Definition name-inl.h:125
static const int kMaxIntegerIndexSize
Definition name.h:163
uint32_t GetRawHashFromForwardingTable(uint32_t raw_hash) const
Definition name-inl.h:167
uint32_t hash() const
Definition name-inl.h:228
bool HasInternalizedForwardingIndex(AcquireLoadTag) const
Definition name-inl.h:160
static bool IsHashFieldComputed(uint32_t raw_hash_field)
Definition name-inl.h:96
void set_is_private(bool value)
friend class TorqueGeneratedSymbolAsserts
Definition name.h:314
TaggedMember< PrimitiveHeapObject > description_
Definition name.h:327
uint32_t flags() const
Definition name.h:319
friend struct OffsetsForDebug
Definition name.h:310
void set_is_private_name()
Definition name-inl.h:60
bool is_private() const
uint32_t flags_
Definition name.h:324
bool is_interesting_symbol() const
void set_description(Tagged< PrimitiveHeapObject > value, WriteBarrierMode mode=UPDATE_WRITE_BARRIER)
Definition name-inl.h:28
void set_flags(uint32_t value)
Definition name.h:320
void set_is_in_public_symbol_table(bool value)
Tagged< PrimitiveHeapObject > description() const
Definition name-inl.h:25
void set_is_well_known_symbol(bool value)
void set_is_interesting_symbol(bool value)
bool is_private_name() const
Definition name-inl.h:54
void SymbolShortPrint(std::ostream &os)
bool is_in_public_symbol_table() const
const char * PrivateSymbolToName() const
Definition objects.cc:4984
bool is_well_known_symbol() const
bool is_private_brand() const
constexpr bool IsPowerOfTwo(T value)
Definition bits.h:187
@ UPDATE_WRITE_BARRIER
Definition objects.h:55
v8::internal::LoadHandler V8_OBJECT_END
constexpr int kBitsPerInt
Definition globals.h:687
constexpr uint64_t TenToThe(uint32_t exponent)
Definition utils.h:544
bool IsUniqueName(Tagged< Name > obj)
return value
Definition map-inl.h:893
constexpr uint32_t kMaxUInt32
Definition globals.h:387
#define DECL_VERIFIER(Name)
#define V8_OBJECT
#define DECL_PRINTER(Name)
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:671