public BlockPtr Alloc(int size) { var result = this.InternalAlloc(size); if (result == IntPtr.Zero) { this.ForceCollection(); result = this.InternalAlloc(size); //if (result == IntPtr.Zero) // throw new OutOfMemoryException(); if (result == IntPtr.Zero) { this.Expand(); result = this.InternalAlloc(size); if (result == IntPtr.Zero) { throw new OutOfMemoryException(); } } } this.Log(string.Join(" ", _stats.currentAllocatedBytes, _stats.currentAvailableBytes)); var ptr = new BlockPtr(result); _knownBlocks.Add(ptr); return(ptr); }
public void *Allocate(int threadIndex) { var blockList = m_perThreadBlockLists + threadIndex; if (blockList->nextWriteAddress > blockList->lastByteAddressInBlock) { if (blockList->elementCount == 0) { blockList->blocks = new UnsafeList(m_allocator); blockList->blocks.SetCapacity <BlockPtr>(10); } BlockPtr newBlockPtr = new BlockPtr { ptr = (byte *)UnsafeUtility.Malloc(m_blockSize, UnsafeUtility.AlignOf <byte>(), m_allocator) }; blockList->nextWriteAddress = newBlockPtr.ptr; blockList->lastByteAddressInBlock = newBlockPtr.ptr + m_blockSize - 1; blockList->blocks.Add(newBlockPtr); } var result = blockList->nextWriteAddress; blockList->nextWriteAddress += m_elementSize; blockList->elementCount++; return(result); }
public unsafe int CountSubgraph(BlockPtr ptr) { var toDo = new Stack <BlockPtr>(); var handled = new HashSet <BlockPtr>(); var buff = stackalloc IntPtr[1]; toDo.Push(ptr); while (toDo.Any()) { var node = toDo.Pop(); if (handled.Add(node)) { foreach (var item in _autoMemoryManagementContext.RuntimeGlobalAccessor.GetLayoutInfo(node).Fields.Where(f => f.IsReference)) { item.GetValue(node, new IntPtr(buff)); var child = new BlockPtr(buff[0]); if (buff[0] != IntPtr.Zero && !handled.Contains(child)) { toDo.Push(child); } } } } return(handled.Count); }
private unsafe IEnumerable <BlockPtr> GetRefs(BlockPtr ptr) { var refBuff = stackalloc BlockPtr[1]; var list = new List <BlockPtr>(); foreach (var field in _autoMemoryManagementContext.RuntimeGlobalAccessor.GetLayoutInfo(ptr).Fields) { if (field.IsReference) { field.GetValue(ptr, new IntPtr(refBuff)); var p = refBuff[0]; if (p.value.ToPointer() >= _pool.ToPointer() && p.value.ToPointer() < (_pool + _poolSize).ToPointer()) { if (!_knownBlocks.Contains(ptr)) { throw new InvalidOperationException(); } list.Add(p); } } } return(list); }
INativeStructureLayoutInfo IRuntimeGlobalAccessor.GetLayoutInfo(BlockPtr blockPtr) { var ptr = stackalloc IntPtr[1]; _typeIdFieldInfo.GetValue(blockPtr, new IntPtr(ptr)); return(this.GetLayoutInfo(ptr[0])); }
public unsafe void GetValue(BlockPtr blockPtr, IntPtr buffer) { if (this.BitIndex == 0) { WinApi.CopyMemory(buffer, blockPtr.value + this.Offset, this.Size); if (this.IsReference) { IntPtr *p = (IntPtr *)buffer.ToPointer(); if (p[0] != IntPtr.Zero) { p[0] -= _ctx.ObjRefDiff; } } } else { var buff = new byte[this.Size]; Marshal.Copy(blockPtr.value + this.Offset, buff, 0, this.Size); var rawValue = new BigInteger(buff); var valueMask = BigInteger.Pow(2, this.BitsCount) - 1; var value = (rawValue >> (this.BitIndex - this.BitsCount)) & valueMask; var valueBytes = value.ToByteArray(); Marshal.Copy(valueBytes, 0, buffer, valueBytes.Length); } }
//write ref from obj to obj public void OnWriteRefMember(BlockPtr blockPtr, BlockPtr refPtr) { if (refPtr.CompareTo(blockPtr) == 0) { throw new NotSupportedException(); //TODO: ref to self } //do nothing }
private unsafe bool IsGarbage(BlockPtr ptr) { var isMarked = this.GetMark(ptr); bool isGarbage = !isMarked; if (_currAvailableBlocks.Contains(ptr) && isGarbage) { throw new InvalidOperationException(); } return(isGarbage); }
public void Free(BlockPtr blockPtr) { Console.WriteLine("Free " + blockPtr); if (_currAvailableBlocks.Contains(blockPtr)) { throw new InvalidOperationException(); } this.InternalFree(blockPtr.value); _knownBlocks.Remove(blockPtr); _releasedBlocks.Add(blockPtr); }
private void Sweep(IntPtr heapStart, IntPtr heapEnd) { var blocksToRecycle = new List <BlockPtr>(); MMFreeBlockHeader *freePtr = _freeBlocks; var ptr = new BlockPtr(heapStart); do { BlockPtr nextPtr; bool isFree = new IntPtr(freePtr) == ptr.value; if (_knownBlocks.Contains(ptr)) { Console.WriteLine("C"); } else if (!isFree) { Console.WriteLine("NC"); } if (isFree) { nextPtr = new BlockPtr(ptr.value + freePtr->size + sizeof(MMFreeBlockHeader)); freePtr = freePtr->next; } else { if (this.IsGarbage(ptr)) { blocksToRecycle.Add(ptr); } else { this.SetMark(ptr, false); } nextPtr = new BlockPtr(ptr.value + this.GetBlockSize(ptr.value)); } if (freePtr < nextPtr.value.ToPointer() && freePtr != (void *)0) { throw new InvalidOperationException(); } ptr = nextPtr; } while (ptr.value.ToPointer() < heapEnd.ToPointer()); blocksToRecycle.ForEach(p => this.Free(p)); }
private unsafe bool GetMark(BlockPtr ptr) { if (!_knownBlocks.Contains(ptr)) { throw new InvalidOperationException(); } var markField = _autoMemoryManagementContext.RuntimeGlobalAccessor.GetLayoutInfo(ptr).Fields[_autoMemoryManagementContext.MarkBitFieldNumber]; var isMarked = stackalloc bool[1]; markField.GetValue(ptr, new IntPtr(isMarked)); return(isMarked[0]); }
//The thread index is passed in because otherwise job reflection can't inject it through a pointer. public void Write <T>(T value, int threadIndex) where T : unmanaged { var blockList = m_perThreadBlockLists + threadIndex; if (blockList->nextWriteAddress > blockList->lastByteAddressInBlock) { if (blockList->elementCount == 0) { blockList->blocks = new UnsafeList(m_allocator); blockList->blocks.SetCapacity <BlockPtr>(10); } BlockPtr newBlockPtr = new BlockPtr { ptr = (byte *)UnsafeUtility.Malloc(m_blockSize, UnsafeUtility.AlignOf <T>(), m_allocator) }; blockList->nextWriteAddress = newBlockPtr.ptr; blockList->lastByteAddressInBlock = newBlockPtr.ptr + m_blockSize - 1; blockList->blocks.Add(newBlockPtr); } UnsafeUtility.CopyStructureToPtr(ref value, blockList->nextWriteAddress); blockList->nextWriteAddress += m_elementSize; blockList->elementCount++; }
public void OnWriteRefMember(BlockPtr blockPtr, BlockPtr refPtr) { }
public ObjPtr BlockToObj(BlockPtr ptr) { return(new ObjPtr(ptr.value + _typeIdFieldInfo.Offset)); }
INativeStructureLayoutInfo IRuntimeGlobalAccessor.GetLayoutInfo(BlockPtr blockPtr) { return(_underlyingRuntimeAccessor.GetLayoutInfo(blockPtr)); }
public void Free(BlockPtr blockPtr) { _memoryManager.Free(blockPtr); }
public void Free(BlockPtr blockPtr) { _allocations.Remove(blockPtr.value); Marshal.FreeHGlobal(blockPtr.value); }
public void Free(BlockPtr blockPtr) { _underlying.Free(blockPtr); }
public void Free(BlockPtr ptr) { this.InternalFree(ptr.value.ToPointer()); }
public void SpliceObjRef(BlockPtr oldPtr, BlockPtr newPtr) { _spliceObj(oldPtr, newPtr); }