Chromium Code Reviews| 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 |