Пример #1
0
            internal static unsafe FreeNode *Create(PhysicalHeap *inHeap,
                                                    UIntPtr addr, UIntPtr pages)
            {
                DebugStub.Assert(addr >= inHeap->startAddr);
                DebugStub.Assert((addr + (pages * MemoryManager.PageSize)) <= inHeap->heapLimit);
                FreeNode *node = (FreeNode *)addr;

                // This had better be a free page in the main table
                DebugStub.Assert(inHeap->PageWord(inHeap->PageIndex(addr)) == FreePage,
                                 "Creating a FreeNode for non-free page {0:x}",
                                 __arglist(addr));

                node->signature = FreeNode.Signature;
                node->bytes     = pages * MemoryManager.PageSize;
                node->prev      = null;
                node->next      = null;
                node->last      = null;

                if (pages > 1)
                {
                    node->last = LastNode.Create(inHeap, addr, node);
                }

                return(node);
            }
Пример #2
0
            internal static unsafe LastNode *Create(PhysicalHeap *inHeap,
                                                    UIntPtr addr, FreeNode *node)
            {
                LastNode *last = (LastNode *)(addr + node->bytes - MemoryManager.PageSize);

                DebugStub.Assert((UIntPtr)last >= inHeap->startAddr);
                DebugStub.Assert((UIntPtr)last <= inHeap->heapLimit);
                DebugStub.Assert(MemoryManager.IsPageAligned((UIntPtr)last));
                last->signature = LastNode.Signature;
                last->node      = node;
                return(last);
            }
Пример #3
0
            internal unsafe void CreateAndInsert(PhysicalHeap *inHeap,
                                                 UIntPtr addr,
                                                 UIntPtr pages)
            {
                DebugStub.Assert(MemoryManager.IsPageAligned(addr),
                                 "PhysicalHeap.CreateAndInsert non page-aligned addr={0:x}",
                                 __arglist(addr));

                FreeNode *node = FreeNode.Create(inHeap, addr, pages);

                DebugStub.Assert(MemoryManager.IsPageAligned(node->bytes),
                                 "PhysicalHeap.CreateAndInsert non page-sized node->bytes={0:x}",
                                 __arglist(node->bytes));

                InsertBySize(node);
            }
Пример #4
0
            internal static unsafe FreeNode *GetNodeFromLast(PhysicalHeap *inHeap,
                                                             UIntPtr addr)
            {
                UIntPtr idx = inHeap->PageIndex(addr);

                // addr must specify a free page
                if (inHeap->PageWord(idx) != FreePage)
                {
                    // addr does not specify a LastNode
                    return(null);
                }

                // addr must specify a page such that the next page (if there
                // is one) is not free
                if ((idx != inHeap->pageCount - 1) &&
                    (inHeap->PageWord(idx + 1) == FreePage))
                {
                    return(null);
                }

                if (idx == 0)
                {
                    // This is a one-page block
                    DebugStub.Assert(((FreeNode *)addr)->signature == FreeNode.Signature);
                    return((FreeNode *)addr);
                }

                // If the preceding page is free, then addr specifies
                // the last page in a multi-page block, otherwise it
                // specifies the only page in a one-page block.
                if (inHeap->PageWord(idx - 1) == FreePage)
                {
                    DebugStub.Assert(((LastNode *)addr)->signature == Signature);
                    return(((LastNode *)addr)->node);
                }
                else
                {
                    DebugStub.Assert(((FreeNode *)addr)->signature == FreeNode.Signature);
                    return((FreeNode *)addr);
                }
            }
Пример #5
0
            internal static unsafe FreeNode *GetNodeAt(PhysicalHeap *inHeap,
                                                       UIntPtr addr)
            {
                UIntPtr idx = inHeap->PageIndex(addr);

                if (inHeap->PageWord(idx) != FreePage)
                {
                    // This address designates a page that is in use.
                    return(null);
                }

                if ((idx > 0) && (inHeap->PageWord(idx - 1) == FreePage))
                {
                    // This address is in the middle of a free block; it does
                    // not designate the beginning of a free block.
                    return(null);
                }

                DebugStub.Assert(((FreeNode *)addr)->signature == Signature);
                return((FreeNode *)addr);
            }