Commit a5c32102 authored by Jochen Eisinger's avatar Jochen Eisinger Committed by V8 LUCI CQ

CallDepthScope should track the current microtask scope

Tracking the context is not enough, as we might clear the context to
avoid repeatedly reentering the same context.

Also fix unittests that relied on the default microtask queue getting
automatically processed instead of the one of the current context.

Bug: chromium:728583
Change-Id: Ia9a51c513fc7363a518af86cc54c5bda26b5fbe8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2859850Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Jochen Eisinger <jochen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74303}
parent d665f40f
...@@ -139,6 +139,7 @@ class V8_NODISCARD CallDepthScope { ...@@ -139,6 +139,7 @@ class V8_NODISCARD CallDepthScope {
CallDepthScope(i::Isolate* isolate, Local<Context> context) CallDepthScope(i::Isolate* isolate, Local<Context> context)
: isolate_(isolate), : isolate_(isolate),
context_(context), context_(context),
did_enter_context_(false),
escaped_(false), escaped_(false),
safe_for_termination_(isolate->next_v8_call_is_safe_for_termination()), safe_for_termination_(isolate->next_v8_call_is_safe_for_termination()),
interrupts_scope_(isolate_, i::StackGuard::TERMINATE_EXECUTION, interrupts_scope_(isolate_, i::StackGuard::TERMINATE_EXECUTION,
...@@ -152,12 +153,11 @@ class V8_NODISCARD CallDepthScope { ...@@ -152,12 +153,11 @@ class V8_NODISCARD CallDepthScope {
if (!context.IsEmpty()) { if (!context.IsEmpty()) {
i::Handle<i::Context> env = Utils::OpenHandle(*context); i::Handle<i::Context> env = Utils::OpenHandle(*context);
i::HandleScopeImplementer* impl = isolate->handle_scope_implementer(); i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
if (!isolate->context().is_null() && if (isolate->context().is_null() ||
isolate->context().native_context() == env->native_context()) { isolate->context().native_context() != env->native_context()) {
context_ = Local<Context>();
} else {
impl->SaveContext(isolate->context()); impl->SaveContext(isolate->context());
isolate->set_context(*env); isolate->set_context(*env);
did_enter_context_ = true;
} }
} }
if (do_callback) isolate_->FireBeforeCallEnteredCallback(); if (do_callback) isolate_->FireBeforeCallEnteredCallback();
...@@ -165,8 +165,10 @@ class V8_NODISCARD CallDepthScope { ...@@ -165,8 +165,10 @@ class V8_NODISCARD CallDepthScope {
~CallDepthScope() { ~CallDepthScope() {
i::MicrotaskQueue* microtask_queue = isolate_->default_microtask_queue(); i::MicrotaskQueue* microtask_queue = isolate_->default_microtask_queue();
if (!context_.IsEmpty()) { if (!context_.IsEmpty()) {
i::HandleScopeImplementer* impl = isolate_->handle_scope_implementer(); if (did_enter_context_) {
isolate_->set_context(impl->RestoreContext()); i::HandleScopeImplementer* impl = isolate_->handle_scope_implementer();
isolate_->set_context(impl->RestoreContext());
}
i::Handle<i::Context> env = Utils::OpenHandle(*context_); i::Handle<i::Context> env = Utils::OpenHandle(*context_);
microtask_queue = env->native_context().microtask_queue(); microtask_queue = env->native_context().microtask_queue();
...@@ -213,9 +215,9 @@ class V8_NODISCARD CallDepthScope { ...@@ -213,9 +215,9 @@ class V8_NODISCARD CallDepthScope {
i::Isolate* const isolate_; i::Isolate* const isolate_;
Local<Context> context_; Local<Context> context_;
bool escaped_; bool did_enter_context_ : 1;
bool do_callback_; bool escaped_ : 1;
bool safe_for_termination_; bool safe_for_termination_ : 1;
i::InterruptsScope interrupts_scope_; i::InterruptsScope interrupts_scope_;
i::Address previous_stack_height_; i::Address previous_stack_height_;
......
...@@ -248,6 +248,7 @@ TEST_P(MicrotaskQueueTest, VisitRoot) { ...@@ -248,6 +248,7 @@ TEST_P(MicrotaskQueueTest, VisitRoot) {
} }
TEST_P(MicrotaskQueueTest, PromiseHandlerContext) { TEST_P(MicrotaskQueueTest, PromiseHandlerContext) {
microtask_queue()->set_microtasks_policy(MicrotasksPolicy::kExplicit);
Local<v8::Context> v8_context2 = v8::Context::New(v8_isolate()); Local<v8::Context> v8_context2 = v8::Context::New(v8_isolate());
Local<v8::Context> v8_context3 = v8::Context::New(v8_isolate()); Local<v8::Context> v8_context3 = v8::Context::New(v8_isolate());
Local<v8::Context> v8_context4 = v8::Context::New(v8_isolate()); Local<v8::Context> v8_context4 = v8::Context::New(v8_isolate());
...@@ -354,6 +355,7 @@ TEST_P(MicrotaskQueueTest, DetachGlobal_Enqueue) { ...@@ -354,6 +355,7 @@ TEST_P(MicrotaskQueueTest, DetachGlobal_Enqueue) {
} }
TEST_P(MicrotaskQueueTest, DetachGlobal_Run) { TEST_P(MicrotaskQueueTest, DetachGlobal_Run) {
microtask_queue()->set_microtasks_policy(MicrotasksPolicy::kExplicit);
EXPECT_EQ(0, microtask_queue()->size()); EXPECT_EQ(0, microtask_queue()->size());
// Enqueue microtasks to the current context. // Enqueue microtasks to the current context.
...@@ -392,6 +394,7 @@ TEST_P(MicrotaskQueueTest, DetachGlobal_Run) { ...@@ -392,6 +394,7 @@ TEST_P(MicrotaskQueueTest, DetachGlobal_Run) {
} }
TEST_P(MicrotaskQueueTest, DetachGlobal_PromiseResolveThenableJobTask) { TEST_P(MicrotaskQueueTest, DetachGlobal_PromiseResolveThenableJobTask) {
microtask_queue()->set_microtasks_policy(MicrotasksPolicy::kExplicit);
RunJS( RunJS(
"var resolve;" "var resolve;"
"var promise = new Promise(r => { resolve = r; });" "var promise = new Promise(r => { resolve = r; });"
...@@ -414,6 +417,7 @@ TEST_P(MicrotaskQueueTest, DetachGlobal_PromiseResolveThenableJobTask) { ...@@ -414,6 +417,7 @@ TEST_P(MicrotaskQueueTest, DetachGlobal_PromiseResolveThenableJobTask) {
} }
TEST_P(MicrotaskQueueTest, DetachGlobal_ResolveThenableForeignThen) { TEST_P(MicrotaskQueueTest, DetachGlobal_ResolveThenableForeignThen) {
microtask_queue()->set_microtasks_policy(MicrotasksPolicy::kExplicit);
Handle<JSArray> result = RunJS<JSArray>( Handle<JSArray> result = RunJS<JSArray>(
"let result = [false];" "let result = [false];"
"result"); "result");
...@@ -425,6 +429,7 @@ TEST_P(MicrotaskQueueTest, DetachGlobal_ResolveThenableForeignThen) { ...@@ -425,6 +429,7 @@ TEST_P(MicrotaskQueueTest, DetachGlobal_ResolveThenableForeignThen) {
// Create a context with its own microtask queue. // Create a context with its own microtask queue.
std::unique_ptr<MicrotaskQueue> sub_microtask_queue = std::unique_ptr<MicrotaskQueue> sub_microtask_queue =
MicrotaskQueue::New(isolate()); MicrotaskQueue::New(isolate());
sub_microtask_queue->set_microtasks_policy(MicrotasksPolicy::kExplicit);
Local<v8::Context> sub_context = v8::Context::New( Local<v8::Context> sub_context = v8::Context::New(
v8_isolate(), v8_isolate(),
/* extensions= */ nullptr, /* extensions= */ nullptr,
......
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