Reland "[atomics] Wire up 64 bit atomic Wait in JS"
Relands 64bit atomic wait with ubsan fix, previously reviewed at:
https://chromium-review.googlesource.com/c/v8/v8/+/1728260
This reverts commit 2a383f4cf1
.
Bug: v8:8100, v8:9576
Change-Id: Ibeec86c8a796bfbef9884cdb836892e902030bf3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1733389
Commit-Queue: Joshua Litt <joshualitt@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63059}
This commit is contained in:
parent
8ab0eed20c
commit
91e53e2695
@ -37,12 +37,16 @@ BUILTIN(AtomicsIsLockFree) {
|
||||
|
||||
// ES #sec-validatesharedintegertypedarray
|
||||
V8_WARN_UNUSED_RESULT MaybeHandle<JSTypedArray> ValidateSharedIntegerTypedArray(
|
||||
Isolate* isolate, Handle<Object> object, bool only_int32 = false) {
|
||||
Isolate* isolate, Handle<Object> object,
|
||||
bool only_int32_and_big_int64 = false) {
|
||||
if (object->IsJSTypedArray()) {
|
||||
Handle<JSTypedArray> typed_array = Handle<JSTypedArray>::cast(object);
|
||||
if (typed_array->GetBuffer()->is_shared()) {
|
||||
if (only_int32) {
|
||||
if (typed_array->type() == kExternalInt32Array) return typed_array;
|
||||
if (only_int32_and_big_int64) {
|
||||
if (typed_array->type() == kExternalInt32Array ||
|
||||
typed_array->type() == kExternalBigInt64Array) {
|
||||
return typed_array;
|
||||
}
|
||||
} else {
|
||||
if (typed_array->type() != kExternalFloat32Array &&
|
||||
typed_array->type() != kExternalFloat64Array &&
|
||||
@ -54,8 +58,9 @@ V8_WARN_UNUSED_RESULT MaybeHandle<JSTypedArray> ValidateSharedIntegerTypedArray(
|
||||
|
||||
THROW_NEW_ERROR(
|
||||
isolate,
|
||||
NewTypeError(only_int32 ? MessageTemplate::kNotInt32SharedTypedArray
|
||||
: MessageTemplate::kNotIntegerSharedTypedArray,
|
||||
NewTypeError(only_int32_and_big_int64
|
||||
? MessageTemplate::kNotInt32OrBigInt64SharedTypedArray
|
||||
: MessageTemplate::kNotIntegerSharedTypedArray,
|
||||
object),
|
||||
JSTypedArray);
|
||||
}
|
||||
@ -83,6 +88,15 @@ V8_WARN_UNUSED_RESULT Maybe<size_t> ValidateAtomicAccess(
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
inline size_t GetAddress64(size_t index, size_t byte_offset) {
|
||||
return (index << 3) + byte_offset;
|
||||
}
|
||||
|
||||
inline size_t GetAddress32(size_t index, size_t byte_offset) {
|
||||
return (index << 2) + byte_offset;
|
||||
}
|
||||
|
||||
MaybeHandle<Object> AtomicsWake(Isolate* isolate, Handle<Object> array,
|
||||
Handle<Object> index, Handle<Object> count) {
|
||||
Handle<JSTypedArray> sta;
|
||||
@ -109,9 +123,19 @@ MaybeHandle<Object> AtomicsWake(Isolate* isolate, Handle<Object> array,
|
||||
}
|
||||
|
||||
Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
|
||||
size_t addr = (i << 2) + sta->byte_offset();
|
||||
|
||||
return Handle<Object>(FutexEmulation::Wake(array_buffer, addr, c), isolate);
|
||||
if (sta->type() == kExternalBigInt64Array) {
|
||||
return Handle<Object>(
|
||||
FutexEmulation::Wake(array_buffer, GetAddress64(i, sta->byte_offset()),
|
||||
c),
|
||||
isolate);
|
||||
} else {
|
||||
DCHECK(sta->type() == kExternalInt32Array);
|
||||
return Handle<Object>(
|
||||
FutexEmulation::Wake(array_buffer, GetAddress32(i, sta->byte_offset()),
|
||||
c),
|
||||
isolate);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@ -157,9 +181,16 @@ BUILTIN(AtomicsWait) {
|
||||
if (maybe_index.IsNothing()) return ReadOnlyRoots(isolate).exception();
|
||||
size_t i = maybe_index.FromJust();
|
||||
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
|
||||
Object::ToInt32(isolate, value));
|
||||
int32_t value_int32 = NumberToInt32(*value);
|
||||
// According to the spec, we have to check value's type before
|
||||
// looking at the timeout.
|
||||
if (sta->type() == kExternalBigInt64Array) {
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
|
||||
BigInt::FromObject(isolate, value));
|
||||
} else {
|
||||
DCHECK(sta->type() == kExternalInt32Array);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value,
|
||||
Object::ToInt32(isolate, value));
|
||||
}
|
||||
|
||||
double timeout_number;
|
||||
if (timeout->IsUndefined(isolate)) {
|
||||
@ -180,10 +211,17 @@ BUILTIN(AtomicsWait) {
|
||||
}
|
||||
|
||||
Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
|
||||
size_t addr = (i << 2) + sta->byte_offset();
|
||||
|
||||
return FutexEmulation::WaitJs(isolate, array_buffer, addr, value_int32,
|
||||
timeout_number);
|
||||
if (sta->type() == kExternalBigInt64Array) {
|
||||
return FutexEmulation::WaitJs64(
|
||||
isolate, array_buffer, GetAddress64(i, sta->byte_offset()),
|
||||
Handle<BigInt>::cast(value)->AsInt64(), timeout_number);
|
||||
} else {
|
||||
DCHECK(sta->type() == kExternalInt32Array);
|
||||
return FutexEmulation::WaitJs32(isolate, array_buffer,
|
||||
GetAddress32(i, sta->byte_offset()),
|
||||
NumberToInt32(*value), timeout_number);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
@ -146,7 +146,8 @@ namespace internal {
|
||||
T(NotSuperConstructorAnonymousClass, \
|
||||
"Super constructor % of anonymous class is not a constructor") \
|
||||
T(NotIntegerSharedTypedArray, "% is not an integer shared typed array.") \
|
||||
T(NotInt32SharedTypedArray, "% is not an int32 shared typed array.") \
|
||||
T(NotInt32OrBigInt64SharedTypedArray, \
|
||||
"% is not an int32 or BigInt64 shared typed array.") \
|
||||
T(ObjectGetterExpectingFunction, \
|
||||
"Object.prototype.__defineGetter__: Expecting function") \
|
||||
T(ObjectGetterCallable, "Getter must be a function: %") \
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "src/execution/isolate.h"
|
||||
#include "src/handles/handles-inl.h"
|
||||
#include "src/numbers/conversions.h"
|
||||
#include "src/objects/bigint.h"
|
||||
#include "src/objects/js-array-buffer-inl.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
|
||||
@ -80,10 +81,9 @@ void AtomicsWaitWakeHandle::Wake() {
|
||||
|
||||
enum WaitReturnValue : int { kOk = 0, kNotEqual = 1, kTimedOut = 2 };
|
||||
|
||||
Object FutexEmulation::WaitJs(Isolate* isolate,
|
||||
Handle<JSArrayBuffer> array_buffer, size_t addr,
|
||||
int32_t value, double rel_timeout_ms) {
|
||||
Object res = Wait32(isolate, array_buffer, addr, value, rel_timeout_ms);
|
||||
namespace {
|
||||
|
||||
Object WaitJsTranslateReturn(Isolate* isolate, Object res) {
|
||||
if (res.IsSmi()) {
|
||||
int val = Smi::ToInt(res);
|
||||
switch (val) {
|
||||
@ -100,6 +100,22 @@ Object FutexEmulation::WaitJs(Isolate* isolate,
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Object FutexEmulation::WaitJs32(Isolate* isolate,
|
||||
Handle<JSArrayBuffer> array_buffer, size_t addr,
|
||||
int32_t value, double rel_timeout_ms) {
|
||||
Object res = Wait32(isolate, array_buffer, addr, value, rel_timeout_ms);
|
||||
return WaitJsTranslateReturn(isolate, res);
|
||||
}
|
||||
|
||||
Object FutexEmulation::WaitJs64(Isolate* isolate,
|
||||
Handle<JSArrayBuffer> array_buffer, size_t addr,
|
||||
int64_t value, double rel_timeout_ms) {
|
||||
Object res = Wait64(isolate, array_buffer, addr, value, rel_timeout_ms);
|
||||
return WaitJsTranslateReturn(isolate, res);
|
||||
}
|
||||
|
||||
Object FutexEmulation::Wait32(Isolate* isolate,
|
||||
Handle<JSArrayBuffer> array_buffer, size_t addr,
|
||||
int32_t value, double rel_timeout_ms) {
|
||||
|
@ -117,8 +117,12 @@ class FutexEmulation : public AllStatic {
|
||||
// |rel_timeout_ms| can be Infinity.
|
||||
// If woken, return "ok", otherwise return "timed-out". The initial check and
|
||||
// the decision to wait happen atomically.
|
||||
static Object WaitJs(Isolate* isolate, Handle<JSArrayBuffer> array_buffer,
|
||||
size_t addr, int32_t value, double rel_timeout_ms);
|
||||
static Object WaitJs32(Isolate* isolate, Handle<JSArrayBuffer> array_buffer,
|
||||
size_t addr, int32_t value, double rel_timeout_ms);
|
||||
|
||||
// An version of WaitJs32 for int64_t values.
|
||||
static Object WaitJs64(Isolate* isolate, Handle<JSArrayBuffer> array_buffer,
|
||||
size_t addr, int64_t value, double rel_timeout_ms);
|
||||
|
||||
// Same as WaitJs above except it returns 0 (ok), 1 (not equal) and 2 (timed
|
||||
// out) as expected by Wasm.
|
||||
|
@ -450,10 +450,6 @@
|
||||
'built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds': [FAIL],
|
||||
'built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-out-of-bounds': [FAIL],
|
||||
|
||||
# https://bugs.chromium.org/p/v8/issues/detail?id=8100
|
||||
'built-ins/Atomics/notify/bigint/*': [SKIP],
|
||||
'built-ins/Atomics/wait/bigint/*': [SKIP],
|
||||
|
||||
# https://bugs.chromium.org/p/v8/issues/detail?id=6049
|
||||
'built-ins/Object/internals/DefineOwnProperty/consistent-value-function-caller': [FAIL_SLOPPY],
|
||||
'built-ins/Object/internals/DefineOwnProperty/consistent-value-function-arguments': [FAIL_SLOPPY],
|
||||
@ -571,7 +567,11 @@
|
||||
######################## NEEDS INVESTIGATION ###########################
|
||||
|
||||
# https://bugs.chromium.org/p/v8/issues/detail?id=7833
|
||||
#
|
||||
# Test262 needs to expose CanBlock
|
||||
'built-ins/Atomics/wait/bigint/cannot-suspend-throws': [SKIP],
|
||||
'built-ins/Atomics/wait/cannot-suspend-throws': [SKIP],
|
||||
# Flaky
|
||||
'built-ins/Atomics/wait/undefined-index-defaults-to-zero': [SKIP],
|
||||
|
||||
##################### DELIBERATE INCOMPATIBILITIES #####################
|
||||
|
Loading…
Reference in New Issue
Block a user