blob: 828a673d7f8f9f7922cac5b24eb8490f90220de3 [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 Murdoch4a90d5f2016-03-22 12:00:34 +000020Object* TransitionArray::next_link() { return get(kNextLinkIndex); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000021
22
Ben Murdoch4a90d5f2016-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 Murdoch4a90d5f2016-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 Murdoch4a90d5f2016-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 Murdoch4a90d5f2016-03-22 12:00:34 +000040void TransitionArray::SetPrototypeTransitions(FixedArray* transitions) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000041 DCHECK(transitions->IsFixedArray());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000042 set(kPrototypeTransitionsIndex, transitions);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000043}
44
45
46Object** TransitionArray::GetPrototypeTransitionsSlot() {
Ben Murdoch4a90d5f2016-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 Murdoch4a90d5f2016-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 Murdoch4a90d5f2016-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 Murdoch4a90d5f2016-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 Bernierd0a1eb72015-03-24 16:35:39 -0400102int TransitionArray::SearchName(Name* name, int* out_insertion_index) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100103 DCHECK(name->IsUniqueName());
104 return internal::Search<ALL_ENTRIES>(this, name, number_of_entries(),
105 out_insertion_index);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400106}
107
108
109#ifdef DEBUG
110bool TransitionArray::IsSpecialTransition(Name* name) {
111 if (!name->IsSymbol()) return false;
112 Heap* heap = name->GetHeap();
113 return name == heap->nonextensible_symbol() ||
114 name == heap->sealed_symbol() || name == heap->frozen_symbol() ||
115 name == heap->elements_transition_symbol() ||
Ben Murdochc5610432016-08-08 18:44:38 +0100116 name == heap->strict_function_transition_symbol();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400117}
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 Murdoch4a90d5f2016-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 Bernierd0a1eb72015-03-24 16:35:39 -0400176void TransitionArray::SetNumberOfTransitions(int number_of_transitions) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000177 DCHECK(number_of_transitions <= Capacity(this));
178 set(kTransitionLengthIndex, Smi::FromInt(number_of_transitions));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400179}
180
Ben Murdoch4a90d5f2016-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_