OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 "src/elements.h" | 5 #include "src/elements.h" |
6 | 6 |
7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
9 #include "src/factory.h" | 9 #include "src/factory.h" |
10 #include "src/messages.h" | 10 #include "src/messages.h" |
(...skipping 2836 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2847 if (elements_accessors_ == NULL) return; | 2847 if (elements_accessors_ == NULL) return; |
2848 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; | 2848 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; |
2849 ELEMENTS_LIST(ACCESSOR_DELETE) | 2849 ELEMENTS_LIST(ACCESSOR_DELETE) |
2850 #undef ACCESSOR_DELETE | 2850 #undef ACCESSOR_DELETE |
2851 elements_accessors_ = NULL; | 2851 elements_accessors_ = NULL; |
2852 } | 2852 } |
2853 | 2853 |
2854 | 2854 |
2855 Handle<JSArray> ElementsAccessor::Concat(Isolate* isolate, Arguments* args, | 2855 Handle<JSArray> ElementsAccessor::Concat(Isolate* isolate, Arguments* args, |
2856 uint32_t concat_size) { | 2856 uint32_t concat_size) { |
2857 uint32_t result_len = 0; | 2857 int result_len = 0; |
2858 bool has_raw_doubles = false; | 2858 ElementsKind elements_kind = GetInitialFastElementsKind(); |
2859 ElementsKind result_elements_kind = GetInitialFastElementsKind(); | 2859 bool has_double = false; |
2860 { | 2860 { |
2861 DisallowHeapAllocation no_gc; | 2861 DisallowHeapAllocation no_gc; |
2862 bool is_holey = false; | |
2863 // Iterate through all the arguments performing checks | 2862 // Iterate through all the arguments performing checks |
2864 // and calculating total length. | 2863 // and calculating total length. |
| 2864 bool is_holey = false; |
2865 for (uint32_t i = 0; i < concat_size; i++) { | 2865 for (uint32_t i = 0; i < concat_size; i++) { |
2866 JSArray* array = JSArray::cast((*args)[i]); | 2866 Object* arg = (*args)[i]; |
2867 uint32_t len = 0; | 2867 int len = Smi::cast(JSArray::cast(arg)->length())->value(); |
2868 array->length()->ToArrayLength(&len); | |
2869 | 2868 |
2870 // We shouldn't overflow when adding another len. | 2869 // We shouldn't overflow when adding another len. |
2871 const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2); | 2870 const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2); |
2872 STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt); | 2871 STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt); |
2873 USE(kHalfOfMaxInt); | 2872 USE(kHalfOfMaxInt); |
2874 result_len += len; | 2873 result_len += len; |
2875 DCHECK(0 <= result_len); | 2874 DCHECK(0 <= result_len); |
2876 DCHECK(result_len <= FixedDoubleArray::kMaxLength); | 2875 DCHECK(result_len <= FixedDoubleArray::kMaxLength); |
2877 | 2876 |
2878 ElementsKind arg_kind = array->GetElementsKind(); | 2877 ElementsKind arg_kind = JSArray::cast(arg)->map()->elements_kind(); |
2879 has_raw_doubles = has_raw_doubles || IsFastDoubleElementsKind(arg_kind); | 2878 has_double = has_double || IsFastDoubleElementsKind(arg_kind); |
2880 is_holey = is_holey || IsFastHoleyElementsKind(arg_kind); | 2879 is_holey = is_holey || IsFastHoleyElementsKind(arg_kind); |
2881 result_elements_kind = | 2880 elements_kind = GetMoreGeneralElementsKind(elements_kind, arg_kind); |
2882 GetMoreGeneralElementsKind(result_elements_kind, arg_kind); | |
2883 } | 2881 } |
2884 if (is_holey) { | 2882 if (is_holey) { |
2885 result_elements_kind = GetHoleyElementsKind(result_elements_kind); | 2883 elements_kind = GetHoleyElementsKind(elements_kind); |
2886 } | 2884 } |
2887 } | 2885 } |
2888 | 2886 |
2889 // If a double array is concatted into a fast elements array, the fast | 2887 // If a double array is concatted into a fast elements array, the fast |
2890 // elements array needs to be initialized to contain proper holes, since | 2888 // elements array needs to be initialized to contain proper holes, since |
2891 // boxing doubles may cause incremental marking. | 2889 // boxing doubles may cause incremental marking. |
2892 bool requires_double_boxing = | 2890 ArrayStorageAllocationMode mode = |
2893 has_raw_doubles && !IsFastDoubleElementsKind(result_elements_kind); | 2891 has_double && IsFastObjectElementsKind(elements_kind) |
2894 ArrayStorageAllocationMode mode = requires_double_boxing | 2892 ? INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE |
2895 ? INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE | 2893 : DONT_INITIALIZE_ARRAY_ELEMENTS; |
2896 : DONT_INITIALIZE_ARRAY_ELEMENTS; | |
2897 Handle<JSArray> result_array = isolate->factory()->NewJSArray( | 2894 Handle<JSArray> result_array = isolate->factory()->NewJSArray( |
2898 result_elements_kind, result_len, result_len, mode); | 2895 elements_kind, result_len, result_len, mode); |
2899 if (result_len == 0) return result_array; | 2896 if (result_len == 0) return result_array; |
2900 | 2897 int j = 0; |
2901 uint32_t insertion_index = 0; | |
2902 Handle<FixedArrayBase> storage(result_array->elements(), isolate); | 2898 Handle<FixedArrayBase> storage(result_array->elements(), isolate); |
2903 ElementsAccessor* accessor = ElementsAccessor::ForKind(result_elements_kind); | 2899 ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind); |
2904 for (uint32_t i = 0; i < concat_size; i++) { | 2900 for (uint32_t i = 0; i < concat_size; i++) { |
2905 // It is crucial to keep |array| in a raw pointer form to avoid | 2901 // It is crucial to keep |array| in a raw pointer form to avoid |
2906 // performance degradation. | 2902 // performance degradation. |
2907 JSArray* array = JSArray::cast((*args)[i]); | 2903 JSArray* array = JSArray::cast((*args)[i]); |
2908 uint32_t len = 0; | 2904 int len = Smi::cast(array->length())->value(); |
2909 array->length()->ToArrayLength(&len); | 2905 if (len > 0) { |
2910 if (len == 0) continue; | 2906 ElementsKind from_kind = array->GetElementsKind(); |
2911 ElementsKind from_kind = array->GetElementsKind(); | 2907 accessor->CopyElements(array, 0, from_kind, storage, j, len); |
2912 accessor->CopyElements(array, 0, from_kind, storage, insertion_index, len); | 2908 j += len; |
2913 insertion_index += len; | 2909 } |
2914 } | 2910 } |
2915 | 2911 |
2916 DCHECK_EQ(insertion_index, result_len); | 2912 DCHECK(j == result_len); |
2917 return result_array; | 2913 return result_array; |
2918 } | 2914 } |
2919 | 2915 |
2920 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2916 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
2921 } // namespace internal | 2917 } // namespace internal |
2922 } // namespace v8 | 2918 } // namespace v8 |
OLD | NEW |