Skip to content

Commit 774bc93

Browse files
Use BitOperations.RoundUpToPowerOf2 in more places (#101405)
* Use BitOperations.RoundUpToPowerOf2 in ThreadLocal * Use BitOperations.RoundUpToPowerOf2 in CacheDict
1 parent 5111fdc commit 774bc93

File tree

2 files changed

+7
-46
lines changed
  • src/libraries

2 files changed

+7
-46
lines changed

src/libraries/System.Linq.Expressions/src/System/Dynamic/Utils/CacheDict.cs

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System.Diagnostics;
55
using System.Diagnostics.CodeAnalysis;
6+
using System.Numerics;
67
using System.Threading;
78

89
namespace System.Dynamic.Utils
@@ -40,27 +41,11 @@ internal Entry(int hash, TKey key, TValue value)
4041
/// <param name="size">The maximum number of elements to store will be this number aligned to next ^2.</param>
4142
internal CacheDict(int size)
4243
{
43-
int alignedSize = AlignSize(size);
44+
int alignedSize = (int)BitOperations.RoundUpToPowerOf2((uint)size);
4445
_mask = alignedSize - 1;
4546
_entries = new Entry[alignedSize];
4647
}
4748

48-
private static int AlignSize(int size)
49-
{
50-
Debug.Assert(size > 0);
51-
52-
size--;
53-
size |= size >> 1;
54-
size |= size >> 2;
55-
size |= size >> 4;
56-
size |= size >> 8;
57-
size |= size >> 16;
58-
size++;
59-
60-
Debug.Assert((size & (~size + 1)) == size, "aligned size should be a power of 2");
61-
return size;
62-
}
63-
6449
/// <summary>
6550
/// Tries to get the value associated with 'key', returning true if it's found and
6651
/// false if it's not present.

src/libraries/System.Private.CoreLib/src/System/Threading/ThreadLocal.cs

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Collections.Generic;
55
using System.Diagnostics;
66
using System.Diagnostics.CodeAnalysis;
7+
using System.Numerics;
78

89
// A class that provides a simple, lightweight implementation of thread-local lazy-initialization, where a value is initialized once per accessing
910
// thread; this provides an alternative to using a ThreadStatic static variable and having
@@ -552,40 +553,15 @@ private static int GetNewTableSize(int minSize)
552553
}
553554
Debug.Assert(minSize > 0);
554555

555-
//
556-
// Round up the size to the next power of 2
557-
//
558-
// The algorithm takes three steps:
559-
// input -> subtract one -> propagate 1-bits to the right -> add one
560-
//
561-
// Let's take a look at the 3 steps in both interesting cases: where the input
562-
// is (Example 1) and isn't (Example 2) a power of 2.
563-
//
564-
// Example 1: 100000 -> 011111 -> 011111 -> 100000
565-
// Example 2: 011010 -> 011001 -> 011111 -> 100000
566-
//
567-
int newSize = minSize;
568-
569-
// Step 1: Decrement
570-
newSize--;
571-
572-
// Step 2: Propagate 1-bits to the right.
573-
newSize |= newSize >> 1;
574-
newSize |= newSize >> 2;
575-
newSize |= newSize >> 4;
576-
newSize |= newSize >> 8;
577-
newSize |= newSize >> 16;
578-
579-
// Step 3: Increment
580-
newSize++;
556+
uint newSize = BitOperations.RoundUpToPowerOf2((uint)minSize);
581557

582558
// Don't set newSize to more than Array.MaxArrayLength
583-
if ((uint)newSize > Array.MaxLength)
559+
if (newSize > Array.MaxLength)
584560
{
585-
newSize = Array.MaxLength;
561+
newSize = (uint)Array.MaxLength;
586562
}
587563

588-
return newSize;
564+
return (int)newSize;
589565
}
590566

591567
/// <summary>

0 commit comments

Comments
 (0)