@@ -457,6 +457,17 @@ namespace snmalloc
457
457
458
458
constexpr SizeClassLookup sizeclass_lookup = SizeClassLookup();
459
459
460
+ /* *
461
+ * @brief Returns true if the size is a small sizeclass. Note that
462
+ * 0 is not considered a small sizeclass.
463
+ */
464
+ constexpr bool is_small_sizeclass (size_t size)
465
+ {
466
+ // Perform the - 1 on size, so that zero wraps around and ends up on
467
+ // slow path.
468
+ return (size - 1 ) < sizeclass_to_size (NUM_SMALL_SIZECLASSES - 1 );
469
+ }
470
+
460
471
constexpr smallsizeclass_t size_to_sizeclass (size_t size)
461
472
{
462
473
auto index = sizeclass_lookup_index (size);
@@ -482,7 +493,7 @@ namespace snmalloc
482
493
*/
483
494
static inline sizeclass_t size_to_sizeclass_full (size_t size)
484
495
{
485
- if ((size - 1 ) < sizeclass_to_size (NUM_SMALL_SIZECLASSES - 1 ))
496
+ if (is_small_sizeclass (size))
486
497
{
487
498
return sizeclass_t::from_small_class (size_to_sizeclass (size));
488
499
}
@@ -493,26 +504,28 @@ namespace snmalloc
493
504
494
505
inline SNMALLOC_FAST_PATH static size_t round_size (size_t size)
495
506
{
496
- if (size > sizeclass_to_size (NUM_SMALL_SIZECLASSES - 1 ))
507
+ if (is_small_sizeclass (size ))
497
508
{
498
- if (size > bits::one_at_bit (bits::BITS - 1 ))
499
- {
500
- // This size is too large, no rounding should occur as will result in a
501
- // failed allocation later.
502
- return size;
503
- }
504
- return bits::next_pow2 (size);
509
+ return sizeclass_to_size (size_to_sizeclass (size));
505
510
}
506
- // If realloc(ptr, 0) returns nullptr, some consumers treat this as a
507
- // reallocation failure and abort. To avoid this, we round up the size of
508
- // requested allocations to the smallest size class. This can be changed
509
- // on any platform that's happy to return nullptr from realloc(ptr,0) and
510
- // should eventually become a configuration option.
511
+
511
512
if (size == 0 )
512
513
{
514
+ // If realloc(ptr, 0) returns nullptr, some consumers treat this as a
515
+ // reallocation failure and abort. To avoid this, we round up the size of
516
+ // requested allocations to the smallest size class. This can be changed
517
+ // on any platform that's happy to return nullptr from realloc(ptr,0) and
518
+ // should eventually become a configuration option.
513
519
return sizeclass_to_size (size_to_sizeclass (1 ));
514
520
}
515
- return sizeclass_to_size (size_to_sizeclass (size));
521
+
522
+ if (size > bits::one_at_bit (bits::BITS - 1 ))
523
+ {
524
+ // This size is too large, no rounding should occur as will result in a
525
+ // failed allocation later.
526
+ return size;
527
+ }
528
+ return bits::next_pow2 (size);
516
529
}
517
530
518
531
// / Returns the alignment that this size naturally has, that is
@@ -549,9 +562,7 @@ namespace snmalloc
549
562
// sizeclass calculation. We use the same fast path constant to
550
563
// move the case where result==0 to the slow path, and then check for which
551
564
// case we are in.
552
- constexpr size_t SmallSizeClassUpperBound =
553
- sizeclass_to_size (NUM_SMALL_SIZECLASSES - 1 ) - 1 ;
554
- if (SNMALLOC_LIKELY ((result - 1 ) < SmallSizeClassUpperBound))
565
+ if (is_small_sizeclass (result))
555
566
return result;
556
567
557
568
// We are in the slow path, so we need to check for overflow.
0 commit comments