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 2878 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2889 } | 2889 } |
2890 if (array->IsDictionary()) return array; | 2890 if (array->IsDictionary()) return array; |
2891 | 2891 |
2892 ASSERT(HasFastElements() || | 2892 ASSERT(HasFastElements() || |
2893 HasFastDoubleElements() || | 2893 HasFastDoubleElements() || |
2894 HasFastArgumentsElements()); | 2894 HasFastArgumentsElements()); |
2895 // Compute the effective length and allocate a new backing store. | 2895 // Compute the effective length and allocate a new backing store. |
2896 int length = IsJSArray() | 2896 int length = IsJSArray() |
2897 ? Smi::cast(JSArray::cast(this)->length())->value() | 2897 ? Smi::cast(JSArray::cast(this)->length())->value() |
2898 : array->length(); | 2898 : array->length(); |
2899 int old_capacity = 0; | |
2900 int used_elements = 0; | |
2901 GetElementsCapacityAndUsage(&old_capacity, &used_elements); | |
2899 NumberDictionary* dictionary = NULL; | 2902 NumberDictionary* dictionary = NULL; |
2900 { Object* object; | 2903 { Object* object; |
2901 MaybeObject* maybe = NumberDictionary::Allocate(length); | 2904 MaybeObject* maybe = NumberDictionary::Allocate(used_elements); |
2902 if (!maybe->ToObject(&object)) return maybe; | 2905 if (!maybe->ToObject(&object)) return maybe; |
2903 dictionary = NumberDictionary::cast(object); | 2906 dictionary = NumberDictionary::cast(object); |
2904 } | 2907 } |
2905 | 2908 |
2906 // Copy the elements to the new backing store. | 2909 // Copy the elements to the new backing store. |
2907 bool has_double_elements = array->IsFixedDoubleArray(); | 2910 bool has_double_elements = array->IsFixedDoubleArray(); |
2908 for (int i = 0; i < length; i++) { | 2911 for (int i = 0; i < length; i++) { |
2909 Object* value = NULL; | 2912 Object* value = NULL; |
2910 if (has_double_elements) { | 2913 if (has_double_elements) { |
2911 FixedDoubleArray* double_array = FixedDoubleArray::cast(array); | 2914 FixedDoubleArray* double_array = FixedDoubleArray::cast(array); |
(...skipping 6164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9076 case NON_STRICT_ARGUMENTS_ELEMENTS: | 9079 case NON_STRICT_ARGUMENTS_ELEMENTS: |
9077 UNIMPLEMENTED(); | 9080 UNIMPLEMENTED(); |
9078 break; | 9081 break; |
9079 } | 9082 } |
9080 return GetHeap()->undefined_value(); | 9083 return GetHeap()->undefined_value(); |
9081 } | 9084 } |
9082 | 9085 |
9083 | 9086 |
9084 bool JSObject::HasDenseElements() { | 9087 bool JSObject::HasDenseElements() { |
9085 int capacity = 0; | 9088 int capacity = 0; |
9086 int number_of_elements = 0; | 9089 int used = 0; |
9090 GetElementsCapacityAndUsage(&capacity, &used); | |
9091 return (capacity == 0) || (used > (capacity / 2)); | |
9092 } | |
9093 | |
9094 | |
9095 void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) { | |
9096 *capacity = 0; | |
9097 *used = 0; | |
9087 | 9098 |
9088 FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements()); | 9099 FixedArrayBase* backing_store_base = FixedArrayBase::cast(elements()); |
9089 FixedArray* backing_store = NULL; | 9100 FixedArray* backing_store = NULL; |
9090 switch (GetElementsKind()) { | 9101 ElementsKind kind = GetElementsKind(); |
9102 switch (kind) { | |
9091 case NON_STRICT_ARGUMENTS_ELEMENTS: | 9103 case NON_STRICT_ARGUMENTS_ELEMENTS: |
9092 backing_store_base = | 9104 backing_store_base = |
9093 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); | 9105 FixedArray::cast(FixedArray::cast(backing_store_base)->get(1)); |
9094 backing_store = FixedArray::cast(backing_store_base); | 9106 backing_store = FixedArray::cast(backing_store_base); |
9095 if (backing_store->IsDictionary()) { | 9107 if (backing_store->IsDictionary()) { |
9096 NumberDictionary* dictionary = NumberDictionary::cast(backing_store); | 9108 NumberDictionary* dictionary = NumberDictionary::cast(backing_store); |
9097 capacity = dictionary->Capacity(); | 9109 *capacity = dictionary->Capacity(); |
9098 number_of_elements = dictionary->NumberOfElements(); | 9110 *used = dictionary->NumberOfElements(); |
9099 break; | 9111 break; |
9100 } | 9112 } |
9101 // Fall through. | 9113 // Fall through. |
9102 case FAST_ELEMENTS: | 9114 case FAST_ELEMENTS: |
9103 backing_store = FixedArray::cast(backing_store_base); | 9115 backing_store = FixedArray::cast(backing_store_base); |
9104 capacity = backing_store->length(); | 9116 *capacity = backing_store->length(); |
9105 for (int i = 0; i < capacity; ++i) { | 9117 for (int i = 0; i < *capacity; ++i) { |
9106 if (!backing_store->get(i)->IsTheHole()) ++number_of_elements; | 9118 if (!backing_store->get(i)->IsTheHole()) ++(*used); |
9107 } | 9119 } |
9108 break; | 9120 break; |
9109 case DICTIONARY_ELEMENTS: { | 9121 case DICTIONARY_ELEMENTS: { |
9110 NumberDictionary* dictionary = | 9122 NumberDictionary* dictionary = |
9111 NumberDictionary::cast(FixedArray::cast(elements())); | 9123 NumberDictionary::cast(FixedArray::cast(elements())); |
9112 capacity = dictionary->Capacity(); | 9124 *capacity = dictionary->Capacity(); |
9113 number_of_elements = dictionary->NumberOfElements(); | 9125 *used = dictionary->NumberOfElements(); |
9114 break; | 9126 break; |
9115 } | 9127 } |
9116 case FAST_DOUBLE_ELEMENTS: { | 9128 case FAST_DOUBLE_ELEMENTS: { |
9117 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); | 9129 FixedDoubleArray* elms = FixedDoubleArray::cast(elements()); |
9118 capacity = elms->length(); | 9130 *capacity = elms->length(); |
9119 for (int i = 0; i < capacity; i++) { | 9131 for (int i = 0; i < *capacity; i++) { |
9120 if (!elms->is_the_hole(i)) number_of_elements++; | 9132 if (!elms->is_the_hole(i)) ++(*used); |
9121 } | 9133 } |
9122 break; | 9134 break; |
9123 } | 9135 } |
9124 case EXTERNAL_PIXEL_ELEMENTS: | 9136 default: |
9125 case EXTERNAL_BYTE_ELEMENTS: | 9137 ASSERT(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND <= kind && |
9126 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 9138 kind <= LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); |
danno
2011/07/22 09:21:25
Please leave this explicitly enumerated and remove
Vitaly Repeshko
2011/07/25 15:50:55
Agreed. I added the external array cases back. The
| |
9127 case EXTERNAL_SHORT_ELEMENTS: | 9139 break; |
9128 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | |
9129 case EXTERNAL_INT_ELEMENTS: | |
9130 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | |
9131 case EXTERNAL_FLOAT_ELEMENTS: | |
9132 case EXTERNAL_DOUBLE_ELEMENTS: { | |
9133 return true; | |
9134 } | |
9135 } | 9140 } |
9136 return (capacity == 0) || (number_of_elements > (capacity / 2)); | |
9137 } | 9141 } |
9138 | 9142 |
9139 | 9143 |
9140 bool JSObject::ShouldConvertToSlowElements(int new_capacity) { | 9144 bool JSObject::ShouldConvertToSlowElements(int new_capacity) { |
9141 if (new_capacity <= kMaxFastElementsLength) return false; | 9145 STATIC_ASSERT(kMaxUncheckedOldFastElementsLength <= |
9146 kMaxUncheckedFastElementsLength); | |
9147 if (new_capacity <= kMaxUncheckedOldFastElementsLength || | |
9148 (new_capacity <= kMaxUncheckedFastElementsLength && | |
9149 GetHeap()->InNewSpace(this))) { | |
9150 return false; | |
9151 } | |
9142 // Keep the array in fast case if the current backing storage is | 9152 // Keep the array in fast case if the current backing storage is |
9143 // almost filled and if the new capacity is no more than twice the | 9153 // almost filled and if the new capacity is no more than twice the |
9144 // old capacity. | 9154 // old capacity. |
9145 int old_capacity = 0; | 9155 int old_capacity = 0; |
9146 if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) { | 9156 if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) { |
9147 FixedArray* backing_store = FixedArray::cast(elements()); | 9157 FixedArray* backing_store = FixedArray::cast(elements()); |
9148 old_capacity = FixedArray::cast(backing_store->get(1))->length(); | 9158 old_capacity = FixedArray::cast(backing_store->get(1))->length(); |
9149 } else if (HasFastElements()) { | 9159 } else if (HasFastElements()) { |
9150 old_capacity = FixedArray::cast(elements())->length(); | 9160 old_capacity = FixedArray::cast(elements())->length(); |
9151 } else if (HasFastDoubleElements()) { | 9161 } else if (HasFastDoubleElements()) { |
(...skipping 2692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11844 if (break_point_objects()->IsUndefined()) return 0; | 11854 if (break_point_objects()->IsUndefined()) return 0; |
11845 // Single beak point. | 11855 // Single beak point. |
11846 if (!break_point_objects()->IsFixedArray()) return 1; | 11856 if (!break_point_objects()->IsFixedArray()) return 1; |
11847 // Multiple break points. | 11857 // Multiple break points. |
11848 return FixedArray::cast(break_point_objects())->length(); | 11858 return FixedArray::cast(break_point_objects())->length(); |
11849 } | 11859 } |
11850 #endif | 11860 #endif |
11851 | 11861 |
11852 | 11862 |
11853 } } // namespace v8::internal | 11863 } } // namespace v8::internal |
OLD | NEW |