(bytes: Uint8Array)
| 88 | } |
| 89 | |
| 90 | function decodeOpcodeHistogram(bytes: Uint8Array): Readonly<{ |
| 91 | histogram: Readonly<Record<string, number>>; |
| 92 | valid: boolean; |
| 93 | }> { |
| 94 | const cmdCount = readHeaderU32(bytes, 24); |
| 95 | const cmdOffset = readHeaderU32(bytes, 16); |
| 96 | const cmdBytes = readHeaderU32(bytes, 20); |
| 97 | if (cmdCount === null || cmdOffset === null || cmdBytes === null) { |
| 98 | return Object.freeze({ histogram: Object.freeze({}), valid: false }); |
| 99 | } |
| 100 | if (cmdCount === 0) { |
| 101 | return Object.freeze({ histogram: Object.freeze({}), valid: true }); |
| 102 | } |
| 103 | if (cmdOffset < 0 || cmdBytes < 0 || cmdOffset + cmdBytes > bytes.byteLength) { |
| 104 | return Object.freeze({ histogram: Object.freeze({}), valid: false }); |
| 105 | } |
| 106 | const dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength); |
| 107 | let off = cmdOffset; |
| 108 | const end = cmdOffset + cmdBytes; |
| 109 | const hist: Record<string, number> = Object.create(null) as Record<string, number>; |
| 110 | for (let i = 0; i < cmdCount; i++) { |
| 111 | if (off + 8 > end) { |
| 112 | return Object.freeze({ histogram: Object.freeze(hist), valid: false }); |
| 113 | } |
| 114 | const opcode = dv.getUint16(off + 0, true); |
| 115 | const size = dv.getUint32(off + 4, true); |
| 116 | if (size < 8 || off + size > end) { |
| 117 | return Object.freeze({ histogram: Object.freeze(hist), valid: false }); |
| 118 | } |
| 119 | const key = String(opcode); |
| 120 | hist[key] = (hist[key] ?? 0) + 1; |
| 121 | off += size; |
| 122 | } |
| 123 | return Object.freeze({ histogram: Object.freeze(hist), valid: off === end }); |
| 124 | } |
| 125 | |
| 126 | function nowUs(): number { |
| 127 | return Math.round(performance.now() * 1000); |
no test coverage detected