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

Unified Diff: src/runtime.cc

Issue 149053009: V8 JavaScript shared memory prototype. Base URL: https://chromium.googlesource.com/external/v8.git@master
Patch Set: Tweaks Created 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/runtime.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index f2e2650ce7d9e7c7c5a6d1c266a8ffead5f8e24a..3c9d0072ad0a70402553fee675ee6714e6020953 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -25,6 +25,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#include <pthread.h>
#include <stdlib.h>
#include <limits>
@@ -783,7 +784,8 @@ void Runtime::SetupArrayBuffer(Isolate* isolate,
Handle<JSArrayBuffer> array_buffer,
bool is_external,
void* data,
- size_t allocated_length) {
+ size_t allocated_length,
+ bool shared) {
ASSERT(array_buffer->GetInternalFieldCount() ==
v8::ArrayBuffer::kInternalFieldCount);
for (int i = 0; i < v8::ArrayBuffer::kInternalFieldCount; i++) {
@@ -792,6 +794,7 @@ void Runtime::SetupArrayBuffer(Isolate* isolate,
array_buffer->set_backing_store(data);
array_buffer->set_flag(Smi::FromInt(0));
array_buffer->set_is_external(is_external);
+ array_buffer->set_is_shared(shared);
Handle<Object> byte_length =
isolate->factory()->NewNumberFromSize(allocated_length);
@@ -808,7 +811,8 @@ bool Runtime::SetupArrayBufferAllocatingData(
Isolate* isolate,
Handle<JSArrayBuffer> array_buffer,
size_t allocated_length,
- bool initialize) {
+ bool initialize,
+ bool shared) {
void* data;
CHECK(V8::ArrayBufferAllocator() != NULL);
if (allocated_length != 0) {
@@ -823,7 +827,8 @@ bool Runtime::SetupArrayBufferAllocatingData(
data = NULL;
}
- SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length);
+ SetupArrayBuffer(isolate, array_buffer, false, data, allocated_length,
+ shared);
isolate->heap()->AdjustAmountOfExternalAllocatedMemory(allocated_length);
@@ -851,9 +856,13 @@ void Runtime::NeuterArrayBuffer(Handle<JSArrayBuffer> array_buffer) {
RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ ASSERT(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, byteLength, 1);
+ CONVERT_BOOLEAN_ARG_CHECKED(shared, 2);
+
+ // PrintF("Shared? %d\n", shared);
+
size_t allocated_length;
if (byteLength->IsSmi()) {
allocated_length = Smi::cast(*byteLength)->value();
@@ -873,7 +882,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferInitialize) {
}
if (!Runtime::SetupArrayBufferAllocatingData(isolate,
- holder, allocated_length)) {
+ holder, allocated_length, true,
+ shared)) {
return isolate->Throw(*isolate->factory()->
NewRangeError("invalid_array_buffer_length",
HandleVector<Object>(NULL, 0)));
@@ -891,6 +901,14 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferGetByteLength) {
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferGetShared) {
+ SealHandleScope shs(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_CHECKED(JSArrayBuffer, holder, 0);
+ return isolate->heap()->ToBoolean(holder->is_shared());
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferSliceImpl) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
@@ -921,6 +939,382 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferIsView) {
: isolate->heap()->false_value();
}
+#if !defined(_POSIX_BARRIERS) || _POSIX_BARRIERS <= 0
+
+typedef int pthread_barrierattr_t;
+
+
+typedef struct {
+ pthread_mutex_t m;
+ pthread_cond_t c;
+ unsigned int maxCount;
+ unsigned int currentCount;
+} pthread_barrier_t;
+
+
+int pthread_barrier_init(pthread_barrier_t *barrier,
+ const pthread_barrierattr_t *attr,
+ unsigned int count) {
+ if (count == 0) {
+ return 22; // EINVAL
+ }
+
+ int err = pthread_mutex_init(&barrier->m, NULL);
+ if (err) {
+ return err;
+ }
+
+ err = pthread_cond_init(&barrier->c, NULL);
+ if (err) {
+ pthread_mutex_destroy(&barrier->m);
+ return err;
+ }
+
+ barrier->maxCount = count;
+ barrier->currentCount = 0;
+
+ return 0;
+}
+
+int pthread_barrier_destroy(pthread_barrier_t *barrier) {
+ int cerr = pthread_cond_destroy(&barrier->c);
+ int merr = pthread_mutex_destroy(&barrier->m);
+ return merr || cerr;
+}
+
+#define PTHREAD_BARRIER_SERIAL_THREAD 1
+
+int pthread_barrier_wait(pthread_barrier_t *barrier) {
+ pthread_mutex_lock(&barrier->m);
+ barrier->currentCount += 1;
+ if (barrier->currentCount >= barrier->maxCount) {
+ barrier->currentCount = 0;
+ pthread_cond_broadcast(&barrier->c);
+ pthread_mutex_unlock(&barrier->m);
+ return PTHREAD_BARRIER_SERIAL_THREAD;
+ } else {
+ pthread_cond_wait(&barrier->c, &barrier->m);
+ pthread_mutex_unlock(&barrier->m);
+ return 0;
+ }
+}
+
+#endif
+
+#define MUTEX_SIZE (sizeof(pthread_mutex_t))
+#define COND_SIZE (sizeof(pthread_cond_t))
+#define BARRIER_SIZE (sizeof(pthread_barrier_t))
+
+pthread_mutex_t* MutexAddr(Isolate *isolate,
+ const Handle<JSArrayBuffer>& buffer,
+ const Handle<Object>& offset) {
+ size_t byte_offset;
+ if (!TryNumberToSize(isolate, *offset, &byte_offset)) {
+ return 0;
+ }
+ size_t byte_length = NumberToSize(isolate, buffer->byte_length());
+ if (byte_offset >= byte_length || byte_offset + MUTEX_SIZE > byte_length) {
+ // overflow
+ return 0;
+ }
+ // TODO(ncbray): alignment
+ pthread_mutex_t* m = reinterpret_cast<pthread_mutex_t*>(
+ reinterpret_cast<char*>(buffer->backing_store()) + byte_offset);
+ return m;
+}
+
+
+pthread_cond_t* CondAddr(Isolate *isolate,
+ const Handle<JSArrayBuffer>& buffer,
+ const Handle<Object>& offset) {
+ size_t byte_offset;
+ if (!TryNumberToSize(isolate, *offset, &byte_offset)) {
+ return 0;
+ }
+ size_t byte_length = NumberToSize(isolate, buffer->byte_length());
+ if (byte_offset >= byte_length || byte_offset + COND_SIZE > byte_length) {
+ // overflow
+ return 0;
+ }
+ // TODO(ncbray): alignment
+ pthread_cond_t* c = reinterpret_cast<pthread_cond_t*>(
+ reinterpret_cast<char*>(buffer->backing_store()) + byte_offset);
+ return c;
+}
+
+
+pthread_barrier_t* BarrierAddr(Isolate *isolate,
+ const Handle<JSArrayBuffer>& buffer,
+ const Handle<Object>& offset) {
+ size_t byte_offset;
+ if (!TryNumberToSize(isolate, *offset, &byte_offset)) {
+ return 0;
+ }
+ size_t byte_length = NumberToSize(isolate, buffer->byte_length());
+ if (byte_offset >= byte_length || byte_offset + BARRIER_SIZE > byte_length) {
+ // overflow
+ return 0;
+ }
+ // TODO(ncbray): alignment
+ pthread_barrier_t* b = reinterpret_cast<pthread_barrier_t*>(
+ reinterpret_cast<char*>(buffer->backing_store()) + byte_offset);
+ return b;
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferMutexInit) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);
+
+ pthread_mutex_t* m = MutexAddr(isolate, holder, offset);
+ if (!m) {
+ return Smi::FromInt(1);
+ }
+
+ //printf("Mutex init %p\n", m);
+ int err = pthread_mutex_init(m, NULL);
+ //printf("Mutex init done.\n");
+
+ return Smi::FromInt(err);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferMutexDestroy) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);
+
+ pthread_mutex_t* m = MutexAddr(isolate, holder, offset);
+ if (!m) {
+ return Smi::FromInt(1);
+ }
+
+ //printf("Mutex destroy %p\n", m);
+ int err = pthread_mutex_destroy(m);
+ //printf("Mutex destroy done.\n");
+
+ return Smi::FromInt(err);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferMutexLock) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);
+
+ pthread_mutex_t* m = MutexAddr(isolate, holder, offset);
+ if (!m) {
+ return Smi::FromInt(1);
+ }
+
+ //printf("Mutex lock %p\n", m);
+ int err = pthread_mutex_lock(m);
+ //printf("Mutex lock done.\n");
+
+ return Smi::FromInt(err);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferMutexUnlock) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);
+
+ pthread_mutex_t* m = MutexAddr(isolate, holder, offset);
+ if (!m) {
+ return Smi::FromInt(1);
+ }
+
+ //printf("Mutex unlock %p\n", m);
+ int err = pthread_mutex_unlock(m);
+ //printf("Mutex unlock done.\n");
+
+ return Smi::FromInt(err);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferMutexSize) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ return Smi::FromInt(MUTEX_SIZE);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferCondInit) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);
+
+ pthread_cond_t* c = CondAddr(isolate, holder, offset);
+ if (!c) {
+ return Smi::FromInt(1);
+ }
+
+ //printf("Cond init %p\n", c);
+ int err = pthread_cond_init(c, NULL);
+ //printf("Cond init done.\n");
+ return Smi::FromInt(err);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferCondDestroy) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);
+
+ pthread_cond_t* c = CondAddr(isolate, holder, offset);
+ if (!c) {
+ return Smi::FromInt(1);
+ }
+
+ //printf("Cond destroy %p\n", c);
+ int err = pthread_cond_destroy(c);
+ //printf("Cond destroy done.\n");
+ return Smi::FromInt(err);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferCondWait) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, coffset, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, moffset, 2);
+
+ pthread_cond_t* c = CondAddr(isolate, holder, coffset);
+ if (!c) {
+ return Smi::FromInt(1);
+ }
+ pthread_mutex_t* m = MutexAddr(isolate, holder, moffset);
+ if (!m) {
+ return Smi::FromInt(1);
+ }
+
+ //printf("Cond wait %p %p\n", c, m);
+ int err = pthread_cond_wait(c, m);
+ //printf("Cond wait done.\n");
+
+ return Smi::FromInt(err);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferCondSignal) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);
+
+ pthread_cond_t* c = CondAddr(isolate, holder, offset);
+ if (!c) {
+ return Smi::FromInt(1);
+ }
+
+ //printf("Cond signal %p\n", c);
+ int err = pthread_cond_signal(c);
+ //printf("Cond signal done.\n");
+ return Smi::FromInt(err);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferCondBroadcast) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);
+
+ pthread_cond_t* c = CondAddr(isolate, holder, offset);
+ if (!c) {
+ return Smi::FromInt(1);
+ }
+
+ //printf("Cond broadcast %p\n", c);
+ int err = pthread_cond_broadcast(c);
+ //printf("Cond broadcast done.\n");
+ return Smi::FromInt(err);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferCondSize) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ return Smi::FromInt(COND_SIZE);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferBarrierInit) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 3);
+ CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, count, 2);
+
+ pthread_barrier_t* b = BarrierAddr(isolate, holder, offset);
+ if (!b) {
+ return Smi::FromInt(1);
+ }
+
+ size_t c;
+ if (!TryNumberToSize(isolate, *count, &c)) {
+ return 0;
+ }
+
+ //printf("Barrier init %p\n", b);
+ int err = pthread_barrier_init(b, NULL, c);
+ //printf("Barrier init done.\n");
+ return Smi::FromInt(err);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferBarrierDestroy) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);
+
+ pthread_barrier_t* b = BarrierAddr(isolate, holder, offset);
+ if (!b) {
+ return Smi::FromInt(1);
+ }
+
+ //printf("Barrier destroy %p\n", b);
+ int err = pthread_barrier_destroy(b);
+ //printf("Barrier destroy done.\n");
+ return Smi::FromInt(err);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferBarrierWait) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, holder, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, offset, 1);
+
+ pthread_barrier_t* b = BarrierAddr(isolate, holder, offset);
+ if (!b) {
+ return Smi::FromInt(1);
+ }
+
+ //printf("Barrier wait %p\n", b);
+ int err = pthread_barrier_wait(b);
+ //printf("Barrier wait done.\n");
+
+ return Smi::FromInt(err);
+}
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferBarrierSize) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ return Smi::FromInt(BARRIER_SIZE);
+}
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayBufferNeuter) {
HandleScope scope(isolate);
« no previous file with comments | « src/runtime.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698