Skip to content

Commit

Permalink
Let the embedder control pending tasks
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarred-Sumner committed Jul 22, 2023
1 parent 770ebc9 commit ecf1b9c
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 9 deletions.
20 changes: 17 additions & 3 deletions Source/JavaScriptCore/runtime/DeferredWorkTimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ void DeferredWorkTimer::runRunLoop()
RunLoop::run();
}

DeferredWorkTimer::Ticket DeferredWorkTimer::addPendingWork(VM& vm, JSObject* target, Vector<Strong<JSCell>>&& dependencies)
DeferredWorkTimer::Ticket DeferredWorkTimer::addPendingWork(VM& vm, JSObject* target, Vector<Strong<JSCell>>&& dependencies, WorkKind workKind)
{
ASSERT(vm.currentThreadIsHoldingAPILock() || (Thread::mayBeGCThread() && vm.heap.worldIsStopped()));
for (unsigned i = 0; i < dependencies.size(); ++i)
Expand All @@ -166,8 +166,13 @@ DeferredWorkTimer::Ticket DeferredWorkTimer::addPendingWork(VM& vm, JSObject* ta
Ticket ticket = ticketData.get();

dataLogLnIf(DeferredWorkTimerInternal::verbose, "Adding new pending ticket: ", RawPointer(ticket));
auto result = m_pendingTickets.add(WTFMove(ticketData));
RELEASE_ASSERT(result.isNewEntry);
if (onAddPendingWork) {
onAddPendingWork(WTFMove(ticketData), workKind);
} else {
auto result = m_pendingTickets.add(WTFMove(ticketData));
RELEASE_ASSERT(result.isNewEntry);
}


return ticket;
}
Expand All @@ -192,6 +197,11 @@ bool DeferredWorkTimer::hasDependancyInPendingWork(Ticket ticket, JSCell* depend

void DeferredWorkTimer::scheduleWorkSoon(Ticket ticket, Task&& task)
{
if (onScheduleWorkSoon) {
onScheduleWorkSoon(ticket, WTFMove(task));
return;
}

Locker locker { m_taskLock };
m_tasks.append(std::make_tuple(ticket, WTFMove(task)));
if (!isScheduled() && !m_currentlyRunningTask)
Expand All @@ -210,6 +220,10 @@ bool DeferredWorkTimer::cancelPendingWork(Ticket ticket)
result = true;
}

if (onCancelPendingWork) {
onCancelPendingWork(ticket);
}

return result;
}

Expand Down
12 changes: 11 additions & 1 deletion Source/JavaScriptCore/runtime/DeferredWorkTimer.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ class JS_EXPORT_PRIVATE DeferredWorkTimer final : public JSRunLoopTimer {
public:
using Base = JSRunLoopTimer;

enum class WorkKind : uint8_t {
Other,
Atomics,
WebAssembly,
};

struct TicketData {
private:
WTF_MAKE_FAST_ALLOCATED;
Expand All @@ -65,7 +71,7 @@ class JS_EXPORT_PRIVATE DeferredWorkTimer final : public JSRunLoopTimer {

void doWork(VM&) final;

Ticket addPendingWork(VM&, JSObject* target, Vector<Strong<JSCell>>&& dependencies);
Ticket addPendingWork(VM&, JSObject* target, Vector<Strong<JSCell>>&& dependencies, WorkKind kind = WorkKind::Other);
bool hasPendingWork(Ticket);
bool hasDependancyInPendingWork(Ticket, JSCell* dependency);
bool cancelPendingWork(Ticket);
Expand All @@ -83,6 +89,10 @@ class JS_EXPORT_PRIVATE DeferredWorkTimer final : public JSRunLoopTimer {
void runRunLoop();

static Ref<DeferredWorkTimer> create(VM& vm) { return adoptRef(*new DeferredWorkTimer(vm)); }

WTF::Function<void(std::unique_ptr<TicketData>, WorkKind)> onAddPendingWork;
WTF::Function<void(Ticket, Task&&)> onScheduleWorkSoon;
WTF::Function<void(Ticket)> onCancelPendingWork;
private:
DeferredWorkTimer(VM&);

Expand Down
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/runtime/WaiterListManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class Waiter final : public WTF::BasicRawSentinelNode<Waiter>, public ThreadSafe

Waiter(JSPromise* promise)
: m_vm(&promise->vm())
, m_ticket(m_vm->deferredWorkTimer->addPendingWork(*m_vm, promise, { }))
, m_ticket(m_vm->deferredWorkTimer->addPendingWork(*m_vm, promise, { }, DeferredWorkTimer::WorkKind::Atomics))
, m_isAsync(true)
{
}
Expand Down
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/wasm/WasmStreamingCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ StreamingCompiler::StreamingCompiler(VM& vm, CompilerMode compilerMode, JSGlobal
dependencies.append(Strong<JSCell>(vm, globalObject));
if (importObject)
dependencies.append(Strong<JSCell>(vm, importObject));
m_ticket = vm.deferredWorkTimer->addPendingWork(vm, promise, WTFMove(dependencies));
m_ticket = vm.deferredWorkTimer->addPendingWork(vm, promise, WTFMove(dependencies), DeferredWorkTimer::WorkKind::WebAssembly);
ASSERT(vm.deferredWorkTimer->hasPendingWork(m_ticket));
ASSERT(vm.deferredWorkTimer->hasDependancyInPendingWork(m_ticket, globalObject));
ASSERT(!importObject || vm.deferredWorkTimer->hasDependancyInPendingWork(m_ticket, importObject));
Expand Down
6 changes: 3 additions & 3 deletions Source/JavaScriptCore/wasm/js/JSWebAssembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ void JSWebAssembly::webAssemblyModuleValidateAsync(JSGlobalObject* globalObject,
Vector<Strong<JSCell>> dependencies;
dependencies.append(Strong<JSCell>(vm, globalObject));

auto ticket = vm.deferredWorkTimer->addPendingWork(vm, promise, WTFMove(dependencies));
auto ticket = vm.deferredWorkTimer->addPendingWork(vm, promise, WTFMove(dependencies), DeferredWorkTimer::WorkKind::WebAssembly);
Wasm::Module::validateAsync(vm, WTFMove(source), createSharedTask<Wasm::Module::CallbackType>([ticket, promise, globalObject, &vm] (Wasm::Module::ValidationResult&& result) mutable {
vm.deferredWorkTimer->scheduleWorkSoon(ticket, [promise, globalObject, result = WTFMove(result), &vm](DeferredWorkTimer::Ticket) mutable {
auto scope = DECLARE_THROW_SCOPE(vm);
Expand Down Expand Up @@ -186,7 +186,7 @@ static void instantiate(VM& vm, JSGlobalObject* globalObject, JSPromise* promise
dependencies.append(Strong<JSCell>(vm, promise));

scope.release();
auto ticket = vm.deferredWorkTimer->addPendingWork(vm, instance, WTFMove(dependencies));
auto ticket = vm.deferredWorkTimer->addPendingWork(vm, instance, WTFMove(dependencies), DeferredWorkTimer::WorkKind::WebAssembly);
// Note: This completion task may or may not get called immediately.
module->module().compileAsync(vm, instance->memoryMode(), createSharedTask<Wasm::CalleeGroup::CallbackType>([ticket, promise, instance, module, resolveKind, creationMode, &vm] (Ref<Wasm::CalleeGroup>&& refCalleeGroup) mutable {
RefPtr<Wasm::CalleeGroup> calleeGroup = WTFMove(refCalleeGroup);
Expand Down Expand Up @@ -238,7 +238,7 @@ static void compileAndInstantiate(VM& vm, JSGlobalObject* globalObject, JSPromis
Vector<Strong<JSCell>> dependencies;
dependencies.append(Strong<JSCell>(vm, importObject));
dependencies.append(Strong<JSCell>(vm, moduleKeyCell));
auto ticket = vm.deferredWorkTimer->addPendingWork(vm, promise, WTFMove(dependencies));
auto ticket = vm.deferredWorkTimer->addPendingWork(vm, promise, WTFMove(dependencies), DeferredWorkTimer::WorkKind::WebAssembly);
Wasm::Module::validateAsync(vm, WTFMove(source), createSharedTask<Wasm::Module::CallbackType>([ticket, promise, importObject, moduleKeyCell, globalObject, resolveKind, creationMode, &vm] (Wasm::Module::ValidationResult&& result) mutable {
vm.deferredWorkTimer->scheduleWorkSoon(ticket, [promise, importObject, moduleKeyCell, globalObject, result = WTFMove(result), resolveKind, creationMode, &vm](DeferredWorkTimer::Ticket) mutable {
auto scope = DECLARE_THROW_SCOPE(vm);
Expand Down

0 comments on commit ecf1b9c

Please sign in to comment.