Introduce v8::MicrotasksScope.
This scope is used to control microtasks execution when MicrotasksPolicy::kScoped is engaged. BUG=chromium:585949 LOG=Y TEST=ScopedMicrotasks Review URL: https://codereview.chromium.org/1741893003 Cr-Commit-Position: refs/heads/master@{#34472}
This commit is contained in:
parent
4b613a67e0
commit
db77cec242
64
include/v8.h
64
include/v8.h
@ -5059,6 +5059,53 @@ typedef void (*PromiseRejectCallback)(PromiseRejectMessage message);
|
||||
typedef void (*MicrotasksCompletedCallback)(Isolate*);
|
||||
typedef void (*MicrotaskCallback)(void* data);
|
||||
|
||||
|
||||
/**
|
||||
* Policy for running microtasks:
|
||||
* - explicit: microtasks are invoked with Isolate::RunMicrotasks() method;
|
||||
* - scoped: microtasks invocation is controlled by MicrotasksScope objects;
|
||||
* - auto: microtasks are invoked when the script call depth decrements
|
||||
* to zero.
|
||||
*/
|
||||
enum class MicrotasksPolicy { kExplicit, kScoped, kAuto };
|
||||
|
||||
|
||||
/**
|
||||
* This scope is used to control microtasks when kScopeMicrotasksInvocation
|
||||
* is used on Isolate. In this mode every non-primitive call to V8 should be
|
||||
* done inside some MicrotasksScope.
|
||||
* Microtasks are executed when topmost MicrotasksScope marked as kRunMicrotasks
|
||||
* exits.
|
||||
* kDoNotRunMicrotasks should be used to annotate calls not intended to trigger
|
||||
* microtasks.
|
||||
*/
|
||||
class V8_EXPORT MicrotasksScope {
|
||||
public:
|
||||
enum Type { kRunMicrotasks, kDoNotRunMicrotasks };
|
||||
|
||||
MicrotasksScope(Isolate* isolate, Type type);
|
||||
~MicrotasksScope();
|
||||
|
||||
/**
|
||||
* Runs microtasks if no kRunMicrotasks scope is currently active.
|
||||
*/
|
||||
static void PerformCheckpoint(Isolate* isolate);
|
||||
|
||||
/**
|
||||
* Returns current depth of nested kRunMicrotasks scopes.
|
||||
*/
|
||||
static int GetCurrentDepth(Isolate* isolate);
|
||||
|
||||
private:
|
||||
internal::Isolate* const isolate_;
|
||||
bool run_;
|
||||
|
||||
// Prevent copying.
|
||||
MicrotasksScope(const MicrotasksScope&);
|
||||
MicrotasksScope& operator=(const MicrotasksScope&);
|
||||
};
|
||||
|
||||
|
||||
// --- Failed Access Check Callback ---
|
||||
typedef void (*FailedAccessCheckCallback)(Local<Object> target,
|
||||
AccessType type,
|
||||
@ -5885,17 +5932,20 @@ class V8_EXPORT Isolate {
|
||||
*/
|
||||
void EnqueueMicrotask(MicrotaskCallback microtask, void* data = NULL);
|
||||
|
||||
/**
|
||||
* Experimental: Controls whether the Microtask Work Queue is automatically
|
||||
* run when the script call depth decrements to zero.
|
||||
/**
|
||||
* Experimental: Controls how Microtasks are invoked. See MicrotasksPolicy
|
||||
* for details.
|
||||
*/
|
||||
void SetAutorunMicrotasks(bool autorun);
|
||||
void SetMicrotasksPolicy(MicrotasksPolicy policy);
|
||||
V8_DEPRECATE_SOON("Use SetMicrotasksPolicy",
|
||||
void SetAutorunMicrotasks(bool autorun));
|
||||
|
||||
/**
|
||||
* Experimental: Returns whether the Microtask Work Queue is automatically
|
||||
* run when the script call depth decrements to zero.
|
||||
* Experimental: Returns the policy controlling how Microtasks are invoked.
|
||||
*/
|
||||
bool WillAutorunMicrotasks() const;
|
||||
MicrotasksPolicy GetMicrotasksPolicy() const;
|
||||
V8_DEPRECATE_SOON("Use GetMicrotasksPolicy",
|
||||
bool WillAutorunMicrotasks() const);
|
||||
|
||||
/**
|
||||
* Experimental: adds a callback to notify the host application after
|
||||
|
78
src/api.cc
78
src/api.cc
@ -157,6 +157,18 @@ class InternalEscapableScope : public v8::EscapableHandleScope {
|
||||
};
|
||||
|
||||
|
||||
#ifdef V8_ENABLE_CHECKS
|
||||
void CheckMicrotasksScopesConsistency(i::Isolate* isolate) {
|
||||
auto handle_scope_implementer = isolate->handle_scope_implementer();
|
||||
if (handle_scope_implementer->microtasks_policy() ==
|
||||
v8::MicrotasksPolicy::kScoped) {
|
||||
DCHECK(handle_scope_implementer->GetMicrotasksScopeDepth() ||
|
||||
!handle_scope_implementer->DebugMicrotasksScopeDepthIsZero());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
class CallDepthScope {
|
||||
public:
|
||||
explicit CallDepthScope(i::Isolate* isolate, Local<Context> context,
|
||||
@ -176,6 +188,9 @@ class CallDepthScope {
|
||||
if (!context_.IsEmpty()) context_->Exit();
|
||||
if (!escaped_) isolate_->handle_scope_implementer()->DecrementCallDepth();
|
||||
if (do_callback_) isolate_->FireCallCompletedCallback();
|
||||
#ifdef V8_ENABLE_CHECKS
|
||||
if (do_callback_) CheckMicrotasksScopesConsistency(isolate_);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Escape() {
|
||||
@ -7298,10 +7313,12 @@ Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
|
||||
Isolate* isolate)
|
||||
: isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
|
||||
isolate_->handle_scope_implementer()->IncrementCallDepth();
|
||||
isolate_->handle_scope_implementer()->IncrementMicrotasksSuppressions();
|
||||
}
|
||||
|
||||
|
||||
Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
|
||||
isolate_->handle_scope_implementer()->DecrementMicrotasksSuppressions();
|
||||
isolate_->handle_scope_implementer()->DecrementCallDepth();
|
||||
}
|
||||
|
||||
@ -7443,6 +7460,7 @@ void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
|
||||
|
||||
|
||||
void Isolate::RunMicrotasks() {
|
||||
DCHECK(MicrotasksPolicy::kScoped != GetMicrotasksPolicy());
|
||||
reinterpret_cast<i::Isolate*>(this)->RunMicrotasks();
|
||||
}
|
||||
|
||||
@ -7466,12 +7484,25 @@ void Isolate::EnqueueMicrotask(MicrotaskCallback microtask, void* data) {
|
||||
|
||||
|
||||
void Isolate::SetAutorunMicrotasks(bool autorun) {
|
||||
reinterpret_cast<i::Isolate*>(this)->set_autorun_microtasks(autorun);
|
||||
SetMicrotasksPolicy(MicrotasksPolicy::kAuto);
|
||||
}
|
||||
|
||||
|
||||
bool Isolate::WillAutorunMicrotasks() const {
|
||||
return reinterpret_cast<const i::Isolate*>(this)->autorun_microtasks();
|
||||
return GetMicrotasksPolicy() == MicrotasksPolicy::kAuto;
|
||||
}
|
||||
|
||||
|
||||
void Isolate::SetMicrotasksPolicy(MicrotasksPolicy policy) {
|
||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
|
||||
isolate->handle_scope_implementer()->set_microtasks_policy(policy);
|
||||
}
|
||||
|
||||
|
||||
MicrotasksPolicy Isolate::GetMicrotasksPolicy() const {
|
||||
i::Isolate* isolate =
|
||||
reinterpret_cast<i::Isolate*>(const_cast<Isolate*>(this));
|
||||
return isolate->handle_scope_implementer()->microtasks_policy();
|
||||
}
|
||||
|
||||
|
||||
@ -7710,6 +7741,49 @@ void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) {
|
||||
}
|
||||
|
||||
|
||||
MicrotasksScope::MicrotasksScope(Isolate* isolate, MicrotasksScope::Type type)
|
||||
: isolate_(reinterpret_cast<i::Isolate*>(isolate)),
|
||||
run_(type == MicrotasksScope::kRunMicrotasks) {
|
||||
auto handle_scope_implementer = isolate_->handle_scope_implementer();
|
||||
if (run_) handle_scope_implementer->IncrementMicrotasksScopeDepth();
|
||||
#ifdef V8_ENABLE_CHECKS
|
||||
if (!run_) handle_scope_implementer->IncrementDebugMicrotasksScopeDepth();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
MicrotasksScope::~MicrotasksScope() {
|
||||
auto handle_scope_implementer = isolate_->handle_scope_implementer();
|
||||
if (run_) {
|
||||
handle_scope_implementer->DecrementMicrotasksScopeDepth();
|
||||
if (MicrotasksPolicy::kScoped ==
|
||||
handle_scope_implementer->microtasks_policy()) {
|
||||
PerformCheckpoint(reinterpret_cast<Isolate*>(isolate_));
|
||||
}
|
||||
}
|
||||
#ifdef V8_ENABLE_CHECKS
|
||||
if (!run_) handle_scope_implementer->DecrementDebugMicrotasksScopeDepth();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void MicrotasksScope::PerformCheckpoint(Isolate* v8Isolate) {
|
||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8Isolate);
|
||||
if (IsExecutionTerminatingCheck(isolate)) return;
|
||||
auto handle_scope_implementer = isolate->handle_scope_implementer();
|
||||
if (!handle_scope_implementer->GetMicrotasksScopeDepth() &&
|
||||
!handle_scope_implementer->HasMicrotasksSuppressions()) {
|
||||
isolate->RunMicrotasks();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int MicrotasksScope::GetCurrentDepth(Isolate* v8Isolate) {
|
||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8Isolate);
|
||||
return isolate->handle_scope_implementer()->GetMicrotasksScopeDepth();
|
||||
}
|
||||
|
||||
|
||||
String::Utf8Value::Utf8Value(v8::Local<v8::Value> obj)
|
||||
: str_(NULL), length_(0) {
|
||||
if (obj.IsEmpty()) return;
|
||||
|
49
src/api.h
49
src/api.h
@ -452,6 +452,12 @@ class HandleScopeImplementer {
|
||||
saved_contexts_(0),
|
||||
spare_(NULL),
|
||||
call_depth_(0),
|
||||
microtasks_depth_(0),
|
||||
microtasks_suppressions_(0),
|
||||
#ifdef V8_ENABLE_CHECKS
|
||||
debug_microtasks_depth_(0),
|
||||
#endif
|
||||
microtasks_policy_(v8::MicrotasksPolicy::kAuto),
|
||||
last_handle_before_deferred_block_(NULL) { }
|
||||
|
||||
~HandleScopeImplementer() {
|
||||
@ -472,10 +478,36 @@ class HandleScopeImplementer {
|
||||
inline internal::Object** GetSpareOrNewBlock();
|
||||
inline void DeleteExtensions(internal::Object** prev_limit);
|
||||
|
||||
// Call depth represents nested v8 api calls.
|
||||
inline void IncrementCallDepth() {call_depth_++;}
|
||||
inline void DecrementCallDepth() {call_depth_--;}
|
||||
inline bool CallDepthIsZero() { return call_depth_ == 0; }
|
||||
|
||||
// Microtasks scope depth represents nested scopes controlling microtasks
|
||||
// invocation, which happens when depth reaches zero.
|
||||
inline void IncrementMicrotasksScopeDepth() {microtasks_depth_++;}
|
||||
inline void DecrementMicrotasksScopeDepth() {microtasks_depth_--;}
|
||||
inline int GetMicrotasksScopeDepth() { return microtasks_depth_; }
|
||||
|
||||
// Possibly nested microtasks suppression scopes prevent microtasks
|
||||
// from running.
|
||||
inline void IncrementMicrotasksSuppressions() {microtasks_suppressions_++;}
|
||||
inline void DecrementMicrotasksSuppressions() {microtasks_suppressions_--;}
|
||||
inline bool HasMicrotasksSuppressions() { return !!microtasks_suppressions_; }
|
||||
|
||||
#ifdef V8_ENABLE_CHECKS
|
||||
// In debug we check that calls not intended to invoke microtasks are
|
||||
// still correctly wrapped with microtask scopes.
|
||||
inline void IncrementDebugMicrotasksScopeDepth() {debug_microtasks_depth_++;}
|
||||
inline void DecrementDebugMicrotasksScopeDepth() {debug_microtasks_depth_--;}
|
||||
inline bool DebugMicrotasksScopeDepthIsZero() {
|
||||
return debug_microtasks_depth_ == 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void set_microtasks_policy(v8::MicrotasksPolicy policy);
|
||||
inline v8::MicrotasksPolicy microtasks_policy() const;
|
||||
|
||||
inline void EnterContext(Handle<Context> context);
|
||||
inline void LeaveContext();
|
||||
inline bool LastEnteredContextWas(Handle<Context> context);
|
||||
@ -532,6 +564,12 @@ class HandleScopeImplementer {
|
||||
List<Context*> saved_contexts_;
|
||||
Object** spare_;
|
||||
int call_depth_;
|
||||
int microtasks_depth_;
|
||||
int microtasks_suppressions_;
|
||||
#ifdef V8_ENABLE_CHECKS
|
||||
int debug_microtasks_depth_;
|
||||
#endif
|
||||
v8::MicrotasksPolicy microtasks_policy_;
|
||||
Object** last_handle_before_deferred_block_;
|
||||
// This is only used for threading support.
|
||||
HandleScopeData handle_scope_data_;
|
||||
@ -550,6 +588,17 @@ class HandleScopeImplementer {
|
||||
const int kHandleBlockSize = v8::internal::KB - 2; // fit in one page
|
||||
|
||||
|
||||
void HandleScopeImplementer::set_microtasks_policy(
|
||||
v8::MicrotasksPolicy policy) {
|
||||
microtasks_policy_ = policy;
|
||||
}
|
||||
|
||||
|
||||
v8::MicrotasksPolicy HandleScopeImplementer::microtasks_policy() const {
|
||||
return microtasks_policy_;
|
||||
}
|
||||
|
||||
|
||||
void HandleScopeImplementer::SaveContext(Context* context) {
|
||||
saved_contexts_.Add(context);
|
||||
}
|
||||
|
@ -2710,7 +2710,11 @@ void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
|
||||
|
||||
void Isolate::FireCallCompletedCallback() {
|
||||
bool has_call_completed_callbacks = !call_completed_callbacks_.is_empty();
|
||||
bool run_microtasks = autorun_microtasks() && pending_microtask_count();
|
||||
bool run_microtasks =
|
||||
pending_microtask_count() &&
|
||||
!handle_scope_implementer()->HasMicrotasksSuppressions() &&
|
||||
handle_scope_implementer()->microtasks_policy() ==
|
||||
v8::MicrotasksPolicy::kAuto;
|
||||
if (!has_call_completed_callbacks && !run_microtasks) return;
|
||||
|
||||
if (!handle_scope_implementer()->CallDepthIsZero()) return;
|
||||
|
@ -378,7 +378,6 @@ typedef List<HeapObject*> DebugObjectCache;
|
||||
V(HashMap*, external_reference_map, NULL) \
|
||||
V(HashMap*, root_index_map, NULL) \
|
||||
V(int, pending_microtask_count, 0) \
|
||||
V(bool, autorun_microtasks, true) \
|
||||
V(HStatistics*, hstatistics, NULL) \
|
||||
V(CompilationStatistics*, turbo_statistics, NULL) \
|
||||
V(HTracer*, htracer, NULL) \
|
||||
|
@ -20921,12 +20921,16 @@ TEST(CallCompletedCallbackTwoExceptions) {
|
||||
|
||||
static void MicrotaskOne(const v8::FunctionCallbackInfo<Value>& info) {
|
||||
v8::HandleScope scope(info.GetIsolate());
|
||||
v8::MicrotasksScope microtasks(info.GetIsolate(),
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
CompileRun("ext1Calls++;");
|
||||
}
|
||||
|
||||
|
||||
static void MicrotaskTwo(const v8::FunctionCallbackInfo<Value>& info) {
|
||||
v8::HandleScope scope(info.GetIsolate());
|
||||
v8::MicrotasksScope microtasks(info.GetIsolate(),
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
CompileRun("ext2Calls++;");
|
||||
}
|
||||
|
||||
@ -21061,7 +21065,7 @@ TEST(SetAutorunMicrotasks) {
|
||||
CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(1u, microtasks_completed_callback_count);
|
||||
|
||||
env->GetIsolate()->SetAutorunMicrotasks(false);
|
||||
env->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
|
||||
env->GetIsolate()->EnqueueMicrotask(
|
||||
Function::New(env.local(), MicrotaskOne).ToLocalChecked());
|
||||
env->GetIsolate()->EnqueueMicrotask(
|
||||
@ -21088,7 +21092,7 @@ TEST(SetAutorunMicrotasks) {
|
||||
CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(3u, microtasks_completed_callback_count);
|
||||
|
||||
env->GetIsolate()->SetAutorunMicrotasks(true);
|
||||
env->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto);
|
||||
env->GetIsolate()->EnqueueMicrotask(
|
||||
Function::New(env.local(), MicrotaskTwo).ToLocalChecked());
|
||||
CompileRun("1+1;");
|
||||
@ -21125,7 +21129,7 @@ TEST(SetAutorunMicrotasks) {
|
||||
TEST(RunMicrotasksWithoutEnteringContext) {
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
HandleScope handle_scope(isolate);
|
||||
isolate->SetAutorunMicrotasks(false);
|
||||
isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
|
||||
Local<Context> context = Context::New(isolate);
|
||||
{
|
||||
Context::Scope context_scope(context);
|
||||
@ -21138,7 +21142,147 @@ TEST(RunMicrotasksWithoutEnteringContext) {
|
||||
Context::Scope context_scope(context);
|
||||
CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(context).FromJust());
|
||||
}
|
||||
isolate->SetAutorunMicrotasks(true);
|
||||
isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto);
|
||||
}
|
||||
|
||||
|
||||
TEST(ScopedMicrotasks) {
|
||||
LocalContext env;
|
||||
v8::HandleScope handles(env->GetIsolate());
|
||||
env->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kScoped);
|
||||
{
|
||||
v8::MicrotasksScope scope1(env->GetIsolate(),
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
env->GetIsolate()->EnqueueMicrotask(
|
||||
Function::New(env.local(), MicrotaskOne).ToLocalChecked());
|
||||
CompileRun(
|
||||
"var ext1Calls = 0;"
|
||||
"var ext2Calls = 0;");
|
||||
CompileRun("1+1;");
|
||||
CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
{
|
||||
v8::MicrotasksScope scope2(env->GetIsolate(),
|
||||
v8::MicrotasksScope::kRunMicrotasks);
|
||||
CompileRun("1+1;");
|
||||
CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
{
|
||||
v8::MicrotasksScope scope3(env->GetIsolate(),
|
||||
v8::MicrotasksScope::kRunMicrotasks);
|
||||
CompileRun("1+1;");
|
||||
CHECK_EQ(0,
|
||||
CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(0,
|
||||
CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
}
|
||||
CHECK_EQ(0, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
}
|
||||
CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
env->GetIsolate()->EnqueueMicrotask(
|
||||
Function::New(env.local(), MicrotaskTwo).ToLocalChecked());
|
||||
}
|
||||
|
||||
{
|
||||
v8::MicrotasksScope scope(env->GetIsolate(),
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
}
|
||||
|
||||
{
|
||||
v8::MicrotasksScope scope1(env->GetIsolate(),
|
||||
v8::MicrotasksScope::kRunMicrotasks);
|
||||
CompileRun("1+1;");
|
||||
CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
{
|
||||
v8::MicrotasksScope scope2(env->GetIsolate(),
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
}
|
||||
CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(0, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
}
|
||||
|
||||
{
|
||||
v8::MicrotasksScope scope(env->GetIsolate(),
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
env->GetIsolate()->EnqueueMicrotask(
|
||||
Function::New(env.local(), MicrotaskTwo).ToLocalChecked());
|
||||
}
|
||||
|
||||
{
|
||||
v8::Isolate::SuppressMicrotaskExecutionScope scope1(env->GetIsolate());
|
||||
{
|
||||
v8::MicrotasksScope scope2(env->GetIsolate(),
|
||||
v8::MicrotasksScope::kRunMicrotasks);
|
||||
}
|
||||
v8::MicrotasksScope scope3(env->GetIsolate(),
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
}
|
||||
|
||||
{
|
||||
v8::MicrotasksScope scope1(env->GetIsolate(),
|
||||
v8::MicrotasksScope::kRunMicrotasks);
|
||||
v8::MicrotasksScope::PerformCheckpoint(env->GetIsolate());
|
||||
CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(1, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
}
|
||||
|
||||
{
|
||||
v8::MicrotasksScope scope(env->GetIsolate(),
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
}
|
||||
|
||||
v8::MicrotasksScope::PerformCheckpoint(env->GetIsolate());
|
||||
|
||||
{
|
||||
v8::MicrotasksScope scope(env->GetIsolate(),
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(2, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
env->GetIsolate()->EnqueueMicrotask(
|
||||
Function::New(env.local(), MicrotaskTwo).ToLocalChecked());
|
||||
}
|
||||
|
||||
v8::MicrotasksScope::PerformCheckpoint(env->GetIsolate());
|
||||
|
||||
{
|
||||
v8::MicrotasksScope scope(env->GetIsolate(),
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
}
|
||||
|
||||
env->GetIsolate()->EnqueueMicrotask(
|
||||
Function::New(env.local(), MicrotaskOne).ToLocalChecked());
|
||||
{
|
||||
v8::Isolate::SuppressMicrotaskExecutionScope scope1(env->GetIsolate());
|
||||
v8::MicrotasksScope::PerformCheckpoint(env->GetIsolate());
|
||||
v8::MicrotasksScope scope2(env->GetIsolate(),
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
CHECK_EQ(1, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
}
|
||||
|
||||
v8::MicrotasksScope::PerformCheckpoint(env->GetIsolate());
|
||||
|
||||
{
|
||||
v8::MicrotasksScope scope(env->GetIsolate(),
|
||||
v8::MicrotasksScope::kDoNotRunMicrotasks);
|
||||
CHECK_EQ(2, CompileRun("ext1Calls")->Int32Value(env.local()).FromJust());
|
||||
CHECK_EQ(3, CompileRun("ext2Calls")->Int32Value(env.local()).FromJust());
|
||||
}
|
||||
|
||||
env->GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto);
|
||||
}
|
||||
|
||||
|
||||
@ -21161,7 +21305,7 @@ TEST(Regress385349) {
|
||||
i::FLAG_allow_natives_syntax = true;
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
HandleScope handle_scope(isolate);
|
||||
isolate->SetAutorunMicrotasks(false);
|
||||
isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
|
||||
Local<Context> context = Context::New(isolate);
|
||||
v8::Debug::SetDebugEventListener(isolate, DebugEventInObserver);
|
||||
{
|
||||
@ -21171,7 +21315,7 @@ TEST(Regress385349) {
|
||||
"obj.a = 0;");
|
||||
}
|
||||
isolate->RunMicrotasks();
|
||||
isolate->SetAutorunMicrotasks(true);
|
||||
isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto);
|
||||
v8::Debug::SetDebugEventListener(isolate, nullptr);
|
||||
}
|
||||
|
||||
|
@ -105,7 +105,7 @@ TEST(MicrotaskPerIsolateState) {
|
||||
HarmonyIsolate isolate;
|
||||
v8::HandleScope scope(isolate.GetIsolate());
|
||||
LocalContext context1(isolate.GetIsolate());
|
||||
isolate.GetIsolate()->SetAutorunMicrotasks(false);
|
||||
isolate.GetIsolate()->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
|
||||
CompileRun(
|
||||
"var obj = { calls: 0 };");
|
||||
v8::Local<v8::Value> obj = CompileRun("obj");
|
||||
|
@ -403,7 +403,7 @@ TEST(TerminateFromOtherThreadWhileMicrotaskRunning) {
|
||||
thread.Start();
|
||||
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
isolate->SetAutorunMicrotasks(false);
|
||||
isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Local<v8::ObjectTemplate> global =
|
||||
CreateGlobalTemplate(CcTest::isolate(), Signal, DoLoop);
|
||||
|
Loading…
Reference in New Issue
Block a user