[SAB] Fix crash in Atomics.wake w/ infinite count.
Also if the count is not specified, it should wake all waiters. BUG=v8:4777 Review-Url: https://codereview.chromium.org/2659083004 Cr-Commit-Position: refs/heads/master@{#42871}
This commit is contained in:
parent
6a82fe9068
commit
aa3422b671
@ -188,10 +188,9 @@ Object* FutexEmulation::Wait(Isolate* isolate,
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Object* FutexEmulation::Wake(Isolate* isolate,
|
||||
Handle<JSArrayBuffer> array_buffer, size_t addr,
|
||||
int num_waiters_to_wake) {
|
||||
uint32_t num_waiters_to_wake) {
|
||||
DCHECK(addr < NumberToSize(array_buffer->byte_length()));
|
||||
|
||||
int waiters_woken = 0;
|
||||
@ -203,7 +202,9 @@ Object* FutexEmulation::Wake(Isolate* isolate,
|
||||
if (backing_store == node->backing_store_ && addr == node->wait_addr_) {
|
||||
node->waiting_ = false;
|
||||
node->cond_.NotifyOne();
|
||||
--num_waiters_to_wake;
|
||||
if (num_waiters_to_wake != kWakeAll) {
|
||||
--num_waiters_to_wake;
|
||||
}
|
||||
waiters_woken++;
|
||||
}
|
||||
|
||||
|
@ -82,6 +82,9 @@ class FutexWaitList {
|
||||
|
||||
class FutexEmulation : public AllStatic {
|
||||
public:
|
||||
// Pass to Wake() to wake all waiters.
|
||||
static const uint32_t kWakeAll = UINT32_MAX;
|
||||
|
||||
// Check that array_buffer[addr] == value, and return "not-equal" if not. If
|
||||
// they are equal, block execution on |isolate|'s thread until woken via
|
||||
// |Wake|, or when the time given in |rel_timeout_ms| elapses. Note that
|
||||
@ -92,10 +95,11 @@ class FutexEmulation : public AllStatic {
|
||||
size_t addr, int32_t value, double rel_timeout_ms);
|
||||
|
||||
// Wake |num_waiters_to_wake| threads that are waiting on the given |addr|.
|
||||
// The rest of the waiters will continue to wait. The return value is the
|
||||
// number of woken waiters.
|
||||
// |num_waiters_to_wake| can be kWakeAll, in which case all waiters are
|
||||
// woken. The rest of the waiters will continue to wait. The return value is
|
||||
// the number of woken waiters.
|
||||
static Object* Wake(Isolate* isolate, Handle<JSArrayBuffer> array_buffer,
|
||||
size_t addr, int num_waiters_to_wake);
|
||||
size_t addr, uint32_t num_waiters_to_wake);
|
||||
|
||||
// Return the number of threads waiting on |addr|. Should only be used for
|
||||
// testing.
|
||||
|
@ -13,10 +13,12 @@
|
||||
|
||||
var GlobalObject = global.Object;
|
||||
var MaxSimple;
|
||||
var MinSimple;
|
||||
var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
|
||||
|
||||
utils.Import(function(from) {
|
||||
MaxSimple = from.MaxSimple;
|
||||
MinSimple = from.MinSimple;
|
||||
});
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@ -123,7 +125,12 @@ function AtomicsWaitJS(ia, index, value, timeout) {
|
||||
function AtomicsWakeJS(ia, index, count) {
|
||||
CheckSharedInteger32TypedArray(ia);
|
||||
index = ValidateIndex(index, %_TypedArrayGetLength(ia));
|
||||
count = MaxSimple(0, TO_INTEGER(count));
|
||||
if (IS_UNDEFINED(count)) {
|
||||
count = kMaxUint32;
|
||||
} else {
|
||||
// Clamp to [0, kMaxUint32].
|
||||
count = MinSimple(MaxSimple(0, TO_INTEGER(count)), kMaxUint32);
|
||||
}
|
||||
return %AtomicsWake(ia, index, count);
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ RUNTIME_FUNCTION(Runtime_AtomicsWake) {
|
||||
DCHECK_EQ(3, args.length());
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, sta, 0);
|
||||
CONVERT_SIZE_ARG_CHECKED(index, 1);
|
||||
CONVERT_INT32_ARG_CHECKED(count, 2);
|
||||
CONVERT_UINT32_ARG_CHECKED(count, 2);
|
||||
CHECK(sta->GetBuffer()->is_shared());
|
||||
CHECK_LT(index, NumberToSize(sta->length()));
|
||||
CHECK_EQ(sta->type(), kExternalInt32Array);
|
||||
|
@ -104,6 +104,11 @@
|
||||
%SetAllowAtomicsWait(true);
|
||||
})();
|
||||
|
||||
(function TestWakePositiveInfinity() {
|
||||
var i32a = new Int32Array(new SharedArrayBuffer(16));
|
||||
Atomics.wake(i32a, 0, Number.POSITIVE_INFINITY);
|
||||
})();
|
||||
|
||||
//// WORKER ONLY TESTS
|
||||
|
||||
if (this.Worker) {
|
||||
|
Loading…
Reference in New Issue
Block a user