[runtime][microtask] Various smaller performance tweaks
- Make sure we use fast prechecks in the header files - MicrotaskQueue::CallEnqueueMicrotask returns a Smi instead of a more costly undefined value (the return value is enforced by the calling convention, but unused) - Merge FireMicrotasksCompletedCallback into OnComplete Change-Id: I3797b946bcffb6349e5693c41478bd2bad1f93fb Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3024154 Commit-Queue: Camillo Bruni <cbruni@chromium.org> Reviewed-by: Victor Gomes <victorgomes@chromium.org> Cr-Commit-Position: refs/heads/master@{#75985}
This commit is contained in:
parent
02ba58d59d
commit
1d249e8cb4
@ -4212,8 +4212,9 @@ void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
|
||||
call_completed_callbacks_.erase(pos);
|
||||
}
|
||||
|
||||
void Isolate::FireCallCompletedCallback(MicrotaskQueue* microtask_queue) {
|
||||
if (!thread_local_top()->CallDepthIsZero()) return;
|
||||
void Isolate::FireCallCompletedCallbackInternal(
|
||||
MicrotaskQueue* microtask_queue) {
|
||||
DCHECK(thread_local_top()->CallDepthIsZero());
|
||||
|
||||
bool perform_checkpoint =
|
||||
microtask_queue &&
|
||||
|
@ -1452,7 +1452,10 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
|
||||
size_t heap_limit);
|
||||
void AddCallCompletedCallback(CallCompletedCallback callback);
|
||||
void RemoveCallCompletedCallback(CallCompletedCallback callback);
|
||||
void FireCallCompletedCallback(MicrotaskQueue* microtask_queue);
|
||||
void FireCallCompletedCallback(MicrotaskQueue* microtask_queue) {
|
||||
if (!thread_local_top()->CallDepthIsZero()) return;
|
||||
FireCallCompletedCallbackInternal(microtask_queue);
|
||||
}
|
||||
|
||||
void AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback);
|
||||
void RemoveBeforeCallEnteredCallback(BeforeCallEnteredCallback callback);
|
||||
@ -1830,6 +1833,8 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
|
||||
|
||||
static void RemoveContextIdCallback(const v8::WeakCallbackInfo<void>& data);
|
||||
|
||||
void FireCallCompletedCallbackInternal(MicrotaskQueue* microtask_queue);
|
||||
|
||||
class ThreadDataTable {
|
||||
public:
|
||||
ThreadDataTable() = default;
|
||||
|
@ -74,7 +74,7 @@ Address MicrotaskQueue::CallEnqueueMicrotask(Isolate* isolate,
|
||||
Microtask microtask = Microtask::cast(Object(raw_microtask));
|
||||
reinterpret_cast<MicrotaskQueue*>(microtask_queue_pointer)
|
||||
->EnqueueMicrotask(microtask);
|
||||
return ReadOnlyRoots(isolate).undefined_value().ptr();
|
||||
return Smi::zero().ptr();
|
||||
}
|
||||
|
||||
void MicrotaskQueue::EnqueueMicrotask(v8::Isolate* v8_isolate,
|
||||
@ -110,23 +110,21 @@ void MicrotaskQueue::EnqueueMicrotask(Microtask microtask) {
|
||||
++size_;
|
||||
}
|
||||
|
||||
void MicrotaskQueue::PerformCheckpoint(v8::Isolate* v8_isolate) {
|
||||
if (!IsRunningMicrotasks() && !GetMicrotasksScopeDepth() &&
|
||||
!HasMicrotasksSuppressions()) {
|
||||
std::unique_ptr<MicrotasksScope> microtasks_scope;
|
||||
if (microtasks_policy_ == v8::MicrotasksPolicy::kScoped) {
|
||||
// If we're using microtask scopes to schedule microtask execution, V8
|
||||
// API calls will check that there's always a microtask scope on the
|
||||
// stack. As the microtasks we're about to execute could invoke embedder
|
||||
// callbacks which then calls back into V8, we create an artificial
|
||||
// microtask scope here to avoid running into the CallDepthScope check.
|
||||
microtasks_scope.reset(new v8::MicrotasksScope(
|
||||
v8_isolate, this, v8::MicrotasksScope::kDoNotRunMicrotasks));
|
||||
}
|
||||
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
|
||||
RunMicrotasks(isolate);
|
||||
isolate->ClearKeptObjects();
|
||||
void MicrotaskQueue::PerformCheckpointInternal(v8::Isolate* v8_isolate) {
|
||||
DCHECK(ShouldPerfomCheckpoint());
|
||||
std::unique_ptr<MicrotasksScope> microtasks_scope;
|
||||
if (microtasks_policy_ == v8::MicrotasksPolicy::kScoped) {
|
||||
// If we're using microtask scopes to schedule microtask execution, V8
|
||||
// API calls will check that there's always a microtask scope on the
|
||||
// stack. As the microtasks we're about to execute could invoke embedder
|
||||
// callbacks which then calls back into V8, we create an artificial
|
||||
// microtask scope here to avoid running into the CallDepthScope check.
|
||||
microtasks_scope.reset(new v8::MicrotasksScope(
|
||||
v8_isolate, this, v8::MicrotasksScope::kDoNotRunMicrotasks));
|
||||
}
|
||||
Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
|
||||
RunMicrotasks(isolate);
|
||||
isolate->ClearKeptObjects();
|
||||
}
|
||||
|
||||
namespace {
|
||||
@ -226,10 +224,6 @@ void MicrotaskQueue::IterateMicrotasks(RootVisitor* visitor) {
|
||||
}
|
||||
}
|
||||
|
||||
int MicrotaskQueue::GetMicrotasksScopeDepth() const {
|
||||
return microtasks_depth_;
|
||||
}
|
||||
|
||||
void MicrotaskQueue::AddMicrotasksCompletedCallback(
|
||||
MicrotasksCompletedCallbackWithData callback, void* data) {
|
||||
CallbackWithData callback_with_data(callback, data);
|
||||
@ -250,7 +244,7 @@ void MicrotaskQueue::RemoveMicrotasksCompletedCallback(
|
||||
microtasks_completed_callbacks_.erase(pos);
|
||||
}
|
||||
|
||||
void MicrotaskQueue::FireMicrotasksCompletedCallback(Isolate* isolate) const {
|
||||
void MicrotaskQueue::OnCompleted(Isolate* isolate) const {
|
||||
std::vector<CallbackWithData> callbacks(microtasks_completed_callbacks_);
|
||||
for (auto& callback : callbacks) {
|
||||
callback.first(reinterpret_cast<v8::Isolate*>(isolate), callback.second);
|
||||
@ -263,10 +257,6 @@ Microtask MicrotaskQueue::get(intptr_t index) const {
|
||||
return Microtask::cast(microtask);
|
||||
}
|
||||
|
||||
void MicrotaskQueue::OnCompleted(Isolate* isolate) {
|
||||
FireMicrotasksCompletedCallback(isolate);
|
||||
}
|
||||
|
||||
void MicrotaskQueue::ResizeBuffer(intptr_t new_capacity) {
|
||||
DCHECK_LE(size_, new_capacity);
|
||||
Address* new_ring_buffer = new Address[new_capacity];
|
||||
|
@ -30,7 +30,7 @@ class V8_EXPORT_PRIVATE MicrotaskQueue final : public v8::MicrotaskQueue {
|
||||
|
||||
// Uses raw Address values because it's called via ExternalReference.
|
||||
// {raw_microtask} is a tagged Microtask pointer.
|
||||
// Returns a tagged Object pointer.
|
||||
// Returns Smi::kZero due to CallCFunction.
|
||||
static Address CallEnqueueMicrotask(Isolate* isolate,
|
||||
intptr_t microtask_queue_pointer,
|
||||
Address raw_microtask);
|
||||
@ -40,7 +40,15 @@ class V8_EXPORT_PRIVATE MicrotaskQueue final : public v8::MicrotaskQueue {
|
||||
v8::Local<Function> microtask) override;
|
||||
void EnqueueMicrotask(v8::Isolate* isolate, v8::MicrotaskCallback callback,
|
||||
void* data) override;
|
||||
void PerformCheckpoint(v8::Isolate* isolate) override;
|
||||
void PerformCheckpoint(v8::Isolate* isolate) override {
|
||||
if (!ShouldPerfomCheckpoint()) return;
|
||||
PerformCheckpointInternal(isolate);
|
||||
}
|
||||
|
||||
bool ShouldPerfomCheckpoint() const {
|
||||
return !IsRunningMicrotasks() && !GetMicrotasksScopeDepth() &&
|
||||
!HasMicrotasksSuppressions();
|
||||
}
|
||||
|
||||
void EnqueueMicrotask(Microtask microtask);
|
||||
void AddMicrotasksCompletedCallback(
|
||||
@ -62,7 +70,7 @@ class V8_EXPORT_PRIVATE MicrotaskQueue final : public v8::MicrotaskQueue {
|
||||
// invocation, which happens when depth reaches zero.
|
||||
void IncrementMicrotasksScopeDepth() { ++microtasks_depth_; }
|
||||
void DecrementMicrotasksScopeDepth() { --microtasks_depth_; }
|
||||
int GetMicrotasksScopeDepth() const override;
|
||||
int GetMicrotasksScopeDepth() const override { return microtasks_depth_; }
|
||||
|
||||
// Possibly nested microtasks suppression scopes prevent microtasks
|
||||
// from running.
|
||||
@ -87,8 +95,6 @@ class V8_EXPORT_PRIVATE MicrotaskQueue final : public v8::MicrotaskQueue {
|
||||
}
|
||||
v8::MicrotasksPolicy microtasks_policy() const { return microtasks_policy_; }
|
||||
|
||||
void FireMicrotasksCompletedCallback(Isolate* isolate) const;
|
||||
|
||||
intptr_t capacity() const { return capacity_; }
|
||||
intptr_t size() const { return size_; }
|
||||
intptr_t start() const { return start_; }
|
||||
@ -107,7 +113,9 @@ class V8_EXPORT_PRIVATE MicrotaskQueue final : public v8::MicrotaskQueue {
|
||||
static const intptr_t kMinimumCapacity;
|
||||
|
||||
private:
|
||||
void OnCompleted(Isolate* isolate);
|
||||
void PerformCheckpointInternal(v8::Isolate* v8_isolate);
|
||||
|
||||
void OnCompleted(Isolate* isolate) const;
|
||||
|
||||
MicrotaskQueue();
|
||||
void ResizeBuffer(intptr_t new_capacity);
|
||||
|
Loading…
Reference in New Issue
Block a user