Commit e8ba5699 authored by Peter Marshall's avatar Peter Marshall Committed by Commit Bot

[tools] Add a VMState for Atomics.wait

We will use this state in devtools via the inspector to indicate
whether a thread is currently stuck polling in atomics.wait.

VMState already distinguishes the important states we care about which
are idle vs. running JS. We also want to know the state for
atomics.wait(), which is commonly used in WebWorkers to poll the main
page for work to do.

This CL just adds and maintains the state and adds assertions in
atomics tests. Another CL will emit inspector notifications when the
VMState changes in a way that the inspector cares about.

Re-flow comments as a drive-by cleanup.

Bug: chromium:1025490
Change-Id: I961051bfb846aa20454a56214310370ea8e47d1c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2033168
Commit-Queue: Peter Marshall <petermarshall@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#66071}
parent a6cf73e5
...@@ -2199,6 +2199,7 @@ enum StateTag { ...@@ -2199,6 +2199,7 @@ enum StateTag {
COMPILER, COMPILER,
OTHER, OTHER,
EXTERNAL, EXTERNAL,
ATOMICS_WAIT,
IDLE IDLE
}; };
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "src/base/macros.h" #include "src/base/macros.h"
#include "src/base/platform/time.h" #include "src/base/platform/time.h"
#include "src/execution/isolate.h" #include "src/execution/isolate.h"
#include "src/execution/vm-state-inl.h"
#include "src/handles/handles-inl.h" #include "src/handles/handles-inl.h"
#include "src/numbers/conversions.h" #include "src/numbers/conversions.h"
#include "src/objects/bigint.h" #include "src/objects/bigint.h"
...@@ -132,6 +133,7 @@ template <typename T> ...@@ -132,6 +133,7 @@ template <typename T>
Object FutexEmulation::Wait(Isolate* isolate, Object FutexEmulation::Wait(Isolate* isolate,
Handle<JSArrayBuffer> array_buffer, size_t addr, Handle<JSArrayBuffer> array_buffer, size_t addr,
T value, double rel_timeout_ms) { T value, double rel_timeout_ms) {
VMState<ATOMICS_WAIT> state(isolate);
DCHECK_LT(addr, array_buffer->byte_length()); DCHECK_LT(addr, array_buffer->byte_length());
bool use_timeout = rel_timeout_ms != V8_INFINITY; bool use_timeout = rel_timeout_ms != V8_INFINITY;
......
...@@ -14,11 +14,9 @@ ...@@ -14,11 +14,9 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
// // VMState class implementation. A simple stack of VM states held by the logger
// VMState class implementation. A simple stack of VM states held by the // and partially threaded through the call stack. States are pushed by VMState
// logger and partially threaded through the call stack. States are pushed by // construction and popped by destruction.
// VMState construction and popped by destruction.
//
inline const char* StateToString(StateTag state) { inline const char* StateToString(StateTag state) {
switch (state) { switch (state) {
case JS: case JS:
...@@ -35,6 +33,8 @@ inline const char* StateToString(StateTag state) { ...@@ -35,6 +33,8 @@ inline const char* StateToString(StateTag state) {
return "OTHER"; return "OTHER";
case EXTERNAL: case EXTERNAL:
return "EXTERNAL"; return "EXTERNAL";
case ATOMICS_WAIT:
return "ATOMICS_WAIT";
case IDLE: case IDLE:
return "IDLE"; return "IDLE";
} }
......
...@@ -11,11 +11,10 @@ ...@@ -11,11 +11,10 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
// Logging and profiling. A StateTag represents a possible state of // Logging and profiling. A StateTag represents a possible state of the VM. The
// the VM. The logger maintains a stack of these. Creating a VMState // logger maintains a stack of these. Creating a VMState object enters a state
// object enters a state by pushing on the stack, and destroying a // by pushing on the stack, and destroying a VMState object leaves a state by
// VMState object leaves a state by popping the current state from the // popping the current state from the stack.
// stack.
template <StateTag Tag> template <StateTag Tag>
class VMState { class VMState {
public: public:
......
...@@ -1007,6 +1007,7 @@ CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) { ...@@ -1007,6 +1007,7 @@ CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) {
case PARSER: case PARSER:
case COMPILER: case COMPILER:
case BYTECODE_COMPILER: case BYTECODE_COMPILER:
case ATOMICS_WAIT:
// DOM events handlers are reported as OTHER / EXTERNAL entries. // DOM events handlers are reported as OTHER / EXTERNAL entries.
// To avoid confusing people, let's put all these entries into // To avoid confusing people, let's put all these entries into
// one bucket. // one bucket.
......
...@@ -178,6 +178,9 @@ SamplingHeapProfiler::AllocationNode* SamplingHeapProfiler::AddStack() { ...@@ -178,6 +178,9 @@ SamplingHeapProfiler::AllocationNode* SamplingHeapProfiler::AddStack() {
case IDLE: case IDLE:
name = "(IDLE)"; name = "(IDLE)";
break; break;
// Treat atomics wait as a normal JS event; we don't care about the
// difference for allocations.
case ATOMICS_WAIT:
case JS: case JS:
name = "(JS)"; name = "(JS)";
break; break;
......
...@@ -25979,6 +25979,8 @@ void AtomicsWaitCallbackForTesting( ...@@ -25979,6 +25979,8 @@ void AtomicsWaitCallbackForTesting(
CHECK_EQ(timeout_in_ms, info->expected_timeout); CHECK_EQ(timeout_in_ms, info->expected_timeout);
CHECK_EQ(value, info->expected_value); CHECK_EQ(value, info->expected_value);
CHECK_EQ(offset_in_bytes, info->expected_offset); CHECK_EQ(offset_in_bytes, info->expected_offset);
CHECK_EQ(v8::StateTag::ATOMICS_WAIT,
reinterpret_cast<i::Isolate*>(info->isolate)->current_vm_state());
auto ThrowSomething = [&]() { auto ThrowSomething = [&]() {
info->isolate->ThrowException(v8::Integer::New(info->isolate, 42)); info->isolate->ThrowException(v8::Integer::New(info->isolate, 42));
......
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