diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp index 6a8671899c85a3..44bdf9d442ed41 100644 --- a/src/coreclr/interpreter/compiler.cpp +++ b/src/coreclr/interpreter/compiler.cpp @@ -1098,6 +1098,9 @@ void InterpCompiler::BuildGCInfo(InterpMethod *pInterpMethod) continue; } + if (pVar->pinned) + flags = (GcSlotFlags)(flags | GC_SLOT_PINNED); + if (pass == 0) slotAllocator.AllocateOrReuseGcSlot(pVar->offset, flags); else @@ -1507,9 +1510,11 @@ void InterpCompiler::CreateILVars() for (int i = 0; i < numILLocals; i++) { CORINFO_CLASS_HANDLE argClass; - CorInfoType argCorType = strip(m_compHnd->getArgType(&m_methodInfo->locals, sigArg, &argClass)); + CorInfoTypeWithMod argCorTypeWithFlags = m_compHnd->getArgType(&m_methodInfo->locals, sigArg, &argClass); + CorInfoType argCorType = strip(argCorTypeWithFlags); + bool pinned = (argCorTypeWithFlags & CORINFO_TYPE_MOD_PINNED) == CORINFO_TYPE_MOD_PINNED; InterpType interpType = GetInterpType(argCorType); - CreateNextLocalVar(index, argClass, interpType, &offset); + CreateNextLocalVar(index, argClass, interpType, &offset, pinned); sigArg = m_compHnd->getArgNext(sigArg); index++; } @@ -1537,7 +1542,7 @@ void InterpCompiler::CreateILVars() m_totalVarsStackSize = offset; } -void InterpCompiler::CreateNextLocalVar(int iArgToSet, CORINFO_CLASS_HANDLE argClass, InterpType interpType, int32_t *pOffset) +void InterpCompiler::CreateNextLocalVar(int iArgToSet, CORINFO_CLASS_HANDLE argClass, InterpType interpType, int32_t *pOffset, bool pinned) { int32_t align; int32_t size = GetInterpTypeStackSize(argClass, interpType, &align); @@ -1549,6 +1554,7 @@ void InterpCompiler::CreateNextLocalVar(int iArgToSet, CORINFO_CLASS_HANDLE argC m_pVars[iArgToSet].size = size; *pOffset = ALIGN_UP_TO(*pOffset, align); m_pVars[iArgToSet].offset = *pOffset; + m_pVars[iArgToSet].pinned = pinned; INTERP_DUMP("alloc arg var %d to offset %d\n", iArgToSet, *pOffset); *pOffset += size; } @@ -5288,7 +5294,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) int byrefOfTypedRefVar = m_pStackPointer[-1].var; m_pLastNewIns->SetDVar(byrefOfTypedRefVar); m_pStackPointer--; - + AddIns(GetStindForType(InterpTypeByRef)); m_pLastNewIns->data[0] = OFFSETOF__CORINFO_TypedReference__dataPtr; m_pLastNewIns->SetSVars2(byrefOfTypedRefVar, addressVar); @@ -5353,7 +5359,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) m_pLastNewIns->data[2] = 0; m_pLastNewIns->SetSVar(typedByRefVar); m_pLastNewIns->SetDVar(classHandleVar); - + AddIns(INTOP_CALL_HELPER_P_S); m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_TYPEHANDLE_TO_RUNTIMETYPEHANDLE_MAYBENULL); m_pLastNewIns->SetSVar(classHandleVar); diff --git a/src/coreclr/interpreter/compiler.h b/src/coreclr/interpreter/compiler.h index 54b25ac2857ce4..c5904ded466b2f 100644 --- a/src/coreclr/interpreter/compiler.h +++ b/src/coreclr/interpreter/compiler.h @@ -359,6 +359,7 @@ struct InterpVar unsigned int global : 1; // Dedicated stack offset throughout method execution unsigned int ILGlobal : 1; // Args and IL locals unsigned int alive : 1; // Used internally by the var offset allocator + unsigned int pinned : 1; // Indicates that the var had the 'pinned' modifier in IL InterpVar(InterpType interpType, CORINFO_CLASS_HANDLE clsHnd, int size) { @@ -374,6 +375,7 @@ struct InterpVar global = false; ILGlobal = false; alive = false; + pinned = false; } }; @@ -683,7 +685,7 @@ class InterpCompiler int32_t GetInterpTypeStackSize(CORINFO_CLASS_HANDLE clsHnd, InterpType interpType, int32_t *pAlign); void CreateILVars(); - void CreateNextLocalVar(int iArgToSet, CORINFO_CLASS_HANDLE argClass, InterpType interpType, int32_t *pOffset); + void CreateNextLocalVar(int iArgToSet, CORINFO_CLASS_HANDLE argClass, InterpType interpType, int32_t *pOffset, bool pinned = false); // Stack StackInfo *m_pStackPointer, *m_pStackBase;