| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 8706 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8717 | 8717 |
| 8718 FixedArray* backing_store = FixedArray::cast(elements()); | 8718 FixedArray* backing_store = FixedArray::cast(elements()); |
| 8719 if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) { | 8719 if (backing_store->map() == GetHeap()->non_strict_arguments_elements_map()) { |
| 8720 backing_store = FixedArray::cast(backing_store->get(1)); | 8720 backing_store = FixedArray::cast(backing_store->get(1)); |
| 8721 } else { | 8721 } else { |
| 8722 Object* writable; | 8722 Object* writable; |
| 8723 MaybeObject* maybe = EnsureWritableFastElements(); | 8723 MaybeObject* maybe = EnsureWritableFastElements(); |
| 8724 if (!maybe->ToObject(&writable)) return maybe; | 8724 if (!maybe->ToObject(&writable)) return maybe; |
| 8725 backing_store = FixedArray::cast(writable); | 8725 backing_store = FixedArray::cast(writable); |
| 8726 } | 8726 } |
| 8727 uint32_t length = static_cast<uint32_t>(backing_store->length()); | 8727 uint32_t capacity = static_cast<uint32_t>(backing_store->length()); |
| 8728 | 8728 |
| 8729 if (check_prototype && | 8729 if (check_prototype && |
| 8730 (index >= length || backing_store->get(index)->IsTheHole())) { | 8730 (index >= capacity || backing_store->get(index)->IsTheHole())) { |
| 8731 bool found; | 8731 bool found; |
| 8732 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, | 8732 MaybeObject* result = SetElementWithCallbackSetterInPrototypes(index, |
| 8733 value, | 8733 value, |
| 8734 &found, | 8734 &found, |
| 8735 strict_mode); | 8735 strict_mode); |
| 8736 if (found) return result; | 8736 if (found) return result; |
| 8737 } | 8737 } |
| 8738 | 8738 |
| 8739 // Check whether there is extra space in fixed array. | 8739 uint32_t new_capacity = capacity; |
| 8740 if (index < length) { | 8740 // Check if the length property of this object needs to be updated. |
| 8741 if (HasFastSmiOnlyElements()) { | 8741 uint32_t array_length = 0; |
| 8742 if (!value->IsSmi()) { | 8742 bool must_update_array_length = false; |
| 8743 // If the value is a number, transition from smi-only to | 8743 if (IsJSArray()) { |
| 8744 // FastDoubleElements. | 8744 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); |
| 8745 if (value->IsNumber()) { | 8745 if (index >= array_length) { |
| 8746 MaybeObject* maybe = | 8746 must_update_array_length = true; |
| 8747 SetFastDoubleElementsCapacityAndLength(length, length); | 8747 array_length = index + 1; |
| 8748 if (maybe->IsFailure()) return maybe; | 8748 } |
| 8749 FixedDoubleArray::cast(elements())->set(index, value->Number()); | 8749 } |
| 8750 return value; | 8750 // Check if the capacity of the backing store needs to be increased, or if |
| 8751 } | 8751 // a transition to slow elements is necessary. |
| 8752 // Value is not a number, transition to generic fast elements. | 8752 if (index >= capacity) { |
| 8753 MaybeObject* maybe_new_map = GetElementsTransitionMap(FAST_ELEMENTS); | 8753 bool convert_to_slow = true; |
| 8754 Map* new_map; | 8754 if ((index - capacity) < kMaxGap) { |
| 8755 if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map; | 8755 new_capacity = NewElementsCapacity(index + 1); |
| 8756 set_map(new_map); | 8756 ASSERT(new_capacity > index); |
| 8757 if (!ShouldConvertToSlowElements(new_capacity)) { |
| 8758 convert_to_slow = false; |
| 8757 } | 8759 } |
| 8758 } | 8760 } |
| 8759 backing_store->set(index, value); | 8761 if (convert_to_slow) { |
| 8760 if (IsJSArray()) { | 8762 MaybeObject* result = NormalizeElements(); |
| 8761 // Update the length of the array if needed. | 8763 if (result->IsFailure()) return result; |
| 8762 uint32_t array_length = 0; | 8764 return SetDictionaryElement(index, value, strict_mode, check_prototype); |
| 8763 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&array_length)); | |
| 8764 if (index >= array_length) { | |
| 8765 JSArray::cast(this)->set_length(Smi::FromInt(index + 1)); | |
| 8766 } | |
| 8767 } | 8765 } |
| 8766 } |
| 8767 // Convert to fast double elements if appropriate. |
| 8768 if (HasFastSmiOnlyElements() && !value->IsSmi() && value->IsNumber()) { |
| 8769 MaybeObject* maybe = |
| 8770 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length); |
| 8771 if (maybe->IsFailure()) return maybe; |
| 8772 FixedDoubleArray::cast(elements())->set(index, value->Number()); |
| 8768 return value; | 8773 return value; |
| 8769 } | 8774 } |
| 8770 | 8775 // Change elements kind from SMI_ONLY to generic FAST if necessary. |
| 8771 // Allow gap in fast case. | 8776 if (HasFastSmiOnlyElements() && !value->IsSmi()) { |
| 8772 if ((index - length) < kMaxGap) { | 8777 MaybeObject* maybe_new_map = GetElementsTransitionMap(FAST_ELEMENTS); |
| 8773 // Try allocating extra space. | 8778 Map* new_map; |
| 8774 int new_capacity = NewElementsCapacity(index + 1); | 8779 if (!maybe_new_map->To<Map>(&new_map)) return maybe_new_map; |
| 8775 if (!ShouldConvertToSlowElements(new_capacity)) { | 8780 set_map(new_map); |
| 8776 ASSERT(static_cast<uint32_t>(new_capacity) > index); | |
| 8777 Object* new_elements; | |
| 8778 SetFastElementsCapacityMode set_capacity_mode = | |
| 8779 value->IsSmi() && HasFastSmiOnlyElements() | |
| 8780 ? kAllowSmiOnlyElements | |
| 8781 : kDontAllowSmiOnlyElements; | |
| 8782 MaybeObject* maybe = | |
| 8783 SetFastElementsCapacityAndLength(new_capacity, | |
| 8784 index + 1, | |
| 8785 set_capacity_mode); | |
| 8786 if (!maybe->ToObject(&new_elements)) return maybe; | |
| 8787 FixedArray::cast(new_elements)->set(index, value); | |
| 8788 return value; | |
| 8789 } | |
| 8790 } | 8781 } |
| 8791 | 8782 // Increase backing store capacity if that's been decided previously. |
| 8792 // Otherwise default to slow case. | 8783 if (new_capacity != capacity) { |
| 8793 MaybeObject* result = NormalizeElements(); | 8784 Object* new_elements; |
| 8794 if (result->IsFailure()) return result; | 8785 SetFastElementsCapacityMode set_capacity_mode = |
| 8795 return SetDictionaryElement(index, value, strict_mode, check_prototype); | 8786 value->IsSmi() && HasFastSmiOnlyElements() |
| 8787 ? kAllowSmiOnlyElements |
| 8788 : kDontAllowSmiOnlyElements; |
| 8789 MaybeObject* maybe = |
| 8790 SetFastElementsCapacityAndLength(new_capacity, |
| 8791 array_length, |
| 8792 set_capacity_mode); |
| 8793 if (!maybe->ToObject(&new_elements)) return maybe; |
| 8794 FixedArray::cast(new_elements)->set(index, value); |
| 8795 return value; |
| 8796 } |
| 8797 // Finally, set the new element and length. |
| 8798 ASSERT(elements()->IsFixedArray()); |
| 8799 backing_store->set(index, value); |
| 8800 if (must_update_array_length) { |
| 8801 JSArray::cast(this)->set_length(Smi::FromInt(array_length)); |
| 8802 } |
| 8803 return value; |
| 8796 } | 8804 } |
| 8797 | 8805 |
| 8798 | 8806 |
| 8799 MaybeObject* JSObject::SetDictionaryElement(uint32_t index, | 8807 MaybeObject* JSObject::SetDictionaryElement(uint32_t index, |
| 8800 Object* value, | 8808 Object* value, |
| 8801 StrictModeFlag strict_mode, | 8809 StrictModeFlag strict_mode, |
| 8802 bool check_prototype) { | 8810 bool check_prototype) { |
| 8803 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); | 8811 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements()); |
| 8804 Isolate* isolate = GetIsolate(); | 8812 Isolate* isolate = GetIsolate(); |
| 8805 Heap* heap = isolate->heap(); | 8813 Heap* heap = isolate->heap(); |
| (...skipping 3255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12061 if (break_point_objects()->IsUndefined()) return 0; | 12069 if (break_point_objects()->IsUndefined()) return 0; |
| 12062 // Single break point. | 12070 // Single break point. |
| 12063 if (!break_point_objects()->IsFixedArray()) return 1; | 12071 if (!break_point_objects()->IsFixedArray()) return 1; |
| 12064 // Multiple break points. | 12072 // Multiple break points. |
| 12065 return FixedArray::cast(break_point_objects())->length(); | 12073 return FixedArray::cast(break_point_objects())->length(); |
| 12066 } | 12074 } |
| 12067 #endif | 12075 #endif |
| 12068 | 12076 |
| 12069 | 12077 |
| 12070 } } // namespace v8::internal | 12078 } } // namespace v8::internal |
| OLD | NEW |