V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
transitions-inl.h
1 // Copyright 2012 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_TRANSITIONS_INL_H_
6 #define V8_TRANSITIONS_INL_H_
7 
8 #include "src/transitions.h"
9 
10 #include "src/ic/handler-configuration-inl.h"
11 #include "src/objects/fixed-array-inl.h"
12 #include "src/objects/maybe-object-inl.h"
13 #include "src/objects/slots.h"
14 #include "src/objects/smi.h"
15 
16 // Has to be the last include (doesn't have include guards):
17 #include "src/objects/object-macros.h"
18 
19 namespace v8 {
20 namespace internal {
21 
22 TransitionArray* TransitionsAccessor::transitions() {
23  DCHECK_EQ(kFullTransitionArray, encoding());
24  return TransitionArray::cast(raw_transitions_->GetHeapObjectAssumeStrong());
25 }
26 
27 CAST_ACCESSOR(TransitionArray)
28 
29 bool TransitionArray::HasPrototypeTransitions() {
30  return Get(kPrototypeTransitionsIndex) != MaybeObject::FromSmi(Smi::zero());
31 }
32 
33 WeakFixedArray* TransitionArray::GetPrototypeTransitions() {
34  DCHECK(HasPrototypeTransitions()); // Callers must check first.
35  Object* prototype_transitions =
36  Get(kPrototypeTransitionsIndex)->GetHeapObjectAssumeStrong();
37  return WeakFixedArray::cast(prototype_transitions);
38 }
39 
40 HeapObjectSlot TransitionArray::GetKeySlot(int transition_number) {
41  DCHECK(transition_number < number_of_transitions());
42  return HeapObjectSlot(RawFieldOfElementAt(ToKeyIndex(transition_number)));
43 }
44 
45 void TransitionArray::SetPrototypeTransitions(WeakFixedArray* transitions) {
46  DCHECK(transitions->IsWeakFixedArray());
47  WeakFixedArray::Set(kPrototypeTransitionsIndex,
48  HeapObjectReference::Strong(transitions));
49 }
50 
51 int TransitionArray::NumberOfPrototypeTransitions(
52  WeakFixedArray* proto_transitions) {
53  if (proto_transitions->length() == 0) return 0;
54  MaybeObject raw =
55  proto_transitions->Get(kProtoTransitionNumberOfEntriesOffset);
56  return raw.ToSmi().value();
57 }
58 
59 Name TransitionArray::GetKey(int transition_number) {
60  DCHECK(transition_number < number_of_transitions());
61  return Name::cast(
62  Get(ToKeyIndex(transition_number))->GetHeapObjectAssumeStrong());
63 }
64 
65 Name TransitionsAccessor::GetKey(int transition_number) {
66  switch (encoding()) {
67  case kPrototypeInfo:
68  case kUninitialized:
69  case kMigrationTarget:
70  UNREACHABLE();
71  return Name();
72  case kWeakRef: {
73  Map map = Map::cast(raw_transitions_->GetHeapObjectAssumeWeak());
74  return GetSimpleTransitionKey(map);
75  }
76  case kFullTransitionArray:
77  return transitions()->GetKey(transition_number);
78  }
79  UNREACHABLE();
80 }
81 
82 void TransitionArray::SetKey(int transition_number, Name key) {
83  DCHECK(transition_number < number_of_transitions());
84  WeakFixedArray::Set(ToKeyIndex(transition_number),
85  HeapObjectReference::Strong(key));
86 }
87 
88 HeapObjectSlot TransitionArray::GetTargetSlot(int transition_number) {
89  DCHECK(transition_number < number_of_transitions());
90  return HeapObjectSlot(RawFieldOfElementAt(ToTargetIndex(transition_number)));
91 }
92 
93 // static
94 PropertyDetails TransitionsAccessor::GetTargetDetails(Name name, Map target) {
95  DCHECK(!IsSpecialTransition(name->GetReadOnlyRoots(), name));
96  int descriptor = target->LastAdded();
97  DescriptorArray* descriptors = target->instance_descriptors();
98  // Transitions are allowed only for the last added property.
99  DCHECK(descriptors->GetKey(descriptor)->Equals(name));
100  return descriptors->GetDetails(descriptor);
101 }
102 
103 // static
104 PropertyDetails TransitionsAccessor::GetSimpleTargetDetails(Map transition) {
105  return transition->GetLastDescriptorDetails();
106 }
107 
108 // static
109 Name TransitionsAccessor::GetSimpleTransitionKey(Map transition) {
110  int descriptor = transition->LastAdded();
111  return transition->instance_descriptors()->GetKey(descriptor);
112 }
113 
114 // static
115 Map TransitionsAccessor::GetTargetFromRaw(MaybeObject raw) {
116  return Map::cast(raw->GetHeapObjectAssumeWeak());
117 }
118 
119 MaybeObject TransitionArray::GetRawTarget(int transition_number) {
120  DCHECK(transition_number < number_of_transitions());
121  return Get(ToTargetIndex(transition_number));
122 }
123 
124 Map TransitionArray::GetTarget(int transition_number) {
125  MaybeObject raw = GetRawTarget(transition_number);
126  return TransitionsAccessor::GetTargetFromRaw(raw);
127 }
128 
129 Map TransitionsAccessor::GetTarget(int transition_number) {
130  switch (encoding()) {
131  case kPrototypeInfo:
132  case kUninitialized:
133  case kMigrationTarget:
134  UNREACHABLE();
135  return Map();
136  case kWeakRef:
137  return Map::cast(raw_transitions_->GetHeapObjectAssumeWeak());
138  case kFullTransitionArray:
139  return transitions()->GetTarget(transition_number);
140  }
141  UNREACHABLE();
142 }
143 
144 void TransitionArray::SetRawTarget(int transition_number, MaybeObject value) {
145  DCHECK(transition_number < number_of_transitions());
146  DCHECK(value->IsWeak());
147  DCHECK(value->GetHeapObjectAssumeWeak()->IsMap());
148  WeakFixedArray::Set(ToTargetIndex(transition_number), value);
149 }
150 
151 bool TransitionArray::GetTargetIfExists(int transition_number, Isolate* isolate,
152  Map* target) {
153  MaybeObject raw = GetRawTarget(transition_number);
154  HeapObject* heap_object;
155  if (raw->GetHeapObjectIfStrong(&heap_object) &&
156  heap_object->IsUndefined(isolate)) {
157  return false;
158  }
159  *target = TransitionsAccessor::GetTargetFromRaw(raw);
160  return true;
161 }
162 
163 int TransitionArray::SearchNameForTesting(Name name, int* out_insertion_index) {
164  return SearchName(name, out_insertion_index);
165 }
166 
167 int TransitionArray::SearchSpecial(Symbol symbol, int* out_insertion_index) {
168  return SearchName(symbol, out_insertion_index);
169 }
170 
171 int TransitionArray::SearchName(Name name, int* out_insertion_index) {
172  DCHECK(name->IsUniqueName());
173  return internal::Search<ALL_ENTRIES>(this, name, number_of_entries(),
174  out_insertion_index);
175 }
176 
177 int TransitionArray::number_of_transitions() const {
178  if (length() < kFirstIndex) return 0;
179  return Get(kTransitionLengthIndex).ToSmi().value();
180 }
181 
182 int TransitionArray::CompareKeys(Name key1, uint32_t hash1, PropertyKind kind1,
183  PropertyAttributes attributes1, Name key2,
184  uint32_t hash2, PropertyKind kind2,
185  PropertyAttributes attributes2) {
186  int cmp = CompareNames(key1, hash1, key2, hash2);
187  if (cmp != 0) return cmp;
188 
189  return CompareDetails(kind1, attributes1, kind2, attributes2);
190 }
191 
192 int TransitionArray::CompareNames(Name key1, uint32_t hash1, Name key2,
193  uint32_t hash2) {
194  if (key1 != key2) {
195  // In case of hash collisions key1 is always "less" than key2.
196  return hash1 <= hash2 ? -1 : 1;
197  }
198 
199  return 0;
200 }
201 
202 int TransitionArray::CompareDetails(PropertyKind kind1,
203  PropertyAttributes attributes1,
204  PropertyKind kind2,
205  PropertyAttributes attributes2) {
206  if (kind1 != kind2) {
207  return static_cast<int>(kind1) < static_cast<int>(kind2) ? -1 : 1;
208  }
209 
210  if (attributes1 != attributes2) {
211  return static_cast<int>(attributes1) < static_cast<int>(attributes2) ? -1
212  : 1;
213  }
214 
215  return 0;
216 }
217 
218 void TransitionArray::Set(int transition_number, Name key, MaybeObject target) {
219  WeakFixedArray::Set(ToKeyIndex(transition_number),
220  MaybeObject::FromObject(key));
221  WeakFixedArray::Set(ToTargetIndex(transition_number), target);
222 }
223 
224 Name TransitionArray::GetSortedKey(int transition_number) {
225  return GetKey(transition_number);
226 }
227 
228 int TransitionArray::number_of_entries() const {
229  return number_of_transitions();
230 }
231 
232 int TransitionArray::Capacity() {
233  if (length() <= kFirstIndex) return 0;
234  return (length() - kFirstIndex) / kEntrySize;
235 }
236 
237 void TransitionArray::SetNumberOfTransitions(int number_of_transitions) {
238  DCHECK(number_of_transitions <= Capacity());
239  WeakFixedArray::Set(
240  kTransitionLengthIndex,
241  MaybeObject::FromSmi(Smi::FromInt(number_of_transitions)));
242 }
243 
244 } // namespace internal
245 } // namespace v8
246 
247 #include "src/objects/object-macros-undef.h"
248 
249 #endif // V8_TRANSITIONS_INL_H_
Definition: libplatform.h:13