codegen: Replace ThreadSafeContext manual locking with withContextDo
LLVM 21 removes `ThreadSafeContext::getLock()`, `::Lock`, and
`::getContext()`, replacing them with callback-based
`ThreadSafeContext::withContextDo(callback)`.
Add a `withContextDo` compatibility shim that works on both LLVM 20
(acquires lock + calls callback) and LLVM 21+ (delegates to the new
API). Update all callsites to use scoped locking through this shim
instead of manual lock/unlock.
Key changes:
- `jl_codegen_output_t` no longer holds a persistent `tsctx_lock`.
All context access goes through `withContextDo`, with debug asserts
ensuring `get_context()`/`get_module()` are only called inside the
callback scope.
- `addOutput()` and `R->replace()` are called outside `withContextDo`
to respect the lock hierarchy (TSC locks must be released before
dispatching materialization units).
- `jl_create_ts_module` and `compileModule` use the free-function shim.
- `disasm.cpp` replaces `std::optional<ThreadSafeContext::Lock>` with
the callback pattern.
Supersedes JuliaLang/julia#59946.
Co-Authored-By: yuyichao <yyc1992@gmail.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>