From 7ff684af49cdf008bebbe10efcc10a2649795d65 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Wed, 28 Aug 2024 11:16:30 +0200 Subject: [PATCH] Ensure the layout of `StackAllocatedBox` matches boxed layouts (#107050) The boxed layout of a struct always has its data at +8, as evidenced by `Object::UnBox`. This means that `StackAllocatedBox` should have `Pack = 1`, otherwise this may not be the case. In the test failure we had a `StackAllocatedBox` which had its `_value` field at offset 16. After object stack allocation this meant that we were saving data in padding of the structure, which promotion does not guarantee to preserve. Fix #106947 --- src/coreclr/jit/valuenum.cpp | 4 +++- src/coreclr/vm/corelib.h | 1 + src/coreclr/vm/jitinterface.cpp | 6 ++++++ .../System/Runtime/CompilerServices/StackAllocatedBox.cs | 2 +- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/valuenum.cpp b/src/coreclr/jit/valuenum.cpp index 2ce97d285206c..1d13229cf96a1 100644 --- a/src/coreclr/jit/valuenum.cpp +++ b/src/coreclr/jit/valuenum.cpp @@ -10299,7 +10299,9 @@ void ValueNumStore::vnDumpSimdType(Compiler* comp, VNFuncApp* simdType) int simdSize = ConstantValue(simdType->m_args[0]); CorInfoType baseJitType = (CorInfoType)ConstantValue(simdType->m_args[1]); - printf("%s(simd%d, %s)", VNFuncName(simdType->m_func), simdSize, varTypeName(JitType2PreciseVarType(baseJitType))); + printf("%s(simd%d, %s)", VNFuncName(simdType->m_func), simdSize, + baseJitType == CORINFO_TYPE_UNDEF ? varTypeName(TYP_UNDEF) + : varTypeName(JitType2PreciseVarType(baseJitType))); } #endif // FEATURE_SIMD diff --git a/src/coreclr/vm/corelib.h b/src/coreclr/vm/corelib.h index 4cffd124370fe..38a05866ff3e2 100644 --- a/src/coreclr/vm/corelib.h +++ b/src/coreclr/vm/corelib.h @@ -1104,6 +1104,7 @@ DEFINE_FIELD_U(_condition, ContractExceptionObject, _Condition) DEFINE_CLASS(MODULEBASE, Reflection, Module) DEFINE_CLASS(STACKALLOCATEDBOX, CompilerServices, StackAllocatedBox`1) +DEFINE_FIELD(STACKALLOCATEDBOX, VALUE, _value) DEFINE_CLASS(UTF8STRINGMARSHALLER, Marshalling, Utf8StringMarshaller) DEFINE_METHOD(UTF8STRINGMARSHALLER, CONVERT_TO_MANAGED, ConvertToManaged, SM_PtrByte_RetStr) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index e7572863016f0..2c470710f0b4c 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -6168,6 +6168,12 @@ CORINFO_CLASS_HANDLE CEEInfo::getTypeForBoxOnStack(CORINFO_CLASS_HANDLE cls) TypeHandle stackAllocatedBox = CoreLibBinder::GetClass(CLASS__STACKALLOCATEDBOX); TypeHandle stackAllocatedBoxInst = stackAllocatedBox.Instantiate(boxedFieldsInst); result = static_cast(stackAllocatedBoxInst.AsPtr()); + +#ifdef _DEBUG + FieldDesc* pValueFD = CoreLibBinder::GetField(FIELD__STACKALLOCATEDBOX__VALUE); + DWORD index = pValueFD->GetApproxEnclosingMethodTable()->GetIndexForFieldDesc(pValueFD); + _ASSERTE(stackAllocatedBoxInst.GetMethodTable()->GetFieldDescByIndex(index)->GetOffset() == TARGET_POINTER_SIZE); +#endif } EE_TO_JIT_TRANSITION(); diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/StackAllocatedBox.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/StackAllocatedBox.cs index 868edb18c1594..33f2131edd115 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/StackAllocatedBox.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/CompilerServices/StackAllocatedBox.cs @@ -7,7 +7,7 @@ namespace System.Runtime.CompilerServices { [NonVersionable] - [StructLayout(LayoutKind.Sequential)] + [StructLayout(LayoutKind.Sequential, Pack = 1)] internal unsafe struct StackAllocatedBox { // These fields are only accessed from jitted code