The per-collection report now includes microsecond timings (with
percentage of total) for each phase and major subphase:
gather_roots
must-survive scan / embedder roots / explicit roots
conservative roots
register scan / stack scan / conservative-vector / cell lookup
mark_live_cells
initial visit / BFS marking / clear uprooted
finalize_unmarked_cells
sweep_weak_blocks
sweep_dead_cells
block iteration / weak containers / sweep callbacks
block reclassify / update threshold
Timings are recorded via a small RAII helper into a file-scope struct,
keeping all the plumbing inside Heap.cpp so the public Heap.h surface
stays untouched. Sweep stats now travel back to collect_garbage() the
same way, which lets the report move out of sweep_dead_cells() into a
single print_gc_report() helper run after every phase has completed.