mirror of
https://github.com/tc39/test262.git
synced 2025-05-03 22:40:28 +02:00
* [javascriptcore-test262-automation] changes from git@github.com:WebKit/webkit.git at sha 949e26452cfa153a7f4afe593da97e2fe9e1b706 on Tue Jul 03 2018 14:35:15 GMT-0400 (Eastern Daylight Time)
126 lines
4.2 KiB
JavaScript
126 lines
4.2 KiB
JavaScript
// This test times out, probably because of the while loop in the agent.
|
|
// https://bugs.webkit.org/show_bug.cgi?id=170958
|
|
//@ skip
|
|
|
|
const pageSize = 64 * 1024;
|
|
|
|
const verbose = false;
|
|
|
|
// Start multiple agents and create WebAssembly.Memory from each of
|
|
// them. Perform writes into each memory, and then check that the memory only
|
|
// contains that agent's writes. This would find bugs where an implementation's
|
|
// memory reuse is buggy.
|
|
|
|
// Use the agent support from test262: https://github.com/tc39/test262/blob/master/INTERPRETING.md#host-defined-functions
|
|
|
|
const testIterations = 2;
|
|
const numAgents = 8;
|
|
const initialPages = 64;
|
|
const numWrites = 1024;
|
|
|
|
const stateWait = 0;
|
|
const stateReady = 1;
|
|
const stateCheck = 2;
|
|
|
|
const startAgents = numAgentsToStart => {
|
|
for (let a = 0; a < numAgentsToStart; ++a) {
|
|
const agentScript = `
|
|
let state = ${stateWait};
|
|
let u8;
|
|
|
|
if (${verbose})
|
|
print("Agent ${a} started");
|
|
$.agent.report("Agent ${a} started");
|
|
|
|
$.agent.receiveBroadcast((sab, newState) => {
|
|
if (${verbose})
|
|
print("Agent ${a} received broadcast");
|
|
u8 = new Uint8Array(sab);
|
|
state = newState;
|
|
});
|
|
|
|
const busyWaitForValue = value => {
|
|
// Busy-wait so that once the SAB write occurs all agents try to create a memory at the same time.
|
|
while (Atomics.load(u8, 0) !== value) ;
|
|
};
|
|
|
|
if (${verbose})
|
|
print("Agent ${a} waits");
|
|
$.agent.report("Agent ${a} waits");
|
|
// FIXME: How can this work? The state variable is in the JS heap and the while loop
|
|
// prevents any JS-heap-modifying things from happening because JS is a synchronous
|
|
// language
|
|
// https://bugs.webkit.org/show_bug.cgi?id=170958
|
|
while (state === ${stateWait}) ;
|
|
$.agent.report("Agent ${a} received SAB");
|
|
// Use it for faster state change so all agents are more likely to execute at the same time.
|
|
busyWaitForValue(${stateReady});
|
|
|
|
let wasmMemory = new WebAssembly.Memory({ initial: ${initialPages} });
|
|
let memory = new Uint8Array((wasmMemory).buffer);
|
|
if (${verbose})
|
|
print("Agent ${a} performing writes");
|
|
for (let write = 0; write < ${numWrites}; ++write) {
|
|
// Perform writes of our agent number at a random location. This memory should not be shared, if we see writes of other values then something went wrong.
|
|
const idx = (Math.random() * ${pageSize} * ${initialPages}) | 0;
|
|
memory[idx] = ${a};
|
|
}
|
|
if (${verbose})
|
|
print("Agent ${a} writes performed");
|
|
$.agent.report("Agent ${a} performed writes");
|
|
busyWaitForValue(${stateCheck});
|
|
|
|
if (${verbose})
|
|
print("Agent ${a} checking");
|
|
// Check that our memory only contains 0 and our agent number.
|
|
for (let idx = 0; idx < ${pageSize} * ${initialPages}; ++idx)
|
|
if (memory[idx] !== 0 && memory[idx] !== ${a})
|
|
throw new Error("Agent ${a} found unexpected value " + memory[idx] + " at location " + idx);
|
|
$.agent.report("Agent ${a} checks out OK");
|
|
$.agent.leaving();
|
|
`;
|
|
|
|
if (verbose)
|
|
print(`Starting agent ${a}`);
|
|
$.agent.start(agentScript);
|
|
}
|
|
};
|
|
|
|
const waitForAgents = numAgentsToWaitFor => {
|
|
for (let a = 0; a < numAgentsToWaitFor; ++a) {
|
|
while (true) {
|
|
const report = $.agent.getReport();
|
|
if (report === null) {
|
|
$.agent.sleep(1);
|
|
continue;
|
|
}
|
|
if (verbose)
|
|
print(`Received: ${report}`);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
const broadcastToAgents = (sab, newState) => {
|
|
$.agent.broadcast(sab, newState);
|
|
};
|
|
|
|
const sab = new SharedArrayBuffer(1024);
|
|
const u8 = new Uint8Array(sab);
|
|
|
|
for (let it = 0; it < testIterations; ++it) {
|
|
startAgents(numAgents);
|
|
waitForAgents(numAgents);
|
|
broadcastToAgents(sab, stateReady);
|
|
waitForAgents(numAgents);
|
|
$.agent.sleep(1);
|
|
Atomics.store(u8, 0, stateReady);
|
|
waitForAgents(numAgents);
|
|
$.agent.sleep(1);
|
|
Atomics.store(u8, 0, stateCheck);
|
|
waitForAgents(numAgents);
|
|
if (verbose)
|
|
print("Everyting was fine");
|
|
$.agent.sleep(1);
|
|
}
|