OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
900 return typed_array->accessor(); \ | 900 return typed_array->accessor(); \ |
901 } | 901 } |
902 | 902 |
903 TYPED_ARRAY_GETTER(Buffer, buffer) | 903 TYPED_ARRAY_GETTER(Buffer, buffer) |
904 TYPED_ARRAY_GETTER(ByteLength, byte_length) | 904 TYPED_ARRAY_GETTER(ByteLength, byte_length) |
905 TYPED_ARRAY_GETTER(ByteOffset, byte_offset) | 905 TYPED_ARRAY_GETTER(ByteOffset, byte_offset) |
906 TYPED_ARRAY_GETTER(Length, length) | 906 TYPED_ARRAY_GETTER(Length, length) |
907 | 907 |
908 #undef TYPED_ARRAY_GETTER | 908 #undef TYPED_ARRAY_GETTER |
909 | 909 |
| 910 // Return codes for Runtime_TypedArraySetFastCases. |
| 911 // Should be synchronized with typedarray.js natives. |
| 912 enum TypedArraySetResultCodes { |
| 913 // Set from typed array of the same type. |
| 914 // This is processed by TypedArraySetFastCases |
| 915 TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE = 0, |
| 916 // Set from typed array of the different type, overlapping in memory. |
| 917 TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING = 1, |
| 918 // Set from typed array of the different type, non-overlapping. |
| 919 TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING = 2, |
| 920 // Set from non-typed array. |
| 921 TYPED_ARRAY_SET_NON_TYPED_ARRAY = 3 |
| 922 }; |
| 923 |
| 924 |
910 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) { | 925 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) { |
911 HandleScope scope(isolate); | 926 HandleScope scope(isolate); |
912 CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0); | 927 CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0); |
913 CONVERT_ARG_HANDLE_CHECKED(Object, source_obj, 1); | 928 CONVERT_ARG_HANDLE_CHECKED(Object, source_obj, 1); |
914 CONVERT_ARG_HANDLE_CHECKED(Object, offset_obj, 2); | 929 CONVERT_ARG_HANDLE_CHECKED(Object, offset_obj, 2); |
915 | 930 |
916 if (!target_obj->IsJSTypedArray()) | 931 if (!target_obj->IsJSTypedArray()) |
917 return isolate->Throw(*isolate->factory()->NewTypeError( | 932 return isolate->Throw(*isolate->factory()->NewTypeError( |
918 "not_typed_array", HandleVector<Object>(NULL, 0))); | 933 "not_typed_array", HandleVector<Object>(NULL, 0))); |
919 | 934 |
920 if (!source_obj->IsJSTypedArray()) | 935 if (!source_obj->IsJSTypedArray()) |
921 return isolate->heap()->false_value(); | 936 return Smi::FromInt(TYPED_ARRAY_SET_NON_TYPED_ARRAY); |
922 | 937 |
923 Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj)); | 938 Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj)); |
924 Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj)); | 939 Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj)); |
925 size_t offset = NumberToSize(isolate, *offset_obj); | 940 size_t offset = NumberToSize(isolate, *offset_obj); |
926 size_t target_length = NumberToSize(isolate, target->length()); | 941 size_t target_length = NumberToSize(isolate, target->length()); |
927 size_t source_length = NumberToSize(isolate, source->length()); | 942 size_t source_length = NumberToSize(isolate, source->length()); |
928 size_t target_byte_length = NumberToSize(isolate, target->byte_length()); | 943 size_t target_byte_length = NumberToSize(isolate, target->byte_length()); |
929 size_t source_byte_length = NumberToSize(isolate, source->byte_length()); | 944 size_t source_byte_length = NumberToSize(isolate, source->byte_length()); |
930 if (offset > target_length || | 945 if (offset > target_length || |
931 offset + source_length > target_length || | 946 offset + source_length > target_length || |
932 offset + source_length < offset) // overflow | 947 offset + source_length < offset) // overflow |
933 return isolate->Throw(*isolate->factory()->NewRangeError( | 948 return isolate->Throw(*isolate->factory()->NewRangeError( |
934 "typed_array_set_source_too_large", HandleVector<Object>(NULL, 0))); | 949 "typed_array_set_source_too_large", HandleVector<Object>(NULL, 0))); |
935 | 950 |
936 Handle<JSArrayBuffer> target_buffer(JSArrayBuffer::cast(target->buffer())); | |
937 Handle<JSArrayBuffer> source_buffer(JSArrayBuffer::cast(source->buffer())); | |
938 size_t target_offset = NumberToSize(isolate, target->byte_offset()); | 951 size_t target_offset = NumberToSize(isolate, target->byte_offset()); |
939 size_t source_offset = NumberToSize(isolate, source->byte_offset()); | 952 size_t source_offset = NumberToSize(isolate, source->byte_offset()); |
940 uint8_t* target_base = | 953 uint8_t* target_base = |
941 static_cast<uint8_t*>(target_buffer->backing_store()) + target_offset; | 954 static_cast<uint8_t*>( |
| 955 JSArrayBuffer::cast(target->buffer())->backing_store()) + target_offset; |
942 uint8_t* source_base = | 956 uint8_t* source_base = |
943 static_cast<uint8_t*>(source_buffer->backing_store()) + source_offset; | 957 static_cast<uint8_t*>( |
| 958 JSArrayBuffer::cast(source->buffer())->backing_store()) + source_offset; |
944 | 959 |
945 // Typed arrays of the same type: use memmove. | 960 // Typed arrays of the same type: use memmove. |
946 if (target->type() == source->type()) { | 961 if (target->type() == source->type()) { |
947 memmove(target_base + offset * target->element_size(), | 962 memmove(target_base + offset * target->element_size(), |
948 source_base, source_byte_length); | 963 source_base, source_byte_length); |
949 return isolate->heap()->true_value(); | 964 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_SAME_TYPE); |
950 } | 965 } |
951 | 966 |
952 // Typed arrays of different types over the same backing store | 967 // Typed arrays of different types over the same backing store |
953 if ((source_base <= target_base && | 968 if ((source_base <= target_base && |
954 source_base + source_byte_length > target_base) || | 969 source_base + source_byte_length > target_base) || |
955 (target_base <= source_base && | 970 (target_base <= source_base && |
956 target_base + target_byte_length > source_base)) { | 971 target_base + target_byte_length > source_base)) { |
957 size_t target_element_size = target->element_size(); | 972 // We do not support overlapping ArrayBuffers |
958 size_t source_element_size = source->element_size(); | 973 ASSERT( |
959 | 974 JSArrayBuffer::cast(target->buffer())->backing_store() == |
960 size_t source_length = NumberToSize(isolate, source->length()); | 975 JSArrayBuffer::cast(source->buffer())->backing_store()); |
961 | 976 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_OVERLAPPING); |
962 // Copy left part | |
963 size_t left_index; | |
964 { | |
965 // First un-mutated byte after the next write | |
966 uint8_t* target_ptr = target_base + (offset + 1) * target_element_size; | |
967 // Next read at source_ptr. We do not care for memory changing before | |
968 // source_ptr - we have already copied it. | |
969 uint8_t* source_ptr = source_base; | |
970 for (left_index = 0; | |
971 left_index < source_length && target_ptr <= source_ptr; | |
972 left_index++) { | |
973 Handle<Object> v = Object::GetElement( | |
974 source, static_cast<uint32_t>(left_index)); | |
975 JSObject::SetElement( | |
976 target, static_cast<uint32_t>(offset + left_index), v, | |
977 NONE, kNonStrictMode); | |
978 target_ptr += target_element_size; | |
979 source_ptr += source_element_size; | |
980 } | |
981 } | |
982 // Copy right part | |
983 size_t right_index; | |
984 { | |
985 // First unmutated byte before the next write | |
986 uint8_t* target_ptr = | |
987 target_base + (offset + source_length - 1) * target_element_size; | |
988 // Next read before source_ptr. We do not care for memory changing after | |
989 // source_ptr - we have already copied it. | |
990 uint8_t* source_ptr = | |
991 source_base + source_length * source_element_size; | |
992 for (right_index = source_length - 1; | |
993 right_index >= left_index && target_ptr >= source_ptr; | |
994 right_index--) { | |
995 Handle<Object> v = Object::GetElement( | |
996 source, static_cast<uint32_t>(right_index)); | |
997 JSObject::SetElement( | |
998 target, static_cast<uint32_t>(offset + right_index), v, | |
999 NONE, kNonStrictMode); | |
1000 target_ptr -= target_element_size; | |
1001 source_ptr -= source_element_size; | |
1002 } | |
1003 } | |
1004 // There can be at most 8 entries left in the middle that need buffering | |
1005 // (because the largest element_size is 8 times the smallest). | |
1006 ASSERT((right_index + 1) - left_index <= 8); | |
1007 Handle<Object> temp[8]; | |
1008 size_t idx; | |
1009 for (idx = left_index; idx <= right_index; idx++) { | |
1010 temp[idx - left_index] = Object::GetElement( | |
1011 source, static_cast<uint32_t>(idx)); | |
1012 } | |
1013 for (idx = left_index; idx <= right_index; idx++) { | |
1014 JSObject::SetElement( | |
1015 target, static_cast<uint32_t>(offset + idx), temp[idx-left_index], | |
1016 NONE, kNonStrictMode); | |
1017 } | |
1018 } else { // Non-overlapping typed arrays | 977 } else { // Non-overlapping typed arrays |
1019 for (size_t idx = 0; idx < source_length; idx++) { | 978 return Smi::FromInt(TYPED_ARRAY_SET_TYPED_ARRAY_NONOVERLAPPING); |
1020 Handle<Object> value = Object::GetElement( | |
1021 source, static_cast<uint32_t>(idx)); | |
1022 JSObject::SetElement( | |
1023 target, static_cast<uint32_t>(offset + idx), value, | |
1024 NONE, kNonStrictMode); | |
1025 } | |
1026 } | 979 } |
1027 | |
1028 return isolate->heap()->true_value(); | |
1029 } | 980 } |
1030 | 981 |
1031 | 982 |
1032 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewInitialize) { | 983 RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewInitialize) { |
1033 HandleScope scope(isolate); | 984 HandleScope scope(isolate); |
1034 ASSERT(args.length() == 4); | 985 ASSERT(args.length() == 4); |
1035 CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); | 986 CONVERT_ARG_HANDLE_CHECKED(JSDataView, holder, 0); |
1036 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1); | 987 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 1); |
1037 CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset, 2); | 988 CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset, 2); |
1038 CONVERT_ARG_HANDLE_CHECKED(Object, byte_length, 3); | 989 CONVERT_ARG_HANDLE_CHECKED(Object, byte_length, 3); |
(...skipping 12868 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13907 // Handle last resort GC and make sure to allow future allocations | 13858 // Handle last resort GC and make sure to allow future allocations |
13908 // to grow the heap without causing GCs (if possible). | 13859 // to grow the heap without causing GCs (if possible). |
13909 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13860 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13910 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13861 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13911 "Runtime::PerformGC"); | 13862 "Runtime::PerformGC"); |
13912 } | 13863 } |
13913 } | 13864 } |
13914 | 13865 |
13915 | 13866 |
13916 } } // namespace v8::internal | 13867 } } // namespace v8::internal |
OLD | NEW |