diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index f12c269b773a12..95b2df06924de8 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -3799,6 +3799,14 @@ void CodeGen::genCheckUseBlockInit() JITDUMP("must init a tracked V%02u because it a struct with a GC ref\n", varNum); mustInitThisVar = true; } +#ifdef TARGET_WASM + else if (hasGCPtr) + { + // On wasm all GC vars are reported as untracked, so the slot must be zero-inited. + JITDUMP("must init V%02u because wasm reports tracked GC vars as untracked\n", varNum); + mustInitThisVar = true; + } +#endif else { // We are done with tracked or GC vars, now look at untracked vars without GC refs. diff --git a/src/coreclr/jit/gcencode.cpp b/src/coreclr/jit/gcencode.cpp index f48e73726ec1b2..4016723ad02806 100644 --- a/src/coreclr/jit/gcencode.cpp +++ b/src/coreclr/jit/gcencode.cpp @@ -4134,7 +4134,9 @@ void GCInfo::gcMakeRegPtrTable( // If it is pinned, it must be an untracked local. assert(!varDsc->lvPinned || !varDsc->lvTracked); - if (varDsc->lvTracked || !varDsc->lvOnFrame) + // When noTrackedGCSlots is true (e.g. on wasm) tracked on-frame GC vars + // must be reported here as untracked, since gcVarPtrList is not populated. + if ((varDsc->lvTracked && !noTrackedGCSlots) || !varDsc->lvOnFrame) { continue; } @@ -4161,7 +4163,9 @@ void GCInfo::gcMakeRegPtrTable( } else { - if (varDsc->lvIsRegArg && varDsc->lvTracked) + // When noTrackedGCSlots is true (e.g. on wasm) tracked register args + // must fall through and be reported as untracked. + if (varDsc->lvIsRegArg && varDsc->lvTracked && !noTrackedGCSlots) { // If this register-passed arg is tracked, then // it has been allocated space near the other