Exemple #1
0
        /// <summary>
        /// Start a new allocator.
        /// This tracks memory usage, but does not do any physical work
        /// </summary>
        /// <param name="start">Start of space (bytes) available to the allocator. Some will be reserved for arena tracking</param>
        /// <param name="limit">Maximum memory before an out-of-memory condition is flagged (bytes)</param>
        /// <param name="memory">Access to real or simulated memory</param>
        public Allocator(long start, long limit, [NotNull] IMemoryAccess memory)
        {
            _limit  = limit;
            _memory = memory;

            // with 64KB arenas (ushort) and 1GB of RAM, we get 16384 arenas.
            // recording only heads and refs would take 64KB of management space
            // recording heads, refs and back-step (an optimisation for very short-lived items) would use 96KB of management space.
            // This seems pretty reasonable.
            _arenaCount   = (int)((_limit - _start) / ArenaSize);
            _currentArena = 0;

            // Allow space for arena tables, store adjusted base
            var sizeOfTables = sizeof(ushort) * _arenaCount;

            _headsPtr     = start;
            _refCountsPtr = start + sizeOfTables;

            _start = start + (sizeOfTables * 2);

            // zero-out the tables
            var zptr = _headsPtr;

            while (zptr < _start)
            {
                _memory.Write <ushort>(zptr, 0);
                zptr += sizeof(ushort);
            }
        }
Exemple #2
0
        private Result <long> NewChunk()
        {
            var res = _alloc.Alloc(ChunkBytes);

            if (!res.Success)
            {
                return(Result.Fail <long>());
            }
            if (res.Value < 0)
            {
                return(Result.Fail <long>());
            }

            var ptr = res.Value;

            _mem.Write <long>(ptr, -1);                             // set the continuation pointer of the new chunk to invalid
            if (_endChunkPtr >= 0)
            {
                _mem.Write(_endChunkPtr, ptr);                     // update the continuation pointer of the old end chunk
            }
            _endChunkPtr    = ptr;                                 // update the end chunk pointer
            _skipTableDirty = true;

            return(Result.Ok(ptr));
        }
Exemple #3
0
 private void SetHead(int arenaIndex, ushort val)
 {
     _memory.Write <ushort>(_headsPtr + (arenaIndex * sizeof(ushort)), val);
 }
Exemple #4
0
 public void SetRootValue(TElement element)
 {
     _mem.Write(Root + NODE_HEAD_SIZE, element);
 }