Skip to content

Commit 5d8b3d6

Browse files
Fix max chunk size limiting (#81607)
When the new stub heaps were implemented, the chunk size needed to be limited so that all precodes for a chunk fit into a single memory page. That was done in `MethodDescChunk::CreateChunk`. But it was discovered now that there is another place where it needs to be limited, the `MethodTableBuilder::AllocAndInitMethodDescChunk`. The JIT\opt\ObjectStackAllocation\ObjectStackAllocationTests started to fail in the outerloop due to too long chunk. The failure happens in crossgen2 as it is using a separate build of runtime in release and only that uncovers the problem. And only when DOTNET_TieredCompilation=0 and DOTNET_ProfApi_RejitOnAttach=0. This change fixes the problem. With this change applied to the dotnet runtime version used by the crossgen2 and patching it in place in the .dotnet/shared/.... directory, the issue doesn't occur. Close #81103 Co-authored-by: Jan Vorlicek <janvorli@microsoft.com>
1 parent 341b81c commit 5d8b3d6

1 file changed

Lines changed: 11 additions & 1 deletion

File tree

src/coreclr/vm/methodtablebuilder.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6871,9 +6871,15 @@ VOID MethodTableBuilder::AllocAndInitMethodDescs()
68716871
SIZE_T sizeOfMethodDescs = 0; // current running size of methodDesc chunk
68726872
int startIndex = 0; // start of the current chunk (index into bmtMethod array)
68736873

6874+
// Limit the maximum MethodDescs per chunk by the number of precodes that can fit to a single memory page,
6875+
// since we allocate consecutive temporary entry points for all MethodDescs in the whole chunk.
6876+
DWORD maxPrecodesPerPage = Precode::GetMaxTemporaryEntryPointsCount();
6877+
DWORD methodDescCount = 0;
6878+
68746879
DeclaredMethodIterator it(*this);
68756880
while (it.Next())
68766881
{
6882+
DWORD currentSlotMethodDescCount = 1;
68776883
int tokenRange = GetTokenRange(it.Token());
68786884

68796885
// This code assumes that iterator returns tokens in ascending order. If this assumption does not hold,
@@ -6896,6 +6902,7 @@ VOID MethodTableBuilder::AllocAndInitMethodDescs()
68966902
// See comment in AllocAndInitMethodDescChunk
68976903
if (NeedsTightlyBoundUnboxingStub(*it))
68986904
{
6905+
currentSlotMethodDescCount = 2;
68996906
size *= 2;
69006907

69016908
if (bmtGenerics->GetNumGenericArgs() == 0) {
@@ -6907,7 +6914,8 @@ VOID MethodTableBuilder::AllocAndInitMethodDescs()
69076914
}
69086915

69096916
if (tokenRange != currentTokenRange ||
6910-
sizeOfMethodDescs + size > MethodDescChunk::MaxSizeOfMethodDescs)
6917+
sizeOfMethodDescs + size > MethodDescChunk::MaxSizeOfMethodDescs ||
6918+
methodDescCount + currentSlotMethodDescCount > maxPrecodesPerPage)
69116919
{
69126920
if (sizeOfMethodDescs != 0)
69136921
{
@@ -6917,9 +6925,11 @@ VOID MethodTableBuilder::AllocAndInitMethodDescs()
69176925

69186926
currentTokenRange = tokenRange;
69196927
sizeOfMethodDescs = 0;
6928+
methodDescCount = 0;
69206929
}
69216930

69226931
sizeOfMethodDescs += size;
6932+
methodDescCount += currentSlotMethodDescCount;
69236933
}
69246934

69256935
if (sizeOfMethodDescs != 0)

0 commit comments

Comments
 (0)