Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: src/runtime.cc

Issue 21353002: Reimplement TypedArray.set in Javascript. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/typedarray.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | src/typedarray.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698