blob: 96d9495bf404cecb30760e01551bbd22a1fd7277 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
10namespace v8 {
11namespace internal {
12
13
Ben Murdochb8a8cc12014-11-26 15:28:44 +000014TransitionArray* TransitionArray::cast(Object* object) {
15 DCHECK(object->IsTransitionArray());
16 return reinterpret_cast<TransitionArray*>(object);
17}
18
19
Ben Murdoch014dc512016-03-22 12:00:34 +000020Object* TransitionArray::next_link() { return get(kNextLinkIndex); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000021
22
Ben Murdoch014dc512016-03-22 12:00:34 +000023void TransitionArray::set_next_link(Object* next, WriteBarrierMode mode) {
24 return set(kNextLinkIndex, next, mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000025}
26
27
28bool TransitionArray::HasPrototypeTransitions() {
Ben Murdoch014dc512016-03-22 12:00:34 +000029 return get(kPrototypeTransitionsIndex) != Smi::FromInt(0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030}
31
32
33FixedArray* TransitionArray::GetPrototypeTransitions() {
Ben Murdoch014dc512016-03-22 12:00:34 +000034 DCHECK(HasPrototypeTransitions()); // Callers must check first.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000035 Object* prototype_transitions = get(kPrototypeTransitionsIndex);
36 return FixedArray::cast(prototype_transitions);
37}
38
39
Ben Murdoch014dc512016-03-22 12:00:34 +000040void TransitionArray::SetPrototypeTransitions(FixedArray* transitions) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000041 DCHECK(transitions->IsFixedArray());
Ben Murdoch014dc512016-03-22 12:00:34 +000042 set(kPrototypeTransitionsIndex, transitions);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000043}
44
45
46Object** TransitionArray::GetPrototypeTransitionsSlot() {
Ben Murdoch014dc512016-03-22 12:00:34 +000047 return RawFieldOfElementAt(kPrototypeTransitionsIndex);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000048}
49
50
51Object** TransitionArray::GetKeySlot(int transition_number) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000052 DCHECK(transition_number < number_of_transitions());
53 return RawFieldOfElementAt(ToKeyIndex(transition_number));
54}
55
56
57Name* TransitionArray::GetKey(int transition_number) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058 DCHECK(transition_number < number_of_transitions());
59 return Name::cast(get(ToKeyIndex(transition_number)));
60}
61
62
Ben Murdoch014dc512016-03-22 12:00:34 +000063Name* TransitionArray::GetKey(Object* raw_transitions, int transition_number) {
64 if (IsSimpleTransition(raw_transitions)) {
65 DCHECK(transition_number == 0);
66 return GetSimpleTransitionKey(GetSimpleTransition(raw_transitions));
67 }
68 DCHECK(IsFullTransitionArray(raw_transitions));
69 return TransitionArray::cast(raw_transitions)->GetKey(transition_number);
70}
71
72
Ben Murdochb8a8cc12014-11-26 15:28:44 +000073void TransitionArray::SetKey(int transition_number, Name* key) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000074 DCHECK(transition_number < number_of_transitions());
75 set(ToKeyIndex(transition_number), key);
76}
77
78
79Map* TransitionArray::GetTarget(int transition_number) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000080 DCHECK(transition_number < number_of_transitions());
81 return Map::cast(get(ToTargetIndex(transition_number)));
82}
83
84
Ben Murdoch014dc512016-03-22 12:00:34 +000085Map* TransitionArray::GetTarget(Object* raw_transitions,
86 int transition_number) {
87 if (IsSimpleTransition(raw_transitions)) {
88 DCHECK(transition_number == 0);
89 return GetSimpleTransition(raw_transitions);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000090 }
Ben Murdoch014dc512016-03-22 12:00:34 +000091 DCHECK(IsFullTransitionArray(raw_transitions));
92 return TransitionArray::cast(raw_transitions)->GetTarget(transition_number);
93}
94
95
96void TransitionArray::SetTarget(int transition_number, Map* value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000097 DCHECK(transition_number < number_of_transitions());
98 set(ToTargetIndex(transition_number), value);
99}
100
101
Emily Bernier958fae72015-03-24 16:35:39 -0400102int TransitionArray::SearchName(Name* name, int* out_insertion_index) {
Emily Bernier958fae72015-03-24 16:35:39 -0400103 return internal::Search<ALL_ENTRIES>(this, name, 0, out_insertion_index);
104}
105
106
107#ifdef DEBUG
108bool TransitionArray::IsSpecialTransition(Name* name) {
109 if (!name->IsSymbol()) return false;
110 Heap* heap = name->GetHeap();
111 return name == heap->nonextensible_symbol() ||
112 name == heap->sealed_symbol() || name == heap->frozen_symbol() ||
113 name == heap->elements_transition_symbol() ||
Ben Murdoch014dc512016-03-22 12:00:34 +0000114 name == heap->strict_function_transition_symbol() ||
115 name == heap->strong_function_transition_symbol() ||
Emily Bernier958fae72015-03-24 16:35:39 -0400116 name == heap->observed_symbol();
117}
118#endif
119
120
121int TransitionArray::CompareKeys(Name* key1, uint32_t hash1, PropertyKind kind1,
122 PropertyAttributes attributes1, Name* key2,
123 uint32_t hash2, PropertyKind kind2,
124 PropertyAttributes attributes2) {
125 int cmp = CompareNames(key1, hash1, key2, hash2);
126 if (cmp != 0) return cmp;
127
128 return CompareDetails(kind1, attributes1, kind2, attributes2);
129}
130
131
132int TransitionArray::CompareNames(Name* key1, uint32_t hash1, Name* key2,
133 uint32_t hash2) {
134 if (key1 != key2) {
135 // In case of hash collisions key1 is always "less" than key2.
136 return hash1 <= hash2 ? -1 : 1;
137 }
138
139 return 0;
140}
141
142
143int TransitionArray::CompareDetails(PropertyKind kind1,
144 PropertyAttributes attributes1,
145 PropertyKind kind2,
146 PropertyAttributes attributes2) {
147 if (kind1 != kind2) {
148 return static_cast<int>(kind1) < static_cast<int>(kind2) ? -1 : 1;
149 }
150
151 if (attributes1 != attributes2) {
152 return static_cast<int>(attributes1) < static_cast<int>(attributes2) ? -1
153 : 1;
154 }
155
156 return 0;
157}
158
159
160PropertyDetails TransitionArray::GetTargetDetails(Name* name, Map* target) {
161 DCHECK(!IsSpecialTransition(name));
162 int descriptor = target->LastAdded();
163 DescriptorArray* descriptors = target->instance_descriptors();
164 // Transitions are allowed only for the last added property.
165 DCHECK(descriptors->GetKey(descriptor)->Equals(name));
166 return descriptors->GetDetails(descriptor);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000167}
168
169
Ben Murdoch014dc512016-03-22 12:00:34 +0000170void TransitionArray::Set(int transition_number, Name* key, Map* target) {
171 set(ToKeyIndex(transition_number), key);
172 set(ToTargetIndex(transition_number), target);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000173}
174
175
Emily Bernier958fae72015-03-24 16:35:39 -0400176void TransitionArray::SetNumberOfTransitions(int number_of_transitions) {
Ben Murdoch014dc512016-03-22 12:00:34 +0000177 DCHECK(number_of_transitions <= Capacity(this));
178 set(kTransitionLengthIndex, Smi::FromInt(number_of_transitions));
Emily Bernier958fae72015-03-24 16:35:39 -0400179}
180
Ben Murdoch014dc512016-03-22 12:00:34 +0000181} // namespace internal
182} // namespace v8
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000183
184#endif // V8_TRANSITIONS_INL_H_