Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use BitOperations in more places #76933

Merged
merged 1 commit into from
Oct 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
Expand Down Expand Up @@ -45,7 +46,7 @@ internal ConcurrentQueueSegment(int boundedLength)
{
// Validate the length
Debug.Assert(boundedLength >= 2, $"Must be >= 2, got {boundedLength}");
Debug.Assert((boundedLength & (boundedLength - 1)) == 0, $"Must be a power of 2, got {boundedLength}");
Debug.Assert(BitOperations.IsPow2(boundedLength), $"Must be a power of 2, got {boundedLength}");
stephentoub marked this conversation as resolved.
Show resolved Hide resolved

// Initialize the slots and the mask. The mask is used as a way of quickly doing "% _slots.Length",
// instead letting us do "& _slotsMask".
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5214,20 +5214,20 @@ public void AddTask(string name, int value)

public void AddKeyword(string name, ulong value)
{
if ((value & (value - 1)) != 0) // Is it a power of 2?
if ((value & (value - 1)) != 0) // Must be zero or a power of 2
stephentoub marked this conversation as resolved.
Show resolved Hide resolved
{
ManifestError(SR.Format(SR.EventSource_KeywordNeedPowerOfTwo, "0x" + value.ToString("x", CultureInfo.CurrentCulture), name), true);
ManifestError(SR.Format(SR.EventSource_KeywordNeedPowerOfTwo, $"0x{value:x}", name), true);
}
if ((flags & EventManifestOptions.Strict) != 0)
{
if (value >= 0x0000100000000000UL && !name.StartsWith("Session", StringComparison.Ordinal))
{
ManifestError(SR.Format(SR.EventSource_IllegalKeywordsValue, name, "0x" + value.ToString("x", CultureInfo.CurrentCulture)));
ManifestError(SR.Format(SR.EventSource_IllegalKeywordsValue, name, $"0x{value:x}"));
}

if (keywordTab != null && keywordTab.TryGetValue(value, out string? prevName) && !name.Equals(prevName, StringComparison.Ordinal))
{
ManifestError(SR.Format(SR.EventSource_KeywordCollision, name, prevName, "0x" + value.ToString("x", CultureInfo.CurrentCulture)));
ManifestError(SR.Format(SR.EventSource_KeywordCollision, name, prevName, $"0x{value:x}"));
}
}

Expand Down Expand Up @@ -5590,7 +5590,7 @@ static FieldInfo[] GetEnumFields(Type localEnumType)

// ETW requires all bitmap values to be powers of 2. Skip the ones that are not.
// TODO: Warn people about the dropping of values.
if (isbitmap && ((hexValue & (hexValue - 1)) != 0 || hexValue == 0))
if (isbitmap && !BitOperations.IsPow2(hexValue))
continue;

hexValue.TryFormat(ulongHexScratch, out int charsWritten, "x");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Numerics;
using System.Threading;

namespace System.Runtime.CompilerServices
Expand Down Expand Up @@ -403,8 +403,6 @@ private void CreateEntry(TKey key, TValue value)
c.CreateEntryNoResize(key, value);
}

private static bool IsPowerOfTwo(int value) => (value > 0) && ((value & (value - 1)) == 0);

//--------------------------------------------------------------------------------------------
// Entry can be in one of four states:
//
Expand Down Expand Up @@ -462,7 +460,7 @@ private sealed class Container
internal Container(ConditionalWeakTable<TKey, TValue> parent)
{
Debug.Assert(parent != null);
Debug.Assert(IsPowerOfTwo(InitialCapacity));
Debug.Assert(BitOperations.IsPow2(InitialCapacity));

const int Size = InitialCapacity;
_buckets = new int[Size];
Expand All @@ -485,7 +483,7 @@ private Container(ConditionalWeakTable<TKey, TValue> parent, int[] buckets, Entr
Debug.Assert(buckets != null);
Debug.Assert(entries != null);
Debug.Assert(buckets.Length == entries.Length);
Debug.Assert(IsPowerOfTwo(buckets.Length));
Debug.Assert(BitOperations.IsPow2(buckets.Length));

_parent = parent;
_buckets = buckets;
Expand Down Expand Up @@ -678,7 +676,7 @@ internal Container Resize()
internal Container Resize(int newSize)
{
Debug.Assert(newSize >= _buckets.Length);
Debug.Assert(IsPowerOfTwo(newSize));
Debug.Assert(BitOperations.IsPow2(newSize));

// Reallocate both buckets and entries and rebuild the bucket and entries from scratch.
// This serves both to scrub entries with expired keys and to put the new entries in the proper bucket.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using System.Threading;
using Debug = System.Diagnostics.Debug;
using Interlocked = System.Threading.Interlocked;
Expand Down Expand Up @@ -143,7 +144,7 @@ private sealed class XHashtableState
/// </summary>
public XHashtableState(ExtractKeyDelegate extractKey, int capacity)
{
Debug.Assert((capacity & (capacity - 1)) == 0, "capacity must be a power of 2");
Debug.Assert(BitOperations.IsPow2(capacity), "capacity must be a power of 2");
Debug.Assert(extractKey != null, "extractKey may not be null");

// Initialize hash table data structures, with specified maximum capacity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
<Compile Include="System\Xml\BinHexDecoder.cs" />
<Compile Include="System\Xml\BinHexEncoder.cs" />
<Compile Include="System\Xml\BinHexEncoderAsync.cs" />
<Compile Include="System\Xml\Bits.cs" />
<Compile Include="System\Xml\BitStack.cs" />
<Compile Include="System\Xml\ByteStack.cs" />
<Compile Include="System\Xml\Core\HtmlEncodedRawTextWriter.cs">
Expand Down
62 changes: 0 additions & 62 deletions src/libraries/System.Private.Xml/src/System/Xml/Bits.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Xml;
using System.Diagnostics;
using System.Numerics;
using System.Text;
using System.Xml;

namespace System.Xml.Schema
{
Expand Down Expand Up @@ -176,10 +177,10 @@ internal static bool TryParse(string text, XsdDateTimeFlags kinds, out XsdDateTi
/// </summary>
public XsdDateTime(DateTime dateTime, XsdDateTimeFlags kinds)
{
Debug.Assert(Bits.ExactlyOne((uint)kinds), "Only one DateTime type code can be set.");
Debug.Assert(BitOperations.IsPow2((uint)kinds), "One and only one DateTime type code can be set.");
_dt = dateTime;

DateTimeTypeCode code = (DateTimeTypeCode)(Bits.LeastPosition((uint)kinds) - 1);
DateTimeTypeCode code = (DateTimeTypeCode)BitOperations.TrailingZeroCount((uint)kinds);
int zoneHour = 0;
int zoneMinute = 0;
XsdDateTimeKind kind;
Expand Down Expand Up @@ -220,12 +221,12 @@ public XsdDateTime(DateTimeOffset dateTimeOffset) : this(dateTimeOffset, XsdDate

public XsdDateTime(DateTimeOffset dateTimeOffset, XsdDateTimeFlags kinds)
{
Debug.Assert(Bits.ExactlyOne((uint)kinds), "Only one DateTime type code can be set.");
Debug.Assert(BitOperations.IsPow2((uint)kinds), "Only one DateTime type code can be set.");

_dt = dateTimeOffset.DateTime;

TimeSpan zoneOffset = dateTimeOffset.Offset;
DateTimeTypeCode code = (DateTimeTypeCode)(Bits.LeastPosition((uint)kinds) - 1);
DateTimeTypeCode code = (DateTimeTypeCode)BitOperations.TrailingZeroCount((uint)kinds);
XsdDateTimeKind kind;
if (zoneOffset.TotalMinutes < 0)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Schema;
using System.Globalization;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Numerics;
using System.Reflection;
using System.Reflection.Emit;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.Xml.Xsl.Qil;
using System.Xml.Xsl.Runtime;
using System.Diagnostics.CodeAnalysis;
using TypeFactory = System.Xml.Xsl.XmlQueryTypeFactory;

namespace System.Xml.Xsl.IlGen
Expand Down Expand Up @@ -3263,7 +3264,7 @@ private bool MatchesNodeKinds(QilTargetType ndIsType, XmlQueryType typDerived, X
kinds = typDerived.NodeKinds & kinds;

// Attempt to allow or disallow exactly one kind
if (!Bits.ExactlyOne((uint)kinds))
if (!BitOperations.IsPow2((uint)kinds))
{
// Not possible to allow one kind, so try to disallow one kind
kinds = ~kinds & XmlNodeKindFlags.Any;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Numerics;
using System.Xml.Schema;
using System.Xml.XPath;
using TF = System.Xml.Xsl.XmlQueryTypeFactory;
Expand Down Expand Up @@ -699,17 +700,20 @@ private sealed class ChoiceType : XmlQueryType
public static XmlQueryType Create(XmlNodeKindFlags nodeKinds)
{
List<XmlQueryType> members;
uint kinds = (uint)nodeKinds;

// If exactly one kind is set, then create singleton ItemType
if (Bits.ExactlyOne((uint)nodeKinds))
return ItemType.Create(s_nodeKindToTypeCode[Bits.LeastPosition((uint)nodeKinds)], false);
if (BitOperations.IsPow2(kinds))
{
return ItemType.Create(s_nodeKindToTypeCode[BitOperations.TrailingZeroCount(kinds) + 1], false);
}

members = new List<XmlQueryType>();
while (nodeKinds != XmlNodeKindFlags.None)
while (kinds != 0)
stephentoub marked this conversation as resolved.
Show resolved Hide resolved
{
members.Add(ItemType.Create(s_nodeKindToTypeCode[Bits.LeastPosition((uint)nodeKinds)], false));
members.Add(ItemType.Create(s_nodeKindToTypeCode[BitOperations.TrailingZeroCount(kinds) + 1], false));

nodeKinds = (XmlNodeKindFlags)Bits.ClearLeast((uint)nodeKinds);
kinds &= kinds - 1;
}

return Create(members);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using QilName = System.Xml.Xsl.Qil.QilName;

namespace System.Xml.Xsl.Xslt
Expand Down Expand Up @@ -145,7 +146,7 @@ private void AddRecord()

private void AddRecord(ScopeFlags flag, string? ncName, string? uri, [AllowNull] V value)
{
Debug.Assert(flag == (flag & ScopeFlags.ExclusiveFlags) && (flag & (flag - 1)) == 0 && flag != 0, "One exclusive flag");
Debug.Assert(flag == (flag & ScopeFlags.ExclusiveFlags) && BitOperations.IsPow2((uint)flag), "One exclusive flag");
Debug.Assert(uri != null || ncName == null, "null, null means exclude '#all'");

ScopeFlags flags = _records[_lastRecord].flags;
Expand All @@ -164,7 +165,7 @@ private void AddRecord(ScopeFlags flag, string? ncName, string? uri, [AllowNull]

private void SetFlag(ScopeFlags flag, bool value)
{
Debug.Assert(flag == (flag & ScopeFlags.InheritedFlags) && (flag & (flag - 1)) == 0 && flag != 0, "one inherited flag");
Debug.Assert(flag == (flag & ScopeFlags.InheritedFlags) && BitOperations.IsPow2((uint)flag), "one inherited flag");
ScopeFlags flags = _records[_lastRecord].flags;
if (((flags & flag) != 0) != value)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Numerics;
using System.Xml.Xsl.Qil;
using System.Xml.Xsl.XPath;
using T = System.Xml.Xsl.XmlQueryTypeFactory;
Expand Down Expand Up @@ -179,7 +180,7 @@ private void NipOffTypeNameCheck()
}

XmlNodeKindFlags nodeKinds = isType.Right.XmlType!.NodeKinds;
if (!Bits.ExactlyOne((uint)nodeKinds))
if (!BitOperations.IsPow2((uint)nodeKinds))
{
return;
}
Expand Down
8 changes: 8 additions & 0 deletions src/libraries/System.Text.RegularExpressions/gen/Stubs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ namespace System.Buffers
internal delegate void SpanAction<T, in TArg>(Span<T> span, TArg arg);
}

namespace System.Numerics
{
internal static class BitOperations
{
public static bool IsPow2(int value) => (value & (value - 1)) == 0 && value > 0;
stephentoub marked this conversation as resolved.
Show resolved Hide resolved
}
}

namespace System.Threading
{
internal static class InterlockedExtensions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Threading;

Expand Down Expand Up @@ -1196,7 +1196,7 @@ public static bool IsBoundaryWordChar(char ch)
public static bool DifferByOneBit(char a, char b, out int mask)
{
mask = a ^ b;
return mask != 0 && (mask & (mask - 1)) == 0;
return BitOperations.IsPow2(mask);
}

/// <summary>Determines a character's membership in a character class (via the string representation of the class).</summary>
Expand Down