@@ -21,8 +21,6 @@ namespace internal {
2121#if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC64 || \
2222 V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_S390 || V8_TARGET_ARCH_S390X
2323
24- // Note: 32-bit platforms may need ldflags += [ "-latomic" ] in BUILD.gn.
25-
2624namespace {
2725
2826#if V8_CC_GNU
@@ -31,9 +29,20 @@ namespace {
3129// can be slow. Good to know, but we don't have a choice.
3230#ifdef V8_TARGET_ARCH_32_BIT
3331#pragma GCC diagnostic push
32+ #pragma GCC diagnostic ignored "-Wpragmas"
3433#pragma GCC diagnostic ignored "-Watomic-alignment"
3534#endif // V8_TARGET_ARCH_32_BIT
3635
36+ template <typename T>
37+ inline T LoadSeqCst (T* p) {
38+ return __atomic_load_n (p, __ATOMIC_SEQ_CST);
39+ }
40+
41+ template <typename T>
42+ inline void StoreSeqCst (T* p, T value) {
43+ __atomic_store_n (p, value, __ATOMIC_SEQ_CST);
44+ }
45+
3746template <typename T>
3847inline T ExchangeSeqCst (T* p, T value) {
3948 return __atomic_exchange_n (p, value, __ATOMIC_SEQ_CST);
@@ -128,6 +137,16 @@ ATOMIC_OPS(uint32_t, 32, long) /* NOLINT(runtime/int) */
128137ATOMIC_OPS(int64_t , 64 , __int64)
129138ATOMIC_OPS(uint64_t , 64 , __int64)
130139
140+ template <typename T>
141+ inline T LoadSeqCst(T* p) {
142+ UNREACHABLE ();
143+ }
144+
145+ template <typename T>
146+ inline void StoreSeqCst (T* p, T value) {
147+ UNREACHABLE ();
148+ }
149+
131150#undef ATOMIC_OPS
132151
133152#undef InterlockedExchange32
@@ -216,6 +235,23 @@ inline Object* ToObject(Isolate* isolate, uint64_t t) {
216235 return *BigInt::FromUint64 (isolate, t);
217236}
218237
238+ template <typename T>
239+ struct Load {
240+ static inline Object* Do (Isolate* isolate, void * buffer, size_t index) {
241+ T result = LoadSeqCst (static_cast <T*>(buffer) + index);
242+ return ToObject (isolate, result);
243+ }
244+ };
245+
246+ template <typename T>
247+ struct Store {
248+ static inline void Do (Isolate* isolate, void * buffer, size_t index,
249+ Handle<Object> obj) {
250+ T value = FromObject<T>(obj);
251+ StoreSeqCst (static_cast <T*>(buffer) + index, value);
252+ }
253+ };
254+
219255template <typename T>
220256struct Exchange {
221257 static inline Object* Do (Isolate* isolate, void * buffer, size_t index,
@@ -347,6 +383,55 @@ Object* GetModifySetValueInBuffer(Arguments args, Isolate* isolate) {
347383 UNREACHABLE ();
348384}
349385
386+ RUNTIME_FUNCTION (Runtime_AtomicsLoad64) {
387+ HandleScope scope (isolate);
388+ DCHECK_EQ (2 , args.length ());
389+ CONVERT_ARG_HANDLE_CHECKED (JSTypedArray, sta, 0 );
390+ CONVERT_SIZE_ARG_CHECKED (index, 1 );
391+ CHECK (sta->GetBuffer ()->is_shared ());
392+
393+ uint8_t * source = static_cast <uint8_t *>(sta->GetBuffer ()->backing_store ()) +
394+ sta->byte_offset ();
395+
396+ DCHECK (sta->type () == kExternalBigInt64Array ||
397+ sta->type () == kExternalBigUint64Array );
398+ // SharedArrayBuffers are not neuterable.
399+ CHECK_LT (index, NumberToSize (sta->length ()));
400+ if (sta->type () == kExternalBigInt64Array ) {
401+ return Load<int64_t >::Do (isolate, source, index);
402+ }
403+ DCHECK (sta->type () == kExternalBigUint64Array );
404+ return Load<uint64_t >::Do (isolate, source, index);
405+ }
406+
407+ RUNTIME_FUNCTION (Runtime_AtomicsStore64) {
408+ HandleScope scope (isolate);
409+ DCHECK_EQ (3 , args.length ());
410+ CONVERT_ARG_HANDLE_CHECKED (JSTypedArray, sta, 0 );
411+ CONVERT_SIZE_ARG_CHECKED (index, 1 );
412+ CONVERT_ARG_HANDLE_CHECKED (Object, value_obj, 2 );
413+ CHECK (sta->GetBuffer ()->is_shared ());
414+
415+ uint8_t * source = static_cast <uint8_t *>(sta->GetBuffer ()->backing_store ()) +
416+ sta->byte_offset ();
417+
418+ Handle<BigInt> bigint;
419+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION (isolate, bigint,
420+ BigInt::FromObject (isolate, value_obj));
421+
422+ DCHECK (sta->type () == kExternalBigInt64Array ||
423+ sta->type () == kExternalBigUint64Array );
424+ // SharedArrayBuffers are not neuterable.
425+ CHECK_LT (index, NumberToSize (sta->length ()));
426+ if (sta->type () == kExternalBigInt64Array ) {
427+ Store<int64_t >::Do (isolate, source, index, bigint);
428+ return *bigint;
429+ }
430+ DCHECK (sta->type () == kExternalBigUint64Array );
431+ Store<uint64_t >::Do (isolate, source, index, bigint);
432+ return *bigint;
433+ }
434+
350435RUNTIME_FUNCTION (Runtime_AtomicsExchange) {
351436 return GetModifySetValueInBuffer<Exchange>(args, isolate);
352437}
@@ -441,6 +526,10 @@ RUNTIME_FUNCTION(Runtime_AtomicsXor) {
441526
442527#else
443528
529+ RUNTIME_FUNCTION (Runtime_AtomicsLoad64) { UNREACHABLE (); }
530+
531+ RUNTIME_FUNCTION (Runtime_AtomicsStore64) { UNREACHABLE (); }
532+
444533RUNTIME_FUNCTION (Runtime_AtomicsExchange) { UNREACHABLE (); }
445534
446535RUNTIME_FUNCTION (Runtime_AtomicsCompareExchange) { UNREACHABLE (); }
0 commit comments