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 |