From fcbb2fa1048d010f8dbe3627289eb43054e30a57 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 10 Mar 2026 12:06:31 -0700 Subject: [PATCH 1/3] Don't leave uninitialized garbage in allocated insGroups --- src/coreclr/jit/emit.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 3eafb5c5bc9344..1f32e8257e62b1 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -9766,6 +9766,7 @@ insGroup* emitter::emitAllocIG() #ifdef DEBUG ig->igSelf = ig; + ig->igDataSize = 0; #endif #if EMITTER_STATS @@ -9832,6 +9833,8 @@ void emitter::emitInitIG(insGroup* ig) // Explicitly call init, since IGs don't actually have a constructor. ig->igBlocks.jitstd::list::init(m_compiler->getAllocator(CMK_DebugOnly)); #endif + + ig->igData = nullptr; } /***************************************************************************** From ef845ed5d64e426e7e03bc067e611bb5cbb14aec Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 10 Mar 2026 12:52:31 -0700 Subject: [PATCH 2/3] Move genHomeRegisterParams' output out of the prolog --- src/coreclr/jit/codegen.h | 3 +++ src/coreclr/jit/codegenlinear.cpp | 10 ++++++++++ src/coreclr/jit/codegenwasm.cpp | 25 ++++++++++++++++++------- 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h index 8472dfe8c0233d..5604db99b65c06 100644 --- a/src/coreclr/jit/codegen.h +++ b/src/coreclr/jit/codegen.h @@ -334,6 +334,9 @@ class CodeGen final : public CodeGenInterface void genEstablishFramePointer(int delta, bool reportUnwindData); void genHomeRegisterParams(regNumber initReg, bool* initRegStillZeroed); +#ifdef TARGET_WASM + void genHomeRegisterParamsOutsideProlog(); +#endif regMaskTP genGetParameterHomingTempRegisterCandidates(); var_types genParamStackType(LclVarDsc* dsc, const ABIPassingSegment& seg); diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp index 7823547e9edbe2..2be7f9c272edad 100644 --- a/src/coreclr/jit/codegenlinear.cpp +++ b/src/coreclr/jit/codegenlinear.cpp @@ -410,6 +410,16 @@ void CodeGen::genCodeForBBlist() } #endif +#ifdef TARGET_WASM + // genHomeRegisterParams can generate arbitrary amounts of code on Wasm, so + // we have moved it out of the prolog to the first basic block in order to + // work around the restriction that the prolog can only be one insGroup. + if (block->IsFirst()) + { + genHomeRegisterParamsOutsideProlog(); + } +#endif + #ifndef TARGET_WASM // TODO-WASM: enable genPoisonFrame // Emit poisoning into the init BB that comes right after prolog. // We cannot emit this code in the prolog as it might make the prolog too large. diff --git a/src/coreclr/jit/codegenwasm.cpp b/src/coreclr/jit/codegenwasm.cpp index 4dc8af8418ac9b..32f5ef4cdb950b 100644 --- a/src/coreclr/jit/codegenwasm.cpp +++ b/src/coreclr/jit/codegenwasm.cpp @@ -121,6 +121,22 @@ void CodeGen::genEnregisterOSRArgsAndLocals() //------------------------------------------------------------------------ // genHomeRegisterParams: place register arguments into their RA-assigned locations. // +// We can't actually do this task here because the prolog will overflow. Instead, we +// do this later on and inject all the relevant code into the first basic block. +// See genHomeRegisterParamsOutsideProlog, below. +// +// Arguments: +// initReg - Unused +// initRegStillZeroed - Unused +// +void CodeGen::genHomeRegisterParams(regNumber initReg, bool* initRegStillZeroed) +{ + // Intentionally empty +} + +//------------------------------------------------------------------------ +// genHomeRegisterParamsOutsideProlog: place register arguments into their RA-assigned locations. +// // For the WASM RA, we have a much simplified (compared to LSRA) contract of: // - If an argument is live on entry in a set of registers, then the RA will // assign those registers to that argument on entry. @@ -129,14 +145,9 @@ void CodeGen::genEnregisterOSRArgsAndLocals() // The main motivation for this (along with the obvious CQ implications) is // obviating the need to adapt the general "RegGraph"-based algorithm to // !HAS_FIXED_REGISTER_SET constraints (no reg masks). -// -// Arguments: -// initReg - Unused -// initRegStillZeroed - Unused -// -void CodeGen::genHomeRegisterParams(regNumber initReg, bool* initRegStillZeroed) +void CodeGen::genHomeRegisterParamsOutsideProlog() { - JITDUMP("*************** In genHomeRegisterParams()\n"); + JITDUMP("*************** In genHomeRegisterParamsOutsideProlog()\n"); auto spillParam = [this](unsigned lclNum, unsigned offset, unsigned paramLclNum, const ABIPassingSegment& segment) { assert(segment.IsPassedInRegister()); From 1db1221342ae2db08cd0e89f9a7ce41d846b1415 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 10 Mar 2026 13:19:16 -0700 Subject: [PATCH 3/3] jit-format --- src/coreclr/jit/codegen.h | 6 +++--- src/coreclr/jit/emit.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h index 5604db99b65c06..6b2ca6af8484d4 100644 --- a/src/coreclr/jit/codegen.h +++ b/src/coreclr/jit/codegen.h @@ -332,10 +332,10 @@ class CodeGen final : public CodeGenInterface // Prolog functions and data (there are a few exceptions for more generally used things) // - void genEstablishFramePointer(int delta, bool reportUnwindData); - void genHomeRegisterParams(regNumber initReg, bool* initRegStillZeroed); + void genEstablishFramePointer(int delta, bool reportUnwindData); + void genHomeRegisterParams(regNumber initReg, bool* initRegStillZeroed); #ifdef TARGET_WASM - void genHomeRegisterParamsOutsideProlog(); + void genHomeRegisterParamsOutsideProlog(); #endif regMaskTP genGetParameterHomingTempRegisterCandidates(); diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 1f32e8257e62b1..e620d149ca10b6 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -9765,7 +9765,7 @@ insGroup* emitter::emitAllocIG() ig = (insGroup*)emitGetMem(sz); #ifdef DEBUG - ig->igSelf = ig; + ig->igSelf = ig; ig->igDataSize = 0; #endif