Parent: #496 Related: #461, #493, #501
Problem
Parser.parseStatement called sourceLocationAt(source, token.pos) for every statement. sourceLocationAt starts at byte zero and scans the entire prefix to count line terminators. A source containing N sequential statements therefore performed quadratic prefix work solely to retain debugger/source metadata. The source bytes and statement count are attacker-controlled, so this was both a cold-frontend bottleneck and a worst-case latency boundary.
Resolution
- Benchmark contract:
3bba3de9(bench(frontend): add statement location growth rows (#554)). - Runtime fix:
87eba6c2(perf(parser): index repeated source locations (#554)). - Evidence:
2de66881(docs(frontend): publish statement location evidence (#554)).
The parser keeps its first two statement-location lookups allocation-free. On the third lookup it performs two bounded linear scans to size and fill one exact arena-owned line-start table, publishes the table only after successful construction, and resolves later locations with binary search. The sizing pass checks integer overflow. Standalone one-shot sourceLocationAt behavior remains unchanged.
Evidence
The overview and linked raw artifacts preserve six ReleaseFast rows, seven order-balanced exact-parent pairs per row, all 84 fresh processes, and no discarded samples.
- Repeated-statement wall medians are
0.006xto0.038xof the quadratic parent; retired instructions are0.0048xto0.0263x. - The 1K/2K/4K sequential candidate instruction counts grow approximately linearly while the parent grows approximately quadratically.
- The single-statement control keeps allocation requests
4133 -> 4133, allocated bytes2470848 -> 2470848, instructions at0.9991x, wall at1.004x, and peak RSS at1.0018x. - The bounded index costs one allocation and 8,200/16,392/32,776 bytes for the 1K/2K/4K sequential rows.
- Raw JSON retains checksums, hashes, CPU, RSS, allocation, instruction, cycle, energy availability, power, thermal state, and dispersion. The battery/fair-thermal run is deliberately diagnostic; candidate energy deltas were below counter resolution, so no energy-ratio claim is made.
Correctness stayed line-terminators 41 -> 41, source-text 1 -> 1, debugger 2 -> 2, and Annex B 1086 -> 1086: 1130 -> 1130, zero failures or flips. Frontend Debug and TSan pass 12/12 each; full units pass 1625 with one expected skip and zero failures/leaks; four real-corpus witnesses pass in both forced tree-walker and required-bytecode modes.
No-workaround rules
- No omitted/coarsened locations, ASCII/LF-only counting, hidden warmup preprocessing, cached benchmark source, token/AST widening, benchmark recognition, or disabled debugger registration.
- Source scanning remains inside the claimed parse boundary.
- No stacks, queues, jobs, Promise/microtask, or Worker lifecycle code changed.
Acceptance
- Benchmark source, base/variant/control identities, jobs, checksums, warmup, and timed boundary landed before the runtime change.
- Total statement-location construction is O(source bytes + statements log lines), with bounded index storage and no repeated full-prefix scans.
- Exact byte offsets and 1-based lines/columns match for LF, CRLF, lone CR, U+2028/U+2029, comments, nested statements, and EOF diagnostics.
- The wide single-statement control does not regress materially in instructions, allocations, bytes, or peak RSS.
- OOM/fault paths are atomic and bounded; fresh parser retries and Context teardown release arena-owned index backing.
- Focused frontend Debug/TSan, full units, source-location/debugger/Annex B test262, and forced tree-walker/VM execution pass without regressions.
- Seven-pair exact-parent evidence publishes wall, CPU, allocation requests/bytes, peak RSS, instructions/cycles/energy availability, thermal state, and dispersion with no discarded samples.
Security boundary
Source length, line-break encoding, comment layout, and statement count are attacker-controlled. The fix bounds their work, checks index sizing overflow, folds CRLF exactly, treats LF/lone CR/U+2028/U+2029 consistently with the lexer, and preserves source/debug metadata.