From d39fe580fcd369e83e9e4804ce02ee7b950e2d06 Mon Sep 17 00:00:00 2001 From: Camden Dixie O'Brien Date: Thu, 19 Mar 2026 22:03:36 +0000 Subject: [PATCH] Implement sampling profiler --- prof.js | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 prof.js diff --git a/prof.js b/prof.js new file mode 100644 index 0000000..f612a74 --- /dev/null +++ b/prof.js @@ -0,0 +1,48 @@ +const INTERVAL_MS = 1; +const RS_TOP_ADDR = 0x10000; +const PROF_DATA_ADDR = 0x58; +const PROF_DATA_IDX = PROF_DATA_ADDR / 8; + +let mem_8; +let mem_64; +let sampler; + +const samples = []; + +function sample() { + const data = Atomics.load(mem_64, PROF_DATA_IDX); + const ip = Number(data & 0xffffffffn); + const rsp = Number(data >> 32n); + samples.push({ ip, rs_bytes: mem_8.slice(rsp, RS_TOP_ADDR) }); +} + +function i32(bytes) { + return bytes[0] + | (bytes[1] << 8) + | (bytes[2] << 16) + | (bytes[3] << 24); +} +function postproc({ ip, rs_bytes }) { + const rs = []; + for (let i = 0; i < rs_bytes.length; i += 4) + rs.push(i32(rs_bytes.slice(i, i + 4))); + rs.reverse(); + return { ip, rs }; +} + +self.onmessage = (e) => { + switch (e.data.type) { + case "start": + console.log("Starting profiler"); + mem_8 = new Uint8Array(e.data.mem.buffer); + mem_64 = new BigUint64Array(e.data.mem.buffer); + ip = e.data.ip; + rsp = e.data.rsp; + sampler = setInterval(sample, INTERVAL_MS); + break; + case "stop": + clearInterval(sample); + console.log("Stopped profiler"); + self.postMessage(samples.map(postproc)); + } +};