Esempio n. 1
0
        private StreamWriter _sw = new StreamWriter(new MemoryStream()); //@"d:\temp\gc-log.txt");

        public AutoMemoryManager(AutoMemoryManagementContext autoMemoryManagementContext, IMemoryManager underlying)
        {
            _sw.BaseStream.SetLength(0);

            _autoMemoryManagementContext = autoMemoryManagementContext;
            _underlying = underlying;

            _poolSize = _initialPoolSize;
            _pool     = underlying.Alloc(_initialPoolSize).value;

            _defaultLayout          = autoMemoryManagementContext.RuntimeGlobalAccessor.GetDefaultLayoutInfo();
            _markBitFieldInfo       = _defaultLayout.Fields[autoMemoryManagementContext.MarkBitFieldNumber];
            _realBlockSizeFieldInfo = _defaultLayout.Fields[autoMemoryManagementContext.RealBlockSizeFieldNumber];

            MMFreeBlockHeader *item = (MMFreeBlockHeader *)_pool;

            item->next = MMFreeBlockHeader.ZeroPtr;
            item->size = _poolSize - sizeof(MMFreeBlockHeader);

            _freeBlocks = item;

            _stats.currentAllocatedBlocksCount = 0;
            _stats.currentAllocatedBytes       = 0;
            _stats.currentAllBlocksCount       = 1;
            _stats.currentAvailableBytes       = _poolSize;

            _stats.totalBlocksCreated   = 1;
            _stats.totalBlocksMerged    = 0;
            _stats.totalBlocksAllocated = 0;
            _stats.totalBlocksFreed     = 0;
        }
Esempio n. 2
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. 3
0
        private void Expand()
        {
            var newPool = _underlying.Alloc(_poolSize).value;

            if (newPool == IntPtr.Zero)
            {
                throw new OutOfMemoryException("Failed to expand memory pool");
            }

            MMFreeBlockHeader *item = (MMFreeBlockHeader *)newPool;

            item->next = MMFreeBlockHeader.ZeroPtr;
            item->size = _poolSize - sizeof(MMFreeBlockHeader);
            this.InsertFreeBlockToList(item);
        }
Esempio n. 4
0
        bool TryMergeFreeBlocks(MMFreeBlockHeader *first, MMFreeBlockHeader *second)
        {
            if (((int)first) + first->size + sizeof(MMFreeBlockHeader) == (int)second)
            {
                first->size += sizeof(MMFreeBlockHeader) + second->size;

                _stats.currentAllBlocksCount--;
                _stats.currentAvailableBytes += sizeof(MMBusyBlockHeader);
                _stats.totalBlocksMerged++;

                return(true);
            }
            else
            {
                return(false);
            }
        }
Esempio n. 5
0
        private void Expand()
        {
            var poolSize         = _poolSize;
            var poolHeaderOffset = poolSize.AlignTo(Alignment);
            var newPool          = _underlyingMM.Alloc((poolHeaderOffset + sizeof(MMPool)).AlignTo(Alignment)).value;

            if (newPool == IntPtr.Zero)
            {
                throw new OutOfMemoryException("Failed to expand memory pool");
            }

            MMFreeBlockHeader *item = (MMFreeBlockHeader *)newPool;

            item->next = MMFreeBlockHeader.ZeroPtr;
            item->size = poolSize - sizeof(MMFreeBlockHeader);
            this.InsertFreeBlockToList(item);

            MMPool *poolHeader = (MMPool *)(((int)newPool) + poolHeaderOffset);

            poolHeader->next     = _pools;
            poolHeader->rangePtr = newPool;
            poolHeader->size     = poolSize;
            _pools = poolHeader;
        }
Esempio n. 6
0
        void *InternalAlloc(int size)
        {
            MMFreeBlockHeader *pprev;
            MMFreeBlockHeader *p;
            MMFreeBlockHeader *next;
            MMBusyBlockHeader *ret;
            int retSize;

            // size += (MM_ALIGNMENT - ((size - 1) % MM_ALIGNMENT)) - 1;
            size = size.AlignTo(Alignment);

            pprev = MMFreeBlockHeader.ZeroPtr;
            p     = _freeBlocks;

            while (p != MMFreeBlockHeader.ZeroPtr)
            {
                if (p->size + sizeof(MMFreeBlockHeader) - sizeof(MMBusyBlockHeader) >= size)
                {
                    if (p->size + sizeof(MMFreeBlockHeader) - sizeof(MMBusyBlockHeader) - size > sizeof(MMFreeBlockHeader))
                    {
                        MMFreeBlockHeader *newBlock = (MMFreeBlockHeader *)(((int)p) + (sizeof(MMBusyBlockHeader) + size));
                        newBlock->size = (p->size + sizeof(MMFreeBlockHeader)) - (sizeof(MMBusyBlockHeader) + size) - sizeof(MMFreeBlockHeader);
                        newBlock->next = p->next;

                        p->size = sizeof(MMBusyBlockHeader) + size - sizeof(MMFreeBlockHeader);
                        p->next = newBlock;

                        _stats.currentAllBlocksCount++;
                        _stats.currentAvailableBytes -= sizeof(MMBusyBlockHeader);
                        _stats.totalBlocksCreated++;
                    }

                    next = p->next;

                    if (pprev == MMFreeBlockHeader.ZeroPtr && next == MMFreeBlockHeader.ZeroPtr)
                    {
                        _freeBlocks = MMFreeBlockHeader.ZeroPtr;
                    }
                    if (pprev == MMFreeBlockHeader.ZeroPtr)
                    {
                        _freeBlocks = next;
                    }
                    else if (next == MMFreeBlockHeader.ZeroPtr)
                    {
                        pprev->next = MMFreeBlockHeader.ZeroPtr;
                    }
                    else
                    {
                        pprev->next = next;
                    }

                    retSize   = p->size + sizeof(MMFreeBlockHeader) - sizeof(MMBusyBlockHeader);
                    ret       = (MMBusyBlockHeader *)p;
                    ret->size = retSize;

                    _stats.currentAllocatedBytes += ret->size;
                    _stats.currentAllocatedBlocksCount++;
                    _stats.currentAvailableBytes -= ret->size;
                    _stats.totalBlocksAllocated++;

                    return((void *)(((int)ret) + sizeof(MMBusyBlockHeader)));
                }

                pprev = p;
                p     = p->next;
            }

            return(MMFreeBlockHeader.ZeroPtr);
        }
Esempio n. 7
0
        void InsertFreeBlockToList(MMFreeBlockHeader *block)
        {
            if (_freeBlocks == MMFreeBlockHeader.ZeroPtr)
            {
                _freeBlocks = block;
            }
            else
            {
                MMFreeBlockHeader *p     = _freeBlocks;
                MMFreeBlockHeader *pprev = MMFreeBlockHeader.ZeroPtr;

                while (p != MMFreeBlockHeader.ZeroPtr)
                {
                    if (p > block)
                    {
                        break;
                    }

                    pprev = p;
                    p     = p->next;
                }

                // insert before p, after pprev

                if (pprev == MMFreeBlockHeader.ZeroPtr) // try merge [block, p]
                {
                    if (TryMergeFreeBlocks(block, p))
                    {
                        block->next = p->next;
                        _freeBlocks = block;
                    }
                    else
                    {
                        block->next = p;
                        _freeBlocks = block;
                    }
                }
                else if (p == MMFreeBlockHeader.ZeroPtr) // try merge [pprev, block]
                {
                    if (TryMergeFreeBlocks(pprev, block))
                    {
                        // do nothing
                    }
                    else
                    {
                        pprev->next = block;
                        block->next = MMFreeBlockHeader.ZeroPtr;
                    }
                }
                else // try merge [pprev, block] and [block, p]
                {
                    if (TryMergeFreeBlocks(pprev, block))
                    {
                        if (TryMergeFreeBlocks(pprev, p))
                        {
                            pprev->next = p->next;
                        }
                    }
                    else
                    {
                        if (TryMergeFreeBlocks(block, p))
                        {
                            pprev->next = block;
                            block->next = p->next;
                        }
                        else
                        {
                            pprev->next = block;
                            block->next = p;
                        }
                    }
                }
            }
        }
Esempio n. 8
0
        private IntPtr InternalAlloc(int size)
        {
            MMFreeBlockHeader *pprev;
            MMFreeBlockHeader *p;
            MMFreeBlockHeader *next;
            IntPtr             ret;
            int retSize;

            size += (_alignment - ((size - 1) % _alignment)) - 1;

            pprev = MMFreeBlockHeader.ZeroPtr;
            p     = _freeBlocks;

            while (p != MMFreeBlockHeader.ZeroPtr)
            {
                if (p->size + sizeof(MMFreeBlockHeader) >= size)
                {
                    if (p->size + sizeof(MMFreeBlockHeader) - size > sizeof(MMFreeBlockHeader))
                    {
                        MMFreeBlockHeader *newBlock = (MMFreeBlockHeader *)(((int)p) + size);
                        newBlock->size = (p->size + sizeof(MMFreeBlockHeader)) - size - sizeof(MMFreeBlockHeader);
                        newBlock->next = p->next;

                        p->size = size - sizeof(MMFreeBlockHeader);
                        p->next = newBlock;

                        _stats.currentAllBlocksCount++;
                        //_stats.currentAvailableBytes -= sizeof(MMBusyBlockHeader);
                        _stats.totalBlocksCreated++;
                    }

                    next = p->next;

                    if (pprev == MMFreeBlockHeader.ZeroPtr && next == MMFreeBlockHeader.ZeroPtr)
                    {
                        _freeBlocks = MMFreeBlockHeader.ZeroPtr;
                    }
                    if (pprev == MMFreeBlockHeader.ZeroPtr)
                    {
                        _freeBlocks = next;
                    }
                    else if (next == MMFreeBlockHeader.ZeroPtr)
                    {
                        pprev->next = MMFreeBlockHeader.ZeroPtr;
                    }
                    else
                    {
                        pprev->next = next;
                    }

                    retSize = p->size + sizeof(MMFreeBlockHeader);
                    ret     = new IntPtr(p);
                    this.SetBlockSize(ret, retSize);

                    _stats.currentAllocatedBytes += retSize;
                    _stats.currentAllocatedBlocksCount++;
                    _stats.currentAvailableBytes -= retSize;
                    _stats.totalBlocksAllocated++;

                    return(ret);
                }

                pprev = p;
                p     = p->next;
            }

            return(IntPtr.Zero);
        }