diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp index 924953f8419da6..6a9ce4b73f987d 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 U8 + EmitConv(m_pStackPointer - 1, StackTypeI8, INTOP_CONV_U8_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..9dbdd5ac105776 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; + GC_TRIGGERS; 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,14 +1950,14 @@ unsigned CEEInfo::getClassAlignmentRequirement(CORINFO_CLASS_HANDLE type, bool f result = getClassAlignmentRequirementStatic(clsHnd); } - EE_TO_JIT_TRANSITION_LEAF(); + EE_TO_JIT_TRANSITION(); return result; } unsigned CEEInfo::getClassAlignmentRequirementStatic(TypeHandle clsHnd) { - LIMITED_METHOD_CONTRACT; + STANDARD_VM_CONTRACT; // Default alignment is sizeof(void*) unsigned result = TARGET_POINTER_SIZE;