[Atomics] Add use counter for Atomics.{wake, notify}

Previously, Atomics.notify was just an alias to Atomics.wake, which
doesn't quite let us add a use counter for these individual builtins.

This patch refactors the existing Atomics.wake into a separate
function that is called from two separate builtins.

Bug: v8:7883
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Change-Id: If54c8f769b7949d88d327cfb2f70db394f32a0b7
Reviewed-on: https://chromium-review.googlesource.com/1234581
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: Adam Klein <adamk@chromium.org>
Reviewed-by: Ben Smith <binji@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56105}
This commit is contained in:
Sathya Gunasekaran 2018-09-19 12:23:29 -07:00 committed by Commit Bot
parent 3587468435
commit 81c9e3936b
6 changed files with 69 additions and 15 deletions

View File

@ -7355,6 +7355,8 @@ class V8_EXPORT Isolate {
kFunctionTokenOffsetTooLongForToString = 49,
kWasmSharedMemory = 50,
kWasmThreadOpcodes = 51,
kAtomicsNotify = 52,
kAtomicsWake = 53,
// If you add new values here, you'll also need to update Chromium's:
// web_feature.mojom, UseCounterCallback.cpp, and enums.xml. V8 changes to

View File

@ -3138,7 +3138,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
SimpleInstallFunction(isolate_, atomics_object, "wake",
Builtins::kAtomicsWake, 3, true);
SimpleInstallFunction(isolate_, atomics_object, "notify",
Builtins::kAtomicsWake, 3, true);
Builtins::kAtomicsNotify, 3, true);
}
{ // -- T y p e d A r r a y

View File

@ -1025,6 +1025,7 @@ namespace internal {
TFJ(AtomicsAnd, 3, kReceiver, kArray, kIndex, kValue) \
TFJ(AtomicsOr, 3, kReceiver, kArray, kIndex, kValue) \
TFJ(AtomicsXor, 3, kReceiver, kArray, kIndex, kValue) \
CPP(AtomicsNotify) \
CPP(AtomicsIsLockFree) \
CPP(AtomicsWait) \
CPP(AtomicsWake) \

View File

@ -82,28 +82,24 @@ V8_WARN_UNUSED_RESULT Maybe<size_t> ValidateAtomicAccess(
return Just<size_t>(access_index);
}
// ES #sec-atomics.wake
// Atomics.wake( typedArray, index, count )
BUILTIN(AtomicsWake) {
HandleScope scope(isolate);
Handle<Object> array = args.atOrUndefined(isolate, 1);
Handle<Object> index = args.atOrUndefined(isolate, 2);
Handle<Object> count = args.atOrUndefined(isolate, 3);
namespace {
MaybeHandle<Object> AtomicsWake(Isolate* isolate, Handle<Object> array,
Handle<Object> index, Handle<Object> count) {
Handle<JSTypedArray> sta;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, sta, ValidateSharedIntegerTypedArray(isolate, array, true));
ASSIGN_RETURN_ON_EXCEPTION(
isolate, sta, ValidateSharedIntegerTypedArray(isolate, array, true),
Object);
Maybe<size_t> maybe_index = ValidateAtomicAccess(isolate, sta, index);
if (maybe_index.IsNothing()) return ReadOnlyRoots(isolate).exception();
MAYBE_RETURN_NULL(maybe_index);
size_t i = maybe_index.FromJust();
uint32_t c;
if (count->IsUndefined(isolate)) {
c = kMaxUInt32;
} else {
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, count,
Object::ToInteger(isolate, count));
ASSIGN_RETURN_ON_EXCEPTION(isolate, count,
Object::ToInteger(isolate, count), Object);
double count_double = count->Number();
if (count_double < 0)
count_double = 0;
@ -115,7 +111,33 @@ BUILTIN(AtomicsWake) {
Handle<JSArrayBuffer> array_buffer = sta->GetBuffer();
size_t addr = (i << 2) + sta->byte_offset();
return FutexEmulation::Wake(array_buffer, addr, c);
return Handle<Object>(FutexEmulation::Wake(array_buffer, addr, c), isolate);
}
} // namespace
// ES #sec-atomics.wake
// Atomics.wake( typedArray, index, count )
BUILTIN(AtomicsWake) {
HandleScope scope(isolate);
Handle<Object> array = args.atOrUndefined(isolate, 1);
Handle<Object> index = args.atOrUndefined(isolate, 2);
Handle<Object> count = args.atOrUndefined(isolate, 3);
isolate->CountUsage(v8::Isolate::UseCounterFeature::kAtomicsWake);
RETURN_RESULT_OR_FAILURE(isolate, AtomicsWake(isolate, array, index, count));
}
// ES #sec-atomics.notify
// Atomics.notify( typedArray, index, count )
BUILTIN(AtomicsNotify) {
HandleScope scope(isolate);
Handle<Object> array = args.atOrUndefined(isolate, 1);
Handle<Object> index = args.atOrUndefined(isolate, 2);
Handle<Object> count = args.atOrUndefined(isolate, 3);
isolate->CountUsage(v8::Isolate::UseCounterFeature::kAtomicsNotify);
RETURN_RESULT_OR_FAILURE(isolate, AtomicsWake(isolate, array, index, count));
}
// ES #sec-atomics.wait

View File

@ -60,6 +60,27 @@ TEST(AssigmentExpressionLHSIsCall) {
use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict] = 0;
}
TEST(AtomicsWakeAndAtomicsNotify) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
LocalContext env;
int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
global_use_counts = use_counts;
i::FLAG_harmony_sharedarraybuffer = true;
CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
CompileRun("Atomics.wake(new Int32Array(new SharedArrayBuffer(16)), 0);");
CHECK_EQ(1, use_counts[v8::Isolate::kAtomicsWake]);
CHECK_EQ(0, use_counts[v8::Isolate::kAtomicsNotify]);
use_counts[v8::Isolate::kAtomicsWake] = 0;
use_counts[v8::Isolate::kAtomicsNotify] = 0;
CompileRun("Atomics.notify(new Int32Array(new SharedArrayBuffer(16)), 0);");
CHECK_EQ(0, use_counts[v8::Isolate::kAtomicsWake]);
CHECK_EQ(1, use_counts[v8::Isolate::kAtomicsNotify]);
}
} // namespace test_usecounters
} // namespace internal
} // namespace v8

View File

@ -0,0 +1,8 @@
// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Flags: --allow-natives-syntax --harmony-sharedarraybuffer
// This test needs to be killed if we remove Atomics.wake.
assertNotSame(Atomics.wake, Atomics.notify);