@@ -129,17 +129,6 @@ namespace snmalloc
129
129
130
130
using sizeclass_compress_t = uint8_t ;
131
131
132
- constexpr SNMALLOC_FAST_PATH static size_t
133
- aligned_size (size_t alignment, size_t size)
134
- {
135
- // Client responsible for checking alignment is not zero
136
- SNMALLOC_ASSERT (alignment != 0 );
137
- // Client responsible for checking alignment is a power of two
138
- SNMALLOC_ASSERT (bits::is_pow2 (alignment));
139
-
140
- return ((alignment - 1 ) | (size - 1 )) + 1 ;
141
- }
142
-
143
132
/* *
144
133
* This structure contains the fields required for fast paths for sizeclasses.
145
134
*/
@@ -535,4 +524,43 @@ namespace snmalloc
535
524
return 1 ;
536
525
return bits::one_at_bit (bits::ctz (rsize));
537
526
}
527
+
528
+ constexpr SNMALLOC_FAST_PATH static size_t
529
+ aligned_size (size_t alignment, size_t size)
530
+ {
531
+ // Client responsible for checking alignment is not zero
532
+ SNMALLOC_ASSERT (alignment != 0 );
533
+ // Client responsible for checking alignment is a power of two
534
+ SNMALLOC_ASSERT (bits::is_pow2 (alignment));
535
+
536
+ // There are a class of corner cases to consider
537
+ // alignment = 0x8
538
+ // size = 0xfff...fff7
539
+ // for this result will be 0. This should fail an allocation, so we need to
540
+ // check for this overflow.
541
+ // However,
542
+ // alignment = 0x8
543
+ // size = 0x0
544
+ // will also result in 0, but this should be allowed to allocate.
545
+ // So we need to check for overflow, and return SIZE_MAX in this first case,
546
+ // and 0 in the second.
547
+ size_t result = ((alignment - 1 ) | (size - 1 )) + 1 ;
548
+ // The following code is designed to fuse well with a subsequent
549
+ // sizeclass calculation. We use the same fast path constant to
550
+ // move the case where result==0 to the slow path, and then check for which
551
+ // 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))
555
+ return result;
556
+
557
+ // We are in the slow path, so we need to check for overflow.
558
+ if (SNMALLOC_UNLIKELY (result == 0 ))
559
+ {
560
+ // Check for overflow and return the maximum size.
561
+ if (SNMALLOC_UNLIKELY (result < size))
562
+ return SIZE_MAX;
563
+ }
564
+ return result;
565
+ }
538
566
} // namespace snmalloc
0 commit comments