internal unsafe void VisitSpecialData(DirectReferenceVisitor visitor)
        {
            HandlePage *limit = null;
            HandlePage *began;

            do
            {
                // Repeat this loop as long as new pages appear.
                // REVIEW: I'm not sure this is needed, the write barrier might
                // take care of this for us.
                began = pages;
                for (HandlePage *page = began; page != limit; page = page->next)
                {
                    // Get the bounds.
                    HandleEntry *entry  = ((HandleEntry *)(page + 1));
                    HandleEntry *elimit = entry + handlesPerPage;

                    for (; entry < elimit; entry++)
                    {
                        entry->Visit(visitor);
                    }
                }
                limit = pages;
            } while (pages != began);
        }
        internal unsafe UIntPtr FreeAllPages()
        {
            // We assume that external code has insured thread safety.
            freeList = null;

            for (HandlePage *next; pages != null; pages = next)
            {
                next = pages->next;

                MemoryManager.KernelFree((UIntPtr)pages, 1, process);
            }

            return((UIntPtr)pageCount * MemoryManager.PageSize);
        }
        internal unsafe void FreeEntry(HandleEntry *entry)
        {
            entry->Set(null);

            HandleEntry *next;

            do
            {
                next        = freeList;
                entry->next = next;

                // Interlocked.CompareExchange only updates freeList if it hasn't
                // changed within this loop.
            } while (next != Interlocked.CompareExchange(ref freeList, entry, next));
        }
        internal unsafe HandleEntry *AllocateEntry()
        {
            HandleEntry *entry = AllocateExisting();

            if (entry != null)
            {
                return(entry);
            }

#if SINGULARITY_KERNEL
            Kernel.Waypoint(830);
#endif // SINGULARITY_KERNEL
            // Need to allocate a new page.
            HandlePage *page
                = (HandlePage *)MemoryManager.KernelAllocate(
                      1, process, 0, PageType.Shared);

#if SINGULARITY_KERNEL
            Kernel.Waypoint(831);
#endif // SINGULARITY_KERNEL

            if (page == null)
            {
                return(null);
            }

            // Get the bounds.
            HandleEntry *beg = ((HandleEntry *)(page + 1));
            HandleEntry *end = beg + handlesPerPage - 1;

            // Save off the first entry to return.
            entry = beg++;
            entry->Set(null);
            entry->next = null;

            // Initialize the free list in the rest of the entries.
            for (HandleEntry *step = beg; step < end; step++)
            {
                step->Set(null);
                step->next = step + 1;
            }
            end->Set(null);
            end->next = null;

            // Initialize the page header and insert into the page list.
            page->SetTable(this);
            page->next = null;
            HandlePage *last;
            do
            {
                last       = pages;
                page->next = last;

                // Interlocked.CompareExchange only updates pages if it hasn't
                // changed within this loop.
            } while (last != Interlocked.CompareExchange(ref pages, page, last));

            // Then insert into the free list.
            HandleEntry *next;
            do
            {
                next      = freeList;
                end->next = next;

                // Interlocked.CompareExchange only updates freeList if it hasn't
                // changed with this loop.
            } while (next != Interlocked.CompareExchange(ref freeList, beg, next));

            Interlocked.Increment(ref pageCount);

            return(entry);
        }
 internal unsafe HandleTable(Process process)
 {
     pages    = null;
     freeList = null;
 }
        internal static unsafe Object GetHandle(UIntPtr handle)
        {
            HandleEntry *entry = (HandleEntry *)handle;

            return(entry->Get());
        }
        internal static unsafe void ClrHandle(UIntPtr handle)
        {
            HandleEntry *entry = (HandleEntry *)handle;

            entry->Set(null);
        }
        internal static unsafe void SetHandle(UIntPtr handle, Object obj)
        {
            HandleEntry *entry = (HandleEntry *)handle;

            entry->Set(obj);
        }
        internal static unsafe HandleTable FindOwner(HandleEntry *entry)
        {
            HandlePage *page = (HandlePage *)MemoryManager.PageAlign((UIntPtr)entry);

            return(page->GetTable());
        }