Commit 65ef6905 authored by Marja Hölttä's avatar Marja Hölttä Committed by Commit Bot

[Atomics.waitAsync] Prework: make FutexWaitListNode::backing_store_ a weak ptr

When we add waitAsync, void* backing_store_ is no longer sufficient,
since we cannot guarantee that the BackingStore stays alive while
we're (asynchronously) waiting.

Bug: v8:10239
Change-Id: I0e4f6049eb0c01faf216a8c6865a41c6e42be3ac
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2208854Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarShu-yu Guo <syg@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67922}
parent 6e164c3a
...@@ -193,8 +193,9 @@ Object FutexEmulation::Wait(Isolate* isolate, ...@@ -193,8 +193,9 @@ Object FutexEmulation::Wait(Isolate* isolate,
do { // Not really a loop, just makes it easier to break out early. do { // Not really a loop, just makes it easier to break out early.
base::MutexGuard lock_guard(mutex_.Pointer()); base::MutexGuard lock_guard(mutex_.Pointer());
void* backing_store = array_buffer->backing_store(); std::shared_ptr<BackingStore> backing_store =
array_buffer->GetBackingStore();
DCHECK(backing_store);
FutexWaitListNode* node = isolate->futex_wait_list_node(); FutexWaitListNode* node = isolate->futex_wait_list_node();
node->backing_store_ = backing_store; node->backing_store_ = backing_store;
node->wait_addr_ = addr; node->wait_addr_ = addr;
...@@ -204,7 +205,8 @@ Object FutexEmulation::Wait(Isolate* isolate, ...@@ -204,7 +205,8 @@ Object FutexEmulation::Wait(Isolate* isolate,
// still holding the lock). // still holding the lock).
ResetWaitingOnScopeExit reset_waiting(node); ResetWaitingOnScopeExit reset_waiting(node);
T* p = reinterpret_cast<T*>(static_cast<int8_t*>(backing_store) + addr); T* p = reinterpret_cast<T*>(
static_cast<int8_t*>(backing_store->buffer_start()) + addr);
if (*p != value) { if (*p != value) {
result = handle(Smi::FromInt(WaitReturnValue::kNotEqual), isolate); result = handle(Smi::FromInt(WaitReturnValue::kNotEqual), isolate);
callback_result = AtomicsWaitEvent::kNotEqual; callback_result = AtomicsWaitEvent::kNotEqual;
...@@ -308,13 +310,16 @@ Object FutexEmulation::Wake(Handle<JSArrayBuffer> array_buffer, size_t addr, ...@@ -308,13 +310,16 @@ Object FutexEmulation::Wake(Handle<JSArrayBuffer> array_buffer, size_t addr,
DCHECK_LT(addr, array_buffer->byte_length()); DCHECK_LT(addr, array_buffer->byte_length());
int waiters_woken = 0; int waiters_woken = 0;
void* backing_store = array_buffer->backing_store(); std::shared_ptr<BackingStore> backing_store = array_buffer->GetBackingStore();
base::MutexGuard lock_guard(mutex_.Pointer()); base::MutexGuard lock_guard(mutex_.Pointer());
FutexWaitListNode* node = wait_list_.Pointer()->head_; FutexWaitListNode* node = wait_list_.Pointer()->head_;
while (node && num_waiters_to_wake > 0) { while (node && num_waiters_to_wake > 0) {
if (backing_store == node->backing_store_ && addr == node->wait_addr_ && std::shared_ptr<BackingStore> node_backing_store =
node->waiting_) { node->backing_store_.lock();
DCHECK(node_backing_store);
if (backing_store.get() == node_backing_store.get() &&
addr == node->wait_addr_ && node->waiting_) {
node->waiting_ = false; node->waiting_ = false;
node->cond_.NotifyOne(); node->cond_.NotifyOne();
if (num_waiters_to_wake != kWakeAll) { if (num_waiters_to_wake != kWakeAll) {
...@@ -332,15 +337,18 @@ Object FutexEmulation::Wake(Handle<JSArrayBuffer> array_buffer, size_t addr, ...@@ -332,15 +337,18 @@ Object FutexEmulation::Wake(Handle<JSArrayBuffer> array_buffer, size_t addr,
Object FutexEmulation::NumWaitersForTesting(Handle<JSArrayBuffer> array_buffer, Object FutexEmulation::NumWaitersForTesting(Handle<JSArrayBuffer> array_buffer,
size_t addr) { size_t addr) {
DCHECK_LT(addr, array_buffer->byte_length()); DCHECK_LT(addr, array_buffer->byte_length());
void* backing_store = array_buffer->backing_store(); std::shared_ptr<BackingStore> backing_store = array_buffer->GetBackingStore();
base::MutexGuard lock_guard(mutex_.Pointer()); base::MutexGuard lock_guard(mutex_.Pointer());
int waiters = 0; int waiters = 0;
FutexWaitListNode* node = wait_list_.Pointer()->head_; FutexWaitListNode* node = wait_list_.Pointer()->head_;
while (node) { while (node) {
if (backing_store == node->backing_store_ && addr == node->wait_addr_ && std::shared_ptr<BackingStore> node_backing_store =
node->waiting_) { node->backing_store_.lock();
DCHECK(node_backing_store);
if (backing_store.get() == node_backing_store.get() &&
addr == node->wait_addr_ && node->waiting_) {
waiters++; waiters++;
} }
......
...@@ -30,6 +30,7 @@ class TimeDelta; ...@@ -30,6 +30,7 @@ class TimeDelta;
namespace internal { namespace internal {
class BackingStore;
template <typename T> template <typename T>
class Handle; class Handle;
class Isolate; class Isolate;
...@@ -52,7 +53,6 @@ class FutexWaitListNode { ...@@ -52,7 +53,6 @@ class FutexWaitListNode {
FutexWaitListNode() FutexWaitListNode()
: prev_(nullptr), : prev_(nullptr),
next_(nullptr), next_(nullptr),
backing_store_(nullptr),
wait_addr_(0), wait_addr_(0),
waiting_(false), waiting_(false),
interrupted_(false) {} interrupted_(false) {}
...@@ -68,7 +68,7 @@ class FutexWaitListNode { ...@@ -68,7 +68,7 @@ class FutexWaitListNode {
// prev_ and next_ are protected by FutexEmulation::mutex_. // prev_ and next_ are protected by FutexEmulation::mutex_.
FutexWaitListNode* prev_; FutexWaitListNode* prev_;
FutexWaitListNode* next_; FutexWaitListNode* next_;
void* backing_store_; std::weak_ptr<BackingStore> backing_store_;
size_t wait_addr_; size_t wait_addr_;
// waiting_ and interrupted_ are protected by FutexEmulation::mutex_ // waiting_ and interrupted_ are protected by FutexEmulation::mutex_
// if this node is currently contained in FutexEmulation::wait_list_ // if this node is currently contained in FutexEmulation::wait_list_
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment