// usage: node prof.mjs flash.bin seconds [--syms a,b] : prints pc histogram by function import fs from 'fs'; import { ESP32 } from '../web/js/soc.js'; import { Syms } from './sym.mjs'; const romDir = new URL('../web/rom/', import.meta.url).pathname; const args = process.argv.slice(2); const flash = args[0]; const secs = parseFloat(args[1] || '2'); const symFiles = (args.find(a => a.startsWith('--syms=')) || '--syms=/tmp/opencode/hello.syms').slice(7).split(',').concat(['/tmp/opencode/rom.syms']); const syms = new Syms(symFiles); const soc = new ESP32({}); soc.loadRoms(fs.readFileSync(romDir + 'esp32-v3-rom.bin'), fs.readFileSync(romDir + 'esp32-v3-rom-app.bin')); soc.setFlash(fs.readFileSync(flash)); soc.enablePsram(args.includes('--psram')); let out = ''; soc.onUart = (n, b) => { out += String.fromCharCode(b); }; soc.reset('power'); const hist = [new Map(), new Map()]; const warm = parseFloat((args.find(a => a.startsWith('--warm=')) || '--warm=0').slice(7)) * 1e9; const limit = secs * 1e9; let samples = 0; while (soc.timeNs < limit) { soc.run(997); if (soc.timeNs < warm) continue; for (let i = 0; i < 2; i++) { const c = soc.cpus[i]; const nm = syms.name(c.pc).replace(/\+.*/, '') + (c.halted ? '[halt]' : c.stalled ? '[stall]' : ''); hist[i].set(nm, (hist[i].get(nm) || 0) + 1); } samples++; } console.log(out.slice(-2000)); for (let i = 0; i < 2; i++) { console.log('--- cpu' + i); [...hist[i].entries()].sort((a, b) => b[1] - a[1]).slice(0, 12).forEach(([n, c]) => console.log(c, n)); } console.log('time', soc.timeNs / 1e9);