From 7ebce7359d905026b25b077e4e3b1acdf7d36814 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Tue, 10 Sep 2024 13:50:54 -0700 Subject: [PATCH] Allow minification of pthread postMessage objects. NFC In the part using unquoted key here meant that closure would minify these key and this was a problem because the separate worker.js files would not then be able to interpret them. However since #21701 landed there is no longer separate worker.js file so closure can minify these keys and it will effect both sending and receiving code. --- src/library_pthread.js | 62 +++++++++---------- src/runtime_pthread.js | 34 +++++----- .../test_codesize_minimal_pthreads.gzsize | 2 +- .../test_codesize_minimal_pthreads.jssize | 2 +- 4 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/library_pthread.js b/src/library_pthread.js index 47340f2a6b843..680a6ac9dd316 100644 --- a/src/library_pthread.js +++ b/src/library_pthread.js @@ -229,16 +229,16 @@ var LibraryPThread = { loadWasmModuleToWorker: (worker) => new Promise((onFinishedLoading) => { worker.onmessage = (e) => { var d = e['data']; - var cmd = d['cmd']; + var cmd = d.cmd; // If this message is intended to a recipient that is not the main // thread, forward it to the target thread. - if (d['targetThread'] && d['targetThread'] != _pthread_self()) { - var targetWorker = PThread.pthreads[d['targetThread']]; + if (d.targetThread && d.targetThread != _pthread_self()) { + var targetWorker = PThread.pthreads[d.targetThread]; if (targetWorker) { - targetWorker.postMessage(d, d['transferList']); + targetWorker.postMessage(d, d.transferList); } else { - err(`Internal error! Worker sent a message "${cmd}" to target pthread ${d['targetThread']}, but that thread no longer exists!`); + err(`Internal error! Worker sent a message "${cmd}" to target pthread ${d.targetThread}, but that thread no longer exists!`); } return; } @@ -248,10 +248,10 @@ var LibraryPThread = { } else if (cmd === 'spawnThread') { spawnThread(d); } else if (cmd === 'cleanupThread') { - cleanupThread(d['thread']); + cleanupThread(d.thread); #if MAIN_MODULE } else if (cmd === 'markAsFinished') { - markAsFinished(d['thread']); + markAsFinished(d.thread); #endif } else if (cmd === 'loaded') { worker.loaded = true; @@ -266,13 +266,13 @@ var LibraryPThread = { #endif onFinishedLoading(worker); } else if (cmd === 'alert') { - alert(`Thread ${d['threadId']}: ${d['text']}`); + alert(`Thread ${d.threadId}: ${d.text}`); } else if (d.target === 'setimmediate') { // Worker wants to postMessage() to itself to implement setImmediate() // emulation. worker.postMessage(d); } else if (cmd === 'callHandler') { - Module[d['handler']](...d['args']); + Module[d.handler](...d.args); } else if (cmd) { // The received message looks like something that should be handled by this message // handler, (since there is a e.data.cmd field present), but is not one of the @@ -333,28 +333,28 @@ var LibraryPThread = { // Ask the new worker to load up the Emscripten-compiled page. This is a heavy operation. worker.postMessage({ - 'cmd': 'load', - 'handlers': handlers, + cmd: 'load', + handlers: handlers, #if WASM2JS // the polyfill WebAssembly.Memory instance has function properties, // which will fail in postMessage, so just send a custom object with the // property we need, the buffer - 'wasmMemory': { 'buffer': wasmMemory.buffer }, + wasmMemory: { 'buffer': wasmMemory.buffer }, #else // WASM2JS - 'wasmMemory': wasmMemory, + wasmMemory, #endif // WASM2JS - 'wasmModule': wasmModule, + wasmModule, #if LOAD_SOURCE_MAP - 'wasmSourceMap': wasmSourceMap, + wasmSourceMap, #endif #if USE_OFFSET_CONVERTER - 'wasmOffsetConverter': wasmOffsetConverter, + wasmOffsetConverter, #endif #if MAIN_MODULE - 'dynamicLibraries': dynamicLibraries, + dynamicLibraries, // Share all modules that have been loaded so far. New workers // won't start running threads until these are all loaded. - 'sharedModules': sharedModules, + sharedModules, #endif #if ASSERTIONS 'workerID': worker.workerID, @@ -503,7 +503,7 @@ var LibraryPThread = { // the onmessage handlers if the message was coming from valid worker. worker.onmessage = (e) => { #if ASSERTIONS - var cmd = e['data']['cmd']; + var cmd = e['data'].cmd; err(`received "${cmd}" command from terminated worker: ${worker.workerID}`); #endif }; @@ -519,7 +519,7 @@ var LibraryPThread = { dbg(`_emscripten_thread_cleanup: ${ptrToString(thread)}`) #endif if (!ENVIRONMENT_IS_PTHREAD) cleanupThread(thread); - else postMessage({ 'cmd': 'cleanupThread', 'thread': thread }); + else postMessage({ cmd: 'cleanupThread', thread }); }, _emscripten_thread_set_strongref: (thread) => { @@ -618,10 +618,10 @@ var LibraryPThread = { worker.pthread_ptr = threadParams.pthread_ptr; var msg = { - 'cmd': 'run', - 'start_routine': threadParams.startRoutine, - 'arg': threadParams.arg, - 'pthread_ptr': threadParams.pthread_ptr, + cmd: 'run', + start_routine: threadParams.startRoutine, + arg: threadParams.arg, + pthread_ptr: threadParams.pthread_ptr, }; #if OFFSCREENCANVAS_SUPPORT // Note that we do not need to quote these names because they are only used @@ -1110,7 +1110,7 @@ var LibraryPThread = { // running, but remain around waiting to be joined. In this state they // cannot run any more proxied work. if (!ENVIRONMENT_IS_PTHREAD) markAsFinished(thread); - else postMessage({ 'cmd': 'markAsFinished', 'thread': thread }); + else postMessage({ cmd: 'markAsFinished', thread }); }, $markAsFinished: (pthread_ptr) => { @@ -1242,20 +1242,20 @@ var LibraryPThread = { // new thread that has not had a chance to initialize itself and execute // Atomics.waitAsync to prepare for the notification. _emscripten_notify_mailbox_postmessage__deps: ['$checkMailbox'], - _emscripten_notify_mailbox_postmessage: (targetThreadId, currThreadId) => { - if (targetThreadId == currThreadId) { + _emscripten_notify_mailbox_postmessage: (targetThread, currThreadId) => { + if (targetThread == currThreadId) { setTimeout(checkMailbox); } else if (ENVIRONMENT_IS_PTHREAD) { - postMessage({'targetThread' : targetThreadId, 'cmd' : 'checkMailbox'}); + postMessage({targetThread, cmd: 'checkMailbox'}); } else { - var worker = PThread.pthreads[targetThreadId]; + var worker = PThread.pthreads[targetThread]; if (!worker) { #if ASSERTIONS - err(`Cannot send message to thread with ID ${targetThreadId}, unknown thread ID!`); + err(`Cannot send message to thread with ID ${targetThread}, unknown thread ID!`); #endif return; } - worker.postMessage({'cmd' : 'checkMailbox'}); + worker.postMessage({cmd: 'checkMailbox'}); } } }; diff --git a/src/runtime_pthread.js b/src/runtime_pthread.js index e4a10d564520f..92c97f5dbceaf 100644 --- a/src/runtime_pthread.js +++ b/src/runtime_pthread.js @@ -103,10 +103,10 @@ if (ENVIRONMENT_IS_PTHREAD) { try { var msgData = e['data']; //dbg('msgData: ' + Object.keys(msgData)); - var cmd = msgData['cmd']; + var cmd = msgData.cmd; if (cmd === 'load') { // Preload command that is called once per worker to parse and load the Emscripten code. #if ASSERTIONS - workerID = msgData['workerID']; + workerID = msgData.workerID; #endif #if PTHREADS_DEBUG dbg('worker: loading module') @@ -119,7 +119,7 @@ if (ENVIRONMENT_IS_PTHREAD) { // And add a callback for when the runtime is initialized. self.startWorker = (instance) => { // Notify the main thread that this thread has loaded. - postMessage({ 'cmd': 'loaded' }); + postMessage({ cmd: 'loaded' }); // Process any messages that were queued before the thread was ready. for (let msg of messageQueue) { handleMessage(msg); @@ -129,16 +129,16 @@ if (ENVIRONMENT_IS_PTHREAD) { }; #if MAIN_MODULE - dynamicLibraries = msgData['dynamicLibraries']; - sharedModules = msgData['sharedModules']; + dynamicLibraries = msgData.dynamicLibraries; + sharedModules = msgData.sharedModules; #if RUNTIME_DEBUG - dbg(`worker: received ${Object.keys(msgData['sharedModules']).length} shared modules: ${Object.keys(msgData.sharedModules)}`); + dbg(`worker: received ${Object.keys(msgData.sharedModules).length} shared modules: ${Object.keys(msgData.sharedModules)}`); #endif #endif // Use `const` here to ensure that the variable is scoped only to // that iteration, allowing safe reference from a closure. - for (const handler of msgData['handlers']) { + for (const handler of msgData.handlers) { // The the main module has a handler for a certain even, but no // handler exists on the pthread worker, then proxy that handler // back to the main thread. @@ -161,41 +161,41 @@ if (ENVIRONMENT_IS_PTHREAD) { #endif } - wasmMemory = msgData['wasmMemory']; + wasmMemory = msgData.wasmMemory; updateMemoryViews(); #if LOAD_SOURCE_MAP - wasmSourceMap = resetPrototype(WasmSourceMap, msgData['wasmSourceMap']); + wasmSourceMap = resetPrototype(WasmSourceMap, msgData.wasmSourceMap); #endif #if USE_OFFSET_CONVERTER - wasmOffsetConverter = resetPrototype(WasmOffsetConverter, msgData['wasmOffsetConverter']); + wasmOffsetConverter = resetPrototype(WasmOffsetConverter, msgData.wasmOffsetConverter); #endif #if MINIMAL_RUNTIME // Pass the shared Wasm module in the Module object for MINIMAL_RUNTIME. - Module['wasm'] = msgData['wasmModule']; + Module['wasm'] = msgData.wasmModule; loadModule(); #else - wasmPromiseResolve(msgData['wasmModule']); + wasmPromiseResolve(msgData.wasmModule); #endif // MINIMAL_RUNTIME } else if (cmd === 'run') { #if ASSERTIONS - assert(msgData['pthread_ptr']); + assert(msgData.pthread_ptr); #endif // Call inside JS module to set up the stack frame for this pthread in JS module scope. // This needs to be the first thing that we do, as we cannot call to any C/C++ functions // until the thread stack is initialized. - establishStackSpace(msgData['pthread_ptr']); + establishStackSpace(msgData.pthread_ptr); // Pass the thread address to wasm to store it for fast access. - __emscripten_thread_init(msgData['pthread_ptr'], /*is_main=*/0, /*is_runtime=*/0, /*can_block=*/1, 0, 0); + __emscripten_thread_init(msgData.pthread_ptr, /*is_main=*/0, /*is_runtime=*/0, /*can_block=*/1, 0, 0); PThread.receiveObjectTransfer(msgData); PThread.threadInitTLS(); // Await mailbox notifications with `Atomics.waitAsync` so we can start // using the fast `Atomics.notify` notification path. - __emscripten_thread_mailbox_await(msgData['pthread_ptr']); + __emscripten_thread_mailbox_await(msgData.pthread_ptr); if (!initializedJS) { #if EMBIND @@ -210,7 +210,7 @@ if (ENVIRONMENT_IS_PTHREAD) { } try { - invokeEntryPoint(msgData['start_routine'], msgData['arg']); + invokeEntryPoint(msgData.start_routine, msgData.arg); } catch(ex) { if (ex != 'unwind') { // The pthread "crashed". Do not call `_emscripten_thread_exit` (which diff --git a/test/other/codesize/test_codesize_minimal_pthreads.gzsize b/test/other/codesize/test_codesize_minimal_pthreads.gzsize index e8df1295e424f..f4833d49363ab 100644 --- a/test/other/codesize/test_codesize_minimal_pthreads.gzsize +++ b/test/other/codesize/test_codesize_minimal_pthreads.gzsize @@ -1 +1 @@ -5012 +4959 diff --git a/test/other/codesize/test_codesize_minimal_pthreads.jssize b/test/other/codesize/test_codesize_minimal_pthreads.jssize index 59d611637cf1c..4cdee9867c3b4 100644 --- a/test/other/codesize/test_codesize_minimal_pthreads.jssize +++ b/test/other/codesize/test_codesize_minimal_pthreads.jssize @@ -1 +1 @@ -10825 +10602