Esempio n. 1
0
        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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
            }
        }
Esempio n. 7
0
 //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
 }
Esempio n. 8
0
        private unsafe bool IsGarbage(BlockPtr ptr)
        {
            var  isMarked  = this.GetMark(ptr);
            bool isGarbage = !isMarked;

            if (_currAvailableBlocks.Contains(ptr) && isGarbage)
            {
                throw new InvalidOperationException();
            }

            return(isGarbage);
        }
Esempio n. 9
0
        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);
        }
Esempio n. 10
0
        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));
        }
Esempio n. 11
0
        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));
 }
Esempio n. 16
0
 public void Free(BlockPtr blockPtr)
 {
     _memoryManager.Free(blockPtr);
 }
Esempio n. 17
0
 public void Free(BlockPtr blockPtr)
 {
     _allocations.Remove(blockPtr.value);
     Marshal.FreeHGlobal(blockPtr.value);
 }
 public void Free(BlockPtr blockPtr)
 {
     _underlying.Free(blockPtr);
 }
Esempio n. 19
0
 public void Free(BlockPtr ptr)
 {
     this.InternalFree(ptr.value.ToPointer());
 }
Esempio n. 20
0
 public void SpliceObjRef(BlockPtr oldPtr, BlockPtr newPtr)
 {
     _spliceObj(oldPtr, newPtr);
 }