@@ -510,6 +510,7 @@ private static bool NumberToBigInteger(ref BigNumberBuffer number, out BigIntege
510510 int currentBufferSize = 0 ;
511511
512512 int [ ] ? arrayFromPool = null ;
513+ int [ ] ? rentedBuffer = null ;
513514
514515 int totalDigitCount = 0 ;
515516 int numberScale = number . scale ;
@@ -607,11 +608,24 @@ bool ProcessChunk(ReadOnlySpan<char> chunkDigits, ref Span<uint> currentBuffer)
607608 int bufferSize = ( totalDigitCount + MaxPartialDigits - 1 ) / MaxPartialDigits ;
608609
609610 Span < uint > buffer = new uint [ bufferSize ] ;
611+ rentedBuffer = ArrayPool < int > . Shared . Rent ( bufferSize ) ;
612+ Span < uint > newBuffer = MemoryMarshal . Cast < int , uint > ( rentedBuffer ) ;
613+ newBuffer . Clear ( ) ;
614+
615+ // To ensure finally stored in newBuffer is the borrowed buffer.
616+ int blockSize = 1 ;
617+ do
618+ {
619+ Span < uint > tmp = buffer ;
620+ buffer = newBuffer ;
621+ newBuffer = tmp ;
622+ blockSize *= 2 ;
623+ } while ( blockSize < bufferSize ) ;
610624
611625 // Separate every MaxPartialDigits digits and store them in the buffer.
612626 // Buffers are treated as little-endian. That means, the array { 234567890, 1 }
613627 // represents the number 1234567890.
614- int bufferIndex = buffer . Length - 1 ;
628+ int bufferIndex = bufferSize - 1 ;
615629 uint currentBlock = 0 ;
616630 int shiftUntil = ( totalDigitCount - 1 ) % MaxPartialDigits ;
617631 int remainingIntDigitCount = totalDigitCount ;
@@ -658,13 +672,11 @@ bool ProcessChunk(ReadOnlySpan<char> chunkDigits, ref Span<uint> currentBuffer)
658672
659673 unsafe
660674 {
661- Span < uint > newBuffer = new uint [ bufferSize ] ;
662-
663675 arrayFromPool = ArrayPool < int > . Shared . Rent ( 1 ) ;
664676 Span < uint > multiplier = MemoryMarshal . Cast < int , uint > ( arrayFromPool ) ;
665677 multiplier [ 0 ] = TenPowMaxPartial ;
666678
667- int blockSize = 1 ;
679+ blockSize = 1 ;
668680 while ( true )
669681 {
670682 fixed ( uint * bufPtr = buffer , newBufPtr = newBuffer , mulPtr = multiplier )
@@ -739,6 +751,8 @@ bool ProcessChunk(ReadOnlySpan<char> chunkDigits, ref Span<uint> currentBuffer)
739751 }
740752 }
741753
754+ Debug . Assert ( MemoryMarshal . Cast < int , uint > ( rentedBuffer ) == newBuffer ) ;
755+
742756 // shrink buffer to the currently used portion.
743757 // First, calculate the rough size of the buffer from the ratio that the number
744758 // of digits follows. Then, shrink the size until there is no more space left.
@@ -794,6 +808,10 @@ bool ProcessChunk(ReadOnlySpan<char> chunkDigits, ref Span<uint> currentBuffer)
794808 {
795809 ArrayPool < int > . Shared . Return ( arrayFromPool ) ;
796810 }
811+ if ( rentedBuffer != null )
812+ {
813+ ArrayPool < int > . Shared . Return ( rentedBuffer ) ;
814+ }
797815 }
798816
799817 void MultiplyAdd ( ref Span < uint > currentBuffer , uint multiplier , uint addValue )
0 commit comments