[inspector] Cache task template for async stack tagging API

This CL changes `scheduleTask` to use a cached ObjectTemplate to
create the JS task objects. Console creates the template lazily upon
first use.

A local micro benchmark that creates 100k task objects shows a
speedup of roughly 4x.

R=jarin@chromium.org

Bug: chromium:1334585
Change-Id: Ice037ad32836fe428b1bcbee15738cb17877a3dd
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3779496
Commit-Queue: Simon Zünd <szuend@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81906}
This commit is contained in:
Simon Zünd 2022-07-25 08:16:18 +02:00 committed by V8 LUCI CQ
parent b838f9dedf
commit 655e76b4f6
2 changed files with 30 additions and 7 deletions

View File

@ -594,13 +594,9 @@ void V8Console::scheduleTask(const v8::FunctionCallbackInfo<v8::Value>& info) {
return;
}
v8::Local<v8::External> data = v8::External::New(isolate, this);
v8::Local<v8::ObjectTemplate> taskTemplate = v8::ObjectTemplate::New(isolate);
v8::Local<v8::FunctionTemplate> funcTemplate = v8::FunctionTemplate::New(
isolate, &V8Console::call<&V8Console::runTask>, data);
taskTemplate->Set(isolate, "run", funcTemplate);
v8::Local<v8::Object> task =
taskTemplate->NewInstance(isolate->GetCurrentContext()).ToLocalChecked();
v8::Local<v8::Object> task = taskTemplate()
->NewInstance(isolate->GetCurrentContext())
.ToLocalChecked();
auto taskInfo = std::make_unique<TaskInfo>(isolate, this, task);
void* taskId = taskInfo->Id();
@ -657,6 +653,22 @@ v8::Local<v8::Private> V8Console::taskInfoKey() {
return m_taskInfoKey.Get(isolate);
}
v8::Local<v8::ObjectTemplate> V8Console::taskTemplate() {
v8::Isolate* isolate = m_inspector->isolate();
if (!m_taskTemplate.IsEmpty()) {
return m_taskTemplate.Get(isolate);
}
v8::Local<v8::External> data = v8::External::New(isolate, this);
v8::Local<v8::ObjectTemplate> taskTemplate = v8::ObjectTemplate::New(isolate);
v8::Local<v8::FunctionTemplate> funcTemplate = v8::FunctionTemplate::New(
isolate, &V8Console::call<&V8Console::runTask>, data);
taskTemplate->Set(isolate, "run", funcTemplate);
m_taskTemplate.Reset(isolate, taskTemplate);
return taskTemplate;
}
void V8Console::cancelConsoleTask(TaskInfo* taskInfo) {
m_inspector->asyncTaskCanceled(taskInfo->Id());
m_tasks.erase(taskInfo->Id());

View File

@ -14,6 +14,7 @@
#include "src/debug/interface-types.h"
namespace v8 {
class ObjectTemplate;
class Set;
} // namespace v8
@ -201,6 +202,11 @@ class V8Console : public v8::debug::ConsoleDelegate {
// Chromium's context snapshot.
v8::Local<v8::Private> taskInfoKey();
// Lazily creates m_taskTemplate and returns a local handle to it.
// Similarly to m_taskInfoKey, we can't create the template upfront as to not
// be part of Chromium's context snapshot.
v8::Local<v8::ObjectTemplate> taskTemplate();
V8InspectorImpl* m_inspector;
// A map of unique pointers used for the scheduling and joining async stacks.
@ -218,6 +224,11 @@ class V8Console : public v8::debug::ConsoleDelegate {
// We use a private symbol to stash the `TaskInfo` as an v8::External on the
// JS task objects created by `console.scheduleTask`.
v8::Global<v8::Private> m_taskInfoKey;
// We cache the task template for the async stack tagging API for faster
// instantiation. Use `taskTemplate()` to retrieve the lazily created
// template.
v8::Global<v8::ObjectTemplate> m_taskTemplate;
};
/**