Skip to content

Commit e5e1b7b

Browse files
committed
Optimize _byteCount with compiler intrinsics
Use compiler intrinsics to make _byteCount faster
1 parent 8a9b69b commit e5e1b7b

File tree

1 file changed

+28
-4
lines changed

1 file changed

+28
-4
lines changed

CoreFoundation/Parsing.subproj/CFBinaryPList.c

+28-4
Original file line numberDiff line numberDiff line change
@@ -518,23 +518,47 @@ static void _flattenPlist(CFPropertyListRef plist, CFMutableArrayRef objlist, CF
518518

519519
/* Get the number of bytes required to hold the value in 'count'. Will return a power of 2 value big enough to hold 'count'.
520520
*/
521-
CF_INLINE uint8_t _byteCount(uint64_t count) {
521+
CF_INLINE uint8_t _byteCount(uint64_t count)
522+
{
523+
if (count == 0)
524+
return 1U; // Special case 0 since it is undefined for __builtin_clzll
525+
526+
#if TARGET_OS_MAC
527+
// Count the number of leading 0s and subtract from the max value, which is 64
528+
unsigned int zeroCount = 64U - __builtin_clzll(count);
529+
530+
// Round to highest by 8 number
531+
zeroCount += -zeroCount & 7U;
532+
533+
// Divide by 8
534+
zeroCount >>= 3;
535+
536+
// Anything 8 or above just use the zeroCount
537+
if (zeroCount >= 8)
538+
return zeroCount;
539+
540+
// calculate nearest power of 2;
541+
return 1U << (32U - __builtin_ctz(zeroCount - 1));
542+
#else
522543
uint64_t mask = ~(uint64_t)0;
523544
uint8_t size = 0;
524545

525546
// Find something big enough to hold 'count'
526-
while (count & mask) {
547+
do
548+
{
527549
size++;
528550
mask = mask << 8;
529-
}
551+
} while (count & mask);
530552

531553
// Ensure that 'count' is a power of 2
532554
// For sizes bigger than 8, just use the required count
533-
while ((size != 1 && size != 2 && size != 4 && size != 8) && size <= 8) {
555+
while ((size != 2 && size != 4) && size <= 8)
556+
{
534557
size++;
535558
}
536559

537560
return size;
561+
#endif
538562
}
539563

540564
// stream can be a CFWriteStreamRef (on supported platforms) or a CFMutableDataRef

0 commit comments

Comments
 (0)