148ef606a7
The existing implementation embedded an isolate-specific pointer to the thread-in-wasm flag in the wrapper code. However, when the module code is shared among multiple workers, this can mean that the workers share the same thread-in-wasm flag. With this change we load the pointer to the flag at runtime from the current isolate. Thereby the correct flag is used even when the same code is executed on different workers. Note that we could access the right flag address by going through the root register. However, changing the code generation to use the root register requires some inconvenient steps: * Pass the isolate to the pipeline again, which we don't want. * Change the WasmCallDescriptor to allow the use of the root register for wrappers but not for other code. To avoid these issues, and allow the CL to be easy to merge back, we got for the changes proposed here. R=mstarzinger@chromium.org, ishell@chromium.org Bug: v8:8533 Change-Id: If15565a7ad7cba835cfc1628e7a4d3fdef90a5c0 Reviewed-on: https://chromium-review.googlesource.com/c/1358518 Commit-Queue: Andreas Haas <ahaas@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org> Cr-Commit-Position: refs/heads/master@{#58044}
86 lines
2.9 KiB
JavaScript
86 lines
2.9 KiB
JavaScript
// Copyright 2018 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Flags: --wasm-shared-engine --no-wasm-disable-structured-cloning --allow-natives-syntax --experimental-wasm-threads
|
|
|
|
load('test/mjsunit/wasm/wasm-constants.js');
|
|
load('test/mjsunit/wasm/wasm-module-builder.js');
|
|
|
|
|
|
// In this test we start a worker which enters wasm and stays there in a loop.
|
|
// The main thread stays in JS and checks that its thread-in-wasm flag is not
|
|
// set. The main thread calls setTimeout after every check to give the worker a
|
|
// chance to be scheculed.
|
|
const sync_address = 12;
|
|
(function TestPostModule() {
|
|
let builder = new WasmModuleBuilder();
|
|
let sig_index = builder.addType(kSig_v_v);
|
|
let import_id = builder.addImport('m', 'func', sig_index);
|
|
builder.addFunction('wait', kSig_v_v)
|
|
.addBody([
|
|
// Calling the imported function sets the thread-in-wasm flag of the
|
|
// main thread.
|
|
kExprCallFunction, import_id, // --
|
|
kExprLoop, kWasmStmt, // --
|
|
kExprI32Const, sync_address, // --
|
|
kExprI32LoadMem, 0, 0, // --
|
|
kExprI32Eqz,
|
|
kExprBrIf, 0, // --
|
|
kExprEnd,
|
|
])
|
|
.exportFunc();
|
|
|
|
builder.addFunction('signal', kSig_v_v)
|
|
.addBody([
|
|
kExprI32Const, sync_address, // --
|
|
kExprI32Const, 1, // --
|
|
kExprI32StoreMem, 0, 0, // --
|
|
])
|
|
.exportFunc();
|
|
builder.addImportedMemory("m", "imported_mem", 0, 1, "shared");
|
|
|
|
let module = builder.toModule();
|
|
let memory = new WebAssembly.Memory({initial: 1, maximum: 1, shared: true});
|
|
|
|
let workerScript = `
|
|
onmessage = function(msg) {
|
|
try {
|
|
let worker_instance = new WebAssembly.Instance(msg.module,
|
|
{m: {imported_mem: msg.memory,
|
|
func: _ => 5}});
|
|
postMessage("start running");
|
|
worker_instance.exports.wait();
|
|
postMessage("finished");
|
|
} catch(e) {
|
|
postMessage('ERROR: ' + e);
|
|
}
|
|
}
|
|
`;
|
|
|
|
let worker = new Worker(workerScript, {type: 'string'});
|
|
worker.postMessage({module: module, memory: memory});
|
|
|
|
let main_instance = new WebAssembly.Instance(
|
|
module, {m: {imported_mem: memory, func: _ => 7}});
|
|
|
|
let counter = 0;
|
|
function CheckThreadNotInWasm() {
|
|
// We check the thread-in-wasm flag many times and reschedule ourselves in
|
|
// between to increase the chance that we read the flag set by the worker.
|
|
assertFalse(%IsThreadInWasm());
|
|
counter++;
|
|
if (counter < 100) {
|
|
setTimeout(CheckThreadNotInWasm, 0);
|
|
} else {
|
|
main_instance.exports.signal(sync_address);
|
|
assertEquals('finished', worker.getMessage());
|
|
worker.terminate();
|
|
}
|
|
}
|
|
|
|
assertFalse(%IsThreadInWasm());
|
|
assertEquals('start running', worker.getMessage());
|
|
CheckThreadNotInWasm();
|
|
})();
|