descriptor-array-inl.h 9.53 KB
Newer Older
1 2 3 4 5 6 7 8 9
// Copyright 2018 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_DESCRIPTOR_ARRAY_INL_H_
#define V8_OBJECTS_DESCRIPTOR_ARRAY_INL_H_

#include "src/objects/descriptor-array.h"

10
#include "src/execution/isolate.h"
11
#include "src/handles/maybe-handles-inl.h"
12 13
#include "src/heap/heap-write-barrier.h"
#include "src/heap/heap.h"
14
#include "src/objects/field-type.h"
15
#include "src/objects/heap-object-inl.h"
16
#include "src/objects/lookup-cache-inl.h"
17
#include "src/objects/maybe-object-inl.h"
18
#include "src/objects/property.h"
19
#include "src/objects/struct-inl.h"
20 21 22 23 24 25 26

// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"

namespace v8 {
namespace internal {

27 28
#include "torque-generated/src/objects/descriptor-array-tq-inl.inc"

29
TQ_OBJECT_CONSTRUCTORS_IMPL(DescriptorArray)
30
TQ_OBJECT_CONSTRUCTORS_IMPL(EnumCache)
31 32 33 34 35

RELAXED_INT16_ACCESSORS(DescriptorArray, number_of_all_descriptors,
                        kNumberOfAllDescriptorsOffset)
RELAXED_INT16_ACCESSORS(DescriptorArray, number_of_descriptors,
                        kNumberOfDescriptorsOffset)
36 37
RELAXED_INT16_ACCESSORS(DescriptorArray, raw_number_of_marked_descriptors,
                        kRawNumberOfMarkedDescriptorsOffset)
38 39 40 41 42 43 44 45 46 47
RELAXED_INT16_ACCESSORS(DescriptorArray, filler16bits, kFiller16BitsOffset)

inline int16_t DescriptorArray::number_of_slack_descriptors() const {
  return number_of_all_descriptors() - number_of_descriptors();
}

inline int DescriptorArray::number_of_entries() const {
  return number_of_descriptors();
}

48 49 50 51
inline int16_t DescriptorArray::CompareAndSwapRawNumberOfMarkedDescriptors(
    int16_t expected, int16_t value) {
  return base::Relaxed_CompareAndSwap(
      reinterpret_cast<base::Atomic16*>(
52
          FIELD_ADDR(*this, kRawNumberOfMarkedDescriptorsOffset)),
53 54 55
      expected, value);
}

56
void DescriptorArray::CopyEnumCacheFrom(DescriptorArray array) {
57
  set_enum_cache(array.enum_cache());
58 59
}

60 61
InternalIndex DescriptorArray::Search(Name name, int valid_descriptors,
                                      bool concurrent_search) {
62
  DCHECK(name.IsUniqueName());
63 64
  return InternalIndex(internal::Search<VALID_ENTRIES>(
      this, name, valid_descriptors, nullptr, concurrent_search));
65 66
}

67 68
InternalIndex DescriptorArray::Search(Name name, Map map,
                                      bool concurrent_search) {
69 70
  DCHECK(name.IsUniqueName());
  int number_of_own_descriptors = map.NumberOfOwnDescriptors();
71
  if (number_of_own_descriptors == 0) return InternalIndex::NotFound();
72
  return Search(name, number_of_own_descriptors, concurrent_search);
73 74
}

75 76
InternalIndex DescriptorArray::SearchWithCache(Isolate* isolate, Name name,
                                               Map map) {
77 78
  DCHECK(name.IsUniqueName());
  int number_of_own_descriptors = map.NumberOfOwnDescriptors();
79
  if (number_of_own_descriptors == 0) return InternalIndex::NotFound();
80 81 82 83 84

  DescriptorLookupCache* cache = isolate->descriptor_lookup_cache();
  int number = cache->Lookup(map, name);

  if (number == DescriptorLookupCache::kAbsent) {
85 86
    InternalIndex result = Search(name, number_of_own_descriptors);
    number = result.is_found() ? result.as_int() : DescriptorArray::kNotFound;
87 88
    cache->Update(map, name, number);
  }
89 90
  if (number == DescriptorArray::kNotFound) return InternalIndex::NotFound();
  return InternalIndex(number);
91 92 93
}

ObjectSlot DescriptorArray::GetFirstPointerSlot() {
94 95 96 97 98
  static_assert(kEndOfStrongFieldsOffset == kStartOfWeakFieldsOffset,
                "Weak and strong fields are continuous.");
  static_assert(kEndOfWeakFieldsOffset == kHeaderSize,
                "Weak fields extend up to the end of the header.");
  return RawField(DescriptorArray::kStartOfStrongFieldsOffset);
99 100 101 102 103 104 105 106 107
}

ObjectSlot DescriptorArray::GetDescriptorSlot(int descriptor) {
  // Allow descriptor == number_of_all_descriptors() for computing the slot
  // address that comes after the last descriptor (for iterating).
  DCHECK_LE(descriptor, number_of_all_descriptors());
  return RawField(OffsetOfDescriptorAt(descriptor));
}

108
Name DescriptorArray::GetKey(InternalIndex descriptor_number) const {
109
  IsolateRoot isolate = GetIsolateForPtrCompr(*this);
110 111 112
  return GetKey(isolate, descriptor_number);
}

113
Name DescriptorArray::GetKey(IsolateRoot isolate,
114 115 116
                             InternalIndex descriptor_number) const {
  DCHECK_LT(descriptor_number.as_int(), number_of_descriptors());
  int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int());
117
  return Name::cast(EntryKeyField::Relaxed_Load(isolate, *this, entry_offset));
118 119
}

120 121 122
void DescriptorArray::SetKey(InternalIndex descriptor_number, Name key) {
  DCHECK_LT(descriptor_number.as_int(), number_of_descriptors());
  int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int());
123 124
  EntryKeyField::Relaxed_Store(*this, entry_offset, key);
  WRITE_BARRIER(*this, entry_offset + kEntryKeyOffset, key);
125 126 127
}

int DescriptorArray::GetSortedKeyIndex(int descriptor_number) {
128
  return GetDetails(InternalIndex(descriptor_number)).pointer();
129 130 131
}

Name DescriptorArray::GetSortedKey(int descriptor_number) {
132
  IsolateRoot isolate = GetIsolateForPtrCompr(*this);
133 134 135
  return GetSortedKey(isolate, descriptor_number);
}

136
Name DescriptorArray::GetSortedKey(IsolateRoot isolate, int descriptor_number) {
137
  return GetKey(isolate, InternalIndex(GetSortedKeyIndex(descriptor_number)));
138 139
}

140
void DescriptorArray::SetSortedKey(int descriptor_number, int pointer) {
141 142
  PropertyDetails details = GetDetails(InternalIndex(descriptor_number));
  SetDetails(InternalIndex(descriptor_number), details.set_pointer(pointer));
143 144
}

145
Object DescriptorArray::GetStrongValue(InternalIndex descriptor_number) {
146
  IsolateRoot isolate = GetIsolateForPtrCompr(*this);
147 148 149
  return GetStrongValue(isolate, descriptor_number);
}

150
Object DescriptorArray::GetStrongValue(IsolateRoot isolate,
151
                                       InternalIndex descriptor_number) {
152
  return GetValue(isolate, descriptor_number).cast<Object>();
153 154
}

155 156 157 158
void DescriptorArray::SetValue(InternalIndex descriptor_number,
                               MaybeObject value) {
  DCHECK_LT(descriptor_number.as_int(), number_of_descriptors());
  int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int());
159 160
  EntryValueField::Relaxed_Store(*this, entry_offset, value);
  WEAK_WRITE_BARRIER(*this, entry_offset + kEntryValueOffset, value);
161 162
}

163
MaybeObject DescriptorArray::GetValue(InternalIndex descriptor_number) {
164
  IsolateRoot isolate = GetIsolateForPtrCompr(*this);
165 166 167
  return GetValue(isolate, descriptor_number);
}

168
MaybeObject DescriptorArray::GetValue(IsolateRoot isolate,
169 170 171
                                      InternalIndex descriptor_number) {
  DCHECK_LT(descriptor_number.as_int(), number_of_descriptors());
  int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int());
172
  return EntryValueField::Relaxed_Load(isolate, *this, entry_offset);
173 174
}

175 176 177
PropertyDetails DescriptorArray::GetDetails(InternalIndex descriptor_number) {
  DCHECK_LT(descriptor_number.as_int(), number_of_descriptors());
  int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int());
178 179 180 181
  Smi details = EntryDetailsField::Relaxed_Load(*this, entry_offset);
  return PropertyDetails(details);
}

182
void DescriptorArray::SetDetails(InternalIndex descriptor_number,
183
                                 PropertyDetails details) {
184 185
  DCHECK_LT(descriptor_number.as_int(), number_of_descriptors());
  int entry_offset = OffsetOfDescriptorAt(descriptor_number.as_int());
186
  EntryDetailsField::Relaxed_Store(*this, entry_offset, details.AsSmi());
187 188
}

189
int DescriptorArray::GetFieldIndex(InternalIndex descriptor_number) {
190 191 192 193
  DCHECK_EQ(GetDetails(descriptor_number).location(), kField);
  return GetDetails(descriptor_number).field_index();
}

194
FieldType DescriptorArray::GetFieldType(InternalIndex descriptor_number) {
195
  IsolateRoot isolate = GetIsolateForPtrCompr(*this);
196 197 198
  return GetFieldType(isolate, descriptor_number);
}

199
FieldType DescriptorArray::GetFieldType(IsolateRoot isolate,
200
                                        InternalIndex descriptor_number) {
201
  DCHECK_EQ(GetDetails(descriptor_number).location(), kField);
202
  MaybeObject wrapped_type = GetValue(isolate, descriptor_number);
203 204 205
  return Map::UnwrapFieldType(wrapped_type);
}

206 207
void DescriptorArray::Set(InternalIndex descriptor_number, Name key,
                          MaybeObject value, PropertyDetails details) {
208 209 210
  SetKey(descriptor_number, key);
  SetDetails(descriptor_number, details);
  SetValue(descriptor_number, value);
211 212
}

213
void DescriptorArray::Set(InternalIndex descriptor_number, Descriptor* desc) {
214 215 216 217 218 219
  Name key = *desc->GetKey();
  MaybeObject value = *desc->GetValue();
  Set(descriptor_number, key, value, desc->GetDetails());
}

void DescriptorArray::Append(Descriptor* desc) {
220
  DisallowGarbageCollection no_gc;
221 222 223
  int descriptor_number = number_of_descriptors();
  DCHECK_LE(descriptor_number + 1, number_of_all_descriptors());
  set_number_of_descriptors(descriptor_number + 1);
224
  Set(InternalIndex(descriptor_number), desc);
225

226
  uint32_t hash = desc->GetKey()->hash();
227 228 229 230 231

  int insertion;

  for (insertion = descriptor_number; insertion > 0; --insertion) {
    Name key = GetSortedKey(insertion - 1);
232
    if (key.hash() <= hash) break;
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
    SetSortedKey(insertion, GetSortedKeyIndex(insertion - 1));
  }

  SetSortedKey(insertion, descriptor_number);
}

void DescriptorArray::SwapSortedKeys(int first, int second) {
  int first_key = GetSortedKeyIndex(first);
  SetSortedKey(first, GetSortedKeyIndex(second));
  SetSortedKey(second, first_key);
}

}  // namespace internal
}  // namespace v8

#include "src/objects/object-macros-undef.h"

#endif  // V8_OBJECTS_DESCRIPTOR_ARRAY_INL_H_