Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(227)

Side by Side Diff: src/transitions.cc

Issue 793453004: Reland of "TransitionArray now uses <is_data_property, name, attributes> tuple as a key, which allo… (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Post-rebase fixes Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/transitions.h ('k') | src/transitions-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/objects.h" 7 #include "src/objects.h"
8 #include "src/transitions-inl.h" 8 #include "src/transitions-inl.h"
9 #include "src/utils.h" 9 #include "src/utils.h"
10 10
(...skipping 30 matching lines...) Expand all
41 } 41 }
42 42
43 43
44 Handle<TransitionArray> TransitionArray::NewWith(Handle<Map> map, 44 Handle<TransitionArray> TransitionArray::NewWith(Handle<Map> map,
45 Handle<Name> name, 45 Handle<Name> name,
46 Handle<Map> target, 46 Handle<Map> target,
47 SimpleTransitionFlag flag) { 47 SimpleTransitionFlag flag) {
48 Handle<TransitionArray> result; 48 Handle<TransitionArray> result;
49 Isolate* isolate = name->GetIsolate(); 49 Isolate* isolate = name->GetIsolate();
50 50
51 if (flag == SIMPLE_TRANSITION) { 51 if (flag == SIMPLE_PROPERTY_TRANSITION) {
52 result = AllocateSimple(isolate, target); 52 result = AllocateSimple(isolate, target);
53 } else { 53 } else {
54 result = Allocate(isolate, 1); 54 result = Allocate(isolate, 1);
55 result->NoIncrementalWriteBarrierSet(0, *name, *target); 55 result->NoIncrementalWriteBarrierSet(0, *name, *target);
56 } 56 }
57 result->set_back_pointer_storage(map->GetBackPointer()); 57 result->set_back_pointer_storage(map->GetBackPointer());
58 return result; 58 return result;
59 } 59 }
60 60
61 61
(...skipping 25 matching lines...) Expand all
87 Handle<Name> name, 87 Handle<Name> name,
88 Handle<Map> target, 88 Handle<Map> target,
89 SimpleTransitionFlag flag) { 89 SimpleTransitionFlag flag) {
90 if (!map->HasTransitionArray()) { 90 if (!map->HasTransitionArray()) {
91 return TransitionArray::NewWith(map, name, target, flag); 91 return TransitionArray::NewWith(map, name, target, flag);
92 } 92 }
93 93
94 int number_of_transitions = map->transitions()->number_of_transitions(); 94 int number_of_transitions = map->transitions()->number_of_transitions();
95 int new_nof = number_of_transitions; 95 int new_nof = number_of_transitions;
96 96
97 bool is_special_transition = flag == SPECIAL_TRANSITION;
98 DCHECK_EQ(is_special_transition, IsSpecialTransition(*name));
99 PropertyDetails details = is_special_transition
100 ? PropertyDetails(NONE, FIELD, 0)
101 : GetTargetDetails(*name, *target);
102
97 int insertion_index = kNotFound; 103 int insertion_index = kNotFound;
98 int index = map->transitions()->Search(*name, &insertion_index); 104 int index =
99 105 is_special_transition
106 ? map->transitions()->SearchSpecial(Symbol::cast(*name),
107 &insertion_index)
108 : map->transitions()->Search(details.type(), *name,
109 details.attributes(), &insertion_index);
100 if (index == kNotFound) { 110 if (index == kNotFound) {
101 ++new_nof; 111 ++new_nof;
102 } else { 112 } else {
103 insertion_index = index; 113 insertion_index = index;
104 } 114 }
105 DCHECK(insertion_index >= 0 && insertion_index <= number_of_transitions); 115 DCHECK(insertion_index >= 0 && insertion_index <= number_of_transitions);
106 116
107 CHECK(new_nof <= kMaxNumberOfTransitions); 117 CHECK(new_nof <= kMaxNumberOfTransitions);
108 118
109 if (new_nof <= map->transitions()->number_of_transitions_storage()) { 119 if (new_nof <= map->transitions()->number_of_transitions_storage()) {
110 DisallowHeapAllocation no_gc; 120 DisallowHeapAllocation no_gc;
111 TransitionArray* array = map->transitions(); 121 TransitionArray* array = map->transitions();
112 122
113 if (index != kNotFound) { 123 if (index != kNotFound) {
114 array->SetTarget(index, *target); 124 array->SetTarget(index, *target);
115 return handle(array); 125 return handle(array);
116 } 126 }
117 127
118 array->SetNumberOfTransitions(new_nof); 128 array->SetNumberOfTransitions(new_nof);
119 for (index = number_of_transitions; index > insertion_index; --index) { 129 for (index = number_of_transitions; index > insertion_index; --index) {
120 Name* key = array->GetKey(index - 1); 130 Name* key = array->GetKey(index - 1);
121 DCHECK(key->Hash() > name->Hash());
122 array->SetKey(index, key); 131 array->SetKey(index, key);
123 array->SetTarget(index, array->GetTarget(index - 1)); 132 array->SetTarget(index, array->GetTarget(index - 1));
124 } 133 }
125 array->SetKey(index, *name); 134 array->SetKey(index, *name);
126 array->SetTarget(index, *target); 135 array->SetTarget(index, *target);
136 SLOW_DCHECK(array->IsSortedNoDuplicates());
127 return handle(array); 137 return handle(array);
128 } 138 }
129 139
130 Handle<TransitionArray> result = Allocate( 140 Handle<TransitionArray> result = Allocate(
131 map->GetIsolate(), new_nof, 141 map->GetIsolate(), new_nof,
132 Map::SlackForArraySize(number_of_transitions, kMaxNumberOfTransitions)); 142 Map::SlackForArraySize(number_of_transitions, kMaxNumberOfTransitions));
133 143
134 // The map's transition array may grown smaller during the allocation above as 144 // The map's transition array may grown smaller during the allocation above as
135 // it was weakly traversed, though it is guaranteed not to disappear. Trim the 145 // it was weakly traversed, though it is guaranteed not to disappear. Trim the
136 // result copy if needed, and recompute variables. 146 // result copy if needed, and recompute variables.
137 DCHECK(map->HasTransitionArray()); 147 DCHECK(map->HasTransitionArray());
138 DisallowHeapAllocation no_gc; 148 DisallowHeapAllocation no_gc;
139 TransitionArray* array = map->transitions(); 149 TransitionArray* array = map->transitions();
140 if (array->number_of_transitions() != number_of_transitions) { 150 if (array->number_of_transitions() != number_of_transitions) {
141 DCHECK(array->number_of_transitions() < number_of_transitions); 151 DCHECK(array->number_of_transitions() < number_of_transitions);
142 152
143 number_of_transitions = array->number_of_transitions(); 153 number_of_transitions = array->number_of_transitions();
144 new_nof = number_of_transitions; 154 new_nof = number_of_transitions;
145 155
146 insertion_index = kNotFound; 156 insertion_index = kNotFound;
147 index = array->Search(*name, &insertion_index); 157 index = is_special_transition ? map->transitions()->SearchSpecial(
158 Symbol::cast(*name), &insertion_index)
159 : map->transitions()->Search(
160 details.type(), *name,
161 details.attributes(), &insertion_index);
148 if (index == kNotFound) { 162 if (index == kNotFound) {
149 ++new_nof; 163 ++new_nof;
150 } else { 164 } else {
151 insertion_index = index; 165 insertion_index = index;
152 } 166 }
153 DCHECK(insertion_index >= 0 && insertion_index <= number_of_transitions); 167 DCHECK(insertion_index >= 0 && insertion_index <= number_of_transitions);
154 168
155 result->Shrink(ToKeyIndex(new_nof)); 169 result->Shrink(ToKeyIndex(new_nof));
156 result->SetNumberOfTransitions(new_nof); 170 result->SetNumberOfTransitions(new_nof);
157 } 171 }
158 172
159 if (array->HasPrototypeTransitions()) { 173 if (array->HasPrototypeTransitions()) {
160 result->SetPrototypeTransitions(array->GetPrototypeTransitions()); 174 result->SetPrototypeTransitions(array->GetPrototypeTransitions());
161 } 175 }
162 176
163 DCHECK_NE(kNotFound, insertion_index); 177 DCHECK_NE(kNotFound, insertion_index);
164 for (int i = 0; i < insertion_index; ++i) { 178 for (int i = 0; i < insertion_index; ++i) {
165 result->NoIncrementalWriteBarrierCopyFrom(array, i, i); 179 result->NoIncrementalWriteBarrierCopyFrom(array, i, i);
166 } 180 }
167 result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target); 181 result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target);
168 for (int i = insertion_index; i < number_of_transitions; ++i) { 182 for (int i = insertion_index; i < number_of_transitions; ++i) {
169 result->NoIncrementalWriteBarrierCopyFrom(array, i, i + 1); 183 result->NoIncrementalWriteBarrierCopyFrom(array, i, i + 1);
170 } 184 }
171 185
172 result->set_back_pointer_storage(array->back_pointer_storage()); 186 result->set_back_pointer_storage(array->back_pointer_storage());
187 SLOW_DCHECK(result->IsSortedNoDuplicates());
173 return result; 188 return result;
174 } 189 }
175 190
176 191
192 int TransitionArray::SearchDetails(int transition, PropertyType type,
193 PropertyAttributes attributes,
194 int* out_insertion_index) {
195 int nof_transitions = number_of_transitions();
196 DCHECK(transition < nof_transitions);
197 Name* key = GetKey(transition);
198 bool is_data = type == FIELD || type == CONSTANT;
199 for (; transition < nof_transitions && GetKey(transition) == key;
200 transition++) {
201 Map* target = GetTarget(transition);
202 PropertyDetails target_details = GetTargetDetails(key, target);
203
204 bool target_is_data =
205 target_details.type() == FIELD || target_details.type() == CONSTANT;
206
207 int cmp = CompareDetails(is_data, attributes, target_is_data,
208 target_details.attributes());
209 if (cmp == 0) {
210 return transition;
211 } else if (cmp < 0) {
212 break;
213 }
214 }
215 if (out_insertion_index != NULL) *out_insertion_index = transition;
216 return kNotFound;
217 }
218
219
220 int TransitionArray::Search(PropertyType type, Name* name,
221 PropertyAttributes attributes,
222 int* out_insertion_index) {
223 int transition = SearchName(name, out_insertion_index);
224 if (transition == kNotFound) {
225 return kNotFound;
226 }
227 return SearchDetails(transition, type, attributes, out_insertion_index);
228 }
177 } } // namespace v8::internal 229 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/transitions.h ('k') | src/transitions-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698