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

Side by Side Diff: src/runtime.cc

Issue 14581005: Implement TypedArray.set function. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: CR feedback Created 7 years, 7 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
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 873 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 return typed_array->accessor(); \ 884 return typed_array->accessor(); \
885 } 885 }
886 886
887 TYPED_ARRAY_GETTER(Buffer, buffer) 887 TYPED_ARRAY_GETTER(Buffer, buffer)
888 TYPED_ARRAY_GETTER(ByteLength, byte_length) 888 TYPED_ARRAY_GETTER(ByteLength, byte_length)
889 TYPED_ARRAY_GETTER(ByteOffset, byte_offset) 889 TYPED_ARRAY_GETTER(ByteOffset, byte_offset)
890 TYPED_ARRAY_GETTER(Length, length) 890 TYPED_ARRAY_GETTER(Length, length)
891 891
892 #undef TYPED_ARRAY_GETTER 892 #undef TYPED_ARRAY_GETTER
893 893
894 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArraySetFastCases) {
895 HandleScope scope(isolate);
896 CONVERT_ARG_HANDLE_CHECKED(Object, target_obj, 0);
897 CONVERT_ARG_HANDLE_CHECKED(Object, source_obj, 1);
898 CONVERT_ARG_HANDLE_CHECKED(Object, offset_obj, 2);
899
900 if (!target_obj->IsJSTypedArray())
901 return isolate->Throw(*isolate->factory()->NewTypeError(
902 "not_typed_array", HandleVector<Object>(NULL, 0)));
903
904 if (!source_obj->IsJSTypedArray())
905 return isolate->heap()->false_value();
906
907 Handle<JSTypedArray> target(JSTypedArray::cast(*target_obj));
908 Handle<JSTypedArray> source(JSTypedArray::cast(*source_obj));
909 size_t offset = NumberToSize(isolate, *offset_obj);
910 size_t target_length = NumberToSize(isolate, target->length());
911 size_t source_length = NumberToSize(isolate, source->length());
912 size_t target_byte_length = NumberToSize(isolate, target->byte_length());
913 size_t source_byte_length = NumberToSize(isolate, source->byte_length());
914 if (offset > target_length ||
915 offset + source_length > target_length ||
916 offset + source_length < offset) // overflow
917 return isolate->Throw(*isolate->factory()->NewRangeError(
918 "typed_array_set_source_too_large", HandleVector<Object>(NULL, 0)));
919
920 Handle<JSArrayBuffer> target_buffer(JSArrayBuffer::cast(target->buffer()));
921 Handle<JSArrayBuffer> source_buffer(JSArrayBuffer::cast(source->buffer()));
922 size_t target_offset = NumberToSize(isolate, target->byte_offset());
923 size_t source_offset = NumberToSize(isolate, source->byte_offset());
924 uint8_t* target_base =
925 static_cast<uint8_t*>(target_buffer->backing_store()) + target_offset;
926 uint8_t* source_base =
927 static_cast<uint8_t*>(source_buffer->backing_store()) + source_offset;
928
929 // Typed arrays of the same type: use memmove.
930 if (target->type() == source->type()) {
931 memmove(target_base + offset * target->element_size(),
932 source_base, source_byte_length);
933 return isolate->heap()->true_value();
934 }
935
936 // Typed arrays of different types over the same backing store
937 if ((source_base <= target_base &&
938 source_base + source_byte_length > target_base) ||
939 (target_base <= source_base &&
940 target_base + target_byte_length > source_base)) {
941 size_t target_element_size = target->element_size();
942 size_t source_element_size = source->element_size();
943
944 size_t source_length = NumberToSize(isolate, source->length());
945
946 // Copy left part
947 size_t left_index;
948 {
949 // First un-mutated byte after the next write
950 uint8_t* target_ptr = target_base + (offset + 1) * target_element_size;
951 // Next read at source_ptr. We do not care for memory changing before
952 // source_ptr - we have already copied it.
953 uint8_t* source_ptr = source_base;
954 for (left_index = 0;
955 left_index < source_length && target_ptr <= source_ptr;
956 left_index++) {
957 Handle<Object> v = Object::GetElement(
958 source, static_cast<uint32_t>(left_index));
959 JSObject::SetElement(
960 target, static_cast<uint32_t>(offset + left_index), v,
961 NONE, kNonStrictMode);
962 target_ptr += target_element_size;
963 source_ptr += source_element_size;
964 }
965 }
966 // Copy right part
967 size_t right_index;
968 {
969 // First unmutated byte before the next write
970 uint8_t* target_ptr =
971 target_base + (offset + source_length - 1) * target_element_size;
972 // Next read before source_ptr. We do not care for memory changing after
973 // source_ptr - we have already copied it.
974 uint8_t* source_ptr =
975 source_base + source_length * source_element_size;
976 for (right_index = source_length - 1;
977 right_index >= left_index && target_ptr >= source_ptr;
978 right_index--) {
979 Handle<Object> v = Object::GetElement(
980 source, static_cast<uint32_t>(right_index));
981 JSObject::SetElement(
982 target, static_cast<uint32_t>(offset + right_index), v,
983 NONE, kNonStrictMode);
984 target_ptr -= target_element_size;
985 source_ptr -= source_element_size;
986 }
987 }
988 // There can be at most 8 entries left in the middle that need buffering
989 // (because the largest element_size is 8 times the smallest).
990 ASSERT((right_index + 1) - left_index <= 8);
991 Handle<Object> temp[8];
992 size_t idx;
993 for (idx = left_index; idx <= right_index; idx++) {
994 temp[idx - left_index] = Object::GetElement(
995 source, static_cast<uint32_t>(idx));
996 }
997 for (idx = left_index; idx <= right_index; idx++) {
998 JSObject::SetElement(
999 target, static_cast<uint32_t>(offset + idx), temp[idx-left_index],
1000 NONE, kNonStrictMode);
1001 }
1002 } else { // Non-overlapping typed arrays
1003 for (size_t idx = 0; idx < source_length; idx++) {
1004 Handle<Object> value = Object::GetElement(
1005 source, static_cast<uint32_t>(idx));
1006 JSObject::SetElement(
1007 target, static_cast<uint32_t>(offset + idx), value,
1008 NONE, kNonStrictMode);
1009 }
1010 }
1011
1012 return isolate->heap()->true_value();
1013 }
1014
1015
894 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) { 1016 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetInitialize) {
895 HandleScope scope(isolate); 1017 HandleScope scope(isolate);
896 ASSERT(args.length() == 1); 1018 ASSERT(args.length() == 1);
897 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0); 1019 CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
898 Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0); 1020 Handle<ObjectHashSet> table = isolate->factory()->NewObjectHashSet(0);
899 holder->set_table(*table); 1021 holder->set_table(*table);
900 return *holder; 1022 return *holder;
901 } 1023 }
902 1024
903 1025
(...skipping 12490 matching lines...) Expand 10 before | Expand all | Expand 10 after
13394 // Handle last resort GC and make sure to allow future allocations 13516 // Handle last resort GC and make sure to allow future allocations
13395 // to grow the heap without causing GCs (if possible). 13517 // to grow the heap without causing GCs (if possible).
13396 isolate->counters()->gc_last_resort_from_js()->Increment(); 13518 isolate->counters()->gc_last_resort_from_js()->Increment();
13397 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13519 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13398 "Runtime::PerformGC"); 13520 "Runtime::PerformGC");
13399 } 13521 }
13400 } 13522 }
13401 13523
13402 13524
13403 } } // namespace v8::internal 13525 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/typedarray.js » ('j') | test/mjsunit/harmony/typedarrays.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698