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 Name* TransitionArray::GetKey(int transition_number) {
51 DCHECK(transition_number < number_of_transitions());
52 return Name::cast(get(ToKeyIndex(transition_number)));
56 Name* TransitionArray::GetKey(Object* raw_transitions, int transition_number) {
57 if (IsSimpleTransition(raw_transitions)) {
58 DCHECK(transition_number == 0);
59 return GetSimpleTransitionKey(GetSimpleTransition(raw_transitions));
61 DCHECK(IsFullTransitionArray(raw_transitions));
62 return TransitionArray::cast(raw_transitions)->GetKey(transition_number);
66 void TransitionArray::SetKey(int transition_number, Name* key) {
67 DCHECK(transition_number < number_of_transitions());
68 set(ToKeyIndex(transition_number), key);
72 Map* TransitionArray::GetTarget(int transition_number) {
73 DCHECK(transition_number < number_of_transitions());
74 return Map::cast(get(ToTargetIndex(transition_number)));
78 Map* TransitionArray::GetTarget(Object* raw_transitions,
79 int transition_number) {
80 if (IsSimpleTransition(raw_transitions)) {
81 DCHECK(transition_number == 0);
82 return GetSimpleTransition(raw_transitions);
84 DCHECK(IsFullTransitionArray(raw_transitions));
85 return TransitionArray::cast(raw_transitions)->GetTarget(transition_number);
89 void TransitionArray::SetTarget(int transition_number, Map* value) {
90 DCHECK(transition_number < number_of_transitions());
91 set(ToTargetIndex(transition_number), value);
95 int TransitionArray::SearchName(Name* name, int* out_insertion_index) {
96 return internal::Search<ALL_ENTRIES>(this, name, 0, out_insertion_index);
101 bool TransitionArray::IsSpecialTransition(Name* name) {
102 if (!name->IsSymbol()) return false;
103 Heap* heap = name->GetHeap();
104 return name == heap->nonextensible_symbol() ||
105 name == heap->sealed_symbol() || name == heap->frozen_symbol() ||
106 name == heap->elements_transition_symbol() ||
107 name == heap->observed_symbol();
112 int TransitionArray::CompareKeys(Name* key1, uint32_t hash1, PropertyKind kind1,
113 PropertyAttributes attributes1, Name* key2,
114 uint32_t hash2, PropertyKind kind2,
115 PropertyAttributes attributes2) {
116 int cmp = CompareNames(key1, hash1, key2, hash2);
117 if (cmp != 0) return cmp;
119 return CompareDetails(kind1, attributes1, kind2, attributes2);
123 int TransitionArray::CompareNames(Name* key1, uint32_t hash1, Name* key2,
126 // In case of hash collisions key1 is always "less" than key2.
127 return hash1 <= hash2 ? -1 : 1;
134 int TransitionArray::CompareDetails(PropertyKind kind1,
135 PropertyAttributes attributes1,
137 PropertyAttributes attributes2) {
138 if (kind1 != kind2) {
139 return static_cast<int>(kind1) < static_cast<int>(kind2) ? -1 : 1;
142 if (attributes1 != attributes2) {
143 return static_cast<int>(attributes1) < static_cast<int>(attributes2) ? -1
151 PropertyDetails TransitionArray::GetTargetDetails(Name* name, Map* target) {
152 DCHECK(!IsSpecialTransition(name));
153 int descriptor = target->LastAdded();
154 DescriptorArray* descriptors = target->instance_descriptors();
155 // Transitions are allowed only for the last added property.
156 DCHECK(descriptors->GetKey(descriptor)->Equals(name));
157 return descriptors->GetDetails(descriptor);
161 void TransitionArray::NoIncrementalWriteBarrierSet(int transition_number,
164 FixedArray::NoIncrementalWriteBarrierSet(
165 this, ToKeyIndex(transition_number), key);
166 FixedArray::NoIncrementalWriteBarrierSet(
167 this, ToTargetIndex(transition_number), target);
171 void TransitionArray::SetNumberOfTransitions(int number_of_transitions) {
172 DCHECK(number_of_transitions <= Capacity(this));
173 set(kTransitionLengthIndex, Smi::FromInt(number_of_transitions));
176 } } // namespace v8::internal
178 #endif // V8_TRANSITIONS_INL_H_