public void ReturnMemory(AllocatedMemoryData allocation) { if (_generation != allocation.ContextGeneration) { ThrowUseAfterFree(allocation); } _arenaAllocator.Return(allocation); }
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); }
public void Dispose() { _unmanagedWriteBuffer.Dispose(); if (_compressionBuffer != null) { _context.ReturnMemory(_compressionBuffer); } _compressionBuffer = null; }
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 }
public AbstractBlittableJsonTextWriter(JsonOperationContext context, Stream stream) { _context = context; _stream = stream; _returnBuffer = context.GetManagedBuffer(out _pinnedBuffer); _buffer = _pinnedBuffer.Pointer; _parserAuxiliarMemory = context.GetMemory(32); }
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); }
public void ResetAndRenew() { _unmanagedWriteBuffer.Dispose(); _unmanagedWriteBuffer = (TWriter)(object)_context.GetStream(_lastSize); _position = 0; if (_innerBuffer == null) { _innerBuffer = _context.GetMemory(32); } }
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. }
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 }
internal UnmanagedWriteBuffer(JsonOperationContext context, AllocatedMemoryData allocatedMemoryData) { _context = context; _sizeInBytes = 0; _current = new Segment { Address = allocatedMemoryData.Address, Allocation = allocatedMemoryData, Used = 0, Previous = null }; }
private void ReturnAllocatedMemory() { if (AllocatedMemoryData == null) { return; } if (_context.Generation == AllocatedMemoryData.ContextGeneration) { _context.ReturnMemory(AllocatedMemoryData); } AllocatedMemoryData = null; }
public void Reset() { _unmanagedWriteBuffer.Dispose(); if (_compressionBuffer != null) { _context.ReturnMemory(_compressionBuffer); _compressionBuffer = null; } if (_innerBuffer != null) { _context.ReturnMemory(_innerBuffer); _innerBuffer = null; } }
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 }
/// <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); }
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); }
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 }
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 }
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); }
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; }
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 }
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); }
public void Return(AllocatedMemoryData allocation) { Marshal.FreeHGlobal((IntPtr)allocation.Address); }
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)); }
public BlittableWriter(JsonOperationContext context, TWriter writer) { _context = context; _unmanagedWriteBuffer = writer; _innerBuffer = _context.GetMemory(32); }
public BlittableWriter(JsonOperationContext context) { _context = context; _innerBuffer = _context.GetMemory(32); }
public bool GrowAllocation(AllocatedMemoryData allocation, int sizeIncrease) { return(_arenaAllocator.GrowAllocation(allocation, sizeIncrease)); }