Exemplo n.º 1
0
        public void ReturnMemory(AllocatedMemoryData allocation)
        {
            if (_generation != allocation.ContextGeneration)
            {
                ThrowUseAfterFree(allocation);
            }

            _arenaAllocator.Return(allocation);
        }
Exemplo n.º 2
0
 public BlittableJsonTextWriter(JsonOperationContext context, Stream stream)
 {
     _context        = context;
     _stream         = stream;
     _returnBuffer   = context.GetManagedBuffer(out _pinnedBuffer);
     _buffer         = _pinnedBuffer.Pointer;
     _bufferLen      = _pinnedBuffer.Length;
     _dateTimeMemory = context.GetMemory(32);
 }
Exemplo n.º 3
0
        public void Dispose()
        {
            _unmanagedWriteBuffer.Dispose();
            if (_compressionBuffer != null)
            {
                _context.ReturnMemory(_compressionBuffer);
            }

            _compressionBuffer = null;
        }
Exemplo n.º 4
0
        private static void ThrowUseAfterFree(AllocatedMemoryData allocation)
        {
#if MEM_GUARD_STACK || TRACK_ALLOCATED_MEMORY_DATA
            throw new InvalidOperationException(
                      "UseAfterFree detected! Attempt to return memory from previous generation, Reset has already been called and the memory reused! Allocated by:" + allocation.AllocatedBy);
#else
            throw new InvalidOperationException(
                      "UseAfterFree detected! Attempt to return memory from previous generation, Reset has already been called and the memory reused!");
#endif
        }
Exemplo n.º 5
0
        public AbstractBlittableJsonTextWriter(JsonOperationContext context, Stream stream)
        {
            _context = context;
            _stream  = stream;

            _returnBuffer = context.GetManagedBuffer(out _pinnedBuffer);
            _buffer       = _pinnedBuffer.Pointer;

            _parserAuxiliarMemory = context.GetMemory(32);
        }
Exemplo n.º 6
0
 private unsafe byte *GetCompressionBuffer(int minSize)
 {
     // enlarge buffer if needed
     if (_compressionBuffer == null ||
         minSize > _compressionBuffer.SizeInBytes)
     {
         _compressionBuffer = _context.GetMemory(minSize);
     }
     return(_compressionBuffer.Address);
 }
        public AllocatedMemoryData Allocate(int size)
        {
            var allocatedMemoryData = new AllocatedMemoryData
            {
                Address     = (byte *)Marshal.AllocHGlobal(size),
                SizeInBytes = size
            };

            return(allocatedMemoryData);
        }
Exemplo n.º 8
0
 public void ResetAndRenew()
 {
     _unmanagedWriteBuffer.Dispose();
     _unmanagedWriteBuffer = (TWriter)(object)_context.GetStream(_lastSize);
     _position             = 0;
     if (_innerBuffer == null)
     {
         _innerBuffer = _context.GetMemory(32);
     }
 }
Exemplo n.º 9
0
        public AllocatedMemoryData Allocate(int size)
        {
            if (_isDisposed ?? true)
            {
                goto ErrorDisposed;
            }

            if (_ptrStart == null)
            {
                goto ErrorResetted;
            }

#if MEM_GUARD
            return(new AllocatedMemoryData
            {
                Address = ElectricFencedMemory.Allocate(size),
                SizeInBytes = size
            });
#else
            size = Bits.PowerOf2(Math.Max(sizeof(FreeSection), size));

            AllocatedMemoryData allocation;

            var index = Bits.MostSignificantBit(size) - 1;
            if (_freed[index] != null)
            {
                var section = _freed[index];
                _freed[index] = section->Previous;

                allocation = new AllocatedMemoryData((byte *)section, section->SizeInBytes);
                goto Return;
            }

            if (_used + size > _allocated)
            {
                GrowArena(size);
            }

            allocation = new AllocatedMemoryData(_ptrCurrent, size);

            _ptrCurrent += size;
            _used       += size;
            TotalUsed   += size;

Return:
            return(allocation);
#endif

ErrorDisposed:
            ThrowAlreadyDisposedException();
ErrorResetted:
            ThrowInvalidAllocateFromResetWithoutRenew();
            return(null); // Will never happen.
        }
Exemplo n.º 10
0
        public void Return(AllocatedMemoryData allocation)
        {
            if (_isDisposed ?? true)
            {
                return;
            }


            var address = allocation.Address;

#if DEBUG
            Debug.Assert(address != _ptrCurrent);
            Debug.Assert(allocation.IsReturned == false);
            allocation.IsReturned = true;
#endif

#if MEM_GUARD
#if MEM_GUARD_STACK
            if (allocation.FreedBy == null)
            {
                allocation.FreedBy = Environment.StackTrace;
            }
#endif
            ElectricFencedMemory.Free(address);
#else
            if (address != _ptrCurrent - allocation.SizeInBytes ||
                address < _ptrStart)
            {
                // we have fragmentation, so'll just store the values that we need here
                // in the memory we just freed :-)

                // note that this fragmentation will be healed by the call to ResetArena
                // trying to do this on the fly is too expensive.

                Debug.Assert(Bits.PowerOf2(allocation.SizeInBytes) == allocation.SizeInBytes,
                             "Allocation size must always be a power of two"
                             );
                Debug.Assert(allocation.SizeInBytes >= sizeof(FreeSection));


                var index   = Bits.MostSignificantBit(allocation.SizeInBytes) - 1;
                var section = (FreeSection *)address;
                section->SizeInBytes = allocation.SizeInBytes;
                section->Previous    = _freed[index];
                _freed[index]        = section;
                return;
            }
            // since the returned allocation is at the end of the arena, we can just move
            // the pointer back
            _used       -= allocation.SizeInBytes;
            TotalUsed   -= allocation.SizeInBytes;
            _ptrCurrent -= allocation.SizeInBytes;
#endif
        }
Exemplo n.º 11
0
 internal UnmanagedWriteBuffer(JsonOperationContext context, AllocatedMemoryData allocatedMemoryData)
 {
     _context     = context;
     _sizeInBytes = 0;
     _current     = new Segment
     {
         Address    = allocatedMemoryData.Address,
         Allocation = allocatedMemoryData,
         Used       = 0,
         Previous   = null
     };
 }
Exemplo n.º 12
0
        private void ReturnAllocatedMemory()
        {
            if (AllocatedMemoryData == null)
            {
                return;
            }

            if (_context.Generation == AllocatedMemoryData.ContextGeneration)
            {
                _context.ReturnMemory(AllocatedMemoryData);
            }

            AllocatedMemoryData = null;
        }
Exemplo n.º 13
0
 public void Reset()
 {
     _unmanagedWriteBuffer.Dispose();
     if (_compressionBuffer != null)
     {
         _context.ReturnMemory(_compressionBuffer);
         _compressionBuffer = null;
     }
     if (_innerBuffer != null)
     {
         _context.ReturnMemory(_innerBuffer);
         _innerBuffer = null;
     }
 }
Exemplo n.º 14
0
        public void Return(AllocatedMemoryData allocation)
        {
#if MEM_GUARD
#if MEM_GUARD_STACK
            allocation.FreedBy = Environment.StackTrace;
#endif
            ElectricFencedMemory.Free(allocation.Address);
#else
            if (allocation.Address != _ptrCurrent - allocation.SizeInBytes ||
                allocation.Address < _ptrStart)
            {
                if (_fragements == null)
                {
                    _fragements = new SortedList <long, AllocatedMemoryData>();
                }
                // we have fragmentation, let us try to heal it
                _fragements.Add((long)allocation.Address, allocation);
                return;
            }
            // since the returned allocation is at the end of the arena, we can just move
            // the pointer back
            _used       -= allocation.SizeInBytes;
            _ptrCurrent -= allocation.SizeInBytes;

            if (_fragements == null)
            {
                return;
            }

            // let us try to heal fragmentation at this point
            while (_fragements.Count > 0)
            {
                var highest = _fragements.Values[_fragements.Count - 1];
                if (highest.Address != _ptrCurrent - allocation.SizeInBytes)
                {
                    break;
                }
                _fragements.RemoveAt(_fragements.Count - 1);
                if (highest.Address < _ptrStart)
                {
                    // this is from another segment, probably, currently we'll just ignore it,
                    // we might want to track if all the memory from a previous segment has been
                    // released, and then free it, but not for now
                    continue;
                }
                _used       -= highest.SizeInBytes;
                _ptrCurrent -= highest.SizeInBytes;
            }
#endif
        }
Exemplo n.º 15
0
        /// <summary>
        /// Returns memory buffer to work with, be aware, this buffer is not thread safe
        /// </summary>
        /// <param name="requestedSize"></param>
        /// <returns></returns>
        public unsafe byte *GetNativeTempBuffer(int requestedSize)
        {
            if (_tempBuffer == null ||
                _tempBuffer.Address == null ||
                _tempBuffer.SizeInBytes < requestedSize)
            {
                if (_tempBuffer != null && _tempBuffer.Address != null)
                {
                    _arenaAllocator.Return(_tempBuffer);
                }
                _tempBuffer = GetMemory(Math.Max(_tempBuffer?.SizeInBytes ?? 0, requestedSize));
            }

            return(_tempBuffer.Address);
        }
Exemplo n.º 16
0
        public void Return(AllocatedMemoryData returned)
        {
            if (returned == null)
            {
                throw new ArgumentNullException(nameof(returned));
            }
            var index = GetIndexFromSize(returned.SizeInBytes);

            if (index == -1)
            {
                Marshal.FreeHGlobal(returned.Address);

                return; // strange size, just free it
            }
            _freeSegments[index].Push(returned);
        }
Exemplo n.º 17
0
        internal UnmanagedWriteBuffer(JsonOperationContext context, AllocatedMemoryData allocatedMemoryData)
        {
            _context     = context;
            _sizeInBytes = 0;
            _current     = new Segment
            {
                Address    = allocatedMemoryData.Address,
                Allocation = allocatedMemoryData,
                Used       = 0,
                Previous   = null
            };

#if MEM_GUARD
            AllocatedBy = Environment.StackTrace;
            FreedBy     = null;
#endif
        }
Exemplo n.º 18
0
        public void Return(AllocatedMemoryData returned)
        {
#if MEM_GUARD
            ElectricFencedMemory.Free(returned.Address);
#else
            if (returned == null)
            {
                throw new ArgumentNullException(nameof(returned));
            }
            var index = GetIndexFromSize(returned.SizeInBytes);
            if (index == -1)
            {
                NativeMemory.Free(returned.Address, returned.SizeInBytes, returned.AllocatingThread);

                return; // strange size, just free it
            }
            _freeSegments[index].Push(returned);
#endif
        }
Exemplo n.º 19
0
        public bool GrowAllocation(AllocatedMemoryData allocation, int sizeIncrease)
        {
            var end      = allocation.Address + allocation.SizeInBytes;
            var distance = end - _ptrCurrent;

            if (distance != 0)
            {
                return(false);
            }

            if (_used + sizeIncrease > _allocated)
            {
                return(false);
            }

            _ptrCurrent            += sizeIncrease;
            _used                  += sizeIncrease;
            allocation.SizeInBytes += sizeIncrease;
            return(true);
        }
Exemplo n.º 20
0
        protected internal virtual unsafe void Reset(bool forceReleaseLongLivedAllocator = false)
        {
            if (_tempBuffer != null && _tempBuffer.Address != null)
            {
                _arenaAllocator.Return(_tempBuffer);
                _tempBuffer = null;
            }

            _documentBuilder.Reset();

            // We don't reset _arenaAllocatorForLongLivedValues. It's used as a cache buffer for long lived strings like field names.
            // When a context is re-used, the buffer containing those field names was not reset and the strings are still valid and alive.

            var allocatorForLongLivedValues = _arenaAllocatorForLongLivedValues;

            if (allocatorForLongLivedValues != null &&
                (allocatorForLongLivedValues.Allocated > _initialSize || forceReleaseLongLivedAllocator))
            {
                foreach (var mem in _fieldNames.Values)
                {
                    _arenaAllocatorForLongLivedValues.Return(mem.AllocatedMemoryData);
                    mem.AllocatedMemoryData = null;
                    mem.Dispose();
                }

                _arenaAllocatorForLongLivedValues = null;

                // at this point, the long lived section is far too large, this is something that can happen
                // if we have dynamic properties. A back of the envelope calculation gives us roughly 32K
                // property names before this kicks in, which is a true abuse of the system. In this case,
                // in order to avoid unlimited growth, we'll reset the long lived section
                allocatorForLongLivedValues.Dispose();

                _fieldNames.Clear();
                CachedProperties = null; // need to release this so can be collected
            }
            _objectJsonParser.Reset(null);
            _arenaAllocator.ResetArena();
            _numberOfAllocatedStringsValues = 0;
            _generation = _generation + 1;
        }
Exemplo n.º 21
0
        public UnmanagedWriteBuffer(JsonOperationContext context, AllocatedMemoryData allocatedMemoryData)
        {
            Debug.Assert(context != null);
            Debug.Assert(allocatedMemoryData != null);

            _context = context;
            _head    = new Segment
            {
                Previous = null,
                DeallocationPendingPrevious = null,
                Allocation             = allocatedMemoryData,
                Address                = allocatedMemoryData.Address,
                Used                   = 0,
                AccumulatedSizeInBytes = 0
            };

#if MEM_GUARD
            AllocatedBy = Environment.StackTrace;
            FreedBy     = null;
#endif
        }
Exemplo n.º 22
0
        public bool GrowAllocation(AllocatedMemoryData allocation, int sizeIncrease)
        {
            byte *end      = allocation.Address + allocation.SizeInBytes;
            var   distance = end - _ptrCurrent;

            if (distance != 0)
            {
                return(false);
            }

            // we need to keep the total allocation size as power of 2
            sizeIncrease = Bits.PowerOf2(allocation.SizeInBytes + sizeIncrease) - allocation.SizeInBytes;

            if (_used + sizeIncrease > _allocated)
            {
                return(false);
            }

            _ptrCurrent            += sizeIncrease;
            _used                  += sizeIncrease;
            TotalUsed              += sizeIncrease;
            allocation.SizeInBytes += sizeIncrease;
            return(true);
        }
Exemplo n.º 23
0
 public void Return(AllocatedMemoryData allocation)
 {
     Marshal.FreeHGlobal((IntPtr)allocation.Address);
 }
Exemplo n.º 24
0
 public void ReturnMemory(AllocatedMemoryData allocation)
 {
     _arenaAllocator.Return(allocation);
 }
 public byte *DecompressToTempBuffer(out AllocatedMemoryData allocatedData, JsonOperationContext externalContext = null)
 {
     allocatedData = DecompressToAllocatedMemoryDataInternal(externalContext, out _);
     return(allocatedData.Address);
 }
 public UnmanagedPointer DecompressToUnmanagedPointer(out AllocatedMemoryData allocatedData, JsonOperationContext externalContext = null)
 {
     allocatedData = DecompressToAllocatedMemoryDataInternal(externalContext, out _);
     return(new UnmanagedPointer(allocatedData.Address));
 }
Exemplo n.º 27
0
 public BlittableWriter(JsonOperationContext context, TWriter writer)
 {
     _context = context;
     _unmanagedWriteBuffer = writer;
     _innerBuffer          = _context.GetMemory(32);
 }
Exemplo n.º 28
0
 public BlittableWriter(JsonOperationContext context)
 {
     _context     = context;
     _innerBuffer = _context.GetMemory(32);
 }
Exemplo n.º 29
0
 public bool GrowAllocation(AllocatedMemoryData allocation, int sizeIncrease)
 {
     return(_arenaAllocator.GrowAllocation(allocation, sizeIncrease));
 }