@@ -445,13 +445,7 @@ private static byte[] RentClean(int minLength)
445445
446446 if ( minLength > MaxCachedArrayLength )
447447 {
448- // Large buffers (Multicall memory, big returndata) would otherwise be fresh LOH allocations
449- // discarded every frame. Pool them through the runtime's per-core, low-contention shared pool
450- // rather than a hand-rolled cache: no per-thread large-array retention, no second pool to
451- // replicate. It may hand back a buffer dirtied by an earlier user, and RentSlow marks the whole
452- // array as zeroed, so clear the full length first. Buffers above the shared pool's 1 MB ceiling
453- // fall through to a plain allocation.
454- byte [ ] pooled = SafeArrayPool < byte > . Shared . Rent ( minLength ) ;
448+ byte [ ] pooled = RentLarge ( minLength ) ;
455449 Array . Clear ( pooled ) ;
456450 return pooled ;
457451 }
@@ -463,9 +457,7 @@ private static void ReturnClean(byte[] array, int dirtyLength)
463457 {
464458 if ( array . Length > MaxCachedArrayLength )
465459 {
466- // Large buffers only ever come from the shared pool above, so return them there for reuse
467- // instead of dropping them to GC. Cleared on rent rather than here to avoid double-zeroing.
468- SafeArrayPool < byte > . Shared . Return ( array ) ;
460+ ReturnLarge ( array ) ;
469461 return ;
470462 }
471463
@@ -477,6 +469,31 @@ private static void ReturnClean(byte[] array, int dirtyLength)
477469 }
478470 }
479471
472+ #if ZK_EVM
473+ private static byte [ ] RentLarge ( int minLength ) => SafeArrayPool < byte > . Shared . Rent ( minLength ) ;
474+
475+ private static void ReturnLarge ( byte [ ] array ) => SafeArrayPool < byte > . Shared . Return ( array ) ;
476+ #else
477+ private const int MaxSharedArrayLength = 1 << 20 ;
478+ // Above this, buffers fall back to plain allocation (not pooled), as before this change.
479+ private const int MaxLargePooledArrayLength = 1 << 22 ;
480+ private static readonly System . Buffers . ArrayPool < byte > _largeArrayPool =
481+ System . Buffers . ArrayPool < byte > . Create ( maxArrayLength : MaxLargePooledArrayLength , maxArraysPerBucket : 16 ) ;
482+
483+ private static byte [ ] RentLarge ( int minLength )
484+ => minLength > MaxSharedArrayLength
485+ ? _largeArrayPool . Rent ( minLength )
486+ : SafeArrayPool < byte > . Shared . Rent ( minLength ) ;
487+
488+ private static void ReturnLarge ( byte [ ] array )
489+ {
490+ if ( array . Length > MaxSharedArrayLength )
491+ _largeArrayPool . Return ( array ) ;
492+ else
493+ SafeArrayPool < byte > . Shared . Return ( array ) ;
494+ }
495+ #endif
496+
480497 [ MethodImpl ( MethodImplOptions . NoInlining ) ]
481498 private void RentSlow ( )
482499 {
0 commit comments