ITADN

Wasm: full-framework R2R generic dictionary lookup leaves thread in preemptive GC mode

#132022OpenAndyAyersMS 创建于 17 天前
arch-wasmarea-ReadyToRun
A
AndyAyersMScommented
When the whole framework (not just System.Private.CoreLib) is ReadyToRun-compiled for wasm, several tests in the JIT subtree fail with a checked assert: ``` !"OBJECTREF being accessed while thread is in preemptive GC mode." src/coreclr/vm/object.cpp:514 Object::Validate ``` Affected tests: `ProfileCastClassAndIsInst` (+ `_random1/2/3`), `Methodical_d1`, `Methodical_r1`, `UnrollEqualsStartsWith` -- all the same root cause. These tests pass with interpreter or with only SPC R2R. AI analysis below ---------------------------------- The falure is in the R2R generic dictionary lookup slow path: - R2R generic code hits a delay-load fixup `READYTORUN_FIXUP_MethodDictionaryLookup`. - `DynamicHelperFixup`/`DynamicHelperWorker` (prestub.cpp) resolves it and builds `DynamicHelper_GenericDictionaryLookup_Method_UseHelper` (wasm stub, dynamichelpers.S). Both run and return cooperative (verified). - The stub `call_indirect`s `g_pMethodWithSlotAndModule` = managed `GenericsHelpers.MethodWithSlotAndModule` (in the R2R SPC), which calls the `GenericHandleWorker` `[LibraryImport(QCall)]` P/Invoke. Instrumented trace (ProfileCastClassAndIsInst): ``` DynamicHelperWorker after-fixup: coopMode=1 (cooperative) GenericHandleWorker enter: coopMode=0 (preemptive - correct for a QCALL) GenericHandleWorker exit: coopMode=0 (still preemptive at C return) ASSERT FAILED ``` The QCALL's `coop -> preempt -> coop` transition never restores COOPERATIVE on this wasm path. After `GenericHandleWorker` returns, the R2R managed code resumes PREEMPTIVE and asserts on the next OBJECTREF access. With only the SPC R2R-compiled, the generic code runs interpreted and the interpreter resolves dictionary lookups correctly. > [!NOTE] > Portions of this issue (the analysis below the line) were produced with GitHub Copilot.
1 条评论