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

Side by Side Diff: src/objects.cc

Issue 1177043012: More cleanly separate adding from setting elements (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rename Created 5 years, 6 months 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/objects.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 11772 matching lines...) Expand 10 before | Expand all | Expand 10 after
11783 if (IsHoleyElementsKind(elements_kind)) { 11783 if (IsHoleyElementsKind(elements_kind)) {
11784 new_elements_kind = FAST_HOLEY_ELEMENTS; 11784 new_elements_kind = FAST_HOLEY_ELEMENTS;
11785 } else { 11785 } else {
11786 new_elements_kind = FAST_ELEMENTS; 11786 new_elements_kind = FAST_ELEMENTS;
11787 } 11787 }
11788 } 11788 }
11789 Handle<FixedArrayBase> old_elements(object->elements()); 11789 Handle<FixedArrayBase> old_elements(object->elements());
11790 ElementsAccessor* accessor = ElementsAccessor::ForKind(new_elements_kind); 11790 ElementsAccessor* accessor = ElementsAccessor::ForKind(new_elements_kind);
11791 accessor->CopyElements(object, new_elements, elements_kind); 11791 accessor->CopyElements(object, new_elements, elements_kind);
11792 11792
11793 if (elements_kind != SLOPPY_ARGUMENTS_ELEMENTS) { 11793 if (elements_kind == SLOPPY_ARGUMENTS_ELEMENTS) {
11794 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(old_elements);
11795 parameter_map->set(1, *new_elements);
11796 } else {
11794 Handle<Map> new_map = (new_elements_kind != elements_kind) 11797 Handle<Map> new_map = (new_elements_kind != elements_kind)
11795 ? GetElementsTransitionMap(object, new_elements_kind) 11798 ? GetElementsTransitionMap(object, new_elements_kind)
11796 : handle(object->map()); 11799 : handle(object->map());
11797 JSObject::ValidateElements(object); 11800 JSObject::ValidateElements(object);
11798 JSObject::SetMapAndElements(object, new_map, new_elements); 11801 JSObject::SetMapAndElements(object, new_map, new_elements);
11799 11802
11800 // Transition through the allocation site as well if present. 11803 // Transition through the allocation site as well if present.
11801 JSObject::UpdateAllocationSite(object, new_elements_kind); 11804 JSObject::UpdateAllocationSite(object, new_elements_kind);
11802 } else {
11803 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(old_elements);
11804 parameter_map->set(1, *new_elements);
11805 } 11805 }
11806 11806
11807 if (FLAG_trace_elements_transitions) { 11807 if (FLAG_trace_elements_transitions) {
11808 PrintElementsTransition(stdout, object, elements_kind, old_elements, 11808 PrintElementsTransition(stdout, object, elements_kind, old_elements,
11809 object->GetElementsKind(), new_elements); 11809 object->GetElementsKind(), new_elements);
11810 } 11810 }
11811 11811
11812 return new_elements; 11812 return new_elements;
11813 } 11813 }
11814 11814
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after
12420 if (!elements()->IsFixedArray()) return false; 12420 if (!elements()->IsFixedArray()) return false;
12421 FixedArray* elements = FixedArray::cast(this->elements()); 12421 FixedArray* elements = FixedArray::cast(this->elements());
12422 if (elements->map() != heap->sloppy_arguments_elements_map()) { 12422 if (elements->map() != heap->sloppy_arguments_elements_map()) {
12423 return false; 12423 return false;
12424 } 12424 }
12425 FixedArray* arguments = FixedArray::cast(elements->get(1)); 12425 FixedArray* arguments = FixedArray::cast(elements->get(1));
12426 return arguments->IsDictionary(); 12426 return arguments->IsDictionary();
12427 } 12427 }
12428 12428
12429 12429
12430 void JSObject::SetFastElement(Handle<JSObject> object, uint32_t index, 12430 void JSObject::AddFastElement(Handle<JSObject> object, uint32_t index,
12431 Handle<Object> value) { 12431 Handle<Object> value) {
12432 DCHECK(object->HasFastSmiOrObjectElements() || 12432 DCHECK(object->HasFastSmiOrObjectElements() ||
12433 object->HasFastArgumentsElements()); 12433 object->HasFastArgumentsElements());
12434 12434
12435 Isolate* isolate = object->GetIsolate(); 12435 Isolate* isolate = object->GetIsolate();
12436 12436
12437 // Array optimizations rely on the prototype lookups of Array objects always
12438 // returning undefined. If there is a store to the initial prototype object,
12439 // make sure all of these optimizations are invalidated.
12440 isolate->UpdateArrayProtectorOnSetElement(object);
12441
12442 Handle<FixedArray> backing_store(FixedArray::cast(object->elements())); 12437 Handle<FixedArray> backing_store(FixedArray::cast(object->elements()));
12443 if (object->HasSloppyArgumentsElements()) { 12438 if (object->HasSloppyArgumentsElements()) {
12444 backing_store = handle(FixedArray::cast(backing_store->get(1))); 12439 backing_store = handle(FixedArray::cast(backing_store->get(1)));
12445 } else { 12440 } else {
12441 // Array optimizations rely on the prototype lookups of Array objects always
12442 // returning undefined. If there is a store to the initial prototype object,
12443 // make sure all of these optimizations are invalidated.
12444 isolate->UpdateArrayProtectorOnSetElement(object);
12446 backing_store = EnsureWritableFastElements(object); 12445 backing_store = EnsureWritableFastElements(object);
12447 } 12446 }
12448 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); 12447 uint32_t capacity = static_cast<uint32_t>(backing_store->length());
12449 12448
12450 uint32_t new_capacity = capacity; 12449 uint32_t new_capacity = capacity;
12451 // Check if the length property of this object needs to be updated. 12450 // Check if the length property of this object needs to be updated.
12452 uint32_t array_length = 0; 12451 uint32_t array_length = 0;
12453 bool must_update_array_length = false; 12452 bool must_update_array_length = false;
12454 bool introduces_holes = true; 12453 bool introduces_holes = true;
12455 if (object->IsJSArray()) { 12454 if (object->IsJSArray()) {
12456 CHECK( 12455 CHECK(
12457 Handle<JSArray>::cast(object)->length()->ToArrayLength(&array_length)); 12456 Handle<JSArray>::cast(object)->length()->ToArrayLength(&array_length));
12458 introduces_holes = index > array_length; 12457 introduces_holes = index > array_length;
12459 if (index >= array_length) { 12458 if (index >= array_length) {
12460 must_update_array_length = true; 12459 must_update_array_length = true;
12461 array_length = index + 1; 12460 array_length = index + 1;
12462 } 12461 }
12463 } else { 12462 } else {
12464 introduces_holes = index >= capacity; 12463 introduces_holes = index >= capacity;
12465 } 12464 }
12466 12465
12467 // If the array is growing, and it's not growth by a single element at the 12466 // If the array is growing, and it's not growth by a single element at the
12468 // end, make sure that the ElementsKind is HOLEY. 12467 // end, make sure that the ElementsKind is HOLEY.
12469 ElementsKind elements_kind = object->GetElementsKind(); 12468 if (introduces_holes && !IsFastHoleyElementsKind(object->GetElementsKind())) {
12470 if (introduces_holes && 12469 ElementsKind transitioned_kind =
12471 IsFastElementsKind(elements_kind) && 12470 GetHoleyElementsKind(object->GetElementsKind());
12472 !IsFastHoleyElementsKind(elements_kind)) {
12473 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind);
12474 TransitionElementsKind(object, transitioned_kind); 12471 TransitionElementsKind(object, transitioned_kind);
12475 } 12472 }
12476 12473
12477 // Check if the capacity of the backing store needs to be increased, or if 12474 // Check if the capacity of the backing store needs to be increased, or if
12478 // a transition to slow elements is necessary. 12475 // a transition to slow elements is necessary.
12479 if (index >= capacity) { 12476 if (index >= capacity) {
12480 bool convert_to_slow = true; 12477 bool convert_to_slow = true;
12481 if ((index - capacity) < kMaxGap) { 12478 if ((index - capacity) < kMaxGap) {
12482 new_capacity = NewElementsCapacity(index + 1); 12479 new_capacity = NewElementsCapacity(index + 1);
12483 DCHECK(new_capacity > index); 12480 DCHECK(new_capacity > index);
12484 if (!object->ShouldConvertToSlowElements(new_capacity)) { 12481 if (!object->ShouldConvertToSlowElements(new_capacity)) {
12485 convert_to_slow = false; 12482 convert_to_slow = false;
12486 } 12483 }
12487 } 12484 }
12488 if (convert_to_slow) { 12485 if (convert_to_slow) {
12489 NormalizeElements(object); 12486 NormalizeElements(object);
12490 SetDictionaryElement(object, index, value, NONE); 12487 AddDictionaryElement(object, index, value, NONE);
12491 return; 12488 return;
12492 } 12489 }
12493 } 12490 }
12491
12494 // Convert to fast double elements if appropriate. 12492 // Convert to fast double elements if appropriate.
12495 if (object->HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { 12493 if (object->HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) {
12496 // Consider fixing the boilerplate as well if we have one. 12494 // Consider fixing the boilerplate as well if we have one.
12497 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) 12495 ElementsKind to_kind = IsHoleyElementsKind(object->GetElementsKind())
12498 ? FAST_HOLEY_DOUBLE_ELEMENTS 12496 ? FAST_HOLEY_DOUBLE_ELEMENTS
12499 : FAST_DOUBLE_ELEMENTS; 12497 : FAST_DOUBLE_ELEMENTS;
12500 12498
12501 UpdateAllocationSite(object, to_kind); 12499 UpdateAllocationSite(object, to_kind);
12502 12500
12503 SetFastDoubleElementsCapacityAndLength(object, new_capacity, array_length); 12501 SetFastDoubleElementsCapacityAndLength(object, new_capacity, array_length);
12504 FixedDoubleArray::cast(object->elements())->set(index, value->Number()); 12502 FixedDoubleArray::cast(object->elements())->set(index, value->Number());
12505 JSObject::ValidateElements(object); 12503 JSObject::ValidateElements(object);
12506 return; 12504 return;
12507 } 12505 }
12506
12508 // Change elements kind from Smi-only to generic FAST if necessary. 12507 // Change elements kind from Smi-only to generic FAST if necessary.
12509 if (object->HasFastSmiElements() && !value->IsSmi()) { 12508 if (object->HasFastSmiElements() && !value->IsSmi()) {
12510 ElementsKind kind = object->HasFastHoleyElements() 12509 ElementsKind kind = object->HasFastHoleyElements()
12511 ? FAST_HOLEY_ELEMENTS 12510 ? FAST_HOLEY_ELEMENTS
12512 : FAST_ELEMENTS; 12511 : FAST_ELEMENTS;
12513 12512
12514 UpdateAllocationSite(object, kind); 12513 UpdateAllocationSite(object, kind);
12515 Handle<Map> new_map = GetElementsTransitionMap(object, kind); 12514 Handle<Map> new_map = GetElementsTransitionMap(object, kind);
12516 JSObject::MigrateToMap(object, new_map); 12515 JSObject::MigrateToMap(object, new_map);
12517 DCHECK(IsFastObjectElementsKind(object->GetElementsKind())); 12516 DCHECK(IsFastObjectElementsKind(object->GetElementsKind()));
12518 } 12517 }
12518
12519 // Increase backing store capacity if that's been decided previously. 12519 // Increase backing store capacity if that's been decided previously.
12520 if (new_capacity != capacity) { 12520 if (new_capacity != capacity) {
12521 SetFastElementsCapacitySmiMode smi_mode = 12521 SetFastElementsCapacitySmiMode smi_mode =
12522 value->IsSmi() && object->HasFastSmiElements() 12522 value->IsSmi() && object->HasFastSmiElements()
12523 ? kAllowSmiElements 12523 ? kAllowSmiElements
12524 : kDontAllowSmiElements; 12524 : kDontAllowSmiElements;
12525 Handle<FixedArray> new_elements = 12525 Handle<FixedArray> new_elements =
12526 SetFastElementsCapacityAndLength(object, new_capacity, array_length, 12526 SetFastElementsCapacityAndLength(object, new_capacity, array_length,
12527 smi_mode); 12527 smi_mode);
12528 new_elements->set(index, *value); 12528 new_elements->set(index, *value);
12529 JSObject::ValidateElements(object); 12529 JSObject::ValidateElements(object);
12530 return; 12530 return;
12531 } 12531 }
12532 12532
12533 // Finally, set the new element and length. 12533 // Finally, set the new element and length.
12534 DCHECK(object->elements()->IsFixedArray()); 12534 DCHECK(object->elements()->IsFixedArray());
12535 backing_store->set(index, *value); 12535 backing_store->set(index, *value);
12536 if (must_update_array_length) { 12536 if (must_update_array_length) {
12537 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length)); 12537 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(array_length));
12538 } 12538 }
12539 } 12539 }
12540 12540
12541 12541
12542 void JSObject::SetSloppyArgumentsElement(Handle<JSObject> object, 12542 void JSObject::SetDictionaryArgumentsElement(Handle<JSObject> object,
12543 uint32_t index, Handle<Object> value, 12543 uint32_t index,
12544 PropertyAttributes attributes) { 12544 Handle<Object> value,
12545 PropertyAttributes attributes) {
12545 // TODO(verwaest): Handle with the elements accessor. 12546 // TODO(verwaest): Handle with the elements accessor.
12546 Isolate* isolate = object->GetIsolate(); 12547 Isolate* isolate = object->GetIsolate();
12547 12548
12548 DCHECK(object->HasSloppyArgumentsElements()); 12549 DCHECK(object->HasDictionaryArgumentsElements());
12549 12550
12550 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); 12551 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
12551 uint32_t length = parameter_map->length(); 12552 uint32_t length = parameter_map->length();
12552 Handle<Object> probe = 12553 Handle<Object> probe =
12553 index < length - 2 12554 index < length - 2
12554 ? Handle<Object>(parameter_map->get(index + 2), isolate) 12555 ? handle(parameter_map->get(index + 2), isolate)
12555 : Handle<Object>(); 12556 : Handle<Object>::cast(isolate->factory()->the_hole_value());
12556 if (!probe.is_null() && !probe->IsTheHole()) { 12557 if (!probe->IsTheHole()) {
12557 Handle<Context> context(Context::cast(parameter_map->get(0))); 12558 Handle<Context> context(Context::cast(parameter_map->get(0)));
12558 int context_index = Handle<Smi>::cast(probe)->value(); 12559 int context_index = Handle<Smi>::cast(probe)->value();
12559 DCHECK(!context->get(context_index)->IsTheHole()); 12560 DCHECK(!context->get(context_index)->IsTheHole());
12560 context->set(context_index, *value); 12561 context->set(context_index, *value);
12561 12562
12562 if (attributes == NONE) return; 12563 DCHECK_NE(NONE, attributes);
12563 12564
12564 // Redefining attributes of an aliased element destroys fast aliasing. 12565 // Redefining attributes of an aliased element destroys fast aliasing.
12565 parameter_map->set_the_hole(index + 2); 12566 parameter_map->set_the_hole(index + 2);
12566 // For elements that are still writable we re-establish slow aliasing. 12567 // For elements that are still writable we re-establish slow aliasing.
12567 if ((attributes & READ_ONLY) == 0) { 12568 if ((attributes & READ_ONLY) == 0) {
12568 value = Handle<Object>::cast( 12569 value = isolate->factory()->NewAliasedArgumentsEntry(context_index);
12569 isolate->factory()->NewAliasedArgumentsEntry(context_index));
12570 } 12570 }
12571 } 12571 AddDictionaryElement(object, index, value, attributes);
12572 12572 } else {
12573 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
12574 if (arguments->IsDictionary()) {
12575 SetDictionaryElement(object, index, value, attributes); 12573 SetDictionaryElement(object, index, value, attributes);
12576 } else {
12577 SetFastElement(object, index, value);
12578 } 12574 }
12579 } 12575 }
12580 12576
12577
12578 void JSObject::AddSloppyArgumentsElement(Handle<JSObject> object,
12579 uint32_t index, Handle<Object> value,
12580 PropertyAttributes attributes) {
12581 DCHECK(object->HasSloppyArgumentsElements());
12582
12583 // TODO(verwaest): Handle with the elements accessor.
12584 FixedArray* parameter_map = FixedArray::cast(object->elements());
12585
12586 #ifdef DEBUG
12587 uint32_t length = parameter_map->length();
12588 if (index < length - 2) {
12589 Object* probe = parameter_map->get(index + 2);
12590 DCHECK(probe->IsTheHole());
12591 }
12592 #endif
12593
12594 if (parameter_map->get(1)->IsDictionary()) {
12595 AddDictionaryElement(object, index, value, attributes);
12596 } else {
12597 AddFastElement(object, index, value);
12598 }
12599 }
12600
12581 12601
12582 void JSObject::SetDictionaryElement(Handle<JSObject> object, uint32_t index, 12602 void JSObject::SetDictionaryElement(Handle<JSObject> object, uint32_t index,
12583 Handle<Object> value, 12603 Handle<Object> value,
12584 PropertyAttributes attributes) { 12604 PropertyAttributes attributes) {
12585 // TODO(verwaest): Handle with the elements accessor. 12605 // TODO(verwaest): Handle with the elements accessor.
12586 Isolate* isolate = object->GetIsolate(); 12606 Isolate* isolate = object->GetIsolate();
12587 12607
12588 // Insert element in the dictionary. 12608 // Insert element in the dictionary.
12589 Handle<FixedArray> elements(FixedArray::cast(object->elements())); 12609 Handle<FixedArray> elements(FixedArray::cast(object->elements()));
12590 bool is_arguments = 12610 bool is_arguments =
12591 (elements->map() == isolate->heap()->sloppy_arguments_elements_map()); 12611 (elements->map() == isolate->heap()->sloppy_arguments_elements_map());
12592 12612
12593 DCHECK(object->HasDictionaryElements() || 12613 DCHECK(object->HasDictionaryElements() ||
12594 object->HasDictionaryArgumentsElements()); 12614 object->HasDictionaryArgumentsElements());
12595 12615
12596 Handle<SeededNumberDictionary> dictionary(is_arguments 12616 Handle<SeededNumberDictionary> dictionary(is_arguments
12597 ? SeededNumberDictionary::cast(elements->get(1)) 12617 ? SeededNumberDictionary::cast(elements->get(1))
12598 : SeededNumberDictionary::cast(*elements)); 12618 : SeededNumberDictionary::cast(*elements));
12599 12619
12600 int entry = dictionary->FindEntry(index); 12620 int entry = dictionary->FindEntry(index);
12601 if (entry != SeededNumberDictionary::kNotFound) { 12621 DCHECK_NE(SeededNumberDictionary::kNotFound, entry);
12622
12623 PropertyDetails details = dictionary->DetailsAt(entry);
12624 details = PropertyDetails(attributes, DATA, details.dictionary_index(),
12625 PropertyCellType::kNoCell);
12626 dictionary->DetailsAtPut(entry, details);
12627
12628 // Elements of the arguments object in slow mode might be slow aliases.
12629 if (is_arguments) {
12602 Handle<Object> element(dictionary->ValueAt(entry), isolate); 12630 Handle<Object> element(dictionary->ValueAt(entry), isolate);
12603 PropertyDetails details = dictionary->DetailsAt(entry); 12631 if (element->IsAliasedArgumentsEntry()) {
12604 DCHECK(details.IsConfigurable() || !details.IsReadOnly() ||
12605 element->IsTheHole());
12606 dictionary->UpdateMaxNumberKey(index);
12607
12608 details = PropertyDetails(attributes, DATA, details.dictionary_index(),
12609 PropertyCellType::kNoCell);
12610 dictionary->DetailsAtPut(entry, details);
12611
12612 // Elements of the arguments object in slow mode might be slow aliases.
12613 if (is_arguments && element->IsAliasedArgumentsEntry()) {
12614 Handle<AliasedArgumentsEntry> entry = 12632 Handle<AliasedArgumentsEntry> entry =
12615 Handle<AliasedArgumentsEntry>::cast(element); 12633 Handle<AliasedArgumentsEntry>::cast(element);
12616 Handle<Context> context(Context::cast(elements->get(0))); 12634 Handle<Context> context(Context::cast(elements->get(0)));
12617 int context_index = entry->aliased_context_slot(); 12635 int context_index = entry->aliased_context_slot();
12618 DCHECK(!context->get(context_index)->IsTheHole()); 12636 DCHECK(!context->get(context_index)->IsTheHole());
12619 context->set(context_index, *value); 12637 context->set(context_index, *value);
12620 // For elements that are still writable we keep slow aliasing. 12638 // For elements that are still writable we keep slow aliasing.
12621 if (!details.IsReadOnly()) value = element; 12639 if (!details.IsReadOnly()) value = element;
12622 } 12640 }
12623 dictionary->ValueAtPut(entry, *value); 12641 }
12624 } else { 12642
12625 DCHECK(object->map()->is_extensible()); 12643 dictionary->ValueAtPut(entry, *value);
12626 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); 12644 }
12627 Handle<SeededNumberDictionary> new_dictionary = 12645
12628 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, 12646
12629 details); 12647 void JSObject::AddDictionaryElement(Handle<JSObject> object, uint32_t index,
12630 if (*dictionary != *new_dictionary) { 12648 Handle<Object> value,
12631 if (is_arguments) { 12649 PropertyAttributes attributes) {
12632 elements->set(1, *new_dictionary); 12650 // TODO(verwaest): Handle with the elements accessor.
12633 } else { 12651 Isolate* isolate = object->GetIsolate();
12634 object->set_elements(*new_dictionary); 12652
12635 } 12653 // Insert element in the dictionary.
12636 dictionary = new_dictionary; 12654 Handle<FixedArray> elements(FixedArray::cast(object->elements()));
12655 bool is_arguments =
12656 (elements->map() == isolate->heap()->sloppy_arguments_elements_map());
12657
12658 DCHECK(object->HasDictionaryElements() ||
12659 object->HasDictionaryArgumentsElements());
12660
12661 Handle<SeededNumberDictionary> dictionary(
12662 is_arguments ? SeededNumberDictionary::cast(elements->get(1))
12663 : SeededNumberDictionary::cast(*elements));
12664
12665 #ifdef DEBUG
12666 int entry = dictionary->FindEntry(index);
12667 DCHECK_EQ(SeededNumberDictionary::kNotFound, entry);
12668 DCHECK(object->map()->is_extensible());
12669 #endif
12670
12671 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
12672 Handle<SeededNumberDictionary> new_dictionary =
12673 SeededNumberDictionary::AddNumberEntry(dictionary, index, value, details);
12674 if (*dictionary != *new_dictionary) {
12675 if (is_arguments) {
12676 elements->set(1, *new_dictionary);
12677 } else {
12678 object->set_elements(*new_dictionary);
12637 } 12679 }
12680 dictionary = new_dictionary;
12638 } 12681 }
12639 12682
12640 // Update the array length if this JSObject is an array. 12683 // Update the array length if this JSObject is an array.
12641 if (object->IsJSArray()) { 12684 if (object->IsJSArray()) {
12642 JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray>::cast(object), index, 12685 JSArray::JSArrayUpdateLengthFromIndex(Handle<JSArray>::cast(object), index,
12643 value); 12686 value);
12644 } 12687 }
12645 12688
12646 // Attempt to put this object back in fast case. 12689 // Attempt to put this object back in fast case.
12647 if (object->ShouldConvertToFastElements()) { 12690 if (object->ShouldConvertToFastElements()) {
(...skipping 20 matching lines...) Expand all
12668 #ifdef DEBUG 12711 #ifdef DEBUG
12669 if (FLAG_trace_normalization) { 12712 if (FLAG_trace_normalization) {
12670 OFStream os(stdout); 12713 OFStream os(stdout);
12671 os << "Object elements are fast case again:\n"; 12714 os << "Object elements are fast case again:\n";
12672 object->Print(os); 12715 object->Print(os);
12673 } 12716 }
12674 #endif 12717 #endif
12675 } 12718 }
12676 } 12719 }
12677 12720
12678 void JSObject::SetFastDoubleElement(Handle<JSObject> object, uint32_t index, 12721
12722 void JSObject::AddFastDoubleElement(Handle<JSObject> object, uint32_t index,
12679 Handle<Object> value) { 12723 Handle<Object> value) {
12680 DCHECK(object->HasFastDoubleElements()); 12724 DCHECK(object->HasFastDoubleElements());
12681 12725
12682 Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements())); 12726 Handle<FixedArrayBase> base_elms(FixedArrayBase::cast(object->elements()));
12683 uint32_t elms_length = static_cast<uint32_t>(base_elms->length()); 12727 uint32_t elms_length = static_cast<uint32_t>(base_elms->length());
12684 uint32_t length = elms_length; 12728 uint32_t length = elms_length;
12685 12729
12686 bool introduces_holes = true; 12730 bool introduces_holes = true;
12687 if (object->IsJSArray()) { 12731 if (object->IsJSArray()) {
12688 // In case of JSArray, the length does not equal the capacity. 12732 // In case of JSArray, the length does not equal the capacity.
12689 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayLength(&length)); 12733 CHECK(Handle<JSArray>::cast(object)->length()->ToArrayLength(&length));
12690 introduces_holes = index > length; 12734 introduces_holes = index > length;
12691 } else { 12735 } else {
12692 introduces_holes = index >= elms_length; 12736 introduces_holes = index >= elms_length;
12693 } 12737 }
12694 12738
12695 // If the value object is not a heap number, switch to fast elements and try 12739 // If the value object is not a heap number, switch to fast elements and try
12696 // again. 12740 // again.
12697 if (!value->IsNumber()) { 12741 if (!value->IsNumber()) {
12698 SetFastElementsCapacityAndLength(object, elms_length, length, 12742 SetFastElementsCapacityAndLength(object, elms_length, length,
12699 kDontAllowSmiElements); 12743 kDontAllowSmiElements);
12700 SetFastElement(object, index, value); 12744 AddFastElement(object, index, value);
12701 return; 12745 return;
12702 } 12746 }
12703 12747
12704 // If the array is growing, and it's not growth by a single element at the 12748 // If the array is growing, and it's not growth by a single element at the
12705 // end, make sure that the ElementsKind is HOLEY. 12749 // end, make sure that the ElementsKind is HOLEY.
12706 ElementsKind elements_kind = object->GetElementsKind(); 12750 if (introduces_holes && !IsFastHoleyElementsKind(object->GetElementsKind())) {
12707 if (introduces_holes && !IsFastHoleyElementsKind(elements_kind)) { 12751 ElementsKind transitioned_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
12708 ElementsKind transitioned_kind = GetHoleyElementsKind(elements_kind);
12709 TransitionElementsKind(object, transitioned_kind); 12752 TransitionElementsKind(object, transitioned_kind);
12710 } 12753 }
12711 12754
12712 // Check whether there is extra space in the fixed array. 12755 // Check whether there is extra space in the fixed array.
12713 if (index < elms_length) { 12756 if (index < elms_length) {
12714 Handle<FixedDoubleArray> elms(FixedDoubleArray::cast(object->elements())); 12757 Handle<FixedDoubleArray> elms(FixedDoubleArray::cast(object->elements()));
12715 elms->set(index, value->Number()); 12758 elms->set(index, value->Number());
12716 if (object->IsJSArray()) { 12759 if (object->IsJSArray()) {
12717 // Update the length of the array if needed. 12760 // Update the length of the array if needed.
12718 uint32_t array_length = 0; 12761 uint32_t array_length = 0;
(...skipping 20 matching lines...) Expand all
12739 } 12782 }
12740 12783
12741 // Otherwise default to slow case. 12784 // Otherwise default to slow case.
12742 DCHECK(object->HasFastDoubleElements()); 12785 DCHECK(object->HasFastDoubleElements());
12743 DCHECK(object->map()->has_fast_double_elements()); 12786 DCHECK(object->map()->has_fast_double_elements());
12744 DCHECK(object->elements()->IsFixedDoubleArray() || 12787 DCHECK(object->elements()->IsFixedDoubleArray() ||
12745 object->elements()->length() == 0); 12788 object->elements()->length() == 0);
12746 12789
12747 NormalizeElements(object); 12790 NormalizeElements(object);
12748 DCHECK(object->HasDictionaryElements()); 12791 DCHECK(object->HasDictionaryElements());
12749 SetDictionaryElement(object, index, value, NONE); 12792 AddDictionaryElement(object, index, value, NONE);
12750 } 12793 }
12751 12794
12752 12795
12753 // static 12796 // static
12754 MaybeHandle<Object> JSReceiver::SetElement(Handle<JSReceiver> object, 12797 MaybeHandle<Object> JSReceiver::SetElement(Handle<JSReceiver> object,
12755 uint32_t index, Handle<Object> value, 12798 uint32_t index, Handle<Object> value,
12756 LanguageMode language_mode) { 12799 LanguageMode language_mode) {
12757 Isolate* isolate = object->GetIsolate(); 12800 Isolate* isolate = object->GetIsolate();
12758 LookupIterator it(isolate, object, index); 12801 LookupIterator it(isolate, object, index);
12759 return SetProperty(&it, value, language_mode, MAY_BE_STORE_FROM_KEYED); 12802 return SetProperty(&it, value, language_mode, MAY_BE_STORE_FROM_KEYED);
(...skipping 21 matching lines...) Expand all
12781 d->set_requires_slow_elements(); 12824 d->set_requires_slow_elements();
12782 } 12825 }
12783 12826
12784 Handle<Object> result = value; 12827 Handle<Object> result = value;
12785 12828
12786 switch (receiver->GetElementsKind()) { 12829 switch (receiver->GetElementsKind()) {
12787 case FAST_SMI_ELEMENTS: 12830 case FAST_SMI_ELEMENTS:
12788 case FAST_ELEMENTS: 12831 case FAST_ELEMENTS:
12789 case FAST_HOLEY_SMI_ELEMENTS: 12832 case FAST_HOLEY_SMI_ELEMENTS:
12790 case FAST_HOLEY_ELEMENTS: 12833 case FAST_HOLEY_ELEMENTS:
12791 SetFastElement(receiver, index, value); 12834 AddFastElement(receiver, index, value);
12792 break; 12835 break;
12793 case FAST_DOUBLE_ELEMENTS: 12836 case FAST_DOUBLE_ELEMENTS:
12794 case FAST_HOLEY_DOUBLE_ELEMENTS: 12837 case FAST_HOLEY_DOUBLE_ELEMENTS:
12795 SetFastDoubleElement(receiver, index, value); 12838 AddFastDoubleElement(receiver, index, value);
12796 break; 12839 break;
12797 12840
12798 case DICTIONARY_ELEMENTS: 12841 case DICTIONARY_ELEMENTS:
12799 SetDictionaryElement(receiver, index, value, attributes); 12842 AddDictionaryElement(receiver, index, value, attributes);
12800 break; 12843 break;
12801 case SLOPPY_ARGUMENTS_ELEMENTS: 12844 case SLOPPY_ARGUMENTS_ELEMENTS:
12802 SetSloppyArgumentsElement(receiver, index, value, attributes); 12845 AddSloppyArgumentsElement(receiver, index, value, attributes);
12803 break; 12846 break;
12804 12847
12805 // Elements cannot be added to typed arrays. 12848 // Elements cannot be added to typed arrays.
12806 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 12849 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
12807 case EXTERNAL_##TYPE##_ELEMENTS: \ 12850 case EXTERNAL_##TYPE##_ELEMENTS: \
12808 case TYPE##_ELEMENTS: 12851 case TYPE##_ELEMENTS:
12809 12852
12810 TYPED_ARRAYS(TYPED_ARRAY_CASE) 12853 TYPED_ARRAYS(TYPED_ARRAY_CASE)
12811 12854
12812 #undef TYPED_ARRAY_CASE 12855 #undef TYPED_ARRAY_CASE
(...skipping 3849 matching lines...) Expand 10 before | Expand all | Expand 10 after
16662 Handle<Object> new_value) { 16705 Handle<Object> new_value) {
16663 if (cell->value() != *new_value) { 16706 if (cell->value() != *new_value) {
16664 cell->set_value(*new_value); 16707 cell->set_value(*new_value);
16665 Isolate* isolate = cell->GetIsolate(); 16708 Isolate* isolate = cell->GetIsolate();
16666 cell->dependent_code()->DeoptimizeDependentCodeGroup( 16709 cell->dependent_code()->DeoptimizeDependentCodeGroup(
16667 isolate, DependentCode::kPropertyCellChangedGroup); 16710 isolate, DependentCode::kPropertyCellChangedGroup);
16668 } 16711 }
16669 } 16712 }
16670 } // namespace internal 16713 } // namespace internal
16671 } // namespace v8 16714 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698