From a28754f7e32b5e19f74c957ff7c0d900d1959100 Mon Sep 17 00:00:00 2001 From: Larry Ewing Date: Sun, 18 Oct 2026 17:27:41 -0500 Subject: [PATCH] JIT: allow stack allocation of R2R arrays allocated with explicit-type helpers Object stack allocation skipped all array allocations in ReadyToRun code because CORINFO_HELP_READYTORUN_NEWARR_1 has no type argument for the stack allocation expansion. ReadyToRun code that allocates through the explicit-type newarr helpers (for example on WebAssembly, where crossgen2 does not use the compact ReadyToRun helpers) passes the type handle as an argument, so it can use the same path as JIT-compiled code. Only classify the explicit-type newarr helpers as array candidates and drop the blanket ReadyToRun bail-out. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8c63b295-3bbc-4eae-ac3b-012e284ba542 --- src/coreclr/jit/objectalloc.cpp | 22 +++++----------------- src/coreclr/jit/objectalloc.h | 1 - 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/coreclr/jit/objectalloc.cpp b/src/coreclr/jit/objectalloc.cpp index 4020ddf3beb8d5..06c3fc24dc3d0f 100644 --- a/src/coreclr/jit/objectalloc.cpp +++ b/src/coreclr/jit/objectalloc.cpp @@ -38,7 +38,6 @@ ObjectAllocator::ObjectAllocator(Compiler* comp) : Phase(comp, PHASE_ALLOCATE_OBJECTS) , m_IsObjectStackAllocationEnabled(false) , m_AnalysisDone(false) - , m_isR2R(comp->IsReadyToRun()) , m_bvCount(0) , m_bitVecTraits(BitVecTraits(comp->lvaCount, comp)) , m_unknownSourceIndex(BAD_VAR_NUM) @@ -1286,9 +1285,12 @@ ObjectAllocator::ObjectAllocationType ObjectAllocator::AllocationKind(GenTree* t bool const canBeOnStack = isValueClass || m_compiler->info.compCompHnd->canAllocateOnStack(clsHnd); allocType = canBeOnStack ? OAT_NEWOBJ : OAT_NEWOBJ_HEAP; } - else if (!m_isR2R && tree->IsHelperCall()) + else if (tree->IsHelperCall()) { GenTreeCall* const call = tree->AsCall(); + + // CORINFO_HELP_READYTORUN_NEWARR_1 is not listed: it has no type argument for the + // stack allocation expansion to use. switch (call->GetHelperNum()) { case CORINFO_HELP_NEWARR_1_VC: @@ -1559,28 +1561,14 @@ bool ObjectAllocator::MorphAllocObjNodeHelperArr(AllocationCandidate& candidate) { assert(candidate.m_block->HasFlag(BBF_HAS_NEWARR)); - // R2R not yet supported - // - if (m_isR2R) - { - candidate.m_onHeapReason = "[R2R array not yet supported]"; - return false; - } - GenTree* const data = candidate.m_tree->AsLclVar()->Data(); //------------------------------------------------------------------------ // We expect the following expression tree at this point - // For non-ReadyToRun: - // STMTx (IL 0x... ???) - // * STORE_LCL_VAR ref - // \--* CALL help ref - // +--* CNS_INT(h) long - // \--* CNS_INT long - // For ReadyToRun: // STMTx (IL 0x... ???) // * STORE_LCL_VAR ref // \--* CALL help ref + // +--* (type handle) // \--* CNS_INT long //------------------------------------------------------------------------ diff --git a/src/coreclr/jit/objectalloc.h b/src/coreclr/jit/objectalloc.h index e169c38955b643..0c4ece3737dca5 100644 --- a/src/coreclr/jit/objectalloc.h +++ b/src/coreclr/jit/objectalloc.h @@ -168,7 +168,6 @@ class ObjectAllocator final : public Phase // Data members bool m_IsObjectStackAllocationEnabled; bool m_AnalysisDone; - bool m_isR2R; unsigned m_bvCount; BitVecTraits m_bitVecTraits; unsigned m_unknownSourceIndex;