• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/runtime/runtime-utils.h"
6 
7 #include "src/arguments.h"
8 #include "src/base/platform/time.h"
9 #include "src/conversions-inl.h"
10 #include "src/futex-emulation.h"
11 #include "src/globals.h"
12 
13 // Implement Futex API for SharedArrayBuffers as defined in the
14 // SharedArrayBuffer draft spec, found here:
15 // https://github.com/tc39/ecmascript_sharedmem
16 
17 namespace v8 {
18 namespace internal {
19 
RUNTIME_FUNCTION(Runtime_AtomicsWait)20 RUNTIME_FUNCTION(Runtime_AtomicsWait) {
21   HandleScope scope(isolate);
22   DCHECK_EQ(4, args.length());
23   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
24   CONVERT_SIZE_ARG_CHECKED(index, 1);
25   CONVERT_INT32_ARG_CHECKED(value, 2);
26   CONVERT_DOUBLE_ARG_CHECKED(timeout, 3);
27   CHECK(sta->GetBuffer()->is_shared());
28   CHECK_LT(index, NumberToSize(sta->length()));
29   CHECK_EQ(sta->type(), kExternalInt32Array);
30   CHECK(timeout == V8_INFINITY || !std::isnan(timeout));
31 
32   if (!isolate->allow_atomics_wait()) {
33     THROW_NEW_ERROR_RETURN_FAILURE(
34         isolate, NewTypeError(MessageTemplate::kAtomicsWaitNotAllowed));
35   }
36 
37   Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
38   size_t addr = (index << 2) + NumberToSize(sta->byte_offset());
39 
40   return FutexEmulation::Wait(isolate, array_buffer, addr, value, timeout);
41 }
42 
RUNTIME_FUNCTION(Runtime_AtomicsWake)43 RUNTIME_FUNCTION(Runtime_AtomicsWake) {
44   HandleScope scope(isolate);
45   DCHECK_EQ(3, args.length());
46   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
47   CONVERT_SIZE_ARG_CHECKED(index, 1);
48   CONVERT_UINT32_ARG_CHECKED(count, 2);
49   CHECK(sta->GetBuffer()->is_shared());
50   CHECK_LT(index, NumberToSize(sta->length()));
51   CHECK_EQ(sta->type(), kExternalInt32Array);
52 
53   Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
54   size_t addr = (index << 2) + NumberToSize(sta->byte_offset());
55 
56   return FutexEmulation::Wake(isolate, array_buffer, addr, count);
57 }
58 
RUNTIME_FUNCTION(Runtime_AtomicsNumWaitersForTesting)59 RUNTIME_FUNCTION(Runtime_AtomicsNumWaitersForTesting) {
60   HandleScope scope(isolate);
61   DCHECK_EQ(2, args.length());
62   CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
63   CONVERT_SIZE_ARG_CHECKED(index, 1);
64   CHECK(sta->GetBuffer()->is_shared());
65   CHECK_LT(index, NumberToSize(sta->length()));
66   CHECK_EQ(sta->type(), kExternalInt32Array);
67 
68   Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
69   size_t addr = (index << 2) + NumberToSize(sta->byte_offset());
70 
71   return FutexEmulation::NumWaitersForTesting(isolate, array_buffer, addr);
72 }
73 
RUNTIME_FUNCTION(Runtime_SetAllowAtomicsWait)74 RUNTIME_FUNCTION(Runtime_SetAllowAtomicsWait) {
75   HandleScope scope(isolate);
76   DCHECK_EQ(1, args.length());
77   CONVERT_BOOLEAN_ARG_CHECKED(set, 0);
78 
79   isolate->set_allow_atomics_wait(set);
80   return isolate->heap()->undefined_value();
81 }
82 }  // namespace internal
83 }  // namespace v8
84