From 2d51acd91a1981ecd9c6b81637bcd111bde16ef1 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 23 Jun 2021 15:02:41 -0700 Subject: [PATCH 1/3] Use specialized new operators to correctly allocate space with the non-array new allocator for MethodDataObject and MethodDataInterfaceImpl. Fixes #54637 --- src/coreclr/vm/methodtable.cpp | 9 ++----- src/coreclr/vm/methodtable.h | 44 +++++++++++++++++++++++++++------- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/src/coreclr/vm/methodtable.cpp b/src/coreclr/vm/methodtable.cpp index 58e64187bc4a2..5cc309e1a15e7 100644 --- a/src/coreclr/vm/methodtable.cpp +++ b/src/coreclr/vm/methodtable.cpp @@ -8504,10 +8504,7 @@ MethodTable::GetMethodDataHelper( MethodDataWrapper hDecl(GetMethodData(pMTDecl, FALSE)); MethodDataWrapper hImpl(GetMethodData(pMTImpl, FALSE)); - UINT32 cb = MethodDataInterfaceImpl::GetObjectSize(pMTDecl); - NewArrayHolder pb(new BYTE[cb]); - MethodDataInterfaceImpl * pData = new (pb.GetValue()) MethodDataInterfaceImpl(rgDeclTypeIDs, cDeclTypeIDs, hDecl, hImpl); - pb.SuppressRelease(); + MethodDataInterfaceImpl * pData = new ({ pMTDecl }) MethodDataInterfaceImpl(rgDeclTypeIDs, cDeclTypeIDs, hDecl, hImpl); return pData; } // MethodTable::GetMethodDataHelper @@ -8548,10 +8545,8 @@ MethodTable::MethodData *MethodTable::GetMethodDataHelper(MethodTable *pMTDecl, } else { UINT32 cb = MethodDataObject::GetObjectSize(pMTDecl); - NewArrayHolder pb(new BYTE[cb]); MethodDataHolder h(FindParentMethodDataHelper(pMTDecl)); - pData = new (pb.GetValue()) MethodDataObject(pMTDecl, h.GetValue()); - pb.SuppressRelease(); + pData = new ({ pMTDecl }) MethodDataObject(pMTDecl, h.GetValue()); } } else { diff --git a/src/coreclr/vm/methodtable.h b/src/coreclr/vm/methodtable.h index 326bcce2c42ce..cc25165dc2aa0 100644 --- a/src/coreclr/vm/methodtable.h +++ b/src/coreclr/vm/methodtable.h @@ -3153,7 +3153,7 @@ public : protected: //-------------------------------------------------------------------------------------- - class MethodDataObject : public MethodData + class MethodDataObject final : public MethodData { public: // Static method that returns the amount of memory to allocate for a particular type. @@ -3233,19 +3233,32 @@ public : { LIMITED_METHOD_CONTRACT; return m_pMDImpl; } }; - // - // At the end of this object is an array, so you cannot derive from this class. - // inline MethodDataObjectEntry *GetEntryData() - { LIMITED_METHOD_CONTRACT; return (MethodDataObjectEntry *)(this + 1); } + { LIMITED_METHOD_CONTRACT; return &m_rgEntries[0]; } inline MethodDataObjectEntry *GetEntry(UINT32 i) { LIMITED_METHOD_CONTRACT; CONSISTENCY_CHECK(i < GetNumMethods()); return GetEntryData() + i; } void FillEntryDataForAncestor(MethodTable *pMT); - // MethodDataObjectEntry m_rgEntries[...]; + // + // At the end of this object is an array + // + MethodDataObjectEntry m_rgEntries[0]; + + public: + struct TargetMethodTable + { + MethodTable* pMT; + }; + + static void* operator new(size_t size, TargetMethodTable targetMT) + { + _ASSERTE(size <= GetObjectSize(targetMT.pMT)); + return ::operator new(GetObjectSize(targetMT.pMT)); + } + static void* operator new(size_t size) = delete; }; // class MethodDataObject //-------------------------------------------------------------------------------------- @@ -3299,7 +3312,7 @@ public : }; // class MethodDataInterface //-------------------------------------------------------------------------------------- - class MethodDataInterfaceImpl : public MethodData + class MethodDataInterfaceImpl final : public MethodData { public: // Object construction-related methods @@ -3373,12 +3386,25 @@ public : // inline MethodDataEntry *GetEntryData() - { LIMITED_METHOD_CONTRACT; return (MethodDataEntry *)(this + 1); } + { LIMITED_METHOD_CONTRACT; return &m_rgEntries[0]; } inline MethodDataEntry *GetEntry(UINT32 i) { LIMITED_METHOD_CONTRACT; CONSISTENCY_CHECK(i < GetNumMethods()); return GetEntryData() + i; } - // MethodDataEntry m_rgEntries[...]; + MethodDataEntry m_rgEntries[0]; + + public: + struct TargetMethodTable + { + MethodTable* pMT; + }; + + static void* operator new(size_t size, TargetMethodTable targetMT) + { + _ASSERTE(size <= GetObjectSize(targetMT.pMT)); + return ::operator new(GetObjectSize(targetMT.pMT)); + } + static void* operator new(size_t size) = delete; }; // class MethodDataInterfaceImpl //-------------------------------------------------------------------------------------- From 1e411793b5eb56c8d7bd0f8ebb5805ab6d552695 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Wed, 23 Jun 2021 15:27:41 -0700 Subject: [PATCH 2/3] Fix alloc-dealloc mismatch in ILStubResolver --- src/coreclr/vm/ilstubresolver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/ilstubresolver.cpp b/src/coreclr/vm/ilstubresolver.cpp index 2df8f543e9e7b..c79a03b8d08bb 100644 --- a/src/coreclr/vm/ilstubresolver.cpp +++ b/src/coreclr/vm/ilstubresolver.cpp @@ -344,7 +344,7 @@ ILStubResolver::AllocGeneratedIL( if (!UseLoaderHeap()) { NewArrayHolder pNewILCodeBuffer = new BYTE[cbCode]; - NewArrayHolder pNewCompileTimeState = (CompileTimeState*)new BYTE[sizeof(CompileTimeState)]; + NewHolder pNewCompileTimeState = new CompileTimeState{}; memset(pNewCompileTimeState, 0, sizeof(CompileTimeState)); NewArrayHolder pNewLocalSig = NULL; From b5313e2c459e7ad2b4859db184efb93b8d249fb4 Mon Sep 17 00:00:00 2001 From: Jeremy Koritzinsky Date: Thu, 24 Jun 2021 16:22:07 -0700 Subject: [PATCH 3/3] Update src/coreclr/vm/ilstubresolver.cpp --- src/coreclr/vm/ilstubresolver.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/vm/ilstubresolver.cpp b/src/coreclr/vm/ilstubresolver.cpp index c79a03b8d08bb..74cd62a70153a 100644 --- a/src/coreclr/vm/ilstubresolver.cpp +++ b/src/coreclr/vm/ilstubresolver.cpp @@ -345,7 +345,6 @@ ILStubResolver::AllocGeneratedIL( { NewArrayHolder pNewILCodeBuffer = new BYTE[cbCode]; NewHolder pNewCompileTimeState = new CompileTimeState{}; - memset(pNewCompileTimeState, 0, sizeof(CompileTimeState)); NewArrayHolder pNewLocalSig = NULL; if (0 != cbLocalSig)