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 int result_len = 0; | 2857 uint32_t result_len = 0; |
2858 ElementsKind elements_kind = GetInitialFastElementsKind(); | 2858 ElementsKind elements_kind = GetInitialFastElementsKind(); |
2859 bool has_double = false; | |
2860 { | 2859 { |
2861 DisallowHeapAllocation no_gc; | 2860 DisallowHeapAllocation no_gc; |
2862 // Iterate through all the arguments performing checks | 2861 // Iterate through all the arguments performing checks |
2863 // and calculating total length. | 2862 // and calculating total length. |
2864 bool is_holey = false; | |
2865 for (uint32_t i = 0; i < concat_size; i++) { | 2863 for (uint32_t i = 0; i < concat_size; i++) { |
2866 Object* arg = (*args)[i]; | 2864 JSArray* array = JSArray::cast((*args)[i]); |
2867 int len = Smi::cast(JSArray::cast(arg)->length())->value(); | 2865 uint32_t len; |
2866 array->length()->ToArrayLength(&len); | |
2868 | 2867 |
2869 // We shouldn't overflow when adding another len. | 2868 // We shouldn't overflow when adding another len. |
2870 const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2); | 2869 const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2); |
2871 STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt); | 2870 STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt); |
2872 USE(kHalfOfMaxInt); | 2871 USE(kHalfOfMaxInt); |
2873 result_len += len; | 2872 result_len += len; |
2874 DCHECK(0 <= result_len); | 2873 DCHECK_LE(0, result_len); |
2875 DCHECK(result_len <= FixedDoubleArray::kMaxLength); | 2874 DCHECK(result_len <= FixedDoubleArray::kMaxLength); |
2876 | 2875 |
2877 ElementsKind arg_kind = JSArray::cast(arg)->map()->elements_kind(); | 2876 ElementsKind arg_kind = array->GetElementsKind(); |
2878 has_double = has_double || IsFastDoubleElementsKind(arg_kind); | 2877 if (IsFastHoleyElementsKind(arg_kind)) { |
2879 is_holey = is_holey || IsFastHoleyElementsKind(arg_kind); | 2878 elements_kind = GetHoleyElementsKind(elements_kind); |
2879 } | |
2880 elements_kind = GetMoreGeneralElementsKind(elements_kind, arg_kind); | 2880 elements_kind = GetMoreGeneralElementsKind(elements_kind, arg_kind); |
2881 } | 2881 } |
2882 if (is_holey) { | |
2883 elements_kind = GetHoleyElementsKind(elements_kind); | |
2884 } | |
2885 } | 2882 } |
2886 | 2883 |
2887 // If a double array is concatted into a fast elements array, the fast | 2884 // If a double array is concatted into a fast elements array, the fast |
2888 // elements array needs to be initialized to contain proper holes, since | 2885 // elements array needs to be initialized to contain proper holes, since |
2889 // boxing doubles may cause incremental marking. | 2886 // boxing doubles may cause incremental marking. |
2890 ArrayStorageAllocationMode mode = | 2887 ArrayStorageAllocationMode mode = IsFastDoubleElementsKind(elements_kind) |
Jakob Kummerow
2016/03/18 10:36:39
This is not the same. Consider the scenario mentio
Camillo Bruni
2016/03/22 12:47:10
Wonder what I was doing... I actually got that par
| |
2891 has_double && IsFastObjectElementsKind(elements_kind) | 2888 ? INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE |
2892 ? INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE | 2889 : DONT_INITIALIZE_ARRAY_ELEMENTS; |
2893 : DONT_INITIALIZE_ARRAY_ELEMENTS; | |
2894 Handle<JSArray> result_array = isolate->factory()->NewJSArray( | 2890 Handle<JSArray> result_array = isolate->factory()->NewJSArray( |
2895 elements_kind, result_len, result_len, mode); | 2891 elements_kind, result_len, result_len, mode); |
2896 if (result_len == 0) return result_array; | 2892 if (result_len == 0) return result_array; |
2897 int j = 0; | 2893 |
2894 uint32_t insertion_index = 0; | |
2898 Handle<FixedArrayBase> storage(result_array->elements(), isolate); | 2895 Handle<FixedArrayBase> storage(result_array->elements(), isolate); |
2899 ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind); | 2896 ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind); |
2900 for (uint32_t i = 0; i < concat_size; i++) { | 2897 for (uint32_t i = 0; i < concat_size; i++) { |
2901 // It is crucial to keep |array| in a raw pointer form to avoid | 2898 // It is crucial to keep |array| in a raw pointer form to avoid |
2902 // performance degradation. | 2899 // performance degradation. |
2903 JSArray* array = JSArray::cast((*args)[i]); | 2900 JSArray* array = JSArray::cast((*args)[i]); |
2904 int len = Smi::cast(array->length())->value(); | 2901 uint32_t len; |
2905 if (len > 0) { | 2902 array->length()->ToArrayLength(&len); |
2906 ElementsKind from_kind = array->GetElementsKind(); | 2903 if (len == 0) continue; |
2907 accessor->CopyElements(array, 0, from_kind, storage, j, len); | 2904 ElementsKind from_kind = array->GetElementsKind(); |
2908 j += len; | 2905 accessor->CopyElements(array, 0, from_kind, storage, insertion_index, len); |
2909 } | 2906 insertion_index += len; |
2910 } | 2907 } |
2911 | 2908 |
2912 DCHECK(j == result_len); | 2909 DCHECK_EQ(insertion_index, result_len); |
2913 return result_array; | 2910 return result_array; |
2914 } | 2911 } |
2915 | 2912 |
2916 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2913 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
2917 } // namespace internal | 2914 } // namespace internal |
2918 } // namespace v8 | 2915 } // namespace v8 |
OLD | NEW |