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.
5 #ifndef V8_TRANSITIONS_INL_H_
6 #define V8_TRANSITIONS_INL_H_
8 #include "src/transitions.h"
14 TransitionArray* TransitionArray::cast(Object* object) {
15 DCHECK(object->IsTransitionArray());
16 return reinterpret_cast<TransitionArray*>(object);
20 bool TransitionArray::HasPrototypeTransitions() {
21 return get(kPrototypeTransitionsIndex) != Smi::FromInt(0);
25 FixedArray* TransitionArray::GetPrototypeTransitions() {
26 DCHECK(HasPrototypeTransitions()); // Callers must check first.
27 Object* prototype_transitions = get(kPrototypeTransitionsIndex);
28 return FixedArray::cast(prototype_transitions);
32 void TransitionArray::SetPrototypeTransitions(FixedArray* transitions,
33 WriteBarrierMode mode) {
34 DCHECK(transitions->IsFixedArray());
35 set(kPrototypeTransitionsIndex, transitions, mode);
39 Object** TransitionArray::GetPrototypeTransitionsSlot() {
40 return RawFieldOfElementAt(kPrototypeTransitionsIndex);
44 Object** TransitionArray::GetKeySlot(int transition_number) {
45 DCHECK(transition_number < number_of_transitions());
46 return RawFieldOfElementAt(ToKeyIndex(transition_number));
50 Object** TransitionArray::GetTargetSlot(int transition_number) {
51 DCHECK(transition_number < number_of_transitions());
52 return RawFieldOfElementAt(ToTargetIndex(transition_number));
56 Name* TransitionArray::GetKey(int transition_number) {
57 DCHECK(transition_number < number_of_transitions());
58 return Name::cast(get(ToKeyIndex(transition_number)));
62 Name* TransitionArray::GetKey(Object* raw_transitions, int transition_number) {
63 if (IsSimpleTransition(raw_transitions)) {
64 DCHECK(transition_number == 0);
65 return GetSimpleTransitionKey(GetSimpleTransition(raw_transitions));
67 DCHECK(IsFullTransitionArray(raw_transitions));
68 return TransitionArray::cast(raw_transitions)->GetKey(transition_number);
72 void TransitionArray::SetKey(int transition_number, Name* key) {
73 DCHECK(transition_number < number_of_transitions());
74 set(ToKeyIndex(transition_number), key);
78 Map* TransitionArray::GetTarget(int transition_number) {
79 DCHECK(transition_number < number_of_transitions());
80 WeakCell* cell = GetTargetCell(transition_number);
81 return Map::cast(cell->value());
85 Map* TransitionArray::GetTarget(Object* raw_transitions,
86 int transition_number) {
87 if (IsSimpleTransition(raw_transitions)) {
88 DCHECK(transition_number == 0);
89 return GetSimpleTransition(raw_transitions);
91 DCHECK(IsFullTransitionArray(raw_transitions));
92 return TransitionArray::cast(raw_transitions)->GetTarget(transition_number);
96 WeakCell* TransitionArray::GetTargetCell(int transition_number) {
97 DCHECK(transition_number < number_of_transitions());
98 return WeakCell::cast(get(ToTargetIndex(transition_number)));
102 void TransitionArray::SetTargetCell(int transition_number, WeakCell* value) {
103 DCHECK(transition_number < number_of_transitions());
104 set(ToTargetIndex(transition_number), value);
108 int TransitionArray::SearchName(Name* name, int* out_insertion_index) {
109 return internal::Search<ALL_ENTRIES>(this, name, 0, out_insertion_index);
114 bool TransitionArray::IsSpecialTransition(Name* name) {
115 if (!name->IsSymbol()) return false;
116 Heap* heap = name->GetHeap();
117 return name == heap->nonextensible_symbol() ||
118 name == heap->sealed_symbol() || name == heap->frozen_symbol() ||
119 name == heap->elements_transition_symbol() ||
120 name == heap->observed_symbol();
125 int TransitionArray::CompareKeys(Name* key1, uint32_t hash1, PropertyKind kind1,
126 PropertyAttributes attributes1, Name* key2,
127 uint32_t hash2, PropertyKind kind2,
128 PropertyAttributes attributes2) {
129 int cmp = CompareNames(key1, hash1, key2, hash2);
130 if (cmp != 0) return cmp;
132 return CompareDetails(kind1, attributes1, kind2, attributes2);
136 int TransitionArray::CompareNames(Name* key1, uint32_t hash1, Name* key2,
139 // In case of hash collisions key1 is always "less" than key2.
140 return hash1 <= hash2 ? -1 : 1;
147 int TransitionArray::CompareDetails(PropertyKind kind1,
148 PropertyAttributes attributes1,
150 PropertyAttributes attributes2) {
151 if (kind1 != kind2) {
152 return static_cast<int>(kind1) < static_cast<int>(kind2) ? -1 : 1;
155 if (attributes1 != attributes2) {
156 return static_cast<int>(attributes1) < static_cast<int>(attributes2) ? -1
164 PropertyDetails TransitionArray::GetTargetDetails(Name* name, Map* target) {
165 DCHECK(!IsSpecialTransition(name));
166 int descriptor = target->LastAdded();
167 DescriptorArray* descriptors = target->instance_descriptors();
168 // Transitions are allowed only for the last added property.
169 DCHECK(descriptors->GetKey(descriptor)->Equals(name));
170 return descriptors->GetDetails(descriptor);
174 void TransitionArray::Set(int transition_number, Name* key, WeakCell* target) {
175 set(ToKeyIndex(transition_number), key);
176 set(ToTargetIndex(transition_number), target);
180 void TransitionArray::SetNumberOfTransitions(int number_of_transitions) {
181 DCHECK(number_of_transitions <= Capacity(this));
182 set(kTransitionLengthIndex, Smi::FromInt(number_of_transitions));
185 } } // namespace v8::internal
187 #endif // V8_TRANSITIONS_INL_H_