| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 <iomanip> | 5 #include <iomanip> |
| 6 #include <sstream> | 6 #include <sstream> |
| 7 | 7 |
| 8 #include "src/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/accessors.h" | 10 #include "src/accessors.h" |
| (...skipping 12335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12346 if (!elements()->IsFixedArray()) return false; | 12346 if (!elements()->IsFixedArray()) return false; |
| 12347 FixedArray* elements = FixedArray::cast(this->elements()); | 12347 FixedArray* elements = FixedArray::cast(this->elements()); |
| 12348 if (elements->map() != heap->sloppy_arguments_elements_map()) { | 12348 if (elements->map() != heap->sloppy_arguments_elements_map()) { |
| 12349 return false; | 12349 return false; |
| 12350 } | 12350 } |
| 12351 FixedArray* arguments = FixedArray::cast(elements->get(1)); | 12351 FixedArray* arguments = FixedArray::cast(elements->get(1)); |
| 12352 return arguments->IsDictionary(); | 12352 return arguments->IsDictionary(); |
| 12353 } | 12353 } |
| 12354 | 12354 |
| 12355 | 12355 |
| 12356 void JSObject::AddFastElement(Handle<JSObject> object, uint32_t index, | 12356 ElementsAccessor* JSObject::GetElementsAccessor() { |
| 12357 Handle<Object> value) { | 12357 return ElementsAccessor::ForKind(GetElementsKind()); |
| 12358 DCHECK(object->HasFastSmiOrObjectElements() || | |
| 12359 object->HasFastArgumentsElements()); | |
| 12360 | |
| 12361 Handle<FixedArray> backing_store(FixedArray::cast(object->elements())); | |
| 12362 if (object->HasSloppyArgumentsElements()) { | |
| 12363 backing_store = handle(FixedArray::cast(backing_store->get(1))); | |
| 12364 } else { | |
| 12365 backing_store = EnsureWritableFastElements(object); | |
| 12366 } | |
| 12367 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); | |
| 12368 | |
| 12369 // Check if the length property of this object needs to be updated. | |
| 12370 uint32_t array_length = 0; | |
| 12371 bool must_update_array_length = false; | |
| 12372 bool introduces_holes = true; | |
| 12373 if (object->IsJSArray()) { | |
| 12374 CHECK(JSArray::cast(*object)->length()->ToArrayLength(&array_length)); | |
| 12375 introduces_holes = index > array_length; | |
| 12376 if (index >= array_length) { | |
| 12377 must_update_array_length = true; | |
| 12378 array_length = index + 1; | |
| 12379 } | |
| 12380 } else { | |
| 12381 introduces_holes = index >= capacity; | |
| 12382 } | |
| 12383 | |
| 12384 uint32_t new_capacity = capacity; | |
| 12385 // Check if the capacity of the backing store needs to be increased, or if | |
| 12386 // a transition to slow elements is necessary. | |
| 12387 if (index >= capacity) { | |
| 12388 bool convert_to_slow = true; | |
| 12389 if ((index - capacity) < kMaxGap) { | |
| 12390 new_capacity = NewElementsCapacity(index + 1); | |
| 12391 DCHECK_LT(index, new_capacity); | |
| 12392 convert_to_slow = object->ShouldConvertToSlowElements(new_capacity); | |
| 12393 } | |
| 12394 if (convert_to_slow) { | |
| 12395 NormalizeElements(object); | |
| 12396 AddDictionaryElement(object, index, value, NONE); | |
| 12397 return; | |
| 12398 } | |
| 12399 } | |
| 12400 | |
| 12401 if (object->HasFastSmiElements() && !value->IsSmi()) { | |
| 12402 // Convert to fast double elements if appropriate. | |
| 12403 if (value->IsNumber()) { | |
| 12404 ElementsKind to_kind = | |
| 12405 introduces_holes ? FAST_HOLEY_DOUBLE_ELEMENTS : FAST_DOUBLE_ELEMENTS; | |
| 12406 ElementsAccessor* accessor = ElementsAccessor::ForKind(to_kind); | |
| 12407 accessor->GrowCapacityAndConvert(object, new_capacity); | |
| 12408 AddFastDoubleElement(object, index, value); | |
| 12409 return; | |
| 12410 } | |
| 12411 | |
| 12412 // Change elements kind from Smi-only to generic FAST if necessary. | |
| 12413 ElementsKind kind = introduces_holes || object->HasFastHoleyElements() | |
| 12414 ? FAST_HOLEY_ELEMENTS | |
| 12415 : FAST_ELEMENTS; | |
| 12416 | |
| 12417 UpdateAllocationSite(object, kind); | |
| 12418 Handle<Map> new_map = GetElementsTransitionMap(object, kind); | |
| 12419 JSObject::MigrateToMap(object, new_map); | |
| 12420 DCHECK(IsFastObjectElementsKind(object->GetElementsKind())); | |
| 12421 } else if (introduces_holes && !object->HasFastHoleyElements()) { | |
| 12422 // If the array is growing, and it's not growth by a single element at the | |
| 12423 // end, make sure that the ElementsKind is HOLEY. | |
| 12424 ElementsKind transitioned_kind = | |
| 12425 GetHoleyElementsKind(object->GetElementsKind()); | |
| 12426 TransitionElementsKind(object, transitioned_kind); | |
| 12427 } | |
| 12428 | |
| 12429 // Increase backing store capacity if that's been decided previously. | |
| 12430 if (capacity != new_capacity) { | |
| 12431 DCHECK(!object->HasFastDoubleElements()); | |
| 12432 ElementsAccessor* accessor = | |
| 12433 value->IsSmi() || object->HasSloppyArgumentsElements() | |
| 12434 ? object->GetElementsAccessor() | |
| 12435 : ElementsAccessor::ForKind(FAST_ELEMENTS); | |
| 12436 accessor->GrowCapacityAndConvert(object, new_capacity); | |
| 12437 } | |
| 12438 | |
| 12439 if (must_update_array_length) { | |
| 12440 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length)); | |
| 12441 } | |
| 12442 | |
| 12443 FixedArray* elements = FixedArray::cast(object->elements()); | |
| 12444 if (object->HasSloppyArgumentsElements()) { | |
| 12445 elements = FixedArray::cast(elements->get(1)); | |
| 12446 } | |
| 12447 elements->set(index, *value); | |
| 12448 } | 12358 } |
| 12449 | 12359 |
| 12450 | 12360 |
| 12361 void JSObject::ValidateElements(Handle<JSObject> object) { |
| 12362 #ifdef ENABLE_SLOW_DCHECKS |
| 12363 if (FLAG_enable_slow_asserts) { |
| 12364 ElementsAccessor* accessor = object->GetElementsAccessor(); |
| 12365 accessor->Validate(object); |
| 12366 } |
| 12367 #endif |
| 12368 } |
| 12369 |
| 12370 |
| 12451 void JSObject::SetDictionaryArgumentsElement(Handle<JSObject> object, | 12371 void JSObject::SetDictionaryArgumentsElement(Handle<JSObject> object, |
| 12452 uint32_t index, | 12372 uint32_t index, |
| 12453 Handle<Object> value, | 12373 Handle<Object> value, |
| 12454 PropertyAttributes attributes) { | 12374 PropertyAttributes attributes) { |
| 12455 // TODO(verwaest): Handle with the elements accessor. | 12375 // TODO(verwaest): Handle with the elements accessor. |
| 12456 Isolate* isolate = object->GetIsolate(); | 12376 Isolate* isolate = object->GetIsolate(); |
| 12457 | 12377 |
| 12458 DCHECK(object->HasDictionaryArgumentsElements()); | 12378 DCHECK(object->HasDictionaryArgumentsElements()); |
| 12459 | 12379 |
| 12460 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); | 12380 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 12477 if ((attributes & READ_ONLY) == 0) { | 12397 if ((attributes & READ_ONLY) == 0) { |
| 12478 value = isolate->factory()->NewAliasedArgumentsEntry(context_index); | 12398 value = isolate->factory()->NewAliasedArgumentsEntry(context_index); |
| 12479 } | 12399 } |
| 12480 AddDictionaryElement(object, index, value, attributes); | 12400 AddDictionaryElement(object, index, value, attributes); |
| 12481 } else { | 12401 } else { |
| 12482 SetDictionaryElement(object, index, value, attributes); | 12402 SetDictionaryElement(object, index, value, attributes); |
| 12483 } | 12403 } |
| 12484 } | 12404 } |
| 12485 | 12405 |
| 12486 | 12406 |
| 12487 void JSObject::AddSloppyArgumentsElement(Handle<JSObject> object, | |
| 12488 uint32_t index, Handle<Object> value, | |
| 12489 PropertyAttributes attributes) { | |
| 12490 DCHECK(object->HasSloppyArgumentsElements()); | |
| 12491 | |
| 12492 // TODO(verwaest): Handle with the elements accessor. | |
| 12493 FixedArray* parameter_map = FixedArray::cast(object->elements()); | |
| 12494 | |
| 12495 #ifdef DEBUG | |
| 12496 uint32_t length = parameter_map->length(); | |
| 12497 if (index < length - 2) { | |
| 12498 Object* probe = parameter_map->get(index + 2); | |
| 12499 DCHECK(probe->IsTheHole()); | |
| 12500 } | |
| 12501 #endif | |
| 12502 | |
| 12503 if (parameter_map->get(1)->IsDictionary()) { | |
| 12504 AddDictionaryElement(object, index, value, attributes); | |
| 12505 } else { | |
| 12506 AddFastElement(object, index, value); | |
| 12507 } | |
| 12508 } | |
| 12509 | |
| 12510 | |
| 12511 void JSObject::SetDictionaryElement(Handle<JSObject> object, uint32_t index, | 12407 void JSObject::SetDictionaryElement(Handle<JSObject> object, uint32_t index, |
| 12512 Handle<Object> value, | 12408 Handle<Object> value, |
| 12513 PropertyAttributes attributes) { | 12409 PropertyAttributes attributes) { |
| 12514 // TODO(verwaest): Handle with the elements accessor. | 12410 // TODO(verwaest): Handle with the elements accessor. |
| 12515 Isolate* isolate = object->GetIsolate(); | 12411 Isolate* isolate = object->GetIsolate(); |
| 12516 | 12412 |
| 12517 // Insert element in the dictionary. | 12413 // Insert element in the dictionary. |
| 12518 Handle<FixedArray> elements(FixedArray::cast(object->elements())); | 12414 Handle<FixedArray> elements(FixedArray::cast(object->elements())); |
| 12519 bool is_arguments = | 12415 bool is_arguments = |
| 12520 (elements->map() == isolate->heap()->sloppy_arguments_elements_map()); | 12416 (elements->map() == isolate->heap()->sloppy_arguments_elements_map()); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12592 // Update the array length if this JSObject is an array. | 12488 // Update the array length if this JSObject is an array. |
| 12593 if (object->IsJSArray()) { | 12489 if (object->IsJSArray()) { |
| 12594 JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray>::cast(object), index, | 12490 JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray>::cast(object), index, |
| 12595 value); | 12491 value); |
| 12596 } | 12492 } |
| 12597 | 12493 |
| 12598 // Attempt to put this object back in fast case. | 12494 // Attempt to put this object back in fast case. |
| 12599 if (object->ShouldConvertToFastElements()) { | 12495 if (object->ShouldConvertToFastElements()) { |
| 12600 uint32_t new_length = 0; | 12496 uint32_t new_length = 0; |
| 12601 if (object->IsJSArray()) { | 12497 if (object->IsJSArray()) { |
| 12602 CHECK( | 12498 CHECK(JSArray::cast(*object)->length()->ToArrayLength(&new_length)); |
| 12603 Handle<JSArray>::cast(object)->length()->ToArrayLength(&new_length)); | |
| 12604 } else { | 12499 } else { |
| 12605 new_length = dictionary->max_number_key() + 1; | 12500 new_length = dictionary->max_number_key() + 1; |
| 12606 } | 12501 } |
| 12607 ElementsKind to_kind = object->BestFittingFastElementsKind(); | 12502 ElementsKind to_kind = object->BestFittingFastElementsKind(); |
| 12608 ElementsAccessor* accessor = ElementsAccessor::ForKind(to_kind); | 12503 ElementsAccessor* accessor = ElementsAccessor::ForKind(to_kind); |
| 12609 accessor->GrowCapacityAndConvert(object, new_length); | 12504 accessor->GrowCapacityAndConvert(object, new_length); |
| 12610 #ifdef DEBUG | 12505 #ifdef DEBUG |
| 12611 if (FLAG_trace_normalization) { | 12506 if (FLAG_trace_normalization) { |
| 12612 OFStream os(stdout); | 12507 OFStream os(stdout); |
| 12613 os << "Object elements are fast case again:\n"; | 12508 os << "Object elements are fast case again:\n"; |
| 12614 object->Print(os); | 12509 object->Print(os); |
| 12615 } | 12510 } |
| 12616 #endif | 12511 #endif |
| 12617 } | 12512 } |
| 12618 } | 12513 } |
| 12619 | 12514 |
| 12620 | 12515 |
| 12621 void JSObject::AddFastDoubleElement(Handle<JSObject> object, uint32_t index, | |
| 12622 Handle<Object> value) { | |
| 12623 DCHECK(object->HasFastDoubleElements()); | |
| 12624 | |
| 12625 Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements())); | |
| 12626 uint32_t capacity = static_cast<uint32_t>(base_elms->length()); | |
| 12627 | |
| 12628 // Check if the length property of this object needs to be updated. | |
| 12629 uint32_t array_length = 0; | |
| 12630 bool must_update_array_length = false; | |
| 12631 bool introduces_holes = true; | |
| 12632 if (object->IsJSArray()) { | |
| 12633 // In case of JSArray, the length does not equal the capacity. | |
| 12634 CHECK(JSArray::cast(*object)->length()->ToArrayLength(&array_length)); | |
| 12635 introduces_holes = index > array_length; | |
| 12636 if (index >= array_length) { | |
| 12637 must_update_array_length = true; | |
| 12638 array_length = index + 1; | |
| 12639 } | |
| 12640 } else { | |
| 12641 introduces_holes = index >= capacity; | |
| 12642 } | |
| 12643 | |
| 12644 uint32_t new_capacity = capacity; | |
| 12645 // Check if the capacity of the backing store needs to be increased, or if | |
| 12646 // a transition to slow elements is necessary. | |
| 12647 if (index >= capacity) { | |
| 12648 bool convert_to_slow = true; | |
| 12649 if ((index - capacity) < kMaxGap) { | |
| 12650 new_capacity = NewElementsCapacity(index + 1); | |
| 12651 DCHECK_LT(index, new_capacity); | |
| 12652 convert_to_slow = object->ShouldConvertToSlowElements(new_capacity); | |
| 12653 } | |
| 12654 if (convert_to_slow) { | |
| 12655 NormalizeElements(object); | |
| 12656 AddDictionaryElement(object, index, value, NONE); | |
| 12657 return; | |
| 12658 } | |
| 12659 } | |
| 12660 | |
| 12661 // If the value object is not a heap number, switch to fast elements and try | |
| 12662 // again. | |
| 12663 if (!value->IsNumber()) { | |
| 12664 ElementsKind to_kind = | |
| 12665 introduces_holes ? FAST_HOLEY_ELEMENTS : FAST_ELEMENTS; | |
| 12666 ElementsAccessor* accessor = ElementsAccessor::ForKind(to_kind); | |
| 12667 accessor->GrowCapacityAndConvert(object, new_capacity); | |
| 12668 return AddFastElement(object, index, value); | |
| 12669 } | |
| 12670 | |
| 12671 // If the array is growing, and it's not growth by a single element at the | |
| 12672 // end, make sure that the ElementsKind is HOLEY. | |
| 12673 if (introduces_holes && !object->HasFastHoleyElements()) { | |
| 12674 ElementsKind transitioned_kind = | |
| 12675 GetHoleyElementsKind(object->GetElementsKind()); | |
| 12676 TransitionElementsKind(object, transitioned_kind); | |
| 12677 } | |
| 12678 | |
| 12679 // Increase backing store capacity if that's been decided previously. | |
| 12680 if (capacity != new_capacity) { | |
| 12681 ElementsAccessor* accessor = object->GetElementsAccessor(); | |
| 12682 accessor->GrowCapacityAndConvert(object, new_capacity); | |
| 12683 } | |
| 12684 | |
| 12685 if (must_update_array_length) { | |
| 12686 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length)); | |
| 12687 } | |
| 12688 | |
| 12689 FixedDoubleArray::cast(object->elements())->set(index, value->Number()); | |
| 12690 } | |
| 12691 | |
| 12692 | |
| 12693 // static | 12516 // static |
| 12694 MaybeHandle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, | 12517 MaybeHandle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, |
| 12695 uint32_t index, Handle<Object> value, | 12518 uint32_t index, Handle<Object> value, |
| 12696 LanguageMode language_mode) { | 12519 LanguageMode language_mode) { |
| 12697 Isolate* isolate = object->GetIsolate(); | 12520 Isolate* isolate = object->GetIsolate(); |
| 12698 LookupIterator it(isolate, object, index); | 12521 LookupIterator it(isolate, object, index); |
| 12699 return SetProperty(&it, value, language_mode, MAY_BE_STORE_FROM_KEYED); | 12522 return SetProperty(&it, value, language_mode, MAY_BE_STORE_FROM_KEYED); |
| 12700 } | 12523 } |
| 12701 | 12524 |
| 12702 | 12525 |
| 12526 static void AddFastElement(Handle<JSObject> object, uint32_t index, |
| 12527 Handle<Object> value, ElementsKind from_kind, |
| 12528 uint32_t capacity, uint32_t new_capacity) { |
| 12529 // Check if the length property of this object needs to be updated. |
| 12530 uint32_t array_length = 0; |
| 12531 bool introduces_holes = true; |
| 12532 if (object->IsJSArray()) { |
| 12533 CHECK(JSArray::cast(*object)->length()->ToArrayLength(&array_length)); |
| 12534 introduces_holes = index > array_length; |
| 12535 } else { |
| 12536 introduces_holes = index >= capacity; |
| 12537 } |
| 12538 |
| 12539 ElementsKind to_kind = value->OptimalElementsKind(); |
| 12540 if (IsHoleyElementsKind(from_kind)) to_kind = GetHoleyElementsKind(to_kind); |
| 12541 to_kind = IsMoreGeneralElementsKindTransition(from_kind, to_kind) ? to_kind |
| 12542 : from_kind; |
| 12543 if (introduces_holes) to_kind = GetHoleyElementsKind(to_kind); |
| 12544 ElementsAccessor* accessor = ElementsAccessor::ForKind(to_kind); |
| 12545 |
| 12546 // Increase backing store capacity if that's been decided previously. |
| 12547 if (capacity != new_capacity || IsDictionaryElementsKind(from_kind) || |
| 12548 IsFastDoubleElementsKind(from_kind) != |
| 12549 IsFastDoubleElementsKind(to_kind)) { |
| 12550 accessor->GrowCapacityAndConvert(object, new_capacity); |
| 12551 } else if (from_kind != to_kind) { |
| 12552 JSObject::TransitionElementsKind(object, to_kind); |
| 12553 } |
| 12554 |
| 12555 if (object->IsJSArray() && index >= array_length) { |
| 12556 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(index + 1)); |
| 12557 } |
| 12558 |
| 12559 accessor->Set(object->elements(), index, *value); |
| 12560 } |
| 12561 |
| 12562 |
| 12703 // static | 12563 // static |
| 12704 MaybeHandle<Object> JSObject::AddDataElement(Handle<JSObject> receiver, | 12564 MaybeHandle<Object> JSObject::AddDataElement(Handle<JSObject> object, |
| 12705 uint32_t index, | 12565 uint32_t index, |
| 12706 Handle<Object> value, | 12566 Handle<Object> value, |
| 12707 PropertyAttributes attributes) { | 12567 PropertyAttributes attributes) { |
| 12708 DCHECK(receiver->map()->is_extensible()); | 12568 DCHECK(object->map()->is_extensible()); |
| 12709 | 12569 |
| 12710 Isolate* isolate = receiver->GetIsolate(); | 12570 Isolate* isolate = object->GetIsolate(); |
| 12711 | 12571 |
| 12712 // TODO(verwaest): Use ElementAccessor. | 12572 // TODO(verwaest): Use ElementAccessor. |
| 12713 Handle<Object> old_length_handle; | 12573 Handle<Object> old_length_handle; |
| 12714 if (receiver->IsJSArray() && receiver->map()->is_observed()) { | 12574 if (object->IsJSArray() && object->map()->is_observed()) { |
| 12715 old_length_handle = handle(JSArray::cast(*receiver)->length(), isolate); | 12575 old_length_handle = handle(JSArray::cast(*object)->length(), isolate); |
| 12716 } | 12576 } |
| 12717 | 12577 |
| 12718 if (attributes != NONE) { | 12578 ElementsKind kind = object->GetElementsKind(); |
| 12719 Handle<SeededNumberDictionary> d = JSObject::NormalizeElements(receiver); | 12579 bool handle_slow = false; |
| 12720 // TODO(verwaest): Move this into NormalizeElements. | 12580 uint32_t capacity = 0; |
| 12721 d->set_requires_slow_elements(); | 12581 uint32_t new_capacity = 0; |
| 12582 if (IsFastElementsKind(kind) || object->HasFastArgumentsElements()) { |
| 12583 if (attributes != NONE) { |
| 12584 // TODO(verwaest): Move set_requires_slow_elements into NormalizeElements. |
| 12585 NormalizeElements(object)->set_requires_slow_elements(); |
| 12586 handle_slow = true; |
| 12587 } else { |
| 12588 if (IsSloppyArgumentsElements(kind)) { |
| 12589 FixedArray* parameter_map = FixedArray::cast(object->elements()); |
| 12590 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 12591 capacity = static_cast<uint32_t>(arguments->length()); |
| 12592 } else { |
| 12593 if (IsFastSmiOrObjectElementsKind(kind)) { |
| 12594 EnsureWritableFastElements(object); |
| 12595 } |
| 12596 capacity = static_cast<uint32_t>(object->elements()->length()); |
| 12597 } |
| 12598 |
| 12599 new_capacity = capacity; |
| 12600 // Check if the capacity of the backing store needs to be increased, or if |
| 12601 // a transition to slow elements is necessary. |
| 12602 if (index >= capacity) { |
| 12603 handle_slow = true; |
| 12604 if ((index - capacity) < kMaxGap) { |
| 12605 new_capacity = NewElementsCapacity(index + 1); |
| 12606 DCHECK_LT(index, new_capacity); |
| 12607 handle_slow = object->ShouldConvertToSlowElements(new_capacity); |
| 12608 } |
| 12609 if (handle_slow) NormalizeElements(object); |
| 12610 } |
| 12611 } |
| 12612 } else { |
| 12613 handle_slow = true; |
| 12722 } | 12614 } |
| 12723 | 12615 |
| 12724 Handle<Object> result = value; | 12616 if (handle_slow) { |
| 12725 | 12617 DCHECK(object->HasDictionaryElements() || |
| 12726 switch (receiver->GetElementsKind()) { | 12618 object->HasDictionaryArgumentsElements()); |
| 12727 case FAST_SMI_ELEMENTS: | 12619 AddDictionaryElement(object, index, value, attributes); |
| 12728 case FAST_ELEMENTS: | 12620 } else { |
| 12729 case FAST_HOLEY_SMI_ELEMENTS: | 12621 AddFastElement(object, index, value, kind, capacity, new_capacity); |
| 12730 case FAST_HOLEY_ELEMENTS: | |
| 12731 AddFastElement(receiver, index, value); | |
| 12732 break; | |
| 12733 case FAST_DOUBLE_ELEMENTS: | |
| 12734 case FAST_HOLEY_DOUBLE_ELEMENTS: | |
| 12735 AddFastDoubleElement(receiver, index, value); | |
| 12736 break; | |
| 12737 | |
| 12738 case DICTIONARY_ELEMENTS: | |
| 12739 AddDictionaryElement(receiver, index, value, attributes); | |
| 12740 break; | |
| 12741 case SLOPPY_ARGUMENTS_ELEMENTS: | |
| 12742 AddSloppyArgumentsElement(receiver, index, value, attributes); | |
| 12743 break; | |
| 12744 | |
| 12745 // Elements cannot be added to typed arrays. | |
| 12746 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | |
| 12747 case EXTERNAL_##TYPE##_ELEMENTS: \ | |
| 12748 case TYPE##_ELEMENTS: | |
| 12749 | |
| 12750 TYPED_ARRAYS(TYPED_ARRAY_CASE) | |
| 12751 | |
| 12752 #undef TYPED_ARRAY_CASE | |
| 12753 UNREACHABLE(); | |
| 12754 break; | |
| 12755 } | 12622 } |
| 12756 | 12623 |
| 12757 if (!old_length_handle.is_null() && | 12624 if (!old_length_handle.is_null() && |
| 12758 !old_length_handle->SameValue( | 12625 !old_length_handle->SameValue(Handle<JSArray>::cast(object)->length())) { |
| 12759 Handle<JSArray>::cast(receiver)->length())) { | 12626 // |old_length_handle| is kept null above unless the object is observed. |
| 12760 // |old_length_handle| is kept null above unless the receiver is observed. | 12627 DCHECK(object->map()->is_observed()); |
| 12761 DCHECK(receiver->map()->is_observed()); | 12628 Handle<JSArray> array = Handle<JSArray>::cast(object); |
| 12762 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | |
| 12763 Handle<String> name = isolate->factory()->Uint32ToString(index); | 12629 Handle<String> name = isolate->factory()->Uint32ToString(index); |
| 12764 Handle<Object> new_length_handle(array->length(), isolate); | 12630 Handle<Object> new_length_handle(array->length(), isolate); |
| 12765 uint32_t old_length = 0; | 12631 uint32_t old_length = 0; |
| 12766 uint32_t new_length = 0; | 12632 uint32_t new_length = 0; |
| 12767 CHECK(old_length_handle->ToArrayLength(&old_length)); | 12633 CHECK(old_length_handle->ToArrayLength(&old_length)); |
| 12768 CHECK(new_length_handle->ToArrayLength(&new_length)); | 12634 CHECK(new_length_handle->ToArrayLength(&new_length)); |
| 12769 | 12635 |
| 12770 RETURN_ON_EXCEPTION(isolate, BeginPerformSplice(array), Object); | 12636 RETURN_ON_EXCEPTION(isolate, BeginPerformSplice(array), Object); |
| 12771 RETURN_ON_EXCEPTION( | 12637 RETURN_ON_EXCEPTION( |
| 12772 isolate, JSObject::EnqueueChangeRecord( | 12638 isolate, EnqueueChangeRecord(array, "add", name, |
| 12773 array, "add", name, isolate->factory()->the_hole_value()), | 12639 isolate->factory()->the_hole_value()), |
| 12774 Object); | 12640 Object); |
| 12775 RETURN_ON_EXCEPTION( | 12641 RETURN_ON_EXCEPTION(isolate, |
| 12776 isolate, JSObject::EnqueueChangeRecord( | 12642 EnqueueChangeRecord(array, "update", |
| 12777 array, "update", isolate->factory()->length_string(), | 12643 isolate->factory()->length_string(), |
| 12778 old_length_handle), | 12644 old_length_handle), |
| 12779 Object); | 12645 Object); |
| 12780 RETURN_ON_EXCEPTION(isolate, EndPerformSplice(array), Object); | 12646 RETURN_ON_EXCEPTION(isolate, EndPerformSplice(array), Object); |
| 12781 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); | 12647 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
| 12782 RETURN_ON_EXCEPTION(isolate, EnqueueSpliceRecord(array, old_length, deleted, | 12648 RETURN_ON_EXCEPTION(isolate, EnqueueSpliceRecord(array, old_length, deleted, |
| 12783 new_length - old_length), | 12649 new_length - old_length), |
| 12784 Object); | 12650 Object); |
| 12785 } else if (receiver->map()->is_observed()) { | 12651 } else if (object->map()->is_observed()) { |
| 12786 Handle<String> name = isolate->factory()->Uint32ToString(index); | 12652 Handle<String> name = isolate->factory()->Uint32ToString(index); |
| 12787 RETURN_ON_EXCEPTION(isolate, JSObject::EnqueueChangeRecord( | 12653 RETURN_ON_EXCEPTION( |
| 12788 receiver, "add", name, | 12654 isolate, EnqueueChangeRecord(object, "add", name, |
| 12789 isolate->factory()->the_hole_value()), | 12655 isolate->factory()->the_hole_value()), |
| 12790 Object); | 12656 Object); |
| 12791 } | 12657 } |
| 12792 | 12658 |
| 12793 return result; | 12659 return value; |
| 12794 } | 12660 } |
| 12795 | 12661 |
| 12796 | 12662 |
| 12797 const double AllocationSite::kPretenureRatio = 0.85; | 12663 const double AllocationSite::kPretenureRatio = 0.85; |
| 12798 | 12664 |
| 12799 | 12665 |
| 12800 void AllocationSite::ResetPretenureDecision() { | 12666 void AllocationSite::ResetPretenureDecision() { |
| 12801 set_pretenure_decision(kUndecided); | 12667 set_pretenure_decision(kUndecided); |
| 12802 set_memento_found_count(0); | 12668 set_memento_found_count(0); |
| 12803 set_memento_create_count(0); | 12669 set_memento_create_count(0); |
| (...skipping 3693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 16497 Handle<Object> new_value) { | 16363 Handle<Object> new_value) { |
| 16498 if (cell->value() != *new_value) { | 16364 if (cell->value() != *new_value) { |
| 16499 cell->set_value(*new_value); | 16365 cell->set_value(*new_value); |
| 16500 Isolate* isolate = cell->GetIsolate(); | 16366 Isolate* isolate = cell->GetIsolate(); |
| 16501 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 16367 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 16502 isolate, DependentCode::kPropertyCellChangedGroup); | 16368 isolate, DependentCode::kPropertyCellChangedGroup); |
| 16503 } | 16369 } |
| 16504 } | 16370 } |
| 16505 } // namespace internal | 16371 } // namespace internal |
| 16506 } // namespace v8 | 16372 } // namespace v8 |
| OLD | NEW |