| 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/v8.h" | 5 #include "src/v8.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/lookup.h" | 9 #include "src/lookup.h" |
| 10 #include "src/lookup-inl.h" | 10 #include "src/lookup-inl.h" |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 | 270 |
| 271 | 271 |
| 272 void LookupIterator::TransitionToAccessorProperty( | 272 void LookupIterator::TransitionToAccessorProperty( |
| 273 AccessorComponent component, Handle<Object> accessor, | 273 AccessorComponent component, Handle<Object> accessor, |
| 274 PropertyAttributes attributes) { | 274 PropertyAttributes attributes) { |
| 275 DCHECK(!accessor->IsNull()); | 275 DCHECK(!accessor->IsNull()); |
| 276 // Can only be called when the receiver is a JSObject. JSProxy has to be | 276 // Can only be called when the receiver is a JSObject. JSProxy has to be |
| 277 // handled via a trap. Adding properties to primitive values is not | 277 // handled via a trap. Adding properties to primitive values is not |
| 278 // observable. | 278 // observable. |
| 279 Handle<JSObject> receiver = GetStoreTarget(); | 279 Handle<JSObject> receiver = GetStoreTarget(); |
| 280 holder_ = receiver; | |
| 281 | 280 |
| 282 if (!IsElement() && !receiver->map()->is_dictionary_map()) { | 281 if (!IsElement() && !receiver->map()->is_dictionary_map()) { |
| 282 holder_ = receiver; |
| 283 holder_map_ = Map::TransitionToAccessorProperty( | 283 holder_map_ = Map::TransitionToAccessorProperty( |
| 284 handle(receiver->map(), isolate_), name_, component, accessor, | 284 handle(receiver->map(), isolate_), name_, component, accessor, |
| 285 attributes); | 285 attributes); |
| 286 JSObject::MigrateToMap(receiver, holder_map_); | 286 JSObject::MigrateToMap(receiver, holder_map_); |
| 287 | 287 |
| 288 ReloadPropertyInformation(); | 288 ReloadPropertyInformation(); |
| 289 | 289 |
| 290 if (!holder_map_->is_dictionary_map()) return; | 290 if (!holder_map_->is_dictionary_map()) return; |
| 291 } | 291 } |
| 292 | 292 |
| 293 PropertyDetails details(attributes, ACCESSOR_CONSTANT, 0, | |
| 294 PropertyCellType::kMutable); | |
| 295 Handle<AccessorPair> pair; | 293 Handle<AccessorPair> pair; |
| 296 if (state() == ACCESSOR && GetAccessors()->IsAccessorPair()) { | 294 if (state() == ACCESSOR && GetAccessors()->IsAccessorPair()) { |
| 297 pair = Handle<AccessorPair>::cast(GetAccessors()); | 295 pair = Handle<AccessorPair>::cast(GetAccessors()); |
| 298 // If the component and attributes are identical, nothing has to be done. | 296 // If the component and attributes are identical, nothing has to be done. |
| 299 if (pair->get(component) == *accessor) { | 297 if (pair->get(component) == *accessor) { |
| 300 if (property_details().attributes() == attributes) return; | 298 if (property_details().attributes() == attributes) return; |
| 301 } else { | 299 } else { |
| 302 pair = AccessorPair::Copy(pair); | 300 pair = AccessorPair::Copy(pair); |
| 303 pair->set(component, *accessor); | 301 pair->set(component, *accessor); |
| 304 } | 302 } |
| 305 } else { | 303 } else { |
| 306 pair = factory()->NewAccessorPair(); | 304 pair = factory()->NewAccessorPair(); |
| 307 pair->set(component, *accessor); | 305 pair->set(component, *accessor); |
| 308 } | 306 } |
| 309 | 307 |
| 308 TransitionToAccessorPair(pair, attributes); |
| 309 } |
| 310 |
| 311 |
| 312 void LookupIterator::TransitionToAccessorPair(Handle<Object> pair, |
| 313 PropertyAttributes attributes) { |
| 314 Handle<JSObject> receiver = GetStoreTarget(); |
| 315 holder_ = receiver; |
| 316 |
| 317 PropertyDetails details(attributes, ACCESSOR_CONSTANT, 0, |
| 318 PropertyCellType::kMutable); |
| 319 |
| 310 if (IsElement()) { | 320 if (IsElement()) { |
| 311 // TODO(verwaest): Remove this hack once we have a quick way to check the | 321 // TODO(verwaest): Remove this hack once we have a quick way to check the |
| 312 // prototype chain in element setters. | 322 // prototype chain in element setters. |
| 313 // TODO(verwaest): Move code into the element accessor. | 323 // TODO(verwaest): Move code into the element accessor. |
| 314 bool was_dictionary = receiver->HasDictionaryElements(); | 324 bool was_dictionary = receiver->HasDictionaryElements(); |
| 315 Handle<SeededNumberDictionary> dictionary = | 325 Handle<SeededNumberDictionary> dictionary = |
| 316 JSObject::NormalizeElements(receiver); | 326 JSObject::NormalizeElements(receiver); |
| 317 was_dictionary = was_dictionary && dictionary->requires_slow_elements(); | 327 was_dictionary = was_dictionary && dictionary->requires_slow_elements(); |
| 318 | 328 |
| 319 dictionary = SeededNumberDictionary::Set(dictionary, index_, pair, details); | 329 dictionary = SeededNumberDictionary::Set(dictionary, index_, pair, details); |
| 320 dictionary->set_requires_slow_elements(); | 330 dictionary->set_requires_slow_elements(); |
| 321 | 331 |
| 322 if (receiver->HasSlowArgumentsElements()) { | 332 if (receiver->HasSlowArgumentsElements()) { |
| 323 FixedArray* parameter_map = FixedArray::cast(receiver->elements()); | 333 FixedArray* parameter_map = FixedArray::cast(receiver->elements()); |
| 324 uint32_t length = parameter_map->length() - 2; | 334 uint32_t length = parameter_map->length() - 2; |
| 325 if (number_ < length) { | 335 if (number_ < length) { |
| 326 parameter_map->set(number_ + 2, heap()->the_hole_value()); | 336 parameter_map->set(number_ + 2, heap()->the_hole_value()); |
| 327 } | 337 } |
| 328 FixedArray::cast(receiver->elements())->set(1, *dictionary); | 338 FixedArray::cast(receiver->elements())->set(1, *dictionary); |
| 329 } else { | 339 } else { |
| 330 receiver->set_elements(*dictionary); | 340 receiver->set_elements(*dictionary); |
| 331 if (!was_dictionary) heap()->ClearAllICsByKind(Code::KEYED_STORE_IC); | 341 if (!was_dictionary) heap()->ClearAllICsByKind(Code::KEYED_STORE_IC); |
| 332 } | 342 } |
| 333 } else { | 343 } else { |
| 344 PropertyNormalizationMode mode = receiver->map()->is_prototype_map() |
| 345 ? KEEP_INOBJECT_PROPERTIES |
| 346 : CLEAR_INOBJECT_PROPERTIES; |
| 347 // Normalize object to make this operation simple. |
| 348 JSObject::NormalizeProperties(receiver, mode, 0, |
| 349 "TransitionToAccessorPair"); |
| 350 |
| 334 JSObject::SetNormalizedProperty(receiver, name_, pair, details); | 351 JSObject::SetNormalizedProperty(receiver, name_, pair, details); |
| 335 JSObject::ReoptimizeIfPrototype(receiver); | 352 JSObject::ReoptimizeIfPrototype(receiver); |
| 336 } | 353 } |
| 337 | 354 |
| 338 holder_map_ = handle(receiver->map(), isolate_); | 355 holder_map_ = handle(receiver->map(), isolate_); |
| 339 ReloadPropertyInformation(); | 356 ReloadPropertyInformation(); |
| 340 } | 357 } |
| 341 | 358 |
| 342 | 359 |
| 343 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const { | 360 bool LookupIterator::HolderIsReceiverOrHiddenPrototype() const { |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 543 case InterceptorState::kSkipNonMasking: | 560 case InterceptorState::kSkipNonMasking: |
| 544 return true; | 561 return true; |
| 545 case InterceptorState::kProcessNonMasking: | 562 case InterceptorState::kProcessNonMasking: |
| 546 return false; | 563 return false; |
| 547 } | 564 } |
| 548 } | 565 } |
| 549 return interceptor_state_ == InterceptorState::kProcessNonMasking; | 566 return interceptor_state_ == InterceptorState::kProcessNonMasking; |
| 550 } | 567 } |
| 551 } // namespace internal | 568 } // namespace internal |
| 552 } // namespace v8 | 569 } // namespace v8 |
| OLD | NEW |