Example #1
0
 // Removes all entries from this sorted list.
 public void Clear()
 {
     // clear does not change the capacity
     version++;
     // Don't need to doc this but we clear the elements so that the gc can reclaim the references.
     if (RuntimeHelpers.IsReferenceOrContainsReferences <TKey>())
     {
         Array.Clear(keys, 0, _size);
     }
     if (RuntimeHelpers.IsReferenceOrContainsReferences <TValue>())
     {
         Array.Clear(values, 0, _size);
     }
     _size = 0;
 }
Example #2
0
        public static void FastClearVectorized <T>(this Span <T> span)
        {
            if (span.IsEmpty)
            {
                return;
            }

            int size = Unsafe.SizeOf <T>();
            int len  = span.Length;

            Debug.Assert(size > 0 && len > 0);

            if (!RuntimeHelpers.IsReferenceOrContainsReferences <T>())
            {
                Unsafe.InitBlockUnaligned(ref Unsafe.As <T, byte>(ref MemoryMarshal.GetReference(span)), default,
Example #3
0
        public bool TryPop(out T result)
        {
            if (_count == 0)
            {
                result = default;
                return(false);
            }

            result = _array[--_count];
            if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
            {
                _array[_count] = default;     // Free memory quicker.
            }
            return(true);
        }
Example #4
0
        /// <summary>
        /// lears the data written to the underlying buffer.
        /// </summary>
        /// <param name="reuseBuffer"><see langword="true"/> to reuse the internal buffer; <see langword="false"/> to destroy the internal buffer.</param>
        public void Clear(bool reuseBuffer)
        {
            initialBuffer.Clear();
            if (!reuseBuffer)
            {
                extraBuffer.Dispose();
                extraBuffer = default;
            }
            else if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
            {
                extraBuffer.Memory.Span.Clear();
            }

            position = 0;
        }
Example #5
0
    public static int test_0_isreference_intrins()
    {
        if (RuntimeHelpers.IsReferenceOrContainsReferences <int> ())
        {
            return(1);
        }
        if (!RuntimeHelpers.IsReferenceOrContainsReferences <string> ())
        {
            return(2);
        }
        if (!RuntimeHelpers.IsReferenceOrContainsReferences <RefStruct> ())
        {
            return(3);
        }
        if (!RuntimeHelpers.IsReferenceOrContainsReferences <NestedRefStruct> ())
        {
            return(4);
        }
        if (RuntimeHelpers.IsReferenceOrContainsReferences <NoRefStruct> ())
        {
            return(5);
        }
        // Generic code
        if (is_ref_or_contains_refs <int> ())
        {
            return(6);
        }
        // Shared code
        if (!is_ref_or_contains_refs <string> ())
        {
            return(7);
        }
        // Complex type from shared code
        if (!is_ref_or_contains_refs_gen_ref <string> ())
        {
            return(8);
        }
        if (is_ref_or_contains_refs_gen_ref <int> ())
        {
            return(9);
        }
        if (is_ref_or_contains_refs_gen_noref <string> ())
        {
            return(10);
        }

        return(0);
    }
Example #6
0
        public static Span <TTo> Cast <TFrom, TTo>(Span <TFrom> span)
            where TFrom : struct
            where TTo : struct
        {
            if (RuntimeHelpers.IsReferenceOrContainsReferences <TFrom>())
            {
                throw new Exception("Type is reference or contains references.");
            }
            if (RuntimeHelpers.IsReferenceOrContainsReferences <TTo>())
            {
                throw new Exception("Type is reference or contains references.");
            }

            // Use unsigned integers - unsigned division by constant (especially by power of 2)
            // and checked casts are faster and smaller.
            uint fromSize   = (uint)Unsafe.SizeOf <TFrom>();
            uint toSize     = (uint)Unsafe.SizeOf <TTo>();
            uint fromLength = (uint)span.Length;
            int  toLength;

            if (fromSize == toSize)
            {
                // Special case for same size types - `(ulong)fromLength * (ulong)fromSize / (ulong)toSize`
                // should be optimized to just `length` but the JIT doesn't do that today.
                toLength = (int)fromLength;
            }
            else if (fromSize == 1)
            {
                // Special case for byte sized TFrom - `(ulong)fromLength * (ulong)fromSize / (ulong)toSize`
                // becomes `(ulong)fromLength / (ulong)toSize` but the JIT can't narrow it down to `int`
                // and can't eliminate the checked cast. This also avoids a 32 bit specific issue,
                // the JIT can't eliminate long multiply by 1.
                toLength = (int)(fromLength / toSize);
            }
            else
            {
                // Ensure that casts are done in such a way that the JIT is able to "see"
                // the uint->ulong casts and the multiply together so that on 32 bit targets
                // 32x32to64 multiplication is used.
                ulong toLengthUInt64 = (ulong)fromLength * (ulong)fromSize / (ulong)toSize;
                // TODO: checked keyword
                toLength = (int)toLengthUInt64;
            }

            return(new Span <TTo>(
                       ref Unsafe.As <TFrom, TTo>(ref span._pointer.Value),
                       toLength));
        }
Example #7
0
        public void Clear()
        {
            if (!IsEmpty)
            {
#if !NETSTANDARD2_1
                Array.Clear(_Buffer, 0, Count);
#else
                if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
                {
                    Span <T> span = _Buffer.AsSpan(0, Count);
                    span.Clear();
                }
#endif
                Count = 0;
            }
        }
Example #8
0
        // Pops an item from the top of the stack.  If the stack is empty, Pop
        // throws an InvalidOperationException.
        public T Pop()
        {
            if (_size == 0)
            {
                ThrowForEmptyStack();
            }

            _version++;
            T item = _array[--_size];

            if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
            {
                _array[_size] = default(T);     // Free memory quicker.
            }
            return(item);
        }
Example #9
0
        public bool TryPop(out T result)
        {
            if (_size == 0)
            {
                result = default(T);
                return(false);
            }

            _version++;
            result = _array[--_size];
            if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
            {
                _array[_size] = default(T);     // Free memory quicker.
            }
            return(true);
        }
Example #10
0
        public unsafe MemoryMappedPtr(void *pointer,
                                      ulong length)
        {
            if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
            {
                throw new ArgumentOutOfRangeException();
            }

            if (length < 0)
            {
                throw new ArgumentOutOfRangeException();
            }

            _pointer = new ByReference <T>(ref Unsafe.As <byte, T>(ref *(byte *)pointer));
            _length  = length;
        }
Example #11
0
        // Removes the object at the head of the queue and returns it. If the queue
        // is empty, this method throws an
        // InvalidOperationException.
        public T Dequeue()
        {
            int head = _head;

            T[] array = _array;

            if (_size == 0)
            {
                ThrowForEmptyQueue();
            }

            T removed = array[head];

            if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
            {
                array[head] = default !;
Example #12
0
        public override void Clear() => Clear(false);   // TODO: Remove this method in future

        /// <summary>
        /// Clears the data written to the underlying memory.
        /// </summary>
        /// <param name="reuseBuffer"><see langword="true"/> to reuse the internal buffer; <see langword="false"/> to destroy the internal buffer.</param>
        /// <exception cref="ObjectDisposedException">This writer has been disposed.</exception>
        public override void Clear(bool reuseBuffer)
        {
            ThrowIfDisposed();

            if (!reuseBuffer)
            {
                buffer.Dispose();
                buffer = default;
            }
            else if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
            {
                buffer.Memory.Span.Clear();
            }

            position = 0;
        }
Example #13
0
        // This method removes all items which matches the predicate.
        // The complexity is O(n).
        public int RemoveAll(Predicate <T> match)
        {
            if (match == null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.match);
            }

            int freeIndex = 0;   // the first free slot in items array

            // Find the first item which needs to be removed.
            while (freeIndex < _size && !match(_items[freeIndex]))
            {
                freeIndex++;
            }
            if (freeIndex >= _size)
            {
                return(0);
            }

            int current = freeIndex + 1;

            while (current < _size)
            {
                // Find the first item which needs to be kept.
                while (current < _size && match(_items[current]))
                {
                    current++;
                }

                if (current < _size)
                {
                    // copy item to the free slot.
                    _items[freeIndex++] = _items[current++];
                }
            }

            if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
            {
                Array.Clear(_items, freeIndex, _size - freeIndex); // Clear the elements so that the gc can reclaim the references.
            }

            int result = _size - freeIndex;

            _size = freeIndex;
            _version++;
            return(result);
        }
Example #14
0
        /// <summary>
        /// Casts a ReadOnlySpan of one primitive type <typeparamref name="TFrom"/> to another primitive type <typeparamref name="TTo"/>.
        /// These types may not contain pointers or references. This is checked at runtime in order to preserve type safety.
        /// </summary>
        /// <remarks>
        /// Supported only for platforms that support misaligned memory access.
        /// </remarks>
        /// <param name="source">The source slice, of type <typeparamref name="TFrom"/>.</param>
        /// <exception cref="System.ArgumentException">
        /// Thrown when <typeparamref name="TFrom"/> or <typeparamref name="TTo"/> contains pointers.
        /// </exception>
        public static ReadOnlySpan <TTo> Cast <TFrom, TTo>(ReadOnlySpan <TFrom> source)
            where TFrom : struct
            where TTo : struct
        {
            if (RuntimeHelpers.IsReferenceOrContainsReferences <TFrom>())
            {
                ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TFrom));
            }
            if (RuntimeHelpers.IsReferenceOrContainsReferences <TTo>())
            {
                ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TTo));
            }

            // Use unsigned integers - unsigned division by constant (especially by power of 2)
            // and checked casts are faster and smaller.
            uint fromSize   = (uint)Unsafe.SizeOf <TFrom>();
            uint toSize     = (uint)Unsafe.SizeOf <TTo>();
            uint fromLength = (uint)source.Length;
            int  toLength;

            if (fromSize == toSize)
            {
                // Special case for same size types - `(ulong)fromLength * (ulong)fromSize / (ulong)toSize`
                // should be optimized to just `length` but the JIT doesn't do that today.
                toLength = (int)fromLength;
            }
            else if (fromSize == 1)
            {
                // Special case for byte sized TFrom - `(ulong)fromLength * (ulong)fromSize / (ulong)toSize`
                // becomes `(ulong)fromLength / (ulong)toSize` but the JIT can't narrow it down to `int`
                // and can't eliminate the checked cast. This also avoids a 32 bit specific issue,
                // the JIT can't eliminate long multiply by 1.
                toLength = (int)(fromLength / toSize);
            }
            else
            {
                // Ensure that casts are done in such a way that the JIT is able to "see"
                // the uint->ulong casts and the multiply together so that on 32 bit targets
                // 32x32to64 multiplication is used.
                ulong toLengthUInt64 = (ulong)fromLength * (ulong)fromSize / (ulong)toSize;
                toLength = checked ((int)toLengthUInt64);
            }

            return(new ReadOnlySpan <TTo>(
                       ref Unsafe.As <TFrom, TTo>(ref MemoryMarshal.GetReference(source)),
                       toLength));
        }
Example #15
0
 public void Clear()
 {
     _version++;
     if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
     {
         int size = _size;
         _size = 0;
         if (size > 0)
         {
             Array.Clear(_items, 0, size); // Clear the elements so that the gc can reclaim the references.
         }
     }
     else
     {
         _size = 0;
     }
 }
Example #16
0
 internal static void Memmove <T>(ref T destination, ref T source, nuint elementCount)
 {
     if (!RuntimeHelpers.IsReferenceOrContainsReferences <T>())
     {
         unsafe {
             fixed(byte *pDestination = &Unsafe.As <T, byte>(ref destination), pSource = &Unsafe.As <T, byte>(ref source))
             Memmove(pDestination, pSource, (uint)elementCount * (uint)Unsafe.SizeOf <T>());
         }
     }
     else
     {
         unsafe {
             fixed(byte *pDestination = &Unsafe.As <T, byte>(ref destination), pSource = &Unsafe.As <T, byte>(ref source))
             RuntimeImports.Memmove_wbarrier(pDestination, pSource, (uint)elementCount, typeof(T).TypeHandle.Value);
         }
     }
 }
Example #17
0
 protected static void SerializeRuntimeDecisionInternal <T, TSymbol, TResolver>(ref JsonWriter <TSymbol> writer,
                                                                                T value, IJsonFormatter <T, TSymbol> formatter)
     where TResolver : IJsonFormatterResolver <TSymbol, TResolver>, new() where TSymbol : struct
 {
     // The first check is to get around the runtime check for primitive types and structs without references, i.e most of the blc types from the bclformatter.tt
     // Then we specifically check for string as it is very common
     // A null value can be serialized by both (doesn't matter, but we need to handle null for the runtime type check)
     // Checking for things like IsValueType and/or IsSealed is actually several times more expensive than the type comparison
     if (!RuntimeHelpers.IsReferenceOrContainsReferences <T>() || typeof(T) == typeof(string) || value == null || value.GetType() == typeof(T))
     {
         formatter.Serialize(ref writer, value);
     }
     else
     {
         RuntimeFormatter <TSymbol, TResolver> .Default.Serialize(ref writer, value);
     }
 }
Example #18
0
        public static Span <TTo> NonPortableCast <TFrom, TTo>(this Span <TFrom> source)
            where TFrom : struct
            where TTo : struct
        {
            if (RuntimeHelpers.IsReferenceOrContainsReferences <TFrom>())
            {
                ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TFrom));
            }
            if (RuntimeHelpers.IsReferenceOrContainsReferences <TTo>())
            {
                ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TTo));
            }

            return(new Span <TTo>(
                       ref Unsafe.As <TFrom, TTo>(ref source.DangerousGetPinnableReference()),
                       checked ((int)((long)source.Length * Unsafe.SizeOf <TFrom>() / Unsafe.SizeOf <TTo>()))));
        }
Example #19
0
        public static ReadOnlySpan <TTo> Cast <TFrom, TTo>(ReadOnlySpan <TFrom> source)
            where TFrom : struct
            where TTo : struct
        {
            if (RuntimeHelpers.IsReferenceOrContainsReferences <TFrom>())
            {
                ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TFrom));
            }
            if (RuntimeHelpers.IsReferenceOrContainsReferences <TTo>())
            {
                ThrowHelper.ThrowInvalidTypeWithPointersNotSupported(typeof(TTo));
            }

            return(new ReadOnlySpan <TTo>(
                       ref Unsafe.As <TFrom, TTo>(ref MemoryMarshal.GetReference(source)),
                       checked ((int)((long)source.Length * Unsafe.SizeOf <TFrom>() / Unsafe.SizeOf <TTo>()))));
        }
Example #20
0
        [MethodImpl(MethodImplOptions.AggressiveInlining)] // forced to ensure no perf drop for small memory buffers (hot path)
        internal static T[] AllocateUninitializedArray <T>(int length)
        {
            if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
            {
                return(new T[length]);
            }

            // for debug builds we always want to call AllocateNewArray to detect AllocateNewArray bugs
#if !DEBUG
            // small arrays are allocated using `new[]` as that is generally faster.
            if (length < 2048 / Unsafe.SizeOf <T>())
            {
                return(new T[length]);
            }
#endif
            // kept outside of the small arrays hot path to have inlining without big size growth
            return(AllocateNewUninitializedArray(length));
Example #21
0
 public void RemoveAt(int index)
 {
     if ((uint)index >= (uint)this._size)
     {
         ThrowHelper.ThrowArgumentOutOfRange_IndexException();
     }
     --this._size;
     if (index < this._size)
     {
         Array.Copy((Array)this._items, index + 1, (Array)this._items, index, this._size - index);
     }
     if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
     {
         this._items[this._size] = default(T);
     }
     ++this._version;
 }
Example #22
0
        public void RemoveAt(int index)
        {
            if (index >= _size)
            {
                throw new ArgumentOutOfRangeException(nameof(index), index, "Index must fit into list.");
            }

            _size -= 1;
            // No need to do a copy if the last element gets removed.
            if (index < _size)
            {
                Array.Copy(_array, index + 1, _array, index, _size - index);
            }

            if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
            {
                _array[_size] = default !;
Example #23
0
 // Removes the element at the given index. The size of the list is
 // decreased by one.
 public void RemoveAt(int index)
 {
     if ((uint)index >= (uint)_size)
     {
         ThrowHelper.ThrowArgumentOutOfRange_IndexException();
     }
     _size--;
     if (index < _size)
     {
         Array.Copy(_items, index + 1, _items, index, _size - index);
     }
     if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
     {
         _items[_size] = default(T);
     }
     _version++;
 }
Example #24
0
        public bool TryDequeue(out T result)
        {
            if (_size == 0)
            {
                result = default(T);
                return(false);
            }

            result = _array[_head];
            if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
            {
                _array[_head] = default(T);
            }
            MoveNext(ref _head);
            _size--;
            _version++;
            return(true);
        }
Example #25
0
        // Removes the object at the head of the queue and returns it. If the queue
        // is empty, this method throws an
        // InvalidOperationException.
        public T Dequeue()
        {
            if (_size == 0)
            {
                ThrowForEmptyQueue();
            }

            T removed = _array[_head];

            if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
            {
                _array[_head] = default(T);
            }
            MoveNext(ref _head);
            _size--;
            _version++;
            return(removed);
        }
Example #26
0
 public void Clear()
 {
     ++this._version;
     if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
     {
         int size = this._size;
         this._size = 0;
         if (size <= 0)
         {
             return;
         }
         Array.Clear((Array)this._items, 0, size);
     }
     else
     {
         this._size = 0;
     }
 }
Example #27
0
        public bool TryTake(out TMessage item)
        {
            if (_size == 0)
            {
                throw new InvalidOperationException();
            }

            TMessage removed = _array[_head];

            if (RuntimeHelpers.IsReferenceOrContainsReferences <TMessage>())
            {
                _array[_head] = default(TMessage);
            }
            MoveNext(ref _head);
            _size--;
            _version++;
            item = removed;
            return(true);
        }
Example #28
0
 internal static void Memmove <T>(ref T destination, ref T source, nuint elementCount)
 {
     if (!RuntimeHelpers.IsReferenceOrContainsReferences <T>())
     {
         // Blittable memmove
         Memmove(
             ref Unsafe.As <T, byte>(ref destination),
             ref Unsafe.As <T, byte>(ref source),
             elementCount * (nuint)Unsafe.SizeOf <T>());
     }
     else
     {
         // Non-blittable memmove
         BulkMoveWithWriteBarrier(
             ref Unsafe.As <T, byte>(ref destination),
             ref Unsafe.As <T, byte>(ref source),
             elementCount * (nuint)Unsafe.SizeOf <T>());
     }
 }
Example #29
0
        /// <summary>
        /// Removes the element at the specified index of the <see cref="PoolBackedCollection{T}"/>.
        /// </summary>
        /// <param name="index">The zero-based index of the element to remove.</param>
        public void RemoveAt(int index)
        {
            if ((uint)index >= (uint)Count)
            {
                throw new ArgumentOutOfRangeException(nameof(index));
            }

            Count--;
            if (index < Count)
            {
                Array.Copy(_Buffer, index + 1, _Buffer, index, Count - index);
            }

#if NETSTANDARD2_0
            _Buffer[Count] = default;
#else
            if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
            {
                _Buffer[Count] = default !;
Example #30
0
        public static T ReadMachineEndian <T>(ReadOnlySpan <byte> source)
            where T : struct
        {
#if netstandard
            if (SpanHelpers.IsReferenceOrContainsReferences <T>())
            {
                ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
            }
#else
            if (RuntimeHelpers.IsReferenceOrContainsReferences <T>())
            {
                ThrowHelper.ThrowArgumentException_InvalidTypeWithPointersNotSupported(typeof(T));
            }
#endif
            if (Unsafe.SizeOf <T>() > source.Length)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.length);
            }
            return(Unsafe.ReadUnaligned <T>(ref MemoryMarshal.GetReference(source)));
        }