aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/microtask-queue.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/microtask-queue.cc')
-rw-r--r--deps/v8/src/microtask-queue.cc73
1 files changed, 59 insertions, 14 deletions
diff --git a/deps/v8/src/microtask-queue.cc b/deps/v8/src/microtask-queue.cc
index 5010b0bc25..4b8b0410c6 100644
--- a/deps/v8/src/microtask-queue.cc
+++ b/deps/v8/src/microtask-queue.cc
@@ -7,7 +7,7 @@
#include <stddef.h>
#include <algorithm>
-#include "src/api.h"
+#include "src/api-inl.h"
#include "src/base/logging.h"
#include "src/handles-inl.h"
#include "src/isolate.h"
@@ -25,6 +25,8 @@ const size_t MicrotaskQueue::kCapacityOffset =
OFFSET_OF(MicrotaskQueue, capacity_);
const size_t MicrotaskQueue::kSizeOffset = OFFSET_OF(MicrotaskQueue, size_);
const size_t MicrotaskQueue::kStartOffset = OFFSET_OF(MicrotaskQueue, start_);
+const size_t MicrotaskQueue::kFinishedMicrotaskCountOffset =
+ OFFSET_OF(MicrotaskQueue, finished_microtask_count_);
const intptr_t MicrotaskQueue::kMinimumCapacity = 8;
@@ -75,6 +77,26 @@ Address MicrotaskQueue::CallEnqueueMicrotask(Isolate* isolate,
return ReadOnlyRoots(isolate).undefined_value().ptr();
}
+void MicrotaskQueue::EnqueueMicrotask(v8::Isolate* v8_isolate,
+ v8::Local<Function> function) {
+ Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
+ HandleScope scope(isolate);
+ Handle<CallableTask> microtask = isolate->factory()->NewCallableTask(
+ Utils::OpenHandle(*function), isolate->native_context());
+ EnqueueMicrotask(*microtask);
+}
+
+void MicrotaskQueue::EnqueueMicrotask(v8::Isolate* v8_isolate,
+ v8::MicrotaskCallback callback,
+ void* data) {
+ Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
+ HandleScope scope(isolate);
+ Handle<CallbackTask> microtask = isolate->factory()->NewCallbackTask(
+ isolate->factory()->NewForeign(reinterpret_cast<Address>(callback)),
+ isolate->factory()->NewForeign(reinterpret_cast<Address>(data)));
+ EnqueueMicrotask(*microtask);
+}
+
void MicrotaskQueue::EnqueueMicrotask(Microtask microtask) {
if (size_ == capacity_) {
// Keep the capacity of |ring_buffer_| power of 2, so that the JIT
@@ -88,6 +110,14 @@ void MicrotaskQueue::EnqueueMicrotask(Microtask microtask) {
++size_;
}
+void MicrotaskQueue::PerformCheckpoint(v8::Isolate* v8_isolate) {
+ if (!IsRunningMicrotasks() && !GetMicrotasksScopeDepth() &&
+ !HasMicrotasksSuppressions()) {
+ Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
+ RunMicrotasks(isolate);
+ }
+}
+
namespace {
class SetIsRunningMicrotasks {
@@ -114,20 +144,27 @@ int MicrotaskQueue::RunMicrotasks(Isolate* isolate) {
return 0;
}
+ intptr_t base_count = finished_microtask_count_;
+
HandleScope handle_scope(isolate);
MaybeHandle<Object> maybe_exception;
MaybeHandle<Object> maybe_result;
+ int processed_microtask_count;
{
SetIsRunningMicrotasks scope(&is_running_microtasks_);
v8::Isolate::SuppressMicrotaskExecutionScope suppress(
reinterpret_cast<v8::Isolate*>(isolate));
HandleScopeImplementer::EnteredContextRewindScope rewind_scope(
isolate->handle_scope_implementer());
- TRACE_EVENT0("v8.execute", "RunMicrotasks");
+ TRACE_EVENT_BEGIN0("v8.execute", "RunMicrotasks");
TRACE_EVENT_CALL_STATS_SCOPED(isolate, "v8", "V8.RunMicrotasks");
maybe_result = Execution::TryRunMicrotasks(isolate, this, &maybe_exception);
+ processed_microtask_count =
+ static_cast<int>(finished_microtask_count_ - base_count);
+ TRACE_EVENT_END1("v8.execute", "RunMicrotasks", "microtask_count",
+ processed_microtask_count);
}
// If execution is terminating, clean up and propagate that to TryCatch scope.
@@ -144,8 +181,7 @@ int MicrotaskQueue::RunMicrotasks(Isolate* isolate) {
DCHECK_EQ(0, size());
OnCompleted(isolate);
- // TODO(tzik): Return the number of microtasks run in this round.
- return 0;
+ return processed_microtask_count;
}
void MicrotaskQueue::IterateMicrotasks(RootVisitor* visitor) {
@@ -176,29 +212,38 @@ void MicrotaskQueue::IterateMicrotasks(RootVisitor* visitor) {
}
void MicrotaskQueue::AddMicrotasksCompletedCallback(
- MicrotasksCompletedCallback callback) {
- auto pos = std::find(microtasks_completed_callbacks_.begin(),
- microtasks_completed_callbacks_.end(), callback);
+ MicrotasksCompletedCallbackWithData callback, void* data) {
+ CallbackWithData callback_with_data(callback, data);
+ auto pos =
+ std::find(microtasks_completed_callbacks_.begin(),
+ microtasks_completed_callbacks_.end(), callback_with_data);
if (pos != microtasks_completed_callbacks_.end()) return;
- microtasks_completed_callbacks_.push_back(callback);
+ microtasks_completed_callbacks_.push_back(callback_with_data);
}
void MicrotaskQueue::RemoveMicrotasksCompletedCallback(
- MicrotasksCompletedCallback callback) {
- auto pos = std::find(microtasks_completed_callbacks_.begin(),
- microtasks_completed_callbacks_.end(), callback);
+ MicrotasksCompletedCallbackWithData callback, void* data) {
+ CallbackWithData callback_with_data(callback, data);
+ auto pos =
+ std::find(microtasks_completed_callbacks_.begin(),
+ microtasks_completed_callbacks_.end(), callback_with_data);
if (pos == microtasks_completed_callbacks_.end()) return;
microtasks_completed_callbacks_.erase(pos);
}
void MicrotaskQueue::FireMicrotasksCompletedCallback(Isolate* isolate) const {
- std::vector<MicrotasksCompletedCallback> callbacks(
- microtasks_completed_callbacks_);
+ std::vector<CallbackWithData> callbacks(microtasks_completed_callbacks_);
for (auto& callback : callbacks) {
- callback(reinterpret_cast<v8::Isolate*>(isolate));
+ callback.first(reinterpret_cast<v8::Isolate*>(isolate), callback.second);
}
}
+Microtask MicrotaskQueue::get(intptr_t index) const {
+ DCHECK_LT(index, size_);
+ Object microtask(ring_buffer_[(index + start_) % capacity_]);
+ return Microtask::cast(microtask);
+}
+
void MicrotaskQueue::OnCompleted(Isolate* isolate) {
// TODO(marja): (spec) The discussion about when to clear the KeepDuringJob
// set is still open (whether to clear it after every microtask or once