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 |