Changeset 287421 in webkit
- Timestamp:
- Dec 23, 2021, 9:58:47 PM (5 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 9 edited
-
ChangeLog (modified) (1 diff)
-
jsc.cpp (modified) (1 diff)
-
runtime/DeferredWorkTimer.cpp (modified) (9 diffs)
-
runtime/DeferredWorkTimer.h (modified) (5 diffs)
-
runtime/JSFinalizationRegistry.cpp (modified) (1 diff)
-
runtime/JSFinalizationRegistry.h (modified) (1 diff)
-
wasm/WasmStreamingCompiler.cpp (modified) (7 diffs)
-
wasm/WasmStreamingCompiler.h (modified) (2 diffs)
-
wasm/js/JSWebAssembly.cpp (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r287379 r287421 1 2021-12-23 Mark Lam <mark.lam@apple.com> 2 3 Make DeferredWorkTimer::addPendingWork() return a Ticket. 4 https://bugs.webkit.org/show_bug.cgi?id=234628 5 rdar://84260429 6 7 Reviewed by Yusuke Suzuki. 8 9 1. Make Ticket a unique token instead of the JSObject* target object. 10 The Ticket is now a pointer to the TicketData in the pending work list. 11 12 2. Instead of taking a Ticket argument, DeferredWorkTimer::addPendingWork() now 13 takes a JSObject* `target` argument explicitly, and returns the Ticket for the 14 added TicketData instead. 15 16 All the relevant DeferredWorkTimer APIS already take a Ticket as an argument. 17 This ensures that addPendingWork() is called before we start doing work with 18 these APIs (especially scheduleWorkSoon()). 19 20 3. Previously, addPendingWork() will only save one instance of TicketData for 21 a given JSObject* key. With this patch, we'll register a new TicketData 22 instance for every call to addPendingWork(), and return a unique Ticket for it. 23 24 This is needed because it may be possible for 2 different clients to call 25 addPendingWork() and scheduleWorkSoon() with the same target JSObject* but with 26 different sets of dependencies. 27 28 Secondly, even is the both sets of dependencies are identical, a client may 29 call addPendingWork() and scheduleWorkSoon() with the same JSObject* target 30 more than once because it intended to schedule more than 1 task to run. 31 32 Note that DeferredWorkTimer::doWork() consumes the corresponding TicketData 33 (i.e. removes it from the m_pendingTickets list) for each task as it is run. 34 To ensure that the dependencies for each task is protected, we'll either need 35 to ref count the TicketData for the same target object (and hold off on removing 36 it from the list), or we'll need to register a different TicketData instance 37 for each task. Ref counting can solve the second issue above, but does not 38 solve the first. So, this patch goes with the more generic solution to allow 39 each task to have its own TicketData instance (and, its own unique Ticket). 40 41 4. Previously, if the client cancels pending work, we would remove the TicketData 42 immediately from the m_pendingTickets list. This opens up an opportunity for 43 the same TicketData memory to be re-allocated by another client. This, in turn, 44 would make the Ticket token not unique and potentially allow a cancelled ticket 45 to be reused before DeferredWorkTimer::doWork() is called. 46 47 This patch changes DeferredWorkTimer::cancelPendingWork() to only clear the 48 contents of the TicketData instead. TicketData::scriptExecutionOwner being 49 null is used as an indication that the ticket has been cancelled. Since the 50 TicketData itself is not "freed" yet, all TicketData will remain unique until 51 DeferredWorkTimer::doWork(). 52 53 Consequently, DeferredWorkTimer::doWork() will now check for cancelled tickets 54 and remove them from the m_pendingTickets list. 55 56 5. JSFinalizationRegistry was previously calling DeferredWorkTimer::hasPendingWork() 57 to check if it has already scheduled a task, so as not to reschedule again until 58 after the previously scheduled task has been run. This does not play nice 59 with the new Ticket API, because this hasPendingWork() check needs to be done 60 before calling addPendingWork(), and hence, the Ticket is not available yet. 61 62 Fortunately, JSFinalizationRegistry should know if it has already scheduled 63 a task itself. This patch adds a m_hasAlreadyScheduledWork flag to 64 JSFinalizationRegistry that can be used for this check instead. 65 66 * jsc.cpp: 67 (JSC_DEFINE_HOST_FUNCTION): 68 * runtime/DeferredWorkTimer.cpp: 69 (JSC::DeferredWorkTimer::TicketData::TicketData): 70 (JSC::DeferredWorkTimer::TicketData::vm): 71 (JSC::DeferredWorkTimer::TicketData::cancel): 72 (JSC::DeferredWorkTimer::doWork): 73 (JSC::DeferredWorkTimer::addPendingWork): 74 (JSC::DeferredWorkTimer::hasPendingWork): 75 (JSC::DeferredWorkTimer::hasDependancyInPendingWork): 76 (JSC::DeferredWorkTimer::cancelPendingWork): 77 * runtime/DeferredWorkTimer.h: 78 (JSC::DeferredWorkTimer::TicketData::target): 79 * runtime/JSFinalizationRegistry.cpp: 80 (JSC::JSFinalizationRegistry::finalizeUnconditionally): 81 * runtime/JSFinalizationRegistry.h: 82 * wasm/WasmStreamingCompiler.cpp: 83 (JSC::Wasm::StreamingCompiler::StreamingCompiler): 84 (JSC::Wasm::StreamingCompiler::~StreamingCompiler): 85 (JSC::Wasm::StreamingCompiler::didComplete): 86 (JSC::Wasm::StreamingCompiler::fail): 87 (JSC::Wasm::StreamingCompiler::cancel): 88 * wasm/WasmStreamingCompiler.h: 89 * wasm/js/JSWebAssembly.cpp: 90 (JSC::JSWebAssembly::webAssemblyModuleValidateAsync): 91 (JSC::instantiate): 92 (JSC::compileAndInstantiate): 93 (JSC::JSWebAssembly::webAssemblyModuleInstantinateAsync): 94 1 95 2021-12-22 Saam Barati <sbarati@apple.com> 2 96 -
trunk/Source/JavaScriptCore/jsc.cpp
r287379 r287421 2505 2505 2506 2506 // FIXME: We don't look at the timeout parameter because we don't have a schedule work later API. 2507 vm.deferredWorkTimer->addPendingWork(vm, callback, { });2508 vm.deferredWorkTimer->scheduleWorkSoon( callback, [callback](DeferredWorkTimer::Ticket, DeferredWorkTimer::TicketData&&) {2507 auto ticket = vm.deferredWorkTimer->addPendingWork(vm, callback, { }); 2508 vm.deferredWorkTimer->scheduleWorkSoon(ticket, [callback](DeferredWorkTimer::Ticket) { 2509 2509 JSGlobalObject* globalObject = callback->globalObject(); 2510 2510 MarkedArgumentBuffer args; -
trunk/Source/JavaScriptCore/runtime/DeferredWorkTimer.cpp
r277920 r287421 1 1 /* 2 * Copyright (C) 2017-202 0Apple Inc. All rights reserved.2 * Copyright (C) 2017-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 38 38 } 39 39 40 inline DeferredWorkTimer::TicketData::TicketData(VM& vm, JSObject* scriptExecutionOwner, Vector<Strong<JSCell>>&& dependencies) 41 : dependencies(WTFMove(dependencies)) 42 , scriptExecutionOwner(vm, scriptExecutionOwner) 43 { 44 } 45 46 inline VM& DeferredWorkTimer::TicketData::vm() 47 { 48 ASSERT(!isCancelled()); 49 return target()->vm(); 50 } 51 52 inline void DeferredWorkTimer::TicketData::cancel() 53 { 54 scriptExecutionOwner.clear(); 55 dependencies.clear(); 56 } 57 58 40 59 DeferredWorkTimer::DeferredWorkTimer(VM& vm) 41 60 : Base(vm) … … 55 74 while (!m_tasks.isEmpty()) { 56 75 auto [ticket, task] = m_tasks.takeFirst(); 57 auto globalObject = ticket->structure(vm)->globalObject();58 76 dataLogLnIf(DeferredWorkTimerInternal::verbose, "Doing work on: ", RawPointer(ticket)); 59 77 … … 62 80 if (pendingTicket == m_pendingTickets.end()) 63 81 continue; 64 65 switch (globalObject->globalObjectMethodTable()->scriptExecutionStatus(globalObject, pendingTicket->value.scriptExecutionOwner.get())) { 82 ASSERT(ticket == pendingTicket->get()); 83 84 if (ticket->isCancelled()) { 85 m_pendingTickets.remove(pendingTicket); 86 continue; 87 } 88 89 // We shouldn't access the TicketData to get this globalObject until 90 // after we confirm that the ticket is still valid (which we did above). 91 auto globalObject = ticket->target()->structure(vm)->globalObject(); 92 switch (globalObject->globalObjectMethodTable()->scriptExecutionStatus(globalObject, ticket->scriptExecutionOwner.get())) { 66 93 case ScriptExecutionStatus::Suspended: 67 94 suspendedTasks.append(std::make_tuple(ticket, WTFMove(task))); … … 76 103 // Remove ticket from m_pendingTickets since we are going to run it. 77 104 // But we want to keep ticketData while running task since it ensures dependencies are strongly held. 78 auto ticketData = WTFMove(pendingTicket->value); 79 m_pendingTickets.remove(pendingTicket); 105 std::unique_ptr<TicketData> ticketData = m_pendingTickets.take(pendingTicket); 80 106 81 107 // Allow tasks we are about to run to schedule work. … … 88 114 89 115 auto scope = DECLARE_CATCH_SCOPE(vm); 90 task(ticket, WTFMove(ticketData)); 116 task(ticket); 117 ticketData = nullptr; 91 118 if (Exception* exception = scope.exception()) { 92 auto* globalObject = ticket->globalObject();93 119 scope.clearException(); 94 120 globalObject->globalObjectMethodTable()->reportUncaughtExceptionAtEventLoop(globalObject, exception); … … 104 130 m_tasks.prepend(suspendedTasks.takeLast()); 105 131 132 // It is theoretically possible that a client may cancel a pending ticket and 133 // never call scheduleWorkSoon() on it. As such, it would not be found when 134 // we iterated m_tasks above. We'll need to make sure to purge them here. 135 m_pendingTickets.removeIf([] (auto& ticket) { 136 return ticket->isCancelled(); 137 }); 138 106 139 if (m_pendingTickets.isEmpty() && m_shouldStopRunLoopWhenAllTicketsFinish) { 107 140 ASSERT(m_tasks.isEmpty()); … … 119 152 } 120 153 121 void DeferredWorkTimer::addPendingWork(VM& vm, Ticket ticket, Vector<Strong<JSCell>>&& dependencies)154 DeferredWorkTimer::Ticket DeferredWorkTimer::addPendingWork(VM& vm, JSObject* target, Vector<Strong<JSCell>>&& dependencies) 122 155 { 123 156 ASSERT(vm.currentThreadIsHoldingAPILock() || (Thread::mayBeGCThread() && vm.heap.worldIsStopped())); 124 157 for (unsigned i = 0; i < dependencies.size(); ++i) 125 ASSERT(dependencies[i].get() != ticket); 126 127 auto globalObject = ticket->globalObject(); 128 auto result = m_pendingTickets.ensure(ticket, [&] { 129 dataLogLnIf(DeferredWorkTimerInternal::verbose, "Adding new pending ticket: ", RawPointer(ticket)); 130 JSObject* scriptExecutionOwner = globalObject->globalObjectMethodTable()->currentScriptExecutionOwner(globalObject); 131 dependencies.append(Strong<JSCell>(vm, ticket)); 132 return TicketData { WTFMove(dependencies), Strong<JSObject>(vm, scriptExecutionOwner) }; 133 }); 134 if (!result.isNewEntry) { 135 dataLogLnIf(DeferredWorkTimerInternal::verbose, "Adding new dependencies for ticket: ", RawPointer(ticket)); 136 result.iterator->value.dependencies.appendVector(WTFMove(dependencies)); 137 } 158 ASSERT(dependencies[i].get() != target); 159 160 auto* globalObject = target->globalObject(); 161 JSObject* scriptExecutionOwner = globalObject->globalObjectMethodTable()->currentScriptExecutionOwner(globalObject); 162 dependencies.append(Strong<JSCell>(vm, target)); 163 164 auto ticketData = makeUnique<TicketData>(vm, scriptExecutionOwner, WTFMove(dependencies)); 165 Ticket ticket = ticketData.get(); 166 167 dataLogLnIf(DeferredWorkTimerInternal::verbose, "Adding new pending ticket: ", RawPointer(ticket)); 168 auto result = m_pendingTickets.add(WTFMove(ticketData)); 169 RELEASE_ASSERT(result.isNewEntry); 170 171 return ticket; 138 172 } 139 173 140 174 bool DeferredWorkTimer::hasPendingWork(Ticket ticket) 141 175 { 176 auto result = m_pendingTickets.find(ticket); 177 if (result == m_pendingTickets.end() || ticket->isCancelled()) 178 return false; 142 179 ASSERT(ticket->vm().currentThreadIsHoldingAPILock() || (Thread::mayBeGCThread() && ticket->vm().heap.worldIsStopped())); 143 return m_pendingTickets.contains(ticket);180 return true; 144 181 } 145 182 146 183 bool DeferredWorkTimer::hasDependancyInPendingWork(Ticket ticket, JSCell* dependency) 147 184 { 185 auto result = m_pendingTickets.find(ticket); 186 if (result == m_pendingTickets.end() || ticket->isCancelled()) 187 return false; 148 188 ASSERT(ticket->vm().currentThreadIsHoldingAPILock() || (Thread::mayBeGCThread() && ticket->vm().heap.worldIsStopped())); 149 ASSERT(m_pendingTickets.contains(ticket)); 150 151 auto result = m_pendingTickets.get(ticket); 152 return result.dependencies.contains(dependency); 189 return (*result)->dependencies.contains(dependency); 153 190 } 154 191 … … 163 200 bool DeferredWorkTimer::cancelPendingWork(Ticket ticket) 164 201 { 165 ASSERT(ticket->vm().currentThreadIsHoldingAPILock() || (Thread::mayBeGCThread() && ticket->vm().heap.worldIsStopped())); 166 bool result = m_pendingTickets.remove(ticket); 167 168 if (result) 202 ASSERT(m_pendingTickets.contains(ticket)); 203 ASSERT(ticket->isCancelled() || ticket->vm().currentThreadIsHoldingAPILock() || (Thread::mayBeGCThread() && ticket->vm().heap.worldIsStopped())); 204 205 bool result = false; 206 if (!ticket->isCancelled()) { 169 207 dataLogLnIf(DeferredWorkTimerInternal::verbose, "Canceling ticket: ", RawPointer(ticket)); 208 ticket->cancel(); 209 result = true; 210 } 170 211 171 212 return result; -
trunk/Source/JavaScriptCore/runtime/DeferredWorkTimer.h
r278093 r287421 1 1 /* 2 * Copyright (C) 2017-202 0Apple Inc. All rights reserved.2 * Copyright (C) 2017-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 30 30 31 31 #include <wtf/Deque.h> 32 #include <wtf/Hash Map.h>32 #include <wtf/HashSet.h> 33 33 #include <wtf/Lock.h> 34 34 #include <wtf/Vector.h> … … 45 45 46 46 struct TicketData { 47 private: 48 WTF_MAKE_FAST_ALLOCATED; 49 public: 50 TicketData(VM&, JSObject* scriptExecutionOwner, Vector<Strong<JSCell>>&& dependencies); 51 52 VM& vm(); 53 JSObject* target(); 54 55 void cancel(); 56 bool isCancelled() const { return !scriptExecutionOwner.get(); } 57 47 58 Vector<Strong<JSCell>> dependencies; 48 59 Strong<JSObject> scriptExecutionOwner; 49 60 }; 50 61 62 using Ticket = TicketData*; 63 51 64 void doWork(VM&) final; 52 65 53 using Ticket = JSObject*; 54 void addPendingWork(VM&, Ticket, Vector<Strong<JSCell>>&& dependencies); 66 Ticket addPendingWork(VM&, JSObject* target, Vector<Strong<JSCell>>&& dependencies); 55 67 bool hasPendingWork(Ticket); 56 68 bool hasDependancyInPendingWork(Ticket, JSCell* dependency); … … 62 74 // this occurs. The easiest way is to make sure everything is either owned 63 75 // by a GC'd value in dependencies or by the Task lambda. 64 using Task = Function<void(Ticket , TicketData&&)>;76 using Task = Function<void(Ticket)>; 65 77 void scheduleWorkSoon(Ticket, Task&&); 66 78 void didResumeScriptExecutionOwner(); … … 78 90 bool m_currentlyRunningTask { false }; 79 91 Deque<std::tuple<Ticket, Task>> m_tasks WTF_GUARDED_BY_LOCK(m_taskLock); 80 Hash Map<Ticket, TicketData> m_pendingTickets;92 HashSet<std::unique_ptr<TicketData>> m_pendingTickets; 81 93 }; 82 94 95 inline JSObject* DeferredWorkTimer::TicketData::target() 96 { 97 ASSERT(!isCancelled()); 98 return jsCast<JSObject*>(dependencies.last().get()); 99 } 100 83 101 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSFinalizationRegistry.cpp
r285730 r287421 150 150 }); 151 151 152 if (! vm.deferredWorkTimer->hasPendingWork(this)&& (readiedCell || deadCount(locker))) {153 vm.deferredWorkTimer->addPendingWork(vm, this, { });154 ASSERT(vm.deferredWorkTimer->hasPendingWork(t his));155 vm.deferredWorkTimer->scheduleWorkSoon(t his, [this](DeferredWorkTimer::Ticket, DeferredWorkTimer::TicketData&&) {152 if (!m_hasAlreadyScheduledWork && (readiedCell || deadCount(locker))) { 153 auto ticket = vm.deferredWorkTimer->addPendingWork(vm, this, { }); 154 ASSERT(vm.deferredWorkTimer->hasPendingWork(ticket)); 155 vm.deferredWorkTimer->scheduleWorkSoon(ticket, [this](DeferredWorkTimer::Ticket) { 156 156 JSGlobalObject* globalObject = this->globalObject(); 157 this->m_hasAlreadyScheduledWork = false; 157 158 this->runFinalizationCleanup(globalObject); 158 159 }); 160 m_hasAlreadyScheduledWork = true; 159 161 } 160 162 } -
trunk/Source/JavaScriptCore/runtime/JSFinalizationRegistry.h
r275788 r287421 107 107 LiveRegistrations m_noUnregistrationLive; 108 108 DeadRegistrations m_noUnregistrationDead; 109 bool m_hasAlreadyScheduledWork { false }; 109 110 }; 110 111 -
trunk/Source/JavaScriptCore/wasm/WasmStreamingCompiler.cpp
r285654 r287421 27 27 #include "WasmStreamingCompiler.h" 28 28 29 #include "DeferredWorkTimer.h"30 29 #include "JSBigInt.h" 31 30 #include "JSWebAssembly.h" … … 46 45 : m_vm(vm) 47 46 , m_compilerMode(compilerMode) 48 , m_promise(promise)49 47 , m_info(Wasm::ModuleInformation::create()) 50 48 , m_parser(m_info.get(), *this) … … 54 52 if (importObject) 55 53 dependencies.append(Strong<JSCell>(vm, importObject)); 56 vm.deferredWorkTimer->addPendingWork(vm, promise, WTFMove(dependencies));57 ASSERT(vm.deferredWorkTimer->hasPendingWork( promise));58 ASSERT(vm.deferredWorkTimer->hasDependancyInPendingWork( promise, globalObject));59 ASSERT(!importObject || vm.deferredWorkTimer->hasDependancyInPendingWork( promise, importObject));54 m_ticket = vm.deferredWorkTimer->addPendingWork(vm, promise, WTFMove(dependencies)); 55 ASSERT(vm.deferredWorkTimer->hasPendingWork(m_ticket)); 56 ASSERT(vm.deferredWorkTimer->hasDependancyInPendingWork(m_ticket, globalObject)); 57 ASSERT(!importObject || vm.deferredWorkTimer->hasDependancyInPendingWork(m_ticket, importObject)); 60 58 } 61 59 62 60 StreamingCompiler::~StreamingCompiler() 63 61 { 64 if (m_ promise) {65 auto * promise = std::exchange(m_promise, nullptr);66 m_vm.deferredWorkTimer->scheduleWorkSoon( promise, [](DeferredWorkTimer::Ticket, DeferredWorkTimer::TicketData&&) mutable { });62 if (m_ticket) { 63 auto ticket = std::exchange(m_ticket, nullptr); 64 m_vm.deferredWorkTimer->scheduleWorkSoon(ticket, [](DeferredWorkTimer::Ticket) mutable { }); 67 65 } 68 66 } … … 139 137 140 138 auto result = makeValidationResult(*m_plan); 141 auto * promise = std::exchange(m_promise, nullptr);139 auto ticket = std::exchange(m_ticket, nullptr); 142 140 switch (m_compilerMode) { 143 141 case CompilerMode::Validation: { 144 m_vm.deferredWorkTimer->scheduleWorkSoon( promise, [result = WTFMove(result)](DeferredWorkTimer::Ticket ticket, DeferredWorkTimer::TicketData&& ticketData) mutable {145 JSPromise* promise = jsCast<JSPromise*>(ticket );146 JSGlobalObject* globalObject = jsCast<JSGlobalObject*>(ticket Data.dependencies[0].get());142 m_vm.deferredWorkTimer->scheduleWorkSoon(ticket, [result = WTFMove(result)](DeferredWorkTimer::Ticket ticket) mutable { 143 JSPromise* promise = jsCast<JSPromise*>(ticket->target()); 144 JSGlobalObject* globalObject = jsCast<JSGlobalObject*>(ticket->dependencies[0].get()); 147 145 VM& vm = globalObject->vm(); 148 146 auto scope = DECLARE_THROW_SCOPE(vm); … … 161 159 162 160 case CompilerMode::FullCompile: { 163 m_vm.deferredWorkTimer->scheduleWorkSoon( promise, [result = WTFMove(result)](DeferredWorkTimer::Ticket ticket, DeferredWorkTimer::TicketData&& ticketData) mutable {164 JSPromise* promise = jsCast<JSPromise*>(ticket );165 JSGlobalObject* globalObject = jsCast<JSGlobalObject*>(ticket Data.dependencies[0].get());166 JSObject* importObject = jsCast<JSObject*>(ticket Data.dependencies[1].get());161 m_vm.deferredWorkTimer->scheduleWorkSoon(ticket, [result = WTFMove(result)](DeferredWorkTimer::Ticket ticket) mutable { 162 JSPromise* promise = jsCast<JSPromise*>(ticket->target()); 163 JSGlobalObject* globalObject = jsCast<JSGlobalObject*>(ticket->dependencies[0].get()); 164 JSObject* importObject = jsCast<JSObject*>(ticket->dependencies[1].get()); 167 165 VM& vm = globalObject->vm(); 168 166 auto scope = DECLARE_THROW_SCOPE(vm); … … 208 206 m_eagerFailed = true; 209 207 } 210 auto* promise = std::exchange(m_promise, nullptr); 211 m_vm.deferredWorkTimer->cancelPendingWork(promise); 208 auto ticket = std::exchange(m_ticket, nullptr); 209 JSPromise* promise = jsCast<JSPromise*>(ticket->target()); 210 // The pending work TicketData was keeping the promise alive. We need to 211 // make sure it is reachable from the stack before we remove it from the 212 // pending work list. Note: m_ticket stores it as a PackedPtr, which is not 213 // scannable by the GC. 214 WTF::compilerFence(); 215 m_vm.deferredWorkTimer->cancelPendingWork(ticket); 212 216 promise->reject(globalObject, error); 213 217 } … … 222 226 m_eagerFailed = true; 223 227 } 224 auto * promise = std::exchange(m_promise, nullptr);225 m_vm.deferredWorkTimer->cancelPendingWork( promise);228 auto ticket = std::exchange(m_ticket, nullptr); 229 m_vm.deferredWorkTimer->cancelPendingWork(ticket); 226 230 } 227 231 -
trunk/Source/JavaScriptCore/wasm/WasmStreamingCompiler.h
r278093 r287421 30 30 #if ENABLE(WEBASSEMBLY) 31 31 32 #include "DeferredWorkTimer.h" 32 33 #include "JSCJSValue.h" 33 34 … … 73 74 Lock m_lock; 74 75 unsigned m_remainingCompilationRequests { 0 }; 75 JSPromise* m_promise; // Raw pointer, but held by DeferredWorkTimer.76 DeferredWorkTimer::Ticket m_ticket; 76 77 Ref<Wasm::ModuleInformation> m_info; 77 78 StreamingParser m_parser; -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssembly.cpp
r287122 r287421 171 171 dependencies.append(Strong<JSCell>(vm, globalObject)); 172 172 173 vm.deferredWorkTimer->addPendingWork(vm, promise, WTFMove(dependencies));174 Wasm::Module::validateAsync(&vm.wasmContext, WTFMove(source), createSharedTask<Wasm::Module::CallbackType>([ promise, globalObject, &vm] (Wasm::Module::ValidationResult&& result) mutable {175 vm.deferredWorkTimer->scheduleWorkSoon( promise, [promise, globalObject, result = WTFMove(result), &vm](DeferredWorkTimer::Ticket, DeferredWorkTimer::TicketData&&) mutable {173 auto ticket = vm.deferredWorkTimer->addPendingWork(vm, promise, WTFMove(dependencies)); 174 Wasm::Module::validateAsync(&vm.wasmContext, WTFMove(source), createSharedTask<Wasm::Module::CallbackType>([ticket, promise, globalObject, &vm] (Wasm::Module::ValidationResult&& result) mutable { 175 vm.deferredWorkTimer->scheduleWorkSoon(ticket, [promise, globalObject, result = WTFMove(result), &vm](DeferredWorkTimer::Ticket) mutable { 176 176 auto scope = DECLARE_THROW_SCOPE(vm); 177 177 JSValue module = JSWebAssemblyModule::createStub(vm, globalObject, globalObject->webAssemblyModuleStructure(), WTFMove(result)); … … 203 203 dependencies.append(Strong<JSCell>(vm, importObject)); 204 204 205 vm.deferredWorkTimer->addPendingWork(vm, instance, WTFMove(dependencies));205 auto ticket = vm.deferredWorkTimer->addPendingWork(vm, instance, WTFMove(dependencies)); 206 206 // Note: This completion task may or may not get called immediately. 207 module->module().compileAsync(&vm.wasmContext, instance->memoryMode(), createSharedTask<Wasm::CalleeGroup::CallbackType>([ promise, instance, module, importObject, resolveKind, creationMode, &vm] (Ref<Wasm::CalleeGroup>&& refCalleeGroup) mutable {207 module->module().compileAsync(&vm.wasmContext, instance->memoryMode(), createSharedTask<Wasm::CalleeGroup::CallbackType>([ticket, promise, instance, module, importObject, resolveKind, creationMode, &vm] (Ref<Wasm::CalleeGroup>&& refCalleeGroup) mutable { 208 208 RefPtr<Wasm::CalleeGroup> calleeGroup = WTFMove(refCalleeGroup); 209 vm.deferredWorkTimer->scheduleWorkSoon( instance, [promise, instance, module, importObject, resolveKind, creationMode, &vm, calleeGroup = WTFMove(calleeGroup)](DeferredWorkTimer::Ticket, DeferredWorkTimer::TicketData&&) mutable {209 vm.deferredWorkTimer->scheduleWorkSoon(ticket, [promise, instance, module, importObject, resolveKind, creationMode, &vm, calleeGroup = WTFMove(calleeGroup)](DeferredWorkTimer::Ticket) mutable { 210 210 JSGlobalObject* globalObject = instance->globalObject(); 211 211 resolve(vm, globalObject, promise, instance, module, importObject, calleeGroup.releaseNonNull(), resolveKind, creationMode); … … 228 228 dependencies.append(Strong<JSCell>(vm, importObject)); 229 229 dependencies.append(Strong<JSCell>(vm, moduleKeyCell)); 230 vm.deferredWorkTimer->addPendingWork(vm, promise, WTFMove(dependencies));231 Wasm::Module::validateAsync(&vm.wasmContext, WTFMove(source), createSharedTask<Wasm::Module::CallbackType>([ promise, importObject, moduleKeyCell, globalObject, resolveKind, creationMode, &vm] (Wasm::Module::ValidationResult&& result) mutable {232 vm.deferredWorkTimer->scheduleWorkSoon( promise, [promise, importObject, moduleKeyCell, globalObject, result = WTFMove(result), resolveKind, creationMode, &vm](DeferredWorkTimer::Ticket, DeferredWorkTimer::TicketData&&) mutable {230 auto ticket = vm.deferredWorkTimer->addPendingWork(vm, promise, WTFMove(dependencies)); 231 Wasm::Module::validateAsync(&vm.wasmContext, WTFMove(source), createSharedTask<Wasm::Module::CallbackType>([ticket, promise, importObject, moduleKeyCell, globalObject, resolveKind, creationMode, &vm] (Wasm::Module::ValidationResult&& result) mutable { 232 vm.deferredWorkTimer->scheduleWorkSoon(ticket, [promise, importObject, moduleKeyCell, globalObject, result = WTFMove(result), resolveKind, creationMode, &vm](DeferredWorkTimer::Ticket) mutable { 233 233 auto scope = DECLARE_THROW_SCOPE(vm); 234 234 JSWebAssemblyModule* module = JSWebAssemblyModule::createStub(vm, globalObject, globalObject->webAssemblyModuleStructure(), WTFMove(result)); … … 272 272 dependencies.append(Strong<JSCell>(vm, importObject)); 273 273 dependencies.append(Strong<JSCell>(vm, globalObject)); 274 vm.deferredWorkTimer->addPendingWork(vm, promise, WTFMove(dependencies));275 Wasm::Module::validateAsync(&vm.wasmContext, WTFMove(source), createSharedTask<Wasm::Module::CallbackType>([ promise, importObject, globalObject, &vm] (Wasm::Module::ValidationResult&& result) mutable {276 vm.deferredWorkTimer->scheduleWorkSoon( promise, [promise, importObject, globalObject, result = WTFMove(result), &vm](DeferredWorkTimer::Ticket, DeferredWorkTimer::TicketData&&) mutable {274 auto ticket = vm.deferredWorkTimer->addPendingWork(vm, promise, WTFMove(dependencies)); 275 Wasm::Module::validateAsync(&vm.wasmContext, WTFMove(source), createSharedTask<Wasm::Module::CallbackType>([ticket, promise, importObject, globalObject, &vm] (Wasm::Module::ValidationResult&& result) mutable { 276 vm.deferredWorkTimer->scheduleWorkSoon(ticket, [promise, importObject, globalObject, result = WTFMove(result), &vm](DeferredWorkTimer::Ticket) mutable { 277 277 auto scope = DECLARE_THROW_SCOPE(vm); 278 278 JSWebAssemblyModule* module = JSWebAssemblyModule::createStub(vm, globalObject, globalObject->webAssemblyModuleStructure(), WTFMove(result));
Note:
See TracChangeset
for help on using the changeset viewer.