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 |
11 // with the distribution. | 11 // with the distribution. |
12 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
13 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
14 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
15 // | 15 // |
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
| 28 #include <pthread.h> |
28 #include <stdlib.h> | 29 #include <stdlib.h> |
29 #include <limits> | 30 #include <limits> |
30 | 31 |
31 #include "v8.h" | 32 #include "v8.h" |
32 | 33 |
33 #include "accessors.h" | 34 #include "accessors.h" |
34 #include "allocation-site-scopes.h" | 35 #include "allocation-site-scopes.h" |
35 #include "api.h" | 36 #include "api.h" |
36 #include "arguments.h" | 37 #include "arguments.h" |
37 #include "bootstrapper.h" | 38 #include "bootstrapper.h" |
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
776 V8::ArrayBufferAllocator()->Free( | 777 V8::ArrayBufferAllocator()->Free( |
777 phantom_array_buffer->backing_store(), | 778 phantom_array_buffer->backing_store(), |
778 allocated_length); | 779 allocated_length); |
779 } | 780 } |
780 | 781 |
781 | 782 |
782 void Runtime::SetupArrayBuffer(Isolate* isolate, | 783 void Runtime::SetupArrayBuffer(Isolate* isolate, |
783 Handle<JSArrayBuffer> array_buffer, | 784 Handle<JSArrayBuffer> array_buffer, |
784 bool is_external, | 785 bool is_external, |
785 void* data, | 786 void* data, |
786 size_t allocated_length) { | 787 size_t allocated_length, |
| 788 bool shared) { |
787 ASSERT(array_buffer->GetInternalFieldCount() == | 789 ASSERT(array_buffer->GetInternalFieldCount() == |
788 v8::ArrayBuffer::kInternalFieldCount); | 790 v8::ArrayBuffer::kInternalFieldCount); |
789 for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) { | 791 for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) { |
790 array_buffer->SetInternalField(i, Smi::FromInt(0)); | 792 array_buffer->SetInternalField(i, Smi::FromInt(0)); |
791 } | 793 } |
792 array_buffer->set_backing_store(data); | 794 array_buffer->set_backing_store(data); |
793 array_buffer->set_flag(Smi::FromInt(0)); | 795 array_buffer->set_flag(Smi::FromInt(0)); |
794 array_buffer->set_is_external(is_external); | 796 array_buffer->set_is_external(is_external); |
| 797 array_buffer->set_is_shared(shared); |
795 | 798 |
796 Handle<Object> byte_length = | 799 Handle<Object> byte_length = |
797 isolate->factory()->NewNumberFromSize(allocated_length); | 800 isolate->factory()->NewNumberFromSize(allocated_length); |
798 CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber()); | 801 CHECK(byte_length->IsSmi() || byte_length->IsHeapNumber()); |
799 array_buffer->set_byte_length(*byte_length); | 802 array_buffer->set_byte_length(*byte_length); |
800 | 803 |
801 array_buffer->set_weak_next(isolate->heap()->array_buffers_list()); | 804 array_buffer->set_weak_next(isolate->heap()->array_buffers_list()); |
802 isolate->heap()->set_array_buffers_list(*array_buffer); | 805 isolate->heap()->set_array_buffers_list(*array_buffer); |
803 array_buffer->set_weak_first_view(isolate->heap()->undefined_value()); | 806 array_buffer->set_weak_first_view(isolate->heap()->undefined_value()); |
804 } | 807 } |
805 | 808 |
806 | 809 |
807 bool Runtime::SetupArrayBufferAllocatingData( | 810 bool Runtime::SetupArrayBufferAllocatingData( |
808 Isolate* isolate, | 811 Isolate* isolate, |
809 Handle<JSArrayBuffer> array_buffer, | 812 Handle<JSArrayBuffer> array_buffer, |
810 size_t allocated_length, | 813 size_t allocated_length, |
811 bool initialize) { | 814 bool initialize, |
| 815 bool shared) { |
812 void* data; | 816 void* data; |
813 CHECK(V8::ArrayBufferAllocator() != NULL); | 817 CHECK(V8::ArrayBufferAllocator() != NULL); |
814 if (allocated_length != 0) { | 818 if (allocated_length != 0) { |
815 if (initialize) { | 819 if (initialize) { |
816 data = V8::ArrayBufferAllocator()->Allocate(allocated_length); | 820 data = V8::ArrayBufferAllocator()->Allocate(allocated_length); |
817 } else { | 821 } else { |
818 data = | 822 data = |
819 V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length); | 823 V8::ArrayBufferAllocator()->AllocateUninitialized(allocated_length); |
820 } | 824 } |
821 if (data == NULL) return false; | 825 if (data == NULL) return false; |
822 } else { | 826 } else { |
823 data = NULL; | 827 data = NULL; |
824 } | 828 } |
825 | 829 |
826 SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length); | 830 SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length, |
| 831 shared); |
827 | 832 |
828 isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length); | 833 isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length); |
829 | 834 |
830 return true; | 835 return true; |
831 } | 836 } |
832 | 837 |
833 | 838 |
834 void Runtime::NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer) { | 839 void Runtime::NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer) { |
835 Isolate* isolate = array_buffer->GetIsolate(); | 840 Isolate* isolate = array_buffer->GetIsolate(); |
836 for (Handle<Object> view_obj(array_buffer->weak_first_view(), isolate); | 841 for (Handle<Object> view_obj(array_buffer->weak_first_view(), isolate); |
837 !view_obj->IsUndefined();) { | 842 !view_obj->IsUndefined();) { |
838 Handle<JSArrayBufferView> view(JSArrayBufferView::cast(*view_obj)); | 843 Handle<JSArrayBufferView> view(JSArrayBufferView::cast(*view_obj)); |
839 if (view->IsJSTypedArray()) { | 844 if (view->IsJSTypedArray()) { |
840 JSTypedArray::cast(*view)->Neuter(); | 845 JSTypedArray::cast(*view)->Neuter(); |
841 } else if (view->IsJSDataView()) { | 846 } else if (view->IsJSDataView()) { |
842 JSDataView::cast(*view)->Neuter(); | 847 JSDataView::cast(*view)->Neuter(); |
843 } else { | 848 } else { |
844 UNREACHABLE(); | 849 UNREACHABLE(); |
845 } | 850 } |
846 view_obj = handle(view->weak_next(), isolate); | 851 view_obj = handle(view->weak_next(), isolate); |
847 } | 852 } |
848 array_buffer->Neuter(); | 853 array_buffer->Neuter(); |
849 } | 854 } |
850 | 855 |
851 | 856 |
852 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) { | 857 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) { |
853 HandleScope scope(isolate); | 858 HandleScope scope(isolate); |
854 ASSERT(args.length() == 2); | 859 ASSERT(args.length() == 3); |
855 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); | 860 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); |
856 CONVERT_ARG_HANDLE_CHECKED(Object, byteLength, 1); | 861 CONVERT_ARG_HANDLE_CHECKED(Object, byteLength, 1); |
| 862 CONVERT_BOOLEAN_ARG_CHECKED(shared, 2); |
| 863 |
| 864 // PrintF("Shared? %d\n", shared); |
| 865 |
857 size_t allocated_length; | 866 size_t allocated_length; |
858 if (byteLength->IsSmi()) { | 867 if (byteLength->IsSmi()) { |
859 allocated_length = Smi::cast(*byteLength)->value(); | 868 allocated_length = Smi::cast(*byteLength)->value(); |
860 } else { | 869 } else { |
861 ASSERT(byteLength->IsHeapNumber()); | 870 ASSERT(byteLength->IsHeapNumber()); |
862 double value = HeapNumber::cast(*byteLength)->value(); | 871 double value = HeapNumber::cast(*byteLength)->value(); |
863 | 872 |
864 ASSERT(value >= 0); | 873 ASSERT(value >= 0); |
865 | 874 |
866 if (value > std::numeric_limits<size_t>::max()) { | 875 if (value > std::numeric_limits<size_t>::max()) { |
867 return isolate->Throw( | 876 return isolate->Throw( |
868 *isolate->factory()->NewRangeError("invalid_array_buffer_length", | 877 *isolate->factory()->NewRangeError("invalid_array_buffer_length", |
869 HandleVector<Object>(NULL, 0))); | 878 HandleVector<Object>(NULL, 0))); |
870 } | 879 } |
871 | 880 |
872 allocated_length = static_cast<size_t>(value); | 881 allocated_length = static_cast<size_t>(value); |
873 } | 882 } |
874 | 883 |
875 if (!Runtime::SetupArrayBufferAllocatingData(isolate, | 884 if (!Runtime::SetupArrayBufferAllocatingData(isolate, |
876 holder, allocated_length)) { | 885 holder, allocated_length, true, |
| 886 shared)) { |
877 return isolate->Throw(*isolate->factory()-> | 887 return isolate->Throw(*isolate->factory()-> |
878 NewRangeError("invalid_array_buffer_length", | 888 NewRangeError("invalid_array_buffer_length", |
879 HandleVector<Object>(NULL, 0))); | 889 HandleVector<Object>(NULL, 0))); |
880 } | 890 } |
881 | 891 |
882 return *holder; | 892 return *holder; |
883 } | 893 } |
884 | 894 |
885 | 895 |
886 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferGetByteLength) { | 896 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferGetByteLength) { |
887 SealHandleScope shs(isolate); | 897 SealHandleScope shs(isolate); |
888 ASSERT(args.length() == 1); | 898 ASSERT(args.length() == 1); |
889 CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0); | 899 CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0); |
890 return holder->byte_length(); | 900 return holder->byte_length(); |
891 } | 901 } |
892 | 902 |
893 | 903 |
| 904 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferGetShared) { |
| 905 SealHandleScope shs(isolate); |
| 906 ASSERT(args.length() == 1); |
| 907 CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0); |
| 908 return isolate->heap()->ToBoolean(holder->is_shared()); |
| 909 } |
| 910 |
| 911 |
894 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferSliceImpl) { | 912 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferSliceImpl) { |
895 HandleScope scope(isolate); | 913 HandleScope scope(isolate); |
896 ASSERT(args.length() == 3); | 914 ASSERT(args.length() == 3); |
897 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0); | 915 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, source, 0); |
898 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1); | 916 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, target, 1); |
899 CONVERT_DOUBLE_ARG_CHECKED(first, 2); | 917 CONVERT_DOUBLE_ARG_CHECKED(first, 2); |
900 size_t start = static_cast<size_t>(first); | 918 size_t start = static_cast<size_t>(first); |
901 size_t target_length = NumberToSize(isolate, target->byte_length()); | 919 size_t target_length = NumberToSize(isolate, target->byte_length()); |
902 | 920 |
903 if (target_length == 0) return isolate->heap()->undefined_value(); | 921 if (target_length == 0) return isolate->heap()->undefined_value(); |
(...skipping 10 matching lines...) Expand all Loading... |
914 | 932 |
915 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferIsView) { | 933 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferIsView) { |
916 HandleScope scope(isolate); | 934 HandleScope scope(isolate); |
917 ASSERT(args.length() == 1); | 935 ASSERT(args.length() == 1); |
918 CONVERT_ARG_CHECKED(Object, object, 0); | 936 CONVERT_ARG_CHECKED(Object, object, 0); |
919 return object->IsJSArrayBufferView() | 937 return object->IsJSArrayBufferView() |
920 ? isolate->heap()->true_value() | 938 ? isolate->heap()->true_value() |
921 : isolate->heap()->false_value(); | 939 : isolate->heap()->false_value(); |
922 } | 940 } |
923 | 941 |
| 942 #if !defined(_POSIX_BARRIERS) || _POSIX_BARRIERS <= 0 |
| 943 |
| 944 typedef int pthread_barrierattr_t; |
| 945 |
| 946 |
| 947 typedef struct { |
| 948 pthread_mutex_t m; |
| 949 pthread_cond_t c; |
| 950 unsigned int maxCount; |
| 951 unsigned int currentCount; |
| 952 } pthread_barrier_t; |
| 953 |
| 954 |
| 955 int pthread_barrier_init(pthread_barrier_t *barrier, |
| 956 const pthread_barrierattr_t *attr, |
| 957 unsigned int count) { |
| 958 if (count == 0) { |
| 959 return 22; // EINVAL |
| 960 } |
| 961 |
| 962 int err = pthread_mutex_init(&barrier->m, NULL); |
| 963 if (err) { |
| 964 return err; |
| 965 } |
| 966 |
| 967 err = pthread_cond_init(&barrier->c, NULL); |
| 968 if (err) { |
| 969 pthread_mutex_destroy(&barrier->m); |
| 970 return err; |
| 971 } |
| 972 |
| 973 barrier->maxCount = count; |
| 974 barrier->currentCount = 0; |
| 975 |
| 976 return 0; |
| 977 } |
| 978 |
| 979 int pthread_barrier_destroy(pthread_barrier_t *barrier) { |
| 980 int cerr = pthread_cond_destroy(&barrier->c); |
| 981 int merr = pthread_mutex_destroy(&barrier->m); |
| 982 return merr || cerr; |
| 983 } |
| 984 |
| 985 #define PTHREAD_BARRIER_SERIAL_THREAD 1 |
| 986 |
| 987 int pthread_barrier_wait(pthread_barrier_t *barrier) { |
| 988 pthread_mutex_lock(&barrier->m); |
| 989 barrier->currentCount += 1; |
| 990 if (barrier->currentCount >= barrier->maxCount) { |
| 991 barrier->currentCount = 0; |
| 992 pthread_cond_broadcast(&barrier->c); |
| 993 pthread_mutex_unlock(&barrier->m); |
| 994 return PTHREAD_BARRIER_SERIAL_THREAD; |
| 995 } else { |
| 996 pthread_cond_wait(&barrier->c, &barrier->m); |
| 997 pthread_mutex_unlock(&barrier->m); |
| 998 return 0; |
| 999 } |
| 1000 } |
| 1001 |
| 1002 #endif |
| 1003 |
| 1004 #define MUTEX_SIZE (sizeof(pthread_mutex_t)) |
| 1005 #define COND_SIZE (sizeof(pthread_cond_t)) |
| 1006 #define BARRIER_SIZE (sizeof(pthread_barrier_t)) |
| 1007 |
| 1008 pthread_mutex_t* MutexAddr(Isolate *isolate, |
| 1009 const Handle<JSArrayBuffer>& buffer, |
| 1010 const Handle<Object>& offset) { |
| 1011 size_t byte_offset; |
| 1012 if (!TryNumberToSize(isolate, *offset, &byte_offset)) { |
| 1013 return 0; |
| 1014 } |
| 1015 size_t byte_length = NumberToSize(isolate, buffer->byte_length()); |
| 1016 if (byte_offset >= byte_length || byte_offset + MUTEX_SIZE > byte_length) { |
| 1017 // overflow |
| 1018 return 0; |
| 1019 } |
| 1020 // TODO(ncbray): alignment |
| 1021 pthread_mutex_t* m = reinterpret_cast<pthread_mutex_t*>( |
| 1022 reinterpret_cast<char*>(buffer->backing_store()) + byte_offset); |
| 1023 return m; |
| 1024 } |
| 1025 |
| 1026 |
| 1027 pthread_cond_t* CondAddr(Isolate *isolate, |
| 1028 const Handle<JSArrayBuffer>& buffer, |
| 1029 const Handle<Object>& offset) { |
| 1030 size_t byte_offset; |
| 1031 if (!TryNumberToSize(isolate, *offset, &byte_offset)) { |
| 1032 return 0; |
| 1033 } |
| 1034 size_t byte_length = NumberToSize(isolate, buffer->byte_length()); |
| 1035 if (byte_offset >= byte_length || byte_offset + COND_SIZE > byte_length) { |
| 1036 // overflow |
| 1037 return 0; |
| 1038 } |
| 1039 // TODO(ncbray): alignment |
| 1040 pthread_cond_t* c = reinterpret_cast<pthread_cond_t*>( |
| 1041 reinterpret_cast<char*>(buffer->backing_store()) + byte_offset); |
| 1042 return c; |
| 1043 } |
| 1044 |
| 1045 |
| 1046 pthread_barrier_t* BarrierAddr(Isolate *isolate, |
| 1047 const Handle<JSArrayBuffer>& buffer, |
| 1048 const Handle<Object>& offset) { |
| 1049 size_t byte_offset; |
| 1050 if (!TryNumberToSize(isolate, *offset, &byte_offset)) { |
| 1051 return 0; |
| 1052 } |
| 1053 size_t byte_length = NumberToSize(isolate, buffer->byte_length()); |
| 1054 if (byte_offset >= byte_length || byte_offset + BARRIER_SIZE > byte_length)
{ |
| 1055 // overflow |
| 1056 return 0; |
| 1057 } |
| 1058 // TODO(ncbray): alignment |
| 1059 pthread_barrier_t* b = reinterpret_cast<pthread_barrier_t*>( |
| 1060 reinterpret_cast<char*>(buffer->backing_store()) + byte_offset); |
| 1061 return b; |
| 1062 } |
| 1063 |
| 1064 |
| 1065 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferMutexInit) { |
| 1066 HandleScope scope(isolate); |
| 1067 ASSERT(args.length() == 2); |
| 1068 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); |
| 1069 CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); |
| 1070 |
| 1071 pthread_mutex_t* m = MutexAddr(isolate, holder, offset); |
| 1072 if (!m) { |
| 1073 return Smi::FromInt(1); |
| 1074 } |
| 1075 |
| 1076 //printf("Mutex init %p\n", m); |
| 1077 int err = pthread_mutex_init(m, NULL); |
| 1078 //printf("Mutex init done.\n"); |
| 1079 |
| 1080 return Smi::FromInt(err); |
| 1081 } |
| 1082 |
| 1083 |
| 1084 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferMutexDestroy) { |
| 1085 HandleScope scope(isolate); |
| 1086 ASSERT(args.length() == 2); |
| 1087 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); |
| 1088 CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); |
| 1089 |
| 1090 pthread_mutex_t* m = MutexAddr(isolate, holder, offset); |
| 1091 if (!m) { |
| 1092 return Smi::FromInt(1); |
| 1093 } |
| 1094 |
| 1095 //printf("Mutex destroy %p\n", m); |
| 1096 int err = pthread_mutex_destroy(m); |
| 1097 //printf("Mutex destroy done.\n"); |
| 1098 |
| 1099 return Smi::FromInt(err); |
| 1100 } |
| 1101 |
| 1102 |
| 1103 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferMutexLock) { |
| 1104 HandleScope scope(isolate); |
| 1105 ASSERT(args.length() == 2); |
| 1106 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); |
| 1107 CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); |
| 1108 |
| 1109 pthread_mutex_t* m = MutexAddr(isolate, holder, offset); |
| 1110 if (!m) { |
| 1111 return Smi::FromInt(1); |
| 1112 } |
| 1113 |
| 1114 //printf("Mutex lock %p\n", m); |
| 1115 int err = pthread_mutex_lock(m); |
| 1116 //printf("Mutex lock done.\n"); |
| 1117 |
| 1118 return Smi::FromInt(err); |
| 1119 } |
| 1120 |
| 1121 |
| 1122 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferMutexUnlock) { |
| 1123 HandleScope scope(isolate); |
| 1124 ASSERT(args.length() == 2); |
| 1125 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); |
| 1126 CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); |
| 1127 |
| 1128 pthread_mutex_t* m = MutexAddr(isolate, holder, offset); |
| 1129 if (!m) { |
| 1130 return Smi::FromInt(1); |
| 1131 } |
| 1132 |
| 1133 //printf("Mutex unlock %p\n", m); |
| 1134 int err = pthread_mutex_unlock(m); |
| 1135 //printf("Mutex unlock done.\n"); |
| 1136 |
| 1137 return Smi::FromInt(err); |
| 1138 } |
| 1139 |
| 1140 |
| 1141 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferMutexSize) { |
| 1142 HandleScope scope(isolate); |
| 1143 ASSERT(args.length() == 1); |
| 1144 return Smi::FromInt(MUTEX_SIZE); |
| 1145 } |
| 1146 |
| 1147 |
| 1148 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferCondInit) { |
| 1149 HandleScope scope(isolate); |
| 1150 ASSERT(args.length() == 2); |
| 1151 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); |
| 1152 CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); |
| 1153 |
| 1154 pthread_cond_t* c = CondAddr(isolate, holder, offset); |
| 1155 if (!c) { |
| 1156 return Smi::FromInt(1); |
| 1157 } |
| 1158 |
| 1159 //printf("Cond init %p\n", c); |
| 1160 int err = pthread_cond_init(c, NULL); |
| 1161 //printf("Cond init done.\n"); |
| 1162 return Smi::FromInt(err); |
| 1163 } |
| 1164 |
| 1165 |
| 1166 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferCondDestroy) { |
| 1167 HandleScope scope(isolate); |
| 1168 ASSERT(args.length() == 2); |
| 1169 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); |
| 1170 CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); |
| 1171 |
| 1172 pthread_cond_t* c = CondAddr(isolate, holder, offset); |
| 1173 if (!c) { |
| 1174 return Smi::FromInt(1); |
| 1175 } |
| 1176 |
| 1177 //printf("Cond destroy %p\n", c); |
| 1178 int err = pthread_cond_destroy(c); |
| 1179 //printf("Cond destroy done.\n"); |
| 1180 return Smi::FromInt(err); |
| 1181 } |
| 1182 |
| 1183 |
| 1184 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferCondWait) { |
| 1185 HandleScope scope(isolate); |
| 1186 ASSERT(args.length() == 3); |
| 1187 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); |
| 1188 CONVERT_ARG_HANDLE_CHECKED(Object, coffset, 1); |
| 1189 CONVERT_ARG_HANDLE_CHECKED(Object, moffset, 2); |
| 1190 |
| 1191 pthread_cond_t* c = CondAddr(isolate, holder, coffset); |
| 1192 if (!c) { |
| 1193 return Smi::FromInt(1); |
| 1194 } |
| 1195 pthread_mutex_t* m = MutexAddr(isolate, holder, moffset); |
| 1196 if (!m) { |
| 1197 return Smi::FromInt(1); |
| 1198 } |
| 1199 |
| 1200 //printf("Cond wait %p %p\n", c, m); |
| 1201 int err = pthread_cond_wait(c, m); |
| 1202 //printf("Cond wait done.\n"); |
| 1203 |
| 1204 return Smi::FromInt(err); |
| 1205 } |
| 1206 |
| 1207 |
| 1208 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferCondSignal) { |
| 1209 HandleScope scope(isolate); |
| 1210 ASSERT(args.length() == 2); |
| 1211 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); |
| 1212 CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); |
| 1213 |
| 1214 pthread_cond_t* c = CondAddr(isolate, holder, offset); |
| 1215 if (!c) { |
| 1216 return Smi::FromInt(1); |
| 1217 } |
| 1218 |
| 1219 //printf("Cond signal %p\n", c); |
| 1220 int err = pthread_cond_signal(c); |
| 1221 //printf("Cond signal done.\n"); |
| 1222 return Smi::FromInt(err); |
| 1223 } |
| 1224 |
| 1225 |
| 1226 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferCondBroadcast) { |
| 1227 HandleScope scope(isolate); |
| 1228 ASSERT(args.length() == 2); |
| 1229 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); |
| 1230 CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); |
| 1231 |
| 1232 pthread_cond_t* c = CondAddr(isolate, holder, offset); |
| 1233 if (!c) { |
| 1234 return Smi::FromInt(1); |
| 1235 } |
| 1236 |
| 1237 //printf("Cond broadcast %p\n", c); |
| 1238 int err = pthread_cond_broadcast(c); |
| 1239 //printf("Cond broadcast done.\n"); |
| 1240 return Smi::FromInt(err); |
| 1241 } |
| 1242 |
| 1243 |
| 1244 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferCondSize) { |
| 1245 HandleScope scope(isolate); |
| 1246 ASSERT(args.length() == 1); |
| 1247 return Smi::FromInt(COND_SIZE); |
| 1248 } |
| 1249 |
| 1250 |
| 1251 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferBarrierInit) { |
| 1252 HandleScope scope(isolate); |
| 1253 ASSERT(args.length() == 3); |
| 1254 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); |
| 1255 CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); |
| 1256 CONVERT_ARG_HANDLE_CHECKED(Object, count, 2); |
| 1257 |
| 1258 pthread_barrier_t* b = BarrierAddr(isolate, holder, offset); |
| 1259 if (!b) { |
| 1260 return Smi::FromInt(1); |
| 1261 } |
| 1262 |
| 1263 size_t c; |
| 1264 if (!TryNumberToSize(isolate, *count, &c)) { |
| 1265 return 0; |
| 1266 } |
| 1267 |
| 1268 //printf("Barrier init %p\n", b); |
| 1269 int err = pthread_barrier_init(b, NULL, c); |
| 1270 //printf("Barrier init done.\n"); |
| 1271 return Smi::FromInt(err); |
| 1272 } |
| 1273 |
| 1274 |
| 1275 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferBarrierDestroy) { |
| 1276 HandleScope scope(isolate); |
| 1277 ASSERT(args.length() == 2); |
| 1278 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); |
| 1279 CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); |
| 1280 |
| 1281 pthread_barrier_t* b = BarrierAddr(isolate, holder, offset); |
| 1282 if (!b) { |
| 1283 return Smi::FromInt(1); |
| 1284 } |
| 1285 |
| 1286 //printf("Barrier destroy %p\n", b); |
| 1287 int err = pthread_barrier_destroy(b); |
| 1288 //printf("Barrier destroy done.\n"); |
| 1289 return Smi::FromInt(err); |
| 1290 } |
| 1291 |
| 1292 |
| 1293 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferBarrierWait) { |
| 1294 HandleScope scope(isolate); |
| 1295 ASSERT(args.length() == 2); |
| 1296 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0); |
| 1297 CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1); |
| 1298 |
| 1299 pthread_barrier_t* b = BarrierAddr(isolate, holder, offset); |
| 1300 if (!b) { |
| 1301 return Smi::FromInt(1); |
| 1302 } |
| 1303 |
| 1304 //printf("Barrier wait %p\n", b); |
| 1305 int err = pthread_barrier_wait(b); |
| 1306 //printf("Barrier wait done.\n"); |
| 1307 |
| 1308 return Smi::FromInt(err); |
| 1309 } |
| 1310 |
| 1311 |
| 1312 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferBarrierSize) { |
| 1313 HandleScope scope(isolate); |
| 1314 ASSERT(args.length() == 1); |
| 1315 return Smi::FromInt(BARRIER_SIZE); |
| 1316 } |
| 1317 |
924 | 1318 |
925 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferNeuter) { | 1319 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferNeuter) { |
926 HandleScope scope(isolate); | 1320 HandleScope scope(isolate); |
927 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0); | 1321 CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, array_buffer, 0); |
928 if (array_buffer->backing_store() == NULL) { | 1322 if (array_buffer->backing_store() == NULL) { |
929 CHECK(Smi::FromInt(0) == array_buffer->byte_length()); | 1323 CHECK(Smi::FromInt(0) == array_buffer->byte_length()); |
930 return isolate->heap()->undefined_value(); | 1324 return isolate->heap()->undefined_value(); |
931 } | 1325 } |
932 ASSERT(!array_buffer->is_external()); | 1326 ASSERT(!array_buffer->is_external()); |
933 void* backing_store = array_buffer->backing_store(); | 1327 void* backing_store = array_buffer->backing_store(); |
(...skipping 14304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15238 } | 15632 } |
15239 } | 15633 } |
15240 | 15634 |
15241 | 15635 |
15242 void Runtime::OutOfMemory() { | 15636 void Runtime::OutOfMemory() { |
15243 Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); | 15637 Heap::FatalProcessOutOfMemory("CALL_AND_RETRY_LAST", true); |
15244 UNREACHABLE(); | 15638 UNREACHABLE(); |
15245 } | 15639 } |
15246 | 15640 |
15247 } } // namespace v8::internal | 15641 } } // namespace v8::internal |
OLD | NEW |