From aa81ad58f8834fbcd1ad17ddc458c43b1e94f579 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 22 Aug 2025 13:43:09 -0700 Subject: [PATCH 1/4] Fix incorrect promotion opcode used for CEE_LOCALLOC Fix contract violations in getClassAlignmentRequirement Basic implementation of CPOBJ in the interpreter Implement initblk in the interpreter --- src/coreclr/interpreter/compiler.cpp | 31 +++++++++++++++++++++++++++- src/coreclr/interpreter/intops.def | 1 + src/coreclr/vm/interpexec.cpp | 12 +++++++++++ src/coreclr/vm/jitinterface.cpp | 8 +++---- 4 files changed, 47 insertions(+), 5 deletions(-) diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp index 924953f8419da6..05941a68dc8d19 100644 --- a/src/coreclr/interpreter/compiler.cpp +++ b/src/coreclr/interpreter/compiler.cpp @@ -3938,6 +3938,18 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) break; } + case CEE_CPOBJ: + { + CHECK_STACK(2); + CORINFO_RESOLVED_TOKEN resolvedToken; + ResolveToken(getU4LittleEndian(m_ip + 1), CORINFO_TOKENKIND_Class, &resolvedToken); + InterpType interpType = GetInterpType(m_compHnd->asCorInfoType(resolvedToken.hClass)); + EmitLdind(interpType, resolvedToken.hClass, 0); + EmitStind(interpType, resolvedToken.hClass, 0, false); + m_ip += 5; + break; + } + case CEE_RET: { CORINFO_SIG_INFO sig = methodInfo->args; @@ -5500,7 +5512,9 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) // Length is natural unsigned int if (m_pStackPointer[-1].type == StackTypeI4) { - EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_MOV_8); + // The localloc instruction allocates size (type native unsigned int or U4) bytes from the local dynamic memory pool ... + // So the size is currently U4 and needs to be promoted to I8 + EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_I8_U4); m_pStackPointer[-1].type = StackTypeI8; } #endif @@ -5615,6 +5629,21 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) m_ip += 5; break; } + case CEE_INITBLK: + { + if (volatile_) + { + AddIns(INTOP_MEMBAR); + volatile_ = false; + } + + CHECK_STACK(3); + AddIns(INTOP_INITBLK); + m_pStackPointer -= 3; + m_pLastNewIns->SetSVars3(m_pStackPointer[0].var, m_pStackPointer[1].var, m_pStackPointer[2].var); + m_ip++; + break; + } case CEE_CPBLK: CHECK_STACK(3); if (volatile_) diff --git a/src/coreclr/interpreter/intops.def b/src/coreclr/interpreter/intops.def index 5850997ec29cc9..23de4306bbbdc4 100644 --- a/src/coreclr/interpreter/intops.def +++ b/src/coreclr/interpreter/intops.def @@ -397,6 +397,7 @@ OPDEF(INTOP_GENERICLOOKUP, "generic", 4, 1, 1, InterpOpGenericLookup) OPDEF(INTOP_CALL_FINALLY, "call.finally", 2, 0, 0, InterpOpBranch) OPDEF(INTOP_ZEROBLK_IMM, "zeroblk.imm", 3, 0, 1, InterpOpInt) +OPDEF(INTOP_INITBLK, "initblk", 4, 0, 3, InterpOpNoArgs) OPDEF(INTOP_CPBLK, "cpblk", 4, 0, 3, InterpOpNoArgs) OPDEF(INTOP_LOCALLOC, "localloc", 3, 1, 1, InterpOpNoArgs) OPDEF(INTOP_BREAKPOINT, "breakpoint", 1, 0, 0, InterpOpNoArgs) diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index 5c82f07e4ec820..d452448dd22dc7 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -2172,6 +2172,18 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr ip += 4; break; } + case INTOP_INITBLK: + { + void* dst = LOCAL_VAR(ip[1], void*); + uint8_t value = LOCAL_VAR(ip[2], uint8_t); + uint32_t size = LOCAL_VAR(ip[3], uint32_t); + if (size && !dst) + COMPlusThrow(kNullReferenceException); + else + memset(dst, value, size); + ip += 4; + break; + } case INTOP_LOCALLOC: { size_t len = LOCAL_VAR(ip[2], size_t); diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index da018369afecf0..45203c58cdd5cf 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -1920,15 +1920,15 @@ bool CEEInfo::canAllocateOnStack(CORINFO_CLASS_HANDLE clsHnd) unsigned CEEInfo::getClassAlignmentRequirement(CORINFO_CLASS_HANDLE type, bool fDoubleAlignHint) { CONTRACTL { - NOTHROW; - GC_NOTRIGGER; + THROWS; // Due to GetNativeLayoutInfo() call in getClassAlignmentRequirementStatic + GC_TRIGGERS; // Due to InitializeNativeLayoutFieldMetadataThrowing() call in GetNativeLayoutInfo MODE_PREEMPTIVE; } CONTRACTL_END; // Default alignment is sizeof(void*) unsigned result = TARGET_POINTER_SIZE; - JIT_TO_EE_TRANSITION_LEAF(); + JIT_TO_EE_TRANSITION(); TypeHandle clsHnd(type); @@ -1950,7 +1950,7 @@ unsigned CEEInfo::getClassAlignmentRequirement(CORINFO_CLASS_HANDLE type, bool f result = getClassAlignmentRequirementStatic(clsHnd); } - EE_TO_JIT_TRANSITION_LEAF(); + EE_TO_JIT_TRANSITION(); return result; } From 45565654815e91ea00695233cdc96ec84018afb8 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Fri, 22 Aug 2025 15:59:38 -0700 Subject: [PATCH 2/4] Fix conv opcode --- src/coreclr/interpreter/compiler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp index 05941a68dc8d19..6a9ce4b73f987d 100644 --- a/src/coreclr/interpreter/compiler.cpp +++ b/src/coreclr/interpreter/compiler.cpp @@ -5513,8 +5513,8 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) if (m_pStackPointer[-1].type == StackTypeI4) { // The localloc instruction allocates size (type native unsigned int or U4) bytes from the local dynamic memory pool ... - // So the size is currently U4 and needs to be promoted to I8 - EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_I8_U4); + // So the size is currently U4 and needs to be promoted to U8 + EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_U8_U4); m_pStackPointer[-1].type = StackTypeI8; } #endif From a0405889fc0e3b71de2b9430c5e0d25448e8e1fe Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 26 Aug 2025 13:05:56 -0700 Subject: [PATCH 3/4] Update contract for getClassAlignmentRequirementStatic and remove comments from getClassAlignmentRequirement --- src/coreclr/vm/jitinterface.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 45203c58cdd5cf..417effba8f660b 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -1920,8 +1920,8 @@ bool CEEInfo::canAllocateOnStack(CORINFO_CLASS_HANDLE clsHnd) unsigned CEEInfo::getClassAlignmentRequirement(CORINFO_CLASS_HANDLE type, bool fDoubleAlignHint) { CONTRACTL { - THROWS; // Due to GetNativeLayoutInfo() call in getClassAlignmentRequirementStatic - GC_TRIGGERS; // Due to InitializeNativeLayoutFieldMetadataThrowing() call in GetNativeLayoutInfo + THROWS; + GC_TRIGGERS; MODE_PREEMPTIVE; } CONTRACTL_END; @@ -1957,7 +1957,10 @@ unsigned CEEInfo::getClassAlignmentRequirement(CORINFO_CLASS_HANDLE type, bool f unsigned CEEInfo::getClassAlignmentRequirementStatic(TypeHandle clsHnd) { - LIMITED_METHOD_CONTRACT; + CONTRACTL { + THROWS; + GC_TRIGGERS; + } CONTRACTL_END; // Default alignment is sizeof(void*) unsigned result = TARGET_POINTER_SIZE; From 82621bc7f286e1c4d6bba48fcdb2d396542d2544 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Tue, 26 Aug 2025 13:16:14 -0700 Subject: [PATCH 4/4] Update src/coreclr/vm/jitinterface.cpp Co-authored-by: Jan Kotas --- src/coreclr/vm/jitinterface.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 417effba8f660b..9dbdd5ac105776 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -1957,10 +1957,7 @@ unsigned CEEInfo::getClassAlignmentRequirement(CORINFO_CLASS_HANDLE type, bool f unsigned CEEInfo::getClassAlignmentRequirementStatic(TypeHandle clsHnd) { - CONTRACTL { - THROWS; - GC_TRIGGERS; - } CONTRACTL_END; + STANDARD_VM_CONTRACT; // Default alignment is sizeof(void*) unsigned result = TARGET_POINTER_SIZE;