| 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/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 uint32_t unshift_size) final { | 677 uint32_t unshift_size) final { |
| 678 return Subclass::UnshiftImpl(receiver, args, unshift_size); | 678 return Subclass::UnshiftImpl(receiver, args, unshift_size); |
| 679 } | 679 } |
| 680 | 680 |
| 681 static uint32_t UnshiftImpl(Handle<JSArray> receiver, Arguments* args, | 681 static uint32_t UnshiftImpl(Handle<JSArray> receiver, Arguments* args, |
| 682 uint32_t unshift_size) { | 682 uint32_t unshift_size) { |
| 683 UNREACHABLE(); | 683 UNREACHABLE(); |
| 684 return 0; | 684 return 0; |
| 685 } | 685 } |
| 686 | 686 |
| 687 Handle<JSArray> Slice(Handle<JSObject> receiver, uint32_t start, | 687 Handle<JSObject> Slice(Handle<JSObject> receiver, uint32_t start, |
| 688 uint32_t end) final { | 688 uint32_t end) final { |
| 689 return Subclass::SliceImpl(receiver, start, end); | 689 return Subclass::SliceImpl(receiver, start, end); |
| 690 } | 690 } |
| 691 | 691 |
| 692 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, | 692 Handle<JSObject> Slice(Handle<JSObject> receiver, uint32_t start, |
| 693 uint32_t start, uint32_t end) { | 693 uint32_t end, Handle<JSObject> result) final { |
| 694 return Subclass::SliceWithResultImpl(receiver, start, end, result); |
| 695 } |
| 696 |
| 697 static Handle<JSObject> SliceImpl(Handle<JSObject> receiver, uint32_t start, |
| 698 uint32_t end) { |
| 694 UNREACHABLE(); | 699 UNREACHABLE(); |
| 695 return Handle<JSArray>(); | 700 return Handle<JSObject>(); |
| 701 } |
| 702 |
| 703 static Handle<JSObject> SliceWithResultImpl(Handle<JSObject> receiver, |
| 704 uint32_t start, uint32_t end, |
| 705 Handle<JSObject> result) { |
| 706 return Subclass::SliceImpl(receiver, start, end); |
| 696 } | 707 } |
| 697 | 708 |
| 698 Handle<JSArray> Splice(Handle<JSArray> receiver, uint32_t start, | 709 Handle<JSArray> Splice(Handle<JSArray> receiver, uint32_t start, |
| 699 uint32_t delete_count, Arguments* args, | 710 uint32_t delete_count, Arguments* args, |
| 700 uint32_t add_count) final { | 711 uint32_t add_count) final { |
| 701 return Subclass::SpliceImpl(receiver, start, delete_count, args, add_count); | 712 return Subclass::SpliceImpl(receiver, start, delete_count, args, add_count); |
| 702 } | 713 } |
| 703 | 714 |
| 704 static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, | 715 static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, |
| 705 uint32_t start, uint32_t delete_count, | 716 uint32_t start, uint32_t delete_count, |
| (...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2010 AT_END); | 2021 AT_END); |
| 2011 } | 2022 } |
| 2012 | 2023 |
| 2013 static uint32_t UnshiftImpl(Handle<JSArray> receiver, | 2024 static uint32_t UnshiftImpl(Handle<JSArray> receiver, |
| 2014 Arguments* args, uint32_t unshift_size) { | 2025 Arguments* args, uint32_t unshift_size) { |
| 2015 Handle<FixedArrayBase> backing_store(receiver->elements()); | 2026 Handle<FixedArrayBase> backing_store(receiver->elements()); |
| 2016 return Subclass::AddArguments(receiver, backing_store, args, unshift_size, | 2027 return Subclass::AddArguments(receiver, backing_store, args, unshift_size, |
| 2017 AT_START); | 2028 AT_START); |
| 2018 } | 2029 } |
| 2019 | 2030 |
| 2020 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, | 2031 static Handle<JSObject> SliceImpl(Handle<JSObject> receiver, uint32_t start, |
| 2021 uint32_t start, uint32_t end) { | 2032 uint32_t end) { |
| 2022 Isolate* isolate = receiver->GetIsolate(); | 2033 Isolate* isolate = receiver->GetIsolate(); |
| 2023 Handle<FixedArrayBase> backing_store(receiver->elements(), isolate); | 2034 Handle<FixedArrayBase> backing_store(receiver->elements(), isolate); |
| 2024 int result_len = end < start ? 0u : end - start; | 2035 int result_len = end < start ? 0u : end - start; |
| 2025 Handle<JSArray> result_array = isolate->factory()->NewJSArray( | 2036 Handle<JSArray> result_array = isolate->factory()->NewJSArray( |
| 2026 KindTraits::Kind, result_len, result_len); | 2037 KindTraits::Kind, result_len, result_len); |
| 2027 DisallowHeapAllocation no_gc; | 2038 DisallowHeapAllocation no_gc; |
| 2028 Subclass::CopyElementsImpl(*backing_store, start, result_array->elements(), | 2039 Subclass::CopyElementsImpl(*backing_store, start, result_array->elements(), |
| 2029 KindTraits::Kind, 0, kPackedSizeNotKnown, | 2040 KindTraits::Kind, 0, kPackedSizeNotKnown, |
| 2030 result_len); | 2041 result_len); |
| 2031 Subclass::TryTransitionResultArrayToPacked(result_array); | 2042 Subclass::TryTransitionResultArrayToPacked(result_array); |
| (...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2963 | 2974 |
| 2964 DCHECK_LT(start_from, elements->length()); | 2975 DCHECK_LT(start_from, elements->length()); |
| 2965 | 2976 |
| 2966 uint32_t k = start_from; | 2977 uint32_t k = start_from; |
| 2967 do { | 2978 do { |
| 2968 ctype element_k = elements->get_scalar(k); | 2979 ctype element_k = elements->get_scalar(k); |
| 2969 if (element_k == typed_search_value) return Just<int64_t>(k); | 2980 if (element_k == typed_search_value) return Just<int64_t>(k); |
| 2970 } while (k-- != 0); | 2981 } while (k-- != 0); |
| 2971 return Just<int64_t>(-1); | 2982 return Just<int64_t>(-1); |
| 2972 } | 2983 } |
| 2984 |
| 2985 static Handle<JSObject> SliceWithResultImpl(Handle<JSObject> receiver, |
| 2986 uint32_t start, uint32_t end, |
| 2987 Handle<JSObject> result) { |
| 2988 Isolate* isolate = receiver->GetIsolate(); |
| 2989 DCHECK(!WasNeutered(*receiver)); |
| 2990 DCHECK(result->IsJSTypedArray()); |
| 2991 DCHECK(!WasNeutered(*result)); |
| 2992 DCHECK_LE(start, end); |
| 2993 |
| 2994 Handle<JSTypedArray> array = Handle<JSTypedArray>::cast(receiver); |
| 2995 Handle<JSTypedArray> result_array = Handle<JSTypedArray>::cast(result); |
| 2996 DCHECK_LE(end, array->length_value()); |
| 2997 |
| 2998 // Fast path for the same type result array |
| 2999 if (result_array->type() == array->type()) { |
| 3000 int64_t element_size = array->element_size(); |
| 3001 int64_t count = std::max<int64_t>(end - start, 0); |
| 3002 |
| 3003 DisallowHeapAllocation no_gc; |
| 3004 BackingStore* src_elements = BackingStore::cast(receiver->elements()); |
| 3005 BackingStore* result_elements = |
| 3006 BackingStore::cast(result_array->elements()); |
| 3007 |
| 3008 DCHECK_LE(count, result_elements->length()); |
| 3009 |
| 3010 uint8_t* src = static_cast<uint8_t*>(src_elements->DataPtr()); |
| 3011 uint8_t* result = static_cast<uint8_t*>(result_elements->DataPtr()); |
| 3012 std::memcpy(result, src + start * element_size, count * element_size); |
| 3013 return result_array; |
| 3014 } |
| 3015 |
| 3016 // If the types of the two typed arrays are different, properly convert |
| 3017 // elements |
| 3018 Handle<BackingStore> from(BackingStore::cast(array->elements()), isolate); |
| 3019 ElementsAccessor* result_accessor = result_array->GetElementsAccessor(); |
| 3020 for (uint32_t k = start; k < end; k++) { |
| 3021 Handle<Object> elem = AccessorClass::GetImpl(isolate, *from, k); |
| 3022 result_accessor->Set(result_array, k, *elem); |
| 3023 } |
| 3024 return result_array; |
| 3025 } |
| 2973 }; | 3026 }; |
| 2974 | 3027 |
| 2975 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ | 3028 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ |
| 2976 typedef TypedElementsAccessor<TYPE##_ELEMENTS, ctype> \ | 3029 typedef TypedElementsAccessor<TYPE##_ELEMENTS, ctype> \ |
| 2977 Fixed##Type##ElementsAccessor; | 3030 Fixed##Type##ElementsAccessor; |
| 2978 | 3031 |
| 2979 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) | 3032 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) |
| 2980 #undef FIXED_ELEMENTS_ACCESSOR | 3033 #undef FIXED_ELEMENTS_ACCESSOR |
| 2981 | 3034 |
| 2982 template <typename Subclass, typename ArgumentsAccessor, typename KindTraits> | 3035 template <typename Subclass, typename ArgumentsAccessor, typename KindTraits> |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3400 FastSloppyArgumentsElementsAccessor, | 3453 FastSloppyArgumentsElementsAccessor, |
| 3401 FastHoleyObjectElementsAccessor, | 3454 FastHoleyObjectElementsAccessor, |
| 3402 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} | 3455 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} |
| 3403 | 3456 |
| 3404 static Handle<FixedArray> GetArguments(Isolate* isolate, | 3457 static Handle<FixedArray> GetArguments(Isolate* isolate, |
| 3405 FixedArrayBase* backing_store) { | 3458 FixedArrayBase* backing_store) { |
| 3406 FixedArray* parameter_map = FixedArray::cast(backing_store); | 3459 FixedArray* parameter_map = FixedArray::cast(backing_store); |
| 3407 return Handle<FixedArray>(FixedArray::cast(parameter_map->get(1)), isolate); | 3460 return Handle<FixedArray>(FixedArray::cast(parameter_map->get(1)), isolate); |
| 3408 } | 3461 } |
| 3409 | 3462 |
| 3410 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, uint32_t start, | 3463 static Handle<JSObject> SliceImpl(Handle<JSObject> receiver, uint32_t start, |
| 3411 uint32_t end) { | 3464 uint32_t end) { |
| 3412 Isolate* isolate = receiver->GetIsolate(); | 3465 Isolate* isolate = receiver->GetIsolate(); |
| 3413 uint32_t result_len = end < start ? 0u : end - start; | 3466 uint32_t result_len = end < start ? 0u : end - start; |
| 3414 Handle<JSArray> result_array = isolate->factory()->NewJSArray( | 3467 Handle<JSArray> result_array = isolate->factory()->NewJSArray( |
| 3415 FAST_HOLEY_ELEMENTS, result_len, result_len); | 3468 FAST_HOLEY_ELEMENTS, result_len, result_len); |
| 3416 DisallowHeapAllocation no_gc; | 3469 DisallowHeapAllocation no_gc; |
| 3417 FixedArray* elements = FixedArray::cast(result_array->elements()); | 3470 FixedArray* elements = FixedArray::cast(result_array->elements()); |
| 3418 FixedArray* parameters = FixedArray::cast(receiver->elements()); | 3471 FixedArray* parameters = FixedArray::cast(receiver->elements()); |
| 3419 uint32_t insertion_index = 0; | 3472 uint32_t insertion_index = 0; |
| 3420 for (uint32_t i = start; i < end; i++) { | 3473 for (uint32_t i = start; i < end; i++) { |
| 3421 uint32_t entry = GetEntryForIndexImpl(isolate, *receiver, parameters, i, | 3474 uint32_t entry = GetEntryForIndexImpl(isolate, *receiver, parameters, i, |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3918 insertion_index += len; | 3971 insertion_index += len; |
| 3919 } | 3972 } |
| 3920 | 3973 |
| 3921 DCHECK_EQ(insertion_index, result_len); | 3974 DCHECK_EQ(insertion_index, result_len); |
| 3922 return result_array; | 3975 return result_array; |
| 3923 } | 3976 } |
| 3924 | 3977 |
| 3925 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 3978 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
| 3926 } // namespace internal | 3979 } // namespace internal |
| 3927 } // namespace v8 | 3980 } // namespace v8 |
| OLD | NEW |