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

Side by Side Diff: src/runtime.cc

Issue 21369002: Speed-up 'new TypedArray(arrayLike)'. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: References -> pointers (argh!) 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 | « src/runtime.h ('k') | 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 694 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 705
706 array_buffer->set_weak_next(isolate->heap()->array_buffers_list()); 706 array_buffer->set_weak_next(isolate->heap()->array_buffers_list());
707 isolate->heap()->set_array_buffers_list(*array_buffer); 707 isolate->heap()->set_array_buffers_list(*array_buffer);
708 array_buffer->set_weak_first_view(isolate->heap()->undefined_value()); 708 array_buffer->set_weak_first_view(isolate->heap()->undefined_value());
709 } 709 }
710 710
711 711
712 bool Runtime::SetupArrayBufferAllocatingData( 712 bool Runtime::SetupArrayBufferAllocatingData(
713 Isolate* isolate, 713 Isolate* isolate,
714 Handle<JSArrayBuffer> array_buffer, 714 Handle<JSArrayBuffer> array_buffer,
715 size_t allocated_length) { 715 size_t allocated_length,
716 bool initialize) {
716 void* data; 717 void* data;
717 CHECK(V8::ArrayBufferAllocator() != NULL); 718 CHECK(V8::ArrayBufferAllocator() != NULL);
718 if (allocated_length != 0) { 719 if (allocated_length != 0) {
719 data = V8::ArrayBufferAllocator()->Allocate(allocated_length); 720 if (initialize) {
721 data = V8::ArrayBufferAllocator()->Allocate(allocated_length);
722 } else {
723 data =
724 V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length);
725 }
720 if (data == NULL) return false; 726 if (data == NULL) return false;
721 memset(data, 0, allocated_length);
722 } else { 727 } else {
723 data = NULL; 728 data = NULL;
724 } 729 }
725 730
726 SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length); 731 SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
727 732
728 isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length); 733 isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length);
729 734
730 return true; 735 return true;
731 } 736 }
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 ARRAY_ID_INT8 = 2, 803 ARRAY_ID_INT8 = 2,
799 ARRAY_ID_UINT16 = 3, 804 ARRAY_ID_UINT16 = 3,
800 ARRAY_ID_INT16 = 4, 805 ARRAY_ID_INT16 = 4,
801 ARRAY_ID_UINT32 = 5, 806 ARRAY_ID_UINT32 = 5,
802 ARRAY_ID_INT32 = 6, 807 ARRAY_ID_INT32 = 6,
803 ARRAY_ID_FLOAT32 = 7, 808 ARRAY_ID_FLOAT32 = 7,
804 ARRAY_ID_FLOAT64 = 8, 809 ARRAY_ID_FLOAT64 = 8,
805 ARRAY_ID_UINT8C = 9 810 ARRAY_ID_UINT8C = 9
806 }; 811 };
807 812
813 static void ArrayIdToTypeAndSize(
814 int arrayId, ExternalArrayType* array_type, size_t* element_size) {
815 switch (arrayId) {
816 case ARRAY_ID_UINT8:
817 *array_type = kExternalUnsignedByteArray;
818 *element_size = 1;
819 break;
820 case ARRAY_ID_INT8:
821 *array_type = kExternalByteArray;
822 *element_size = 1;
823 break;
824 case ARRAY_ID_UINT16:
825 *array_type = kExternalUnsignedShortArray;
826 *element_size = 2;
827 break;
828 case ARRAY_ID_INT16:
829 *array_type = kExternalShortArray;
830 *element_size = 2;
831 break;
832 case ARRAY_ID_UINT32:
833 *array_type = kExternalUnsignedIntArray;
834 *element_size = 4;
835 break;
836 case ARRAY_ID_INT32:
837 *array_type = kExternalIntArray;
838 *element_size = 4;
839 break;
840 case ARRAY_ID_FLOAT32:
841 *array_type = kExternalFloatArray;
842 *element_size = 4;
843 break;
844 case ARRAY_ID_FLOAT64:
845 *array_type = kExternalDoubleArray;
846 *element_size = 8;
847 break;
848 case ARRAY_ID_UINT8C:
849 *array_type = kExternalPixelArray;
850 *element_size = 1;
851 break;
852 default:
853 UNREACHABLE();
854 }
855 }
856
808 857
809 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) { 858 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) {
810 HandleScope scope(isolate); 859 HandleScope scope(isolate);
811 ASSERT(args.length() == 5); 860 ASSERT(args.length() == 5);
812 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0); 861 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
813 CONVERT_SMI_ARG_CHECKED(arrayId, 1); 862 CONVERT_SMI_ARG_CHECKED(arrayId, 1);
814 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 2); 863 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 2);
815 CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset_object, 3); 864 CONVERT_ARG_HANDLE_CHECKED(Object, byte_offset_object, 3);
816 CONVERT_ARG_HANDLE_CHECKED(Object, byte_length_object, 4); 865 CONVERT_ARG_HANDLE_CHECKED(Object, byte_length_object, 4);
817 866
818 ASSERT(holder->GetInternalFieldCount() == 867 ASSERT(holder->GetInternalFieldCount() ==
819 v8::ArrayBufferView::kInternalFieldCount); 868 v8::ArrayBufferView::kInternalFieldCount);
820 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) { 869 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
821 holder->SetInternalField(i, Smi::FromInt(0)); 870 holder->SetInternalField(i, Smi::FromInt(0));
822 } 871 }
823 872
824 ExternalArrayType arrayType; 873 ExternalArrayType array_type;
825 size_t elementSize; 874 size_t element_size;
826 switch (arrayId) { 875 ArrayIdToTypeAndSize(arrayId, &array_type, &element_size);
827 case ARRAY_ID_UINT8:
828 arrayType = kExternalUnsignedByteArray;
829 elementSize = 1;
830 break;
831 case ARRAY_ID_INT8:
832 arrayType = kExternalByteArray;
833 elementSize = 1;
834 break;
835 case ARRAY_ID_UINT16:
836 arrayType = kExternalUnsignedShortArray;
837 elementSize = 2;
838 break;
839 case ARRAY_ID_INT16:
840 arrayType = kExternalShortArray;
841 elementSize = 2;
842 break;
843 case ARRAY_ID_UINT32:
844 arrayType = kExternalUnsignedIntArray;
845 elementSize = 4;
846 break;
847 case ARRAY_ID_INT32:
848 arrayType = kExternalIntArray;
849 elementSize = 4;
850 break;
851 case ARRAY_ID_FLOAT32:
852 arrayType = kExternalFloatArray;
853 elementSize = 4;
854 break;
855 case ARRAY_ID_FLOAT64:
856 arrayType = kExternalDoubleArray;
857 elementSize = 8;
858 break;
859 case ARRAY_ID_UINT8C:
860 arrayType = kExternalPixelArray;
861 elementSize = 1;
862 break;
863 default:
864 UNREACHABLE();
865 return NULL;
866 }
867 876
868 holder->set_buffer(*buffer); 877 holder->set_buffer(*buffer);
869 holder->set_byte_offset(*byte_offset_object); 878 holder->set_byte_offset(*byte_offset_object);
870 holder->set_byte_length(*byte_length_object); 879 holder->set_byte_length(*byte_length_object);
871 880
872 size_t byte_offset = NumberToSize(isolate, *byte_offset_object); 881 size_t byte_offset = NumberToSize(isolate, *byte_offset_object);
873 size_t byte_length = NumberToSize(isolate, *byte_length_object); 882 size_t byte_length = NumberToSize(isolate, *byte_length_object);
874 ASSERT(byte_length % elementSize == 0); 883 ASSERT(byte_length % element_size == 0);
875 size_t length = byte_length / elementSize; 884 size_t length = byte_length / element_size;
876 885
877 Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length); 886 Handle<Object> length_obj = isolate->factory()->NewNumberFromSize(length);
878 holder->set_length(*length_obj); 887 holder->set_length(*length_obj);
879 holder->set_weak_next(buffer->weak_first_view()); 888 holder->set_weak_next(buffer->weak_first_view());
880 buffer->set_weak_first_view(*holder); 889 buffer->set_weak_first_view(*holder);
881 890
882 Handle<ExternalArray> elements = 891 Handle<ExternalArray> elements =
883 isolate->factory()->NewExternalArray( 892 isolate->factory()->NewExternalArray(
884 static_cast<int>(length), arrayType, 893 static_cast<int>(length), array_type,
885 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset); 894 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
886 holder->set_elements(*elements); 895 holder->set_elements(*elements);
887 return isolate->heap()->undefined_value(); 896 return isolate->heap()->undefined_value();
888 } 897 }
889 898
890 899
900 // Initializes a typed array from an array-like object.
901 // If an array-like object happens to be a typed array of the same type,
902 // initializes backing store using memove.
903 //
904 // Returns true if backing store was initialized or false otherwise.
905 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitializeFromArrayLike) {
906 HandleScope scope(isolate);
907 ASSERT(args.length() == 4);
908 CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
909 CONVERT_SMI_ARG_CHECKED(arrayId, 1);
910 CONVERT_ARG_HANDLE_CHECKED(Object, source, 2);
911 CONVERT_ARG_HANDLE_CHECKED(Object, length_obj, 3);
912
913 ASSERT(holder->GetInternalFieldCount() ==
914 v8::ArrayBufferView::kInternalFieldCount);
915 for (int i = 0; i < v8::ArrayBufferView::kInternalFieldCount; i++) {
916 holder->SetInternalField(i, Smi::FromInt(0));
917 }
918
919 ExternalArrayType array_type;
920 size_t element_size;
921 ArrayIdToTypeAndSize(arrayId, &array_type, &element_size);
922
923 Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
924 size_t length = NumberToSize(isolate, *length_obj);
925 size_t byte_length = length * element_size;
926 if (byte_length < length) { // Overflow
927 return isolate->Throw(*isolate->factory()->
928 NewRangeError("invalid_array_buffer_length",
929 HandleVector<Object>(NULL, 0)));
930 }
931
932 // We assume that the caller of this function will initialize holder
933 // with the loop
934 // for(i = 0; i < length; i++) { holder[i] = source[i]; }
935 // If source is a typed array, this loop will always run to completion,
936 // so we are sure that the backing store will be initialized.
937 // Otherwise, we do not know (the indexing operation might throw).
938 // Hence we require zero initialization unless our sourec is a typed array.
939 bool should_zero_initialize = !source->IsJSTypedArray();
940
941 if (!Runtime::SetupArrayBufferAllocatingData(
942 isolate, buffer, byte_length, should_zero_initialize)) {
943 return isolate->Throw(*isolate->factory()->
944 NewRangeError("invalid_array_buffer_length",
945 HandleVector<Object>(NULL, 0)));
946 }
947
948 holder->set_buffer(*buffer);
949 holder->set_byte_offset(Smi::FromInt(0));
950 Handle<Object> byte_length_obj(
951 isolate->factory()->NewNumberFromSize(byte_length));
952 holder->set_byte_length(*byte_length_obj);
953 holder->set_length(*length_obj);
954 holder->set_weak_next(buffer->weak_first_view());
955 buffer->set_weak_first_view(*holder);
956
957 Handle<ExternalArray> elements =
958 isolate->factory()->NewExternalArray(
959 static_cast<int>(length), array_type,
960 static_cast<uint8_t*>(buffer->backing_store()));
961 holder->set_elements(*elements);
962
963 if (source->IsJSTypedArray()) {
964 Handle<JSTypedArray> typed_array(JSTypedArray::cast(*source));
965
966 if (typed_array->type() == holder->type()) {
967 uint8_t* backing_store =
968 static_cast<uint8_t*>(
969 JSArrayBuffer::cast(typed_array->buffer())->backing_store());
970 size_t source_byte_offset =
971 NumberToSize(isolate, typed_array->byte_offset());
972 OS::MemCopy(
973 buffer->backing_store(),
974 backing_store + source_byte_offset,
975 byte_length);
976 return *isolate->factory()->true_value();
977 } else {
978 return *isolate->factory()->false_value();
979 }
980 }
981
982 return *isolate->factory()->false_value();
983 }
984
985
891 #define TYPED_ARRAY_GETTER(getter, accessor) \ 986 #define TYPED_ARRAY_GETTER(getter, accessor) \
892 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayGet##getter) { \ 987 RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayGet##getter) { \
893 HandleScope scope(isolate); \ 988 HandleScope scope(isolate); \
894 ASSERT(args.length() == 1); \ 989 ASSERT(args.length() == 1); \
895 CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0); \ 990 CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0); \
896 if (!holder->IsJSTypedArray()) \ 991 if (!holder->IsJSTypedArray()) \
897 return isolate->Throw(*isolate->factory()->NewTypeError( \ 992 return isolate->Throw(*isolate->factory()->NewTypeError( \
898 "not_typed_array", HandleVector<Object>(NULL, 0))); \ 993 "not_typed_array", HandleVector<Object>(NULL, 0))); \
899 Handle<JSTypedArray> typed_array(JSTypedArray::cast(*holder)); \ 994 Handle<JSTypedArray> typed_array(JSTypedArray::cast(*holder)); \
900 return typed_array->accessor(); \ 995 return typed_array->accessor(); \
(...skipping 12957 matching lines...) Expand 10 before | Expand all | Expand 10 after
13858 // Handle last resort GC and make sure to allow future allocations 13953 // Handle last resort GC and make sure to allow future allocations
13859 // to grow the heap without causing GCs (if possible). 13954 // to grow the heap without causing GCs (if possible).
13860 isolate->counters()->gc_last_resort_from_js()->Increment(); 13955 isolate->counters()->gc_last_resort_from_js()->Increment();
13861 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13956 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13862 "Runtime::PerformGC"); 13957 "Runtime::PerformGC");
13863 } 13958 }
13864 } 13959 }
13865 13960
13866 13961
13867 } } // namespace v8::internal 13962 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/typedarray.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698