fix: flush CPU profile and coverage data on Deno.exit() (#32591)
## Summary
- When `Deno.exit()` is called, `std::process::exit()` bypasses normal
cleanup in the worker's run loop, causing CPU profile and coverage data
to be lost
- Adds `OpExitCallbacks` stored in `OpState` that are invoked by
`op_exit` before `std::process::exit()`, ensuring profiling and coverage
data is flushed
- Both CPU profiler and coverage collector are wrapped in
`Rc<RefCell<Option<...>>>` so whichever cleanup path runs first (exit
callback or normal teardown) takes the value
Closes #32590
Closes #8713