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 873 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 |
OLD | NEW |