1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_TRANSITIONS_INL_H_
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_TRANSITIONS_INL_H_
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/transitions.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTransitionArray* TransitionArray::cast(Object* object) {
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(object->IsTransitionArray());
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<TransitionArray*>(object);
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochObject* TransitionArray::next_link() { return get(kNextLinkIndex); }
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TransitionArray::set_next_link(Object* next, WriteBarrierMode mode) {
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return set(kNextLinkIndex, next, mode);
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool TransitionArray::HasPrototypeTransitions() {
29c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return get(kPrototypeTransitionsIndex) != Smi::kZero;
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochFixedArray* TransitionArray::GetPrototypeTransitions() {
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(HasPrototypeTransitions());  // Callers must check first.
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Object* prototype_transitions = get(kPrototypeTransitionsIndex);
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return FixedArray::cast(prototype_transitions);
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TransitionArray::SetPrototypeTransitions(FixedArray* transitions) {
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(transitions->IsFixedArray());
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set(kPrototypeTransitionsIndex, transitions);
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObject** TransitionArray::GetPrototypeTransitionsSlot() {
47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return RawFieldOfElementAt(kPrototypeTransitionsIndex);
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObject** TransitionArray::GetKeySlot(int transition_number) {
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(transition_number < number_of_transitions());
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return RawFieldOfElementAt(ToKeyIndex(transition_number));
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochName* TransitionArray::GetKey(int transition_number) {
58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(transition_number < number_of_transitions());
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Name::cast(get(ToKeyIndex(transition_number)));
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochName* TransitionArray::GetKey(Object* raw_transitions, int transition_number) {
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (IsSimpleTransition(raw_transitions)) {
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(transition_number == 0);
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return GetSimpleTransitionKey(GetSimpleTransition(raw_transitions));
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsFullTransitionArray(raw_transitions));
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TransitionArray::cast(raw_transitions)->GetKey(transition_number);
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid TransitionArray::SetKey(int transition_number, Name* key) {
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(transition_number < number_of_transitions());
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set(ToKeyIndex(transition_number), key);
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMap* TransitionArray::GetTarget(int transition_number) {
80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(transition_number < number_of_transitions());
81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Map::cast(get(ToTargetIndex(transition_number)));
82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMap* TransitionArray::GetTarget(Object* raw_transitions,
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                int transition_number) {
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (IsSimpleTransition(raw_transitions)) {
88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(transition_number == 0);
89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return GetSimpleTransition(raw_transitions);
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(IsFullTransitionArray(raw_transitions));
92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TransitionArray::cast(raw_transitions)->GetTarget(transition_number);
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TransitionArray::SetTarget(int transition_number, Map* value) {
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(transition_number < number_of_transitions());
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set(ToTargetIndex(transition_number), value);
99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierint TransitionArray::SearchName(Name* name, int* out_insertion_index) {
103109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK(name->IsUniqueName());
104109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  return internal::Search<ALL_ENTRIES>(this, name, number_of_entries(),
105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                       out_insertion_index);
106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
107958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
109958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#ifdef DEBUG
110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool TransitionArray::IsSpecialTransition(Name* name) {
111958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!name->IsSymbol()) return false;
112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Heap* heap = name->GetHeap();
113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return name == heap->nonextensible_symbol() ||
114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier         name == heap->sealed_symbol() || name == heap->frozen_symbol() ||
115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier         name == heap->elements_transition_symbol() ||
116bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch         name == heap->strict_function_transition_symbol();
117958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#endif
119958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
121958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierint TransitionArray::CompareKeys(Name* key1, uint32_t hash1, PropertyKind kind1,
122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                 PropertyAttributes attributes1, Name* key2,
123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                 uint32_t hash2, PropertyKind kind2,
124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                 PropertyAttributes attributes2) {
125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int cmp = CompareNames(key1, hash1, key2, hash2);
126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (cmp != 0) return cmp;
127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return CompareDetails(kind1, attributes1, kind2, attributes2);
129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierint TransitionArray::CompareNames(Name* key1, uint32_t hash1, Name* key2,
133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                  uint32_t hash2) {
134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (key1 != key2) {
135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // In case of hash collisions key1 is always "less" than key2.
136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return hash1 <= hash2 ? -1 : 1;
137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
139958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return 0;
140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierint TransitionArray::CompareDetails(PropertyKind kind1,
144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                    PropertyAttributes attributes1,
145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                    PropertyKind kind2,
146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                    PropertyAttributes attributes2) {
147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (kind1 != kind2) {
148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return static_cast<int>(kind1) < static_cast<int>(kind2) ? -1 : 1;
149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (attributes1 != attributes2) {
152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return static_cast<int>(attributes1) < static_cast<int>(attributes2) ? -1
153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                                         : 1;
154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return 0;
157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierPropertyDetails TransitionArray::GetTargetDetails(Name* name, Map* target) {
161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(!IsSpecialTransition(name));
162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int descriptor = target->LastAdded();
163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DescriptorArray* descriptors = target->instance_descriptors();
164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Transitions are allowed only for the last added property.
165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(descriptors->GetKey(descriptor)->Equals(name));
166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return descriptors->GetDetails(descriptor);
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TransitionArray::Set(int transition_number, Name* key, Map* target) {
171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set(ToKeyIndex(transition_number), key);
172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set(ToTargetIndex(transition_number), target);
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid TransitionArray::SetNumberOfTransitions(int number_of_transitions) {
177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(number_of_transitions <= Capacity(this));
178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set(kTransitionLengthIndex, Smi::FromInt(number_of_transitions));
179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_TRANSITIONS_INL_H_
185