Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Unified Diff: src/api.cc

Issue 1741893003: Introduce v8::MicrotasksScope. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Merged scopes Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/api.h ('K') | « src/api.h ('k') | src/isolate.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/api.cc
diff --git a/src/api.cc b/src/api.cc
index caa7d002f5fa43b2b4c3649febafbe64db704394..8f92929c959d826e35414fb81880d98c76a2ec03 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -75,17 +75,18 @@ namespace v8 {
#define ENTER_V8(isolate) i::VMState<v8::OTHER> __state__((isolate))
-#define PREPARE_FOR_EXECUTION_GENERIC(isolate, context, function_name, \
- bailout_value, HandleScopeClass, \
- do_callback) \
- if (IsExecutionTerminatingCheck(isolate)) { \
- return bailout_value; \
- } \
- TRACE_EVENT_SCOPED_CONTEXT("v8", "Isolate", isolate); \
- HandleScopeClass handle_scope(isolate); \
- CallDepthScope call_depth_scope(isolate, context, do_callback); \
- LOG_API(isolate, function_name); \
- ENTER_V8(isolate); \
+#define PREPARE_FOR_EXECUTION_GENERIC(isolate, context, function_name, \
+ bailout_value, HandleScopeClass, \
+ do_callback) \
+ if (IsExecutionTerminatingCheck(isolate)) { \
+ return bailout_value; \
+ } \
+ TRACE_EVENT_SCOPED_CONTEXT("v8", "Isolate", isolate); \
+ HandleScopeClass handle_scope(isolate); \
+ isolate->IncrementJsCallsFromApiCounter(); \
+ CallDepthScope call_depth_scope(isolate, context, do_callback, false);\
+ LOG_API(isolate, function_name); \
+ ENTER_V8(isolate); \
bool has_pending_exception = false
@@ -157,41 +158,92 @@ class InternalEscapableScope : public v8::EscapableHandleScope {
};
+inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
+ if (isolate->has_scheduled_exception()) {
+ return isolate->scheduled_exception() ==
+ isolate->heap()->termination_exception();
+ }
+ return false;
+}
+
+
class CallDepthScope {
public:
- explicit CallDepthScope(i::Isolate* isolate, Local<Context> context,
- bool do_callback)
+ CallDepthScope(i::Isolate* isolate,
+ Local<Context> context,
+ bool do_callback_and_microtasks,
+ bool is_external)
: isolate_(isolate),
context_(context),
- escaped_(false),
- do_callback_(do_callback) {
- // TODO(dcarney): remove this when blink stops crashing.
- DCHECK(!isolate_->external_caught_exception());
- isolate_->IncrementJsCallsFromApiCounter();
- isolate_->handle_scope_implementer()->IncrementCallDepth();
+ handle_exception_(!is_external),
+ do_callback_(do_callback_and_microtasks && !is_external) {
+ bool affects_microtasks = is_external ||
+ isolate_->handle_scope_implementer()->microtasks_policy() ==
+ i::kAutoMicrotasksInvocation;
+ run_microtasks_ = affects_microtasks && do_callback_and_microtasks;
+#ifdef V8_ENABLE_CHECKS
+ debug_microtasks_ = affects_microtasks && !do_callback_and_microtasks;
+#endif
+ auto handle_scope_implementer = isolate_->handle_scope_implementer();
+ if (handle_exception_) {
+ // TODO(dcarney): remove this when blink stops crashing.
+ DCHECK(!isolate_->external_caught_exception());
+ handle_scope_implementer->IncrementInternalCallDepth();
+ }
+ if (run_microtasks_) handle_scope_implementer->IncrementCallDepth();
+#ifdef V8_ENABLE_CHECKS
+ if (debug_microtasks_) handle_scope_implementer->IncrementDebugCallDepth();
+#endif
if (!context_.IsEmpty()) context_->Enter();
if (do_callback_) isolate_->FireBeforeCallEnteredCallback();
}
+
~CallDepthScope() {
if (!context_.IsEmpty()) context_->Exit();
- if (!escaped_) isolate_->handle_scope_implementer()->DecrementCallDepth();
+ auto handle_scope_implementer = isolate_->handle_scope_implementer();
+ if (handle_exception_)
+ handle_scope_implementer->DecrementInternalCallDepth();
if (do_callback_) isolate_->FireCallCompletedCallback();
+#ifdef V8_ENABLE_CHECKS
+ bool scoped_policy = handle_scope_implementer->microtasks_policy() ==
+ i::kScopedMicrotasksInvocation;
+ DCHECK(!(scoped_policy && do_callback_
+ && !handle_scope_implementer->GetCallDepth()
+ && !handle_scope_implementer->GetDebugCallDepth()));
+#endif
+ if (run_microtasks_) {
+ handle_scope_implementer->DecrementCallDepth();
+ PerformCheckpoint(isolate_);
+ }
+#ifdef V8_ENABLE_CHECKS
+ if (debug_microtasks_) handle_scope_implementer->DecrementDebugCallDepth();
+#endif
}
void Escape() {
- DCHECK(!escaped_);
- escaped_ = true;
+ DCHECK(handle_exception_);
+ handle_exception_ = false;
auto handle_scope_implementer = isolate_->handle_scope_implementer();
- handle_scope_implementer->DecrementCallDepth();
- bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero();
+ handle_scope_implementer->DecrementInternalCallDepth();
+ bool call_depth_is_zero = !handle_scope_implementer->GetInternalCallDepth();
isolate_->OptionalRescheduleException(call_depth_is_zero);
}
+ static void PerformCheckpoint(i::Isolate* isolate) {
+ if (IsExecutionTerminatingCheck(isolate)) return;
+ if (!isolate->handle_scope_implementer()->GetCallDepth() &&
+ !isolate->handle_scope_implementer()->GetMicrotasksSuppression()) {
+ isolate->RunMicrotasks();
+ }
+ }
+
private:
i::Isolate* const isolate_;
Local<Context> context_;
- bool escaped_;
+ bool handle_exception_;
bool do_callback_;
+ bool run_microtasks_;
+ bool debug_microtasks_;
};
} // namespace
@@ -310,15 +362,6 @@ void Utils::ReportApiFailure(const char* location, const char* message) {
}
-static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
- if (isolate->has_scheduled_exception()) {
- return isolate->scheduled_exception() ==
- isolate->heap()->termination_exception();
- }
- return false;
-}
-
-
void V8::SetNativesDataBlob(StartupData* natives_blob) {
i::V8::SetNativesBlob(natives_blob);
}
@@ -7290,12 +7333,12 @@ Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() {
Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
Isolate* isolate)
: isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
- isolate_->handle_scope_implementer()->IncrementCallDepth();
+ isolate_->handle_scope_implementer()->IncrementMicrotasksSuppression();
}
Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
- isolate_->handle_scope_implementer()->DecrementCallDepth();
+ isolate_->handle_scope_implementer()->DecrementMicrotasksSuppression();
}
@@ -7436,6 +7479,7 @@ void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
void Isolate::RunMicrotasks() {
+ DCHECK_EQ(Isolate::kExplicitMicrotasksInvocation, GetMicrotasksPolicy());
reinterpret_cast<i::Isolate*>(this)->RunMicrotasks();
}
@@ -7459,12 +7503,25 @@ void Isolate::EnqueueMicrotask(MicrotaskCallback microtask, void* data) {
void Isolate::SetAutorunMicrotasks(bool autorun) {
- reinterpret_cast<i::Isolate*>(this)->set_autorun_microtasks(autorun);
+ SetMicrotasksPolicy(kAutoMicrotasksInvocation);
}
bool Isolate::WillAutorunMicrotasks() const {
- return reinterpret_cast<const i::Isolate*>(this)->autorun_microtasks();
+ return GetMicrotasksPolicy() == kAutoMicrotasksInvocation;
+}
+
+
+void Isolate::SetMicrotasksPolicy(MicrotasksPolicy policy) {
+ reinterpret_cast<i::Isolate*>(this)->handle_scope_implementer()->
+ set_microtasks_policy(static_cast<i::MicrotasksPolicy>(policy));
+}
+
+
+Isolate::MicrotasksPolicy Isolate::GetMicrotasksPolicy() const {
+ return static_cast<MicrotasksPolicy>(
+ reinterpret_cast<i::Isolate*>(const_cast<Isolate*>(this))->
+ handle_scope_implementer()->microtasks_policy());
}
@@ -7703,6 +7760,33 @@ void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) {
}
+MicrotasksScope::MicrotasksScope(Isolate* isolate, MicrotasksScope::Type type) {
+ DCHECK_EQ(Isolate::kScopedMicrotasksInvocation,
+ isolate->GetMicrotasksPolicy());
+ internal_ = reinterpret_cast<void*>(new CallDepthScope(
adamk 2016/03/01 19:10:34 I'm a little bit worried about the added heap allo
dgozman 2016/03/03 01:22:06 I think this patch would be easier to understand w
+ reinterpret_cast<i::Isolate*>(isolate),
+ Local<Context>(),
+ type == MicrotasksScope::kRunMicrotasks,
+ true));
+}
+
+
+MicrotasksScope::~MicrotasksScope() {
+ delete reinterpret_cast<CallDepthScope*>(internal_);
+}
+
+
+void MicrotasksScope::PerformCheckpoint(Isolate* isolate) {
+ CallDepthScope::PerformCheckpoint(reinterpret_cast<i::Isolate*>(isolate));
+}
+
+
+int MicrotasksScope::GetRecursionLevel(Isolate* isolate) {
+ return reinterpret_cast<i::Isolate*>(isolate)->handle_scope_implementer()->
+ GetCallDepth();
+}
+
+
String::Utf8Value::Utf8Value(v8::Local<v8::Value> obj)
: str_(NULL), length_(0) {
if (obj.IsEmpty()) return;
« src/api.h ('K') | « src/api.h ('k') | src/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698