• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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