OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/lookup.h" | 5 #include "src/lookup.h" |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/deoptimizer.h" | 8 #include "src/deoptimizer.h" |
9 #include "src/elements.h" | 9 #include "src/elements.h" |
10 #include "src/field-type.h" | 10 #include "src/field-type.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 } | 46 } |
47 | 47 |
48 | 48 |
49 void LookupIterator::Next() { | 49 void LookupIterator::Next() { |
50 DCHECK_NE(JSPROXY, state_); | 50 DCHECK_NE(JSPROXY, state_); |
51 DCHECK_NE(TRANSITION, state_); | 51 DCHECK_NE(TRANSITION, state_); |
52 DisallowHeapAllocation no_gc; | 52 DisallowHeapAllocation no_gc; |
53 has_property_ = false; | 53 has_property_ = false; |
54 | 54 |
55 JSReceiver* holder = *holder_; | 55 JSReceiver* holder = *holder_; |
56 Map* map = *holder_map_; | 56 Map* map = holder->map(); |
57 | 57 |
58 // Perform lookup on current holder. | 58 // Perform lookup on current holder. |
59 state_ = LookupInHolder(map, holder); | 59 state_ = LookupInHolder(map, holder); |
60 if (IsFound()) return; | 60 if (IsFound()) return; |
61 | 61 |
62 // Continue lookup if lookup on current holder failed. | 62 // Continue lookup if lookup on current holder failed. |
63 do { | 63 do { |
64 JSReceiver* maybe_holder = NextHolder(map); | 64 JSReceiver* maybe_holder = NextHolder(map); |
65 if (maybe_holder == nullptr) { | 65 if (maybe_holder == nullptr) { |
66 if (interceptor_state_ == InterceptorState::kSkipNonMasking) { | 66 if (interceptor_state_ == InterceptorState::kSkipNonMasking) { |
67 RestartLookupForNonMaskingInterceptors(); | 67 RestartLookupForNonMaskingInterceptors(); |
68 return; | 68 return; |
69 } | 69 } |
70 break; | 70 break; |
71 } | 71 } |
72 holder = maybe_holder; | 72 holder = maybe_holder; |
73 map = holder->map(); | 73 map = holder->map(); |
74 state_ = LookupInHolder(map, holder); | 74 state_ = LookupInHolder(map, holder); |
75 } while (!IsFound()); | 75 } while (!IsFound()); |
76 | 76 |
77 if (holder != *holder_) { | 77 if (holder != *holder_) holder_ = handle(holder, isolate_); |
78 holder_ = handle(holder, isolate_); | |
79 holder_map_ = handle(map, isolate_); | |
80 } | |
81 } | 78 } |
82 | 79 |
83 | 80 |
84 void LookupIterator::RestartInternal(InterceptorState interceptor_state) { | 81 void LookupIterator::RestartInternal(InterceptorState interceptor_state) { |
85 state_ = NOT_FOUND; | 82 state_ = NOT_FOUND; |
86 interceptor_state_ = interceptor_state; | 83 interceptor_state_ = interceptor_state; |
87 property_details_ = PropertyDetails::Empty(); | 84 property_details_ = PropertyDetails::Empty(); |
88 holder_ = initial_holder_; | 85 holder_ = initial_holder_; |
89 holder_map_ = handle(holder_->map(), isolate_); | |
90 number_ = DescriptorArray::kNotFound; | 86 number_ = DescriptorArray::kNotFound; |
91 Next(); | 87 Next(); |
92 } | 88 } |
93 | 89 |
94 | 90 |
95 // static | 91 // static |
96 Handle<JSReceiver> LookupIterator::GetRootForNonJSReceiver( | 92 Handle<JSReceiver> LookupIterator::GetRootForNonJSReceiver( |
97 Isolate* isolate, Handle<Object> receiver, uint32_t index) { | 93 Isolate* isolate, Handle<Object> receiver, uint32_t index) { |
98 // Strings are the only objects with properties (only elements) directly on | 94 // Strings are the only objects with properties (only elements) directly on |
99 // the wrapper. Hence we can skip generating the wrapper for all other cases. | 95 // the wrapper. Hence we can skip generating the wrapper for all other cases. |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 bool LookupIterator::HasAccess() const { | 131 bool LookupIterator::HasAccess() const { |
136 DCHECK_EQ(ACCESS_CHECK, state_); | 132 DCHECK_EQ(ACCESS_CHECK, state_); |
137 return isolate_->MayAccess(handle(isolate_->context()), | 133 return isolate_->MayAccess(handle(isolate_->context()), |
138 GetHolder<JSObject>()); | 134 GetHolder<JSObject>()); |
139 } | 135 } |
140 | 136 |
141 | 137 |
142 void LookupIterator::ReloadPropertyInformation() { | 138 void LookupIterator::ReloadPropertyInformation() { |
143 state_ = BEFORE_PROPERTY; | 139 state_ = BEFORE_PROPERTY; |
144 interceptor_state_ = InterceptorState::kUninitialized; | 140 interceptor_state_ = InterceptorState::kUninitialized; |
145 state_ = LookupInHolder(*holder_map_, *holder_); | 141 state_ = LookupInHolder(holder_->map(), *holder_); |
146 DCHECK(IsFound() || holder_map_->is_dictionary_map()); | 142 DCHECK(IsFound() || !holder_->HasFastProperties()); |
147 } | 143 } |
148 | 144 |
149 | 145 |
150 void LookupIterator::ReloadHolderMap() { | |
151 DCHECK_EQ(DATA, state_); | |
152 DCHECK(IsElement()); | |
153 DCHECK(JSObject::cast(*holder_)->HasFixedTypedArrayElements()); | |
154 if (*holder_map_ != holder_->map()) { | |
155 holder_map_ = handle(holder_->map(), isolate_); | |
156 } | |
157 } | |
158 | |
159 | |
160 void LookupIterator::PrepareForDataProperty(Handle<Object> value) { | 146 void LookupIterator::PrepareForDataProperty(Handle<Object> value) { |
161 DCHECK(state_ == DATA || state_ == ACCESSOR); | 147 DCHECK(state_ == DATA || state_ == ACCESSOR); |
162 DCHECK(HolderIsReceiverOrHiddenPrototype()); | 148 DCHECK(HolderIsReceiverOrHiddenPrototype()); |
163 | 149 |
164 Handle<JSObject> holder = GetHolder<JSObject>(); | 150 Handle<JSObject> holder = GetHolder<JSObject>(); |
165 | 151 |
166 if (IsElement()) { | 152 if (IsElement()) { |
167 ElementsKind kind = holder_map_->elements_kind(); | 153 ElementsKind kind = holder->GetElementsKind(); |
168 ElementsKind to = value->OptimalElementsKind(); | 154 ElementsKind to = value->OptimalElementsKind(); |
169 if (IsHoleyElementsKind(kind)) to = GetHoleyElementsKind(to); | 155 if (IsHoleyElementsKind(kind)) to = GetHoleyElementsKind(to); |
170 to = GetMoreGeneralElementsKind(kind, to); | 156 to = GetMoreGeneralElementsKind(kind, to); |
171 | 157 |
172 if (kind != to) { | 158 if (kind != to) { |
173 JSObject::TransitionElementsKind(holder, to); | 159 JSObject::TransitionElementsKind(holder, to); |
174 holder_map_ = handle(holder->map(), isolate_); | |
175 } | 160 } |
176 | 161 |
177 // Copy the backing store if it is copy-on-write. | 162 // Copy the backing store if it is copy-on-write. |
178 if (IsFastSmiOrObjectElementsKind(to)) { | 163 if (IsFastSmiOrObjectElementsKind(to)) { |
179 JSObject::EnsureWritableFastElements(holder); | 164 JSObject::EnsureWritableFastElements(holder); |
180 } | 165 } |
181 | |
182 if (kind == to) return; | |
183 | |
184 } else if (holder_map_->is_dictionary_map()) { | |
185 return; | 166 return; |
186 } else { | |
187 holder_map_ = | |
188 Map::PrepareForDataProperty(holder_map_, descriptor_number(), value); | |
189 | |
190 if (holder->map() == *holder_map_) { | |
191 // Update the property details if the representation was None. | |
192 if (representation().IsNone()) { | |
193 property_details_ = holder_map_->instance_descriptors()->GetDetails( | |
194 descriptor_number()); | |
195 } | |
196 return; | |
197 } | |
198 } | 167 } |
199 | 168 |
200 JSObject::MigrateToMap(holder, holder_map_); | 169 if (!holder->HasFastProperties()) return; |
| 170 |
| 171 Handle<Map> old_map(holder->map(), isolate_); |
| 172 Handle<Map> new_map = |
| 173 Map::PrepareForDataProperty(old_map, descriptor_number(), value); |
| 174 |
| 175 if (old_map.is_identical_to(new_map)) { |
| 176 // Update the property details if the representation was None. |
| 177 if (representation().IsNone()) { |
| 178 property_details_ = |
| 179 new_map->instance_descriptors()->GetDetails(descriptor_number()); |
| 180 } |
| 181 return; |
| 182 } |
| 183 |
| 184 JSObject::MigrateToMap(holder, new_map); |
201 ReloadPropertyInformation(); | 185 ReloadPropertyInformation(); |
202 } | 186 } |
203 | 187 |
204 | 188 |
205 void LookupIterator::ReconfigureDataProperty(Handle<Object> value, | 189 void LookupIterator::ReconfigureDataProperty(Handle<Object> value, |
206 PropertyAttributes attributes) { | 190 PropertyAttributes attributes) { |
207 DCHECK(state_ == DATA || state_ == ACCESSOR); | 191 DCHECK(state_ == DATA || state_ == ACCESSOR); |
208 DCHECK(HolderIsReceiverOrHiddenPrototype()); | 192 DCHECK(HolderIsReceiverOrHiddenPrototype()); |
209 Handle<JSObject> holder = GetHolder<JSObject>(); | 193 Handle<JSObject> holder = GetHolder<JSObject>(); |
210 if (IsElement()) { | 194 if (IsElement()) { |
211 DCHECK(!holder->HasFixedTypedArrayElements()); | 195 DCHECK(!holder->HasFixedTypedArrayElements()); |
212 DCHECK(attributes != NONE || !holder->HasFastElements()); | 196 DCHECK(attributes != NONE || !holder->HasFastElements()); |
213 Handle<FixedArrayBase> elements(holder->elements()); | 197 Handle<FixedArrayBase> elements(holder->elements()); |
214 holder->GetElementsAccessor()->Reconfigure(holder, elements, number_, value, | 198 holder->GetElementsAccessor()->Reconfigure(holder, elements, number_, value, |
215 attributes); | 199 attributes); |
216 } else if (holder_map_->is_dictionary_map()) { | 200 } else if (!holder->HasFastProperties()) { |
217 PropertyDetails details(attributes, v8::internal::DATA, 0, | 201 PropertyDetails details(attributes, v8::internal::DATA, 0, |
218 PropertyCellType::kMutable); | 202 PropertyCellType::kMutable); |
219 JSObject::SetNormalizedProperty(holder, name(), value, details); | 203 JSObject::SetNormalizedProperty(holder, name(), value, details); |
220 } else { | 204 } else { |
221 holder_map_ = Map::ReconfigureExistingProperty( | 205 Handle<Map> old_map(holder->map(), isolate_); |
222 holder_map_, descriptor_number(), i::kData, attributes); | 206 Handle<Map> new_map = Map::ReconfigureExistingProperty( |
223 holder_map_ = | 207 old_map, descriptor_number(), i::kData, attributes); |
224 Map::PrepareForDataProperty(holder_map_, descriptor_number(), value); | 208 new_map = Map::PrepareForDataProperty(new_map, descriptor_number(), value); |
225 JSObject::MigrateToMap(holder, holder_map_); | 209 JSObject::MigrateToMap(holder, new_map); |
226 } | 210 } |
227 | 211 |
228 ReloadPropertyInformation(); | 212 ReloadPropertyInformation(); |
229 WriteDataValue(value); | 213 WriteDataValue(value); |
230 | 214 |
231 #if VERIFY_HEAP | 215 #if VERIFY_HEAP |
232 if (FLAG_verify_heap) { | 216 if (FLAG_verify_heap) { |
233 holder->JSObjectVerify(); | 217 holder->JSObjectVerify(); |
234 } | 218 } |
235 #endif | 219 #endif |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
279 | 263 |
280 void LookupIterator::ApplyTransitionToDataProperty(Handle<JSObject> receiver) { | 264 void LookupIterator::ApplyTransitionToDataProperty(Handle<JSObject> receiver) { |
281 DCHECK_EQ(TRANSITION, state_); | 265 DCHECK_EQ(TRANSITION, state_); |
282 | 266 |
283 DCHECK(receiver.is_identical_to(GetStoreTarget())); | 267 DCHECK(receiver.is_identical_to(GetStoreTarget())); |
284 | 268 |
285 if (receiver->IsJSGlobalObject()) return; | 269 if (receiver->IsJSGlobalObject()) return; |
286 holder_ = receiver; | 270 holder_ = receiver; |
287 Handle<Map> transition = transition_map(); | 271 Handle<Map> transition = transition_map(); |
288 bool simple_transition = transition->GetBackPointer() == receiver->map(); | 272 bool simple_transition = transition->GetBackPointer() == receiver->map(); |
289 holder_map_ = transition; | 273 JSObject::MigrateToMap(receiver, transition); |
290 JSObject::MigrateToMap(receiver, holder_map_); | |
291 | 274 |
292 if (simple_transition) { | 275 if (simple_transition) { |
293 int number = transition->LastAdded(); | 276 int number = transition->LastAdded(); |
294 number_ = static_cast<uint32_t>(number); | 277 number_ = static_cast<uint32_t>(number); |
295 property_details_ = transition->GetLastDescriptorDetails(); | 278 property_details_ = transition->GetLastDescriptorDetails(); |
296 state_ = DATA; | 279 state_ = DATA; |
297 } else { | 280 } else { |
298 ReloadPropertyInformation(); | 281 ReloadPropertyInformation(); |
299 } | 282 } |
300 } | 283 } |
301 | 284 |
302 | 285 |
303 void LookupIterator::Delete() { | 286 void LookupIterator::Delete() { |
304 Handle<JSReceiver> holder = Handle<JSReceiver>::cast(holder_); | 287 Handle<JSReceiver> holder = Handle<JSReceiver>::cast(holder_); |
305 if (IsElement()) { | 288 if (IsElement()) { |
306 Handle<JSObject> object = Handle<JSObject>::cast(holder); | 289 Handle<JSObject> object = Handle<JSObject>::cast(holder); |
307 ElementsAccessor* accessor = object->GetElementsAccessor(); | 290 ElementsAccessor* accessor = object->GetElementsAccessor(); |
308 accessor->Delete(object, number_); | 291 accessor->Delete(object, number_); |
309 } else { | 292 } else { |
310 PropertyNormalizationMode mode = holder->map()->is_prototype_map() | 293 PropertyNormalizationMode mode = holder->map()->is_prototype_map() |
311 ? KEEP_INOBJECT_PROPERTIES | 294 ? KEEP_INOBJECT_PROPERTIES |
312 : CLEAR_INOBJECT_PROPERTIES; | 295 : CLEAR_INOBJECT_PROPERTIES; |
313 | 296 |
314 if (holder->HasFastProperties()) { | 297 if (holder->HasFastProperties()) { |
315 JSObject::NormalizeProperties(Handle<JSObject>::cast(holder), mode, 0, | 298 JSObject::NormalizeProperties(Handle<JSObject>::cast(holder), mode, 0, |
316 "DeletingProperty"); | 299 "DeletingProperty"); |
317 holder_map_ = handle(holder->map(), isolate_); | |
318 ReloadPropertyInformation(); | 300 ReloadPropertyInformation(); |
319 } | 301 } |
320 // TODO(verwaest): Get rid of the name_ argument. | 302 // TODO(verwaest): Get rid of the name_ argument. |
321 JSReceiver::DeleteNormalizedProperty(holder, name_, number_); | 303 JSReceiver::DeleteNormalizedProperty(holder, name_, number_); |
322 if (holder->IsJSObject()) { | 304 if (holder->IsJSObject()) { |
323 JSObject::ReoptimizeIfPrototype(Handle<JSObject>::cast(holder)); | 305 JSObject::ReoptimizeIfPrototype(Handle<JSObject>::cast(holder)); |
324 } | 306 } |
325 } | 307 } |
326 state_ = NOT_FOUND; | 308 state_ = NOT_FOUND; |
327 } | 309 } |
328 | 310 |
329 | 311 |
330 void LookupIterator::TransitionToAccessorProperty( | 312 void LookupIterator::TransitionToAccessorProperty( |
331 AccessorComponent component, Handle<Object> accessor, | 313 AccessorComponent component, Handle<Object> accessor, |
332 PropertyAttributes attributes) { | 314 PropertyAttributes attributes) { |
333 DCHECK(!accessor->IsNull()); | 315 DCHECK(!accessor->IsNull()); |
334 // Can only be called when the receiver is a JSObject. JSProxy has to be | 316 // Can only be called when the receiver is a JSObject. JSProxy has to be |
335 // handled via a trap. Adding properties to primitive values is not | 317 // handled via a trap. Adding properties to primitive values is not |
336 // observable. | 318 // observable. |
337 Handle<JSObject> receiver = GetStoreTarget(); | 319 Handle<JSObject> receiver = GetStoreTarget(); |
338 | 320 |
339 if (!IsElement() && !receiver->map()->is_dictionary_map()) { | 321 if (!IsElement() && !receiver->map()->is_dictionary_map()) { |
340 holder_ = receiver; | 322 holder_ = receiver; |
341 holder_map_ = Map::TransitionToAccessorProperty( | 323 Handle<Map> old_map(receiver->map(), isolate_); |
342 handle(receiver->map(), isolate_), name_, component, accessor, | 324 Handle<Map> new_map = Map::TransitionToAccessorProperty( |
343 attributes); | 325 old_map, name_, component, accessor, attributes); |
344 JSObject::MigrateToMap(receiver, holder_map_); | 326 JSObject::MigrateToMap(receiver, new_map); |
345 | 327 |
346 ReloadPropertyInformation(); | 328 ReloadPropertyInformation(); |
347 | 329 |
348 if (!holder_map_->is_dictionary_map()) return; | 330 if (!new_map->is_dictionary_map()) return; |
349 } | 331 } |
350 | 332 |
351 Handle<AccessorPair> pair; | 333 Handle<AccessorPair> pair; |
352 if (state() == ACCESSOR && GetAccessors()->IsAccessorPair()) { | 334 if (state() == ACCESSOR && GetAccessors()->IsAccessorPair()) { |
353 pair = Handle<AccessorPair>::cast(GetAccessors()); | 335 pair = Handle<AccessorPair>::cast(GetAccessors()); |
354 // If the component and attributes are identical, nothing has to be done. | 336 // If the component and attributes are identical, nothing has to be done. |
355 if (pair->get(component) == *accessor) { | 337 if (pair->get(component) == *accessor) { |
356 if (property_details().attributes() == attributes) return; | 338 if (property_details().attributes() == attributes) return; |
357 } else { | 339 } else { |
358 pair = AccessorPair::Copy(pair); | 340 pair = AccessorPair::Copy(pair); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 ? KEEP_INOBJECT_PROPERTIES | 390 ? KEEP_INOBJECT_PROPERTIES |
409 : CLEAR_INOBJECT_PROPERTIES; | 391 : CLEAR_INOBJECT_PROPERTIES; |
410 // Normalize object to make this operation simple. | 392 // Normalize object to make this operation simple. |
411 JSObject::NormalizeProperties(receiver, mode, 0, | 393 JSObject::NormalizeProperties(receiver, mode, 0, |
412 "TransitionToAccessorPair"); | 394 "TransitionToAccessorPair"); |
413 | 395 |
414 JSObject::SetNormalizedProperty(receiver, name_, pair, details); | 396 JSObject::SetNormalizedProperty(receiver, name_, pair, details); |
415 JSObject::ReoptimizeIfPrototype(receiver); | 397 JSObject::ReoptimizeIfPrototype(receiver); |
416 } | 398 } |
417 | 399 |
418 holder_map_ = handle(receiver->map(), isolate_); | |
419 ReloadPropertyInformation(); | 400 ReloadPropertyInformation(); |
420 } | 401 } |
421 | 402 |
422 | 403 |
423 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const { | 404 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const { |
424 DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY); | 405 DCHECK(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY); |
425 // Optimization that only works if configuration_ is not mutable. | 406 // Optimization that only works if configuration_ is not mutable. |
426 if (!check_prototype_chain()) return true; | 407 if (!check_prototype_chain()) return true; |
427 DisallowHeapAllocation no_gc; | 408 DisallowHeapAllocation no_gc; |
428 if (!receiver_->IsJSReceiver()) return false; | 409 if (!receiver_->IsJSReceiver()) return false; |
(...skipping 13 matching lines...) Expand all Loading... |
442 return false; | 423 return false; |
443 } | 424 } |
444 | 425 |
445 | 426 |
446 Handle<Object> LookupIterator::FetchValue() const { | 427 Handle<Object> LookupIterator::FetchValue() const { |
447 Object* result = NULL; | 428 Object* result = NULL; |
448 if (IsElement()) { | 429 if (IsElement()) { |
449 Handle<JSObject> holder = GetHolder<JSObject>(); | 430 Handle<JSObject> holder = GetHolder<JSObject>(); |
450 ElementsAccessor* accessor = holder->GetElementsAccessor(); | 431 ElementsAccessor* accessor = holder->GetElementsAccessor(); |
451 return accessor->Get(holder, number_); | 432 return accessor->Get(holder, number_); |
452 } else if (holder_map_->IsJSGlobalObjectMap()) { | 433 } else if (holder_->IsJSGlobalObject()) { |
453 Handle<JSObject> holder = GetHolder<JSObject>(); | 434 Handle<JSObject> holder = GetHolder<JSObject>(); |
454 result = holder->global_dictionary()->ValueAt(number_); | 435 result = holder->global_dictionary()->ValueAt(number_); |
455 DCHECK(result->IsPropertyCell()); | 436 DCHECK(result->IsPropertyCell()); |
456 result = PropertyCell::cast(result)->value(); | 437 result = PropertyCell::cast(result)->value(); |
457 } else if (holder_map_->is_dictionary_map()) { | 438 } else if (!holder_->HasFastProperties()) { |
458 result = holder_->property_dictionary()->ValueAt(number_); | 439 result = holder_->property_dictionary()->ValueAt(number_); |
459 } else if (property_details_.type() == v8::internal::DATA) { | 440 } else if (property_details_.type() == v8::internal::DATA) { |
460 Handle<JSObject> holder = GetHolder<JSObject>(); | 441 Handle<JSObject> holder = GetHolder<JSObject>(); |
461 FieldIndex field_index = FieldIndex::ForDescriptor(*holder_map_, number_); | 442 FieldIndex field_index = FieldIndex::ForDescriptor(holder->map(), number_); |
462 return JSObject::FastPropertyAt(holder, property_details_.representation(), | 443 return JSObject::FastPropertyAt(holder, property_details_.representation(), |
463 field_index); | 444 field_index); |
464 } else { | 445 } else { |
465 result = holder_map_->instance_descriptors()->GetValue(number_); | 446 result = holder_->map()->instance_descriptors()->GetValue(number_); |
466 } | 447 } |
467 return handle(result, isolate_); | 448 return handle(result, isolate_); |
468 } | 449 } |
469 | 450 |
470 | 451 |
471 int LookupIterator::GetAccessorIndex() const { | 452 int LookupIterator::GetAccessorIndex() const { |
472 DCHECK(has_property_); | 453 DCHECK(has_property_); |
473 DCHECK(!holder_map_->is_dictionary_map()); | 454 DCHECK(holder_->HasFastProperties()); |
474 DCHECK_EQ(v8::internal::ACCESSOR_CONSTANT, property_details_.type()); | 455 DCHECK_EQ(v8::internal::ACCESSOR_CONSTANT, property_details_.type()); |
475 return descriptor_number(); | 456 return descriptor_number(); |
476 } | 457 } |
477 | 458 |
478 | 459 |
479 int LookupIterator::GetConstantIndex() const { | 460 int LookupIterator::GetConstantIndex() const { |
480 DCHECK(has_property_); | 461 DCHECK(has_property_); |
481 DCHECK(!holder_map_->is_dictionary_map()); | 462 DCHECK(holder_->HasFastProperties()); |
482 DCHECK_EQ(v8::internal::DATA_CONSTANT, property_details_.type()); | 463 DCHECK_EQ(v8::internal::DATA_CONSTANT, property_details_.type()); |
483 DCHECK(!IsElement()); | 464 DCHECK(!IsElement()); |
484 return descriptor_number(); | 465 return descriptor_number(); |
485 } | 466 } |
486 | 467 |
487 | 468 |
488 FieldIndex LookupIterator::GetFieldIndex() const { | 469 FieldIndex LookupIterator::GetFieldIndex() const { |
489 DCHECK(has_property_); | 470 DCHECK(has_property_); |
490 DCHECK(!holder_map_->is_dictionary_map()); | 471 DCHECK(holder_->HasFastProperties()); |
491 DCHECK_EQ(v8::internal::DATA, property_details_.type()); | 472 DCHECK_EQ(v8::internal::DATA, property_details_.type()); |
492 DCHECK(!IsElement()); | 473 DCHECK(!IsElement()); |
| 474 Map* holder_map = holder_->map(); |
493 int index = | 475 int index = |
494 holder_map_->instance_descriptors()->GetFieldIndex(descriptor_number()); | 476 holder_map->instance_descriptors()->GetFieldIndex(descriptor_number()); |
495 bool is_double = representation().IsDouble(); | 477 bool is_double = representation().IsDouble(); |
496 return FieldIndex::ForPropertyIndex(*holder_map_, index, is_double); | 478 return FieldIndex::ForPropertyIndex(holder_map, index, is_double); |
497 } | 479 } |
498 | 480 |
499 Handle<FieldType> LookupIterator::GetFieldType() const { | 481 Handle<FieldType> LookupIterator::GetFieldType() const { |
500 DCHECK(has_property_); | 482 DCHECK(has_property_); |
501 DCHECK(!holder_map_->is_dictionary_map()); | 483 DCHECK(holder_->HasFastProperties()); |
502 DCHECK_EQ(v8::internal::DATA, property_details_.type()); | 484 DCHECK_EQ(v8::internal::DATA, property_details_.type()); |
503 return handle( | 485 return handle( |
504 holder_map_->instance_descriptors()->GetFieldType(descriptor_number()), | 486 holder_->map()->instance_descriptors()->GetFieldType(descriptor_number()), |
505 isolate_); | 487 isolate_); |
506 } | 488 } |
507 | 489 |
508 | 490 |
509 Handle<PropertyCell> LookupIterator::GetPropertyCell() const { | 491 Handle<PropertyCell> LookupIterator::GetPropertyCell() const { |
510 DCHECK(!IsElement()); | 492 DCHECK(!IsElement()); |
511 Handle<JSObject> holder = GetHolder<JSObject>(); | 493 Handle<JSObject> holder = GetHolder<JSObject>(); |
512 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(holder); | 494 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(holder); |
513 Object* value = global->global_dictionary()->ValueAt(dictionary_entry()); | 495 Object* value = global->global_dictionary()->ValueAt(dictionary_entry()); |
514 DCHECK(value->IsPropertyCell()); | 496 DCHECK(value->IsPropertyCell()); |
(...skipping 19 matching lines...) Expand all Loading... |
534 Handle<JSReceiver> holder = GetHolder<JSReceiver>(); | 516 Handle<JSReceiver> holder = GetHolder<JSReceiver>(); |
535 if (IsElement()) { | 517 if (IsElement()) { |
536 Handle<JSObject> object = Handle<JSObject>::cast(holder); | 518 Handle<JSObject> object = Handle<JSObject>::cast(holder); |
537 ElementsAccessor* accessor = object->GetElementsAccessor(); | 519 ElementsAccessor* accessor = object->GetElementsAccessor(); |
538 accessor->Set(object, number_, *value); | 520 accessor->Set(object, number_, *value); |
539 } else if (holder->IsJSGlobalObject()) { | 521 } else if (holder->IsJSGlobalObject()) { |
540 Handle<GlobalDictionary> property_dictionary = | 522 Handle<GlobalDictionary> property_dictionary = |
541 handle(JSObject::cast(*holder)->global_dictionary()); | 523 handle(JSObject::cast(*holder)->global_dictionary()); |
542 PropertyCell::UpdateCell(property_dictionary, dictionary_entry(), value, | 524 PropertyCell::UpdateCell(property_dictionary, dictionary_entry(), value, |
543 property_details_); | 525 property_details_); |
544 } else if (holder_map_->is_dictionary_map()) { | 526 } else if (!holder->HasFastProperties()) { |
545 NameDictionary* property_dictionary = holder->property_dictionary(); | 527 NameDictionary* property_dictionary = holder->property_dictionary(); |
546 property_dictionary->ValueAtPut(dictionary_entry(), *value); | 528 property_dictionary->ValueAtPut(dictionary_entry(), *value); |
547 } else if (property_details_.type() == v8::internal::DATA) { | 529 } else if (property_details_.type() == v8::internal::DATA) { |
548 JSObject::cast(*holder)->WriteToField(descriptor_number(), *value); | 530 JSObject::cast(*holder)->WriteToField(descriptor_number(), *value); |
549 } else { | 531 } else { |
550 DCHECK_EQ(v8::internal::DATA_CONSTANT, property_details_.type()); | 532 DCHECK_EQ(v8::internal::DATA_CONSTANT, property_details_.type()); |
551 } | 533 } |
552 } | 534 } |
553 | 535 |
554 | 536 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
700 // Fall through. | 682 // Fall through. |
701 default: | 683 default: |
702 return NOT_FOUND; | 684 return NOT_FOUND; |
703 } | 685 } |
704 UNREACHABLE(); | 686 UNREACHABLE(); |
705 return state_; | 687 return state_; |
706 } | 688 } |
707 | 689 |
708 } // namespace internal | 690 } // namespace internal |
709 } // namespace v8 | 691 } // namespace v8 |
OLD | NEW |