@@ -261,6 +261,27 @@ class DebugAllocator {
261
261
return Status::OK ();
262
262
}
263
263
264
+ static bool ResizeInPlace (int64_t old_size, int64_t new_size, uint8_t * ptr) {
265
+ CheckAllocatedArea (ptr, old_size, " in-place expanding" );
266
+ if (old_size == 0 || new_size == 0 ) {
267
+ // Cannot expand
268
+ return false ;
269
+ }
270
+ auto maybe_raw_new_size = RawSize (new_size);
271
+ if (!maybe_raw_new_size.ok ()) {
272
+ return false ;
273
+ }
274
+ int64_t raw_new_size = *maybe_raw_new_size;
275
+ DCHECK (raw_new_size > new_size)
276
+ << " bug in raw size computation: " << raw_new_size << " for size " << new_size;
277
+ bool success =
278
+ WrappedAllocator::ResizeInPlace (old_size + kOverhead , raw_new_size, ptr);
279
+ if (success) {
280
+ InitAllocatedArea (ptr, new_size);
281
+ }
282
+ return success;
283
+ }
284
+
264
285
static void DeallocateAligned (uint8_t * ptr, int64_t size, int64_t alignment) {
265
286
CheckAllocatedArea (ptr, size, " deallocation" );
266
287
if (ptr != memory_pool::internal::kZeroSizeArea ) {
@@ -363,6 +384,11 @@ class SystemAllocator {
363
384
return Status::OK ();
364
385
}
365
386
387
+ static bool ResizeInPlace (int64_t old_size, int64_t new_size, uint8_t * ptr) {
388
+ // No standard C API for this
389
+ return false ;
390
+ }
391
+
366
392
static void DeallocateAligned (uint8_t * ptr, int64_t size, int64_t /* alignment*/ ) {
367
393
if (ptr == memory_pool::internal::kZeroSizeArea ) {
368
394
DCHECK_EQ (size, 0 );
@@ -425,6 +451,14 @@ class MimallocAllocator {
425
451
return Status::OK ();
426
452
}
427
453
454
+ static bool ResizeInPlace (int64_t old_size, int64_t new_size, uint8_t * ptr) {
455
+ if (old_size == 0 || new_size == 0 ) {
456
+ // Cannot resize
457
+ return false ;
458
+ }
459
+ return mi_expand (ptr, static_cast <size_t >(new_size)) != nullptr ;
460
+ }
461
+
428
462
static void DeallocateAligned (uint8_t * ptr, int64_t size, int64_t /* alignment*/ ) {
429
463
if (ptr == memory_pool::internal::kZeroSizeArea ) {
430
464
DCHECK_EQ (size, 0 );
@@ -498,6 +532,43 @@ class BaseMemoryPoolImpl : public MemoryPool {
498
532
return Status::OK ();
499
533
}
500
534
535
+ Status ReallocateNoCopy (int64_t old_size, int64_t new_size, int64_t alignment,
536
+ uint8_t ** ptr) override {
537
+ if (new_size == old_size) {
538
+ return Status::OK ();
539
+ }
540
+ if (new_size < 0 ) {
541
+ return Status::Invalid (" negative realloc size" );
542
+ }
543
+ if (static_cast <uint64_t >(new_size) >= std::numeric_limits<size_t >::max ()) {
544
+ return Status::OutOfMemory (" realloc overflows size_t" );
545
+ }
546
+ // First try resizing in place
547
+ if (!Allocator::ResizeInPlace (old_size, new_size, *ptr)) {
548
+ // TODO comment
549
+ if (std::max (old_size, new_size) >= 32 * 1024 ) {
550
+ // Deallocate then allocate (faster than copying data?)
551
+ Allocator::DeallocateAligned (*ptr, old_size, alignment);
552
+ RETURN_NOT_OK (Allocator::AllocateAligned (new_size, alignment, ptr));
553
+ } else {
554
+ RETURN_NOT_OK (Allocator::ReallocateAligned (old_size, new_size, alignment, ptr));
555
+ }
556
+ }
557
+ #ifndef NDEBUG
558
+ // Poison data
559
+ if (new_size > 0 ) {
560
+ DCHECK_NE (*ptr, nullptr );
561
+ if (new_size > old_size) {
562
+ (*ptr)[old_size] = kReallocPoison ;
563
+ }
564
+ (*ptr)[new_size - 1 ] = kReallocPoison ;
565
+ }
566
+ #endif
567
+
568
+ stats_.UpdateAllocatedBytes (new_size - old_size);
569
+ return Status::OK ();
570
+ }
571
+
501
572
void Free (uint8_t * buffer, int64_t size, int64_t alignment) override {
502
573
#ifndef NDEBUG
503
574
// Poison data
@@ -721,6 +792,14 @@ Status LoggingMemoryPool::Reallocate(int64_t old_size, int64_t new_size,
721
792
return s;
722
793
}
723
794
795
+ Status LoggingMemoryPool::ReallocateNoCopy (int64_t old_size, int64_t new_size,
796
+ int64_t alignment, uint8_t ** ptr) {
797
+ Status s = pool_->ReallocateNoCopy (old_size, new_size, ptr);
798
+ std::cout << " ReallocateNoCopy: old_size = " << old_size << " , new_size = " << new_size
799
+ << " , alignment = " << alignment << std::endl;
800
+ return s;
801
+ }
802
+
724
803
void LoggingMemoryPool::Free (uint8_t * buffer, int64_t size, int64_t alignment) {
725
804
pool_->Free (buffer, size, alignment);
726
805
std::cout << " Free: size = " << size << " , alignment = " << alignment << std::endl;
@@ -772,6 +851,13 @@ class ProxyMemoryPool::ProxyMemoryPoolImpl {
772
851
return Status::OK ();
773
852
}
774
853
854
+ Status ReallocateNoCopy (int64_t old_size, int64_t new_size, int64_t alignment,
855
+ uint8_t ** ptr) {
856
+ RETURN_NOT_OK (pool_->ReallocateNoCopy (old_size, new_size, alignment, ptr));
857
+ stats_.UpdateAllocatedBytes (new_size - old_size);
858
+ return Status::OK ();
859
+ }
860
+
775
861
void Free (uint8_t * buffer, int64_t size, int64_t alignment) {
776
862
pool_->Free (buffer, size, alignment);
777
863
stats_.UpdateAllocatedBytes (-size, /* is_free=*/ true );
@@ -807,6 +893,11 @@ Status ProxyMemoryPool::Reallocate(int64_t old_size, int64_t new_size, int64_t a
807
893
return impl_->Reallocate (old_size, new_size, alignment, ptr);
808
894
}
809
895
896
+ Status ProxyMemoryPool::ReallocateNoCopy (int64_t old_size, int64_t new_size,
897
+ int64_t alignment, uint8_t ** ptr) {
898
+ return impl_->ReallocateNoCopy (old_size, new_size, alignment, ptr);
899
+ }
900
+
810
901
void ProxyMemoryPool::Free (uint8_t * buffer, int64_t size, int64_t alignment) {
811
902
return impl_->Free (buffer, size, alignment);
812
903
}
0 commit comments