Skip to content

Commit

Permalink
Use RuntimeHelpers.IsReferenceOrContainsReferences to skip clearing…
Browse files Browse the repository at this point in the history
… types without references.
  • Loading branch information
timcassell committed Nov 17, 2024
1 parent d23ba0c commit 8e97625
Show file tree
Hide file tree
Showing 21 changed files with 93 additions and 76 deletions.
2 changes: 1 addition & 1 deletion Package/Core/Cancelations/Internal/CancelationInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ internal override void Dispose()
{
++_nodeId;
}
_cancelable = default;
ClearReferences(ref _cancelable);
ObjectPool.MaybeRepool(this);
}
} // class CallbackNodeImpl<TCancelable>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ internal bool TryDequeue(out T item)
Slot[] slots = _slots;

// Loop in case of contention...
SpinWait spinner = default;
var spinner = new SpinWait();
while (true)
{
// Get the head at which to try to dequeue.
Expand Down Expand Up @@ -183,11 +183,7 @@ internal bool TryDequeue(out T item)
// peeking. And we don't update the sequence number,
// so that an enqueuer will see it as full and be forced to move to a new segment.

// TODO
//if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
{
slots[slotsIndex].item = default;
}
Internal.ClearReferences(ref slots[slotsIndex].item);
Volatile.Write(ref slots[slotsIndex].sequenceNumber, currentHead + slots.Length);
}
return true;
Expand Down Expand Up @@ -247,7 +243,7 @@ internal bool TryPeek(out T result, bool resultUsed)
Slot[] slots = _slots;

// Loop in case of contention...
SpinWait spinner = default;
var spinner = new SpinWait();
while (true)
{
// Get the head at which to try to peek.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ internal int Count
{
get
{
SpinWait spinner = default;
var spinner = new SpinWait();
while (true)
{
// Capture the head and tail, as well as the head's head and tail.
Expand Down
32 changes: 19 additions & 13 deletions Package/Core/Collections/Internal/PoolBackedDequeInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public T DequeueHead()
Debug.Assert(!IsEmpty); // caller's responsibility to make sure there are elements remaining

T item = _array[_head];
_array[_head] = default;
Internal.ClearReferences(ref _array[_head]);

if (++_head == _array.Length)
{
Expand Down Expand Up @@ -117,7 +117,7 @@ public T DequeueTail()
}

T item = _array[_tail];
_array[_tail] = default;
Internal.ClearReferences(ref _array[_tail]);

_size--;
return item;
Expand All @@ -141,14 +141,14 @@ private void Grow()
if (_head < _tail)
{
Array.Copy(_array, _head, newArray, 0, _size);
Array.Clear(_array, _head, _size);
Internal.ClearReferences(_array, _head, _size);
}
else
{
Array.Copy(_array, _head, newArray, 0, _array.Length - _head);
Array.Copy(_array, 0, newArray, _array.Length - _head, _tail);
Array.Clear(_array, _head, _array.Length - _head);
Array.Clear(_array, 0, _tail);
Internal.ClearReferences(_array, _head, _array.Length - _head);
Internal.ClearReferences(_array, 0, _tail);
}

ArrayPool<T>.Shared.Return(_array, false);
Expand All @@ -159,20 +159,26 @@ private void Grow()

public void Dispose()
{
if (_size > 0)
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
#endif
{
if (_head < _tail)
{
Array.Clear(_array, _head, _size);
}
else
if (_size > 0)
{
Array.Clear(_array, _head, _array.Length - _head);
Array.Clear(_array, 0, _tail);
if (_head < _tail)
{
Array.Clear(_array, _head, _size);
}
else
{
Array.Clear(_array, _head, _array.Length - _head);
Array.Clear(_array, 0, _tail);
}
}
}

ArrayPool<T>.Shared.Return(_array, false);
this = default;
}
}
}
8 changes: 4 additions & 4 deletions Package/Core/Collections/TempCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ internal TempCollectionBuilder(int capacity, int count = 0)

internal void SetCapacityNoCopy(int capacity)
{
Array.Clear(_items, 0, _count);
Internal.ClearReferences(_items, 0, _count);
ArrayPool<T>.Shared.Return(_items, false);
_items = ArrayPool<T>.Shared.Rent(capacity);
}
Expand All @@ -287,7 +287,7 @@ internal void SetCapacityAndCopy(int capacity)
{
var newStorage = ArrayPool<T>.Shared.Rent(capacity);
_items.CopyTo(newStorage, 0);
Array.Clear(_items, 0, _count);
Internal.ClearReferences(_items, 0, _count);
ArrayPool<T>.Shared.Return(_items, false);
_items = newStorage;
}
Expand All @@ -312,7 +312,7 @@ internal void Add(T item)

internal void Clear()
{
Array.Clear(_items, 0, _count);
Internal.ClearReferences(_items, 0, _count);
_count = 0;
}

Expand All @@ -323,7 +323,7 @@ public void Dispose()
_disposedChecker._isDisposed = true;
Internal.Discard(_disposedChecker);
#endif
Array.Clear(_items, 0, _count);
Internal.ClearReferences(_items, 0, _count);
ArrayPool<T>.Shared.Return(_items, false);
this = default;
}
Expand Down
22 changes: 22 additions & 0 deletions Package/Core/InternalShared/HelperFunctionsInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -252,5 +252,27 @@ internal static void MaybeShrink<T>(this IList<T> list, int expectedCount)
internal static void SpinOnce(this ref SpinWait spinner, int sleep1Threshold)
=> spinner.SpinOnce();
#endif

[MethodImpl(InlineOption)]
internal static void ClearReferences<T>(ref T location)
{
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP || UNITY_2021_2_OR_NEWER
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
#endif
{
location = default;
}
}

[MethodImpl(InlineOption)]
internal static void ClearReferences<T>(T[] array, int index, int length)
{
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP || UNITY_2021_2_OR_NEWER
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
#endif
{
Array.Clear(array, index, length);
}
}
} // class Internal
} // namespace Proto.Promises
2 changes: 1 addition & 1 deletion Package/Core/InternalShared/ValueCollectionsInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ internal void Add(T item)
internal void Clear()
{
_count = 0;
Array.Clear(_storage, 0, _storage.Length);
ClearReferences(_storage, 0, _storage.Length);
}
}
} // class Internal
Expand Down
2 changes: 1 addition & 1 deletion Package/Core/Linq/Generators/Repeat.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ internal override Promise DisposeAsync(int id)
{
PrepareEarlyDispose();
base.Dispose();
_current = default;
ClearReferences(ref _current);
_disposed = true;
ObjectPool.MaybeRepool(this);
}
Expand Down
2 changes: 1 addition & 1 deletion Package/Core/Linq/Generators/Return.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ internal override Promise DisposeAsync(int id)
{
PrepareEarlyDispose();
base.Dispose();
_current = default;
ClearReferences(ref _current);
_disposed = true;
ObjectPool.MaybeRepool(this);
}
Expand Down
10 changes: 5 additions & 5 deletions Package/Core/Linq/Internal/AppendPrependInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ internal static Prepend1AsyncEnumerable<TSource> GetOrCreate(AsyncEnumerator<TSo
private void Dispose()
{
_source = default;
_prepended = default;
ClearReferences(ref _prepended);
ObjectPool.MaybeRepool(this);
}

Expand Down Expand Up @@ -203,7 +203,7 @@ internal static Append1AsyncEnumerable<TSource> GetOrCreate(AsyncEnumerator<TSou
private void Dispose()
{
_source = default;
_appended = default;
ClearReferences(ref _appended);
ObjectPool.MaybeRepool(this);
}

Expand Down Expand Up @@ -293,8 +293,8 @@ internal static AppendPrepend1AsyncEnumerable<TSource> GetOrCreate(AsyncEnumerat
private void Dispose()
{
_source = default;
_prepended = default;
_appended = default;
ClearReferences(ref _prepended);
ClearReferences(ref _appended);
ObjectPool.MaybeRepool(this);
}

Expand Down Expand Up @@ -404,7 +404,7 @@ public override Promise DisposeAsyncWithoutStart()
private void RepoolWithoutDispose()
{
_source = default;
_prepended = default;
ClearReferences(ref _prepended);
ObjectPool.MaybeRepool(this);
}

Expand Down
4 changes: 2 additions & 2 deletions Package/Core/Linq/Internal/CountByInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,8 @@ public void Dispose()
{
_hashNext = null;
_nextNode = null;
_key = default;
_value = default;
ClearReferences(ref _key);
ClearReferences(ref _value);
ObjectPool.MaybeRepool(this);
}
}
Expand Down
2 changes: 1 addition & 1 deletion Package/Core/Linq/Internal/GroupingInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public void Dispose()
_nextGrouping = null;
_elements.Dispose();
_elements = default;
_key = default;
ClearReferences(ref _key);
ObjectPool.MaybeRepool(this);
}
}
Expand Down
6 changes: 3 additions & 3 deletions Package/Core/Linq/Internal/OrderByInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ internal abstract class Comparer<TComparer> : OrderedAsyncEnumerableHead<TSource

protected void Dispose()
{
_comparer = default;
ClearReferences(ref _comparer);
// Dispose ThenBys
var next = _next;
_next = null;
Expand Down Expand Up @@ -439,7 +439,7 @@ internal abstract class Comparer<TKey, TComparer> : OrderedAsyncEnumerableHead<T

protected void Dispose()
{
_comparer = default;
ClearReferences(ref _comparer);
// Dispose ThenBys
var next = _next;
_next = null;
Expand Down Expand Up @@ -937,7 +937,7 @@ internal override void Dispose()
{
_keys.Dispose();
}
_comparer = default;
ClearReferences(ref _comparer);
}
}

Expand Down
47 changes: 20 additions & 27 deletions Package/Core/Linq/Internal/PoolBackedQueueInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,24 @@ internal int Count

internal void Clear()
{
if (_size != 0)
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
#endif
{
if (_head < _tail)
{
Array.Clear(_array, _head, _size);
}
else
if (_size != 0)
{
Array.Clear(_array, _head, _array.Length - _head);
Array.Clear(_array, 0, _tail);
if (_head < _tail)
{
Array.Clear(_array, _head, _size);
}
else
{
Array.Clear(_array, _head, _array.Length - _head);
Array.Clear(_array, 0, _tail);
}

_size = 0;
}

_size = 0;
}

_head = 0;
Expand All @@ -78,7 +83,7 @@ internal T Dequeue()
#endif
int head = _head;
T removed = _array[head];
_array[head] = default;
ClearReferences(ref _array[head]);
MoveNext(ref _head);
_size--;
return removed;
Expand Down Expand Up @@ -125,14 +130,14 @@ private void SetCapacity(int capacity)
if (_head < _tail)
{
Array.Copy(_array, _head, newarray, 0, _size);
Array.Clear(_array, _head, _size);
ClearReferences(_array, _head, _size);
}
else
{
Array.Copy(_array, _head, newarray, 0, _array.Length - _head);
Array.Copy(_array, 0, newarray, _array.Length - _head, _tail);
Array.Clear(_array, _head, _array.Length - _head);
Array.Clear(_array, 0, _tail);
ClearReferences(_array, _head, _array.Length - _head);
ClearReferences(_array, 0, _tail);
}
}

Expand Down Expand Up @@ -165,19 +170,7 @@ internal void EnsureCapacity(int capacity)

public void Dispose()
{
if (_size > 0)
{
if (_head < _tail)
{
Array.Clear(_array, _head, _size);
}
else
{
Array.Clear(_array, _head, _array.Length - _head);
Array.Clear(_array, 0, _tail);
}
}

Clear();
ArrayPool<T>.Shared.Return(_array, false);
}
}
Expand Down
2 changes: 1 addition & 1 deletion Package/Core/Linq/Internal/PoolBackedSetInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public bool Remove(TElement value)
}

_slots[i]._hashCode = -1;
_slots[i]._value = default;
ClearReferences(ref _slots[i]._value);
_slots[i]._next = -1;
return true;
}
Expand Down
Loading

0 comments on commit 8e97625

Please sign in to comment.