private static PageOfHeaps* AllocatePageOfHeaps() { ulong pageSize = PageAllocator.MinimumPageSize; ulong pageAddress = PageAllocator.Allocate(ref pageSize); PageOfHeaps* pageOfHeaps = (PageOfHeaps*)pageAddress; pageOfHeaps->PageSize = pageSize; pageOfHeaps->Heaps = (GC.GCHeap*)(pageAddress + (ulong)sizeof(PageOfHeaps)); pageOfHeaps->TotalHeaps = (pageSize - (ulong)sizeof(PageOfHeaps)) / (ulong)sizeof(GC.GCHeap); pageOfHeaps->Next = null; pageOfHeaps->Prev = PageOfHeapsLast; if (PageOfHeapsLast != null) PageOfHeapsLast->Next = pageOfHeaps; else PageOfHeapsFirst = pageOfHeaps; PageOfHeapsLast = pageOfHeaps; pageOfHeaps->AllocatedFirst = null; pageOfHeaps->AllocatedLast = null; pageOfHeaps->AvailableFirst = pageOfHeaps->Heaps; pageOfHeaps->AvailableLast = &pageOfHeaps->Heaps[pageOfHeaps->TotalHeaps - 1]; for (ulong heapIndex = 0; heapIndex < pageOfHeaps->TotalHeaps; ++heapIndex) { bool lastHeap = heapIndex == (pageOfHeaps->TotalHeaps - 1); GC.GCHeap* heap = &pageOfHeaps->Heaps[heapIndex]; heap->PageOfHeaps = pageOfHeaps; if (lastHeap) heap->AllocatorNext = null; else heap->AllocatorNext = &pageOfHeaps->Heaps[heapIndex + 1]; if (heapIndex == 0) heap->AllocatorPrev = null; else heap->AllocatorPrev = &pageOfHeaps->Heaps[heapIndex - 1]; heap->HeapSize = 0; heap->Heap = null; heap->TreeSize = 0; heap->Tree = null; heap->TreeLevels = 0; heap->AllocatedFirst = null; heap->AllocatedLast = null; } return pageOfHeaps; }
private static void DeallocatePageOfHeaps(PageOfHeaps* pPage) { if (pPage->Prev == null) PageOfHeapsFirst = pPage->Next; else pPage->Prev->Next = pPage->Next; if (pPage->Next == null) PageOfHeapsLast = pPage->Prev; else pPage->Next->Prev = pPage->Prev; PageAllocator.Deallocate((ulong)pPage, pPage->PageSize); }