f31eff96ba19e6e8e1dca0f1a4b3ee0c7c654a53
[platform/upstream/v8.git] / src / transitions-inl.h
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.
4
5 #ifndef V8_TRANSITIONS_INL_H_
6 #define V8_TRANSITIONS_INL_H_
7
8 #include "src/transitions.h"
9
10 namespace v8 {
11 namespace internal {
12
13
14 TransitionArray* TransitionArray::cast(Object* object) {
15   DCHECK(object->IsTransitionArray());
16   return reinterpret_cast<TransitionArray*>(object);
17 }
18
19
20 bool TransitionArray::HasPrototypeTransitions() {
21   return get(kPrototypeTransitionsIndex) != Smi::FromInt(0);
22 }
23
24
25 FixedArray* TransitionArray::GetPrototypeTransitions() {
26   DCHECK(HasPrototypeTransitions());  // Callers must check first.
27   Object* prototype_transitions = get(kPrototypeTransitionsIndex);
28   return FixedArray::cast(prototype_transitions);
29 }
30
31
32 void TransitionArray::SetPrototypeTransitions(FixedArray* transitions,
33                                               WriteBarrierMode mode) {
34   DCHECK(transitions->IsFixedArray());
35   set(kPrototypeTransitionsIndex, transitions, mode);
36 }
37
38
39 Object** TransitionArray::GetPrototypeTransitionsSlot() {
40   return RawFieldOfElementAt(kPrototypeTransitionsIndex);
41 }
42
43
44 Object** TransitionArray::GetKeySlot(int transition_number) {
45   DCHECK(transition_number < number_of_transitions());
46   return RawFieldOfElementAt(ToKeyIndex(transition_number));
47 }
48
49
50 Name* TransitionArray::GetKey(int transition_number) {
51   DCHECK(transition_number < number_of_transitions());
52   return Name::cast(get(ToKeyIndex(transition_number)));
53 }
54
55
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));
60   }
61   DCHECK(IsFullTransitionArray(raw_transitions));
62   return TransitionArray::cast(raw_transitions)->GetKey(transition_number);
63 }
64
65
66 void TransitionArray::SetKey(int transition_number, Name* key) {
67   DCHECK(transition_number < number_of_transitions());
68   set(ToKeyIndex(transition_number), key);
69 }
70
71
72 Map* TransitionArray::GetTarget(int transition_number) {
73   DCHECK(transition_number < number_of_transitions());
74   return Map::cast(get(ToTargetIndex(transition_number)));
75 }
76
77
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);
83   }
84   DCHECK(IsFullTransitionArray(raw_transitions));
85   return TransitionArray::cast(raw_transitions)->GetTarget(transition_number);
86 }
87
88
89 void TransitionArray::SetTarget(int transition_number, Map* value) {
90   DCHECK(transition_number < number_of_transitions());
91   set(ToTargetIndex(transition_number), value);
92 }
93
94
95 int TransitionArray::SearchName(Name* name, int* out_insertion_index) {
96   return internal::Search<ALL_ENTRIES>(this, name, 0, out_insertion_index);
97 }
98
99
100 #ifdef DEBUG
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();
108 }
109 #endif
110
111
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;
118
119   return CompareDetails(kind1, attributes1, kind2, attributes2);
120 }
121
122
123 int TransitionArray::CompareNames(Name* key1, uint32_t hash1, Name* key2,
124                                   uint32_t hash2) {
125   if (key1 != key2) {
126     // In case of hash collisions key1 is always "less" than key2.
127     return hash1 <= hash2 ? -1 : 1;
128   }
129
130   return 0;
131 }
132
133
134 int TransitionArray::CompareDetails(PropertyKind kind1,
135                                     PropertyAttributes attributes1,
136                                     PropertyKind kind2,
137                                     PropertyAttributes attributes2) {
138   if (kind1 != kind2) {
139     return static_cast<int>(kind1) < static_cast<int>(kind2) ? -1 : 1;
140   }
141
142   if (attributes1 != attributes2) {
143     return static_cast<int>(attributes1) < static_cast<int>(attributes2) ? -1
144                                                                          : 1;
145   }
146
147   return 0;
148 }
149
150
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);
158 }
159
160
161 void TransitionArray::NoIncrementalWriteBarrierSet(int transition_number,
162                                                    Name* key,
163                                                    Map* target) {
164   FixedArray::NoIncrementalWriteBarrierSet(
165       this, ToKeyIndex(transition_number), key);
166   FixedArray::NoIncrementalWriteBarrierSet(
167       this, ToTargetIndex(transition_number), target);
168 }
169
170
171 void TransitionArray::SetNumberOfTransitions(int number_of_transitions) {
172   DCHECK(number_of_transitions <= Capacity(this));
173   set(kTransitionLengthIndex, Smi::FromInt(number_of_transitions));
174 }
175
176 } }  // namespace v8::internal
177
178 #endif  // V8_TRANSITIONS_INL_H_