[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:
binji 2017-02-01 13:47:22 -08:00 committed by Commit bot
parent 6a82fe9068
commit aa3422b671
5 changed files with 25 additions and 8 deletions

View File

@ -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++;
}

View File

@ -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.

View File

@ -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);
}

View File

@ -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);

View File

@ -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) {