From cab949098dcdab9d458f102eb59e81311bac45c4 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Sun, 3 Feb 2019 09:07:09 -0800 Subject: Use unsigned index extension in muldi-dimensional array stubs (#22376) Delete unnecessary parallel logic that kept track of the total multiplier Fixes #22348 --- src/vm/array.cpp | 38 +++++++-------------- .../coreclr/GitHub_22348/Test22348.csproj | 39 ++++++++++++++++++++++ .../Regressions/coreclr/GitHub_22348/test22348.cs | 23 +++++++++++++ 3 files changed, 74 insertions(+), 26 deletions(-) create mode 100644 tests/src/Regressions/coreclr/GitHub_22348/Test22348.csproj create mode 100644 tests/src/Regressions/coreclr/GitHub_22348/test22348.cs diff --git a/src/vm/array.cpp b/src/vm/array.cpp index d5366a28d1..2c0c936d94 100644 --- a/src/vm/array.cpp +++ b/src/vm/array.cpp @@ -781,7 +781,6 @@ public: BOOL fHasLowerBounds = pMT->GetInternalCorElementType() == ELEMENT_TYPE_ARRAY; DWORD dwTotalLocalNum = NewLocal(ELEMENT_TYPE_I4); - DWORD dwFactorLocalNum = NewLocal(ELEMENT_TYPE_I4); DWORD dwLengthLocalNum = NewLocal(ELEMENT_TYPE_I4); mdToken tokRawData = GetToken(MscorlibBinder::GetField(FIELD__RAW_DATA__DATA)); @@ -793,16 +792,13 @@ public: ILCodeLabel * pTypeMismatchExceptionLabel = NULL; UINT rank = pMT->GetRank(); - UINT idx = rank; UINT firstIdx = 0; UINT hiddenArgIdx = rank; _ASSERTE(rank>0); - #ifndef _TARGET_X86_ if(m_pMD->GetArrayFuncIndex() == ArrayMethodDesc::ARRAY_FUNC_ADDRESS) { - idx++; firstIdx = 1; hiddenArgIdx = 0; } @@ -903,30 +899,30 @@ public: m_pCode->EmitLDFLDA(tokRawData); m_pCode->EmitLDC(ArrayBase::GetBoundsOffset(pMT) - Object::GetOffsetOfFirstField()); m_pCode->EmitADD(); - m_pCode->EmitLDARG(firstIdx); + m_pCode->EmitLDARG(firstIdx); m_pCode->EmitBR(pCheckDone); m_pCode->EmitLabel(pNotSZArray); } - while(idx-- > firstIdx) + for (UINT i = 0; i < rank; i++) { // Cache length m_pCode->EmitLoadThis(); m_pCode->EmitLDFLDA(tokRawData); - m_pCode->EmitLDC((ArrayBase::GetBoundsOffset(pMT) - Object::GetOffsetOfFirstField()) + (idx-firstIdx)*sizeof(DWORD)); + m_pCode->EmitLDC((ArrayBase::GetBoundsOffset(pMT) - Object::GetOffsetOfFirstField()) + i*sizeof(DWORD)); m_pCode->EmitADD(); m_pCode->EmitLDIND_I4(); m_pCode->EmitSTLOC(dwLengthLocalNum); // Fetch index - m_pCode->EmitLDARG(idx); + m_pCode->EmitLDARG(firstIdx + i); if (fHasLowerBounds) { // Load lower bound m_pCode->EmitLoadThis(); m_pCode->EmitLDFLDA(tokRawData); - m_pCode->EmitLDC((ArrayBase::GetLowerBoundsOffset(pMT) - Object::GetOffsetOfFirstField()) + (idx-firstIdx)*sizeof(DWORD)); + m_pCode->EmitLDC((ArrayBase::GetLowerBoundsOffset(pMT) - Object::GetOffsetOfFirstField()) + i*sizeof(DWORD)); m_pCode->EmitADD(); m_pCode->EmitLDIND_I4(); @@ -940,26 +936,14 @@ public: m_pCode->EmitBGE_UN(pRangeExceptionLabel1); // Add to the running total if we have one already - if ((idx-firstIdx) != (rank - 1)) + if (i > 0) { - m_pCode->EmitLDLOC(dwFactorLocalNum); - m_pCode->EmitMUL(); m_pCode->EmitLDLOC(dwTotalLocalNum); + m_pCode->EmitLDLOC(dwLengthLocalNum); + m_pCode->EmitMUL(); m_pCode->EmitADD(); } m_pCode->EmitSTLOC(dwTotalLocalNum); - - // Update factor if this is not the last iteration - if ((idx-firstIdx) != 0) - { - m_pCode->EmitLDLOC(dwLengthLocalNum); - if ((idx-firstIdx) != (rank - 1)) - { - m_pCode->EmitLDLOC(dwFactorLocalNum); - m_pCode->EmitMUL(); - } - m_pCode->EmitSTLOC(dwFactorLocalNum); - } } // Compute element address @@ -968,9 +952,11 @@ public: m_pCode->EmitLDC(ArrayBase::GetDataPtrOffset(pMT) - Object::GetOffsetOfFirstField()); m_pCode->EmitADD(); m_pCode->EmitLDLOC(dwTotalLocalNum); - + m_pCode->EmitLabel(pCheckDone); - + + m_pCode->EmitCONV_U(); + SIZE_T elemSize = pMT->GetComponentSize(); if (elemSize != 1) { diff --git a/tests/src/Regressions/coreclr/GitHub_22348/Test22348.csproj b/tests/src/Regressions/coreclr/GitHub_22348/Test22348.csproj new file mode 100644 index 0000000000..2fefb9c7af --- /dev/null +++ b/tests/src/Regressions/coreclr/GitHub_22348/Test22348.csproj @@ -0,0 +1,39 @@ + + + + + Debug + AnyCPU + 2.0 + {E55A6F8B-B9E3-45CE-88F4-22AE70F606CB} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + BuildAndRun + 1 + + + + + + + + + False + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/src/Regressions/coreclr/GitHub_22348/test22348.cs b/tests/src/Regressions/coreclr/GitHub_22348/test22348.cs new file mode 100644 index 0000000000..383e575569 --- /dev/null +++ b/tests/src/Regressions/coreclr/GitHub_22348/test22348.cs @@ -0,0 +1,23 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using System; + +public class Test22348 +{ + public static int Main() + { + try + { + byte[,] tooBig = new byte[267784, 15351]; + tooBig[139893, 12] = 100; + return (byte)tooBig.GetValue(139893, 12); + } + catch (OutOfMemoryException e) + { + Console.WriteLine(e); + } + + return 100; + } +} -- cgit v1.2.3