mirror of
				https://github.com/tc39/test262.git
				synced 2025-10-31 11:44:31 +01: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);
 | |
| }
 |