internal static unsafe void SetFirst(UIntPtr newAddr) { VTable.Assert(PageTable.IsGcPage(PageTable.Page(newAddr)), "SetFirst on a non-GC page"); UIntPtr page = PageTable.Page(newAddr); UIntPtr offset = newAddr - PageTable.PageAddr(page); PageTable.SetExtra(page, unchecked ((uint)(offset + OFFSET_SKEW))); }
// Bartok uses the extra field in the PageTable to easily // map from a stack address to the thread that owns that stack. // This is used to implement GetCurrentThread. // Singularity uses a different mechanism that does not involve // the extra data at all. private static unsafe void SetStackPages(UIntPtr startAddr, UIntPtr endAddr, Thread thread) { UIntPtr startPage = PageTable.Page(startAddr); UIntPtr endPage = PageTable.Page(endAddr); UIntPtr pageCount = endPage - startPage; PageTable.VerifyType(startPage, pageCount, PageType.Unallocated); PageTable.VerifyExtra(startPage, pageCount, 0); PageTable.SetType(startPage, pageCount, PageType.Stack); PageTable.SetExtra(startPage, pageCount, (uint)thread.threadIndex); }
// Tell the GC that a certain data area is no longer allowed to // contain off-limits, non-moveable data. private static unsafe void SetUnallocatedPages(UIntPtr startAddr, UIntPtr size) { UIntPtr startPage = PageTable.Page(startAddr); UIntPtr endAddr = startAddr + size; UIntPtr endPage = PageTable.Page(endAddr); UIntPtr pageCount = endPage - startPage; if (pageCount == 1) { PageTable.SetExtra(startPage, 0); PageTable.SetType(startPage, PageType.Unallocated); PageTable.SetProcess(startPage, 0); } else { PageTable.SetExtra(startPage, pageCount, 0); PageTable.SetType(startPage, pageCount, PageType.Unallocated); PageTable.SetProcess(startPage, pageCount, 0); } }
internal static unsafe void ClearFirst(UIntPtr startPage, UIntPtr endPage) { PageTable.SetExtra(startPage, endPage - startPage, OFFSET_NO_DATA); }
internal static unsafe void ClearFirst(UIntPtr page) { PageTable.SetExtra(page, OFFSET_NO_DATA); }