internal unsafe override void Visit(UIntPtr *loc) { UIntPtr addr = *loc; UIntPtr page = PageTable.Page(addr); Trace.Log(Trace.Area.Pointer, "FwdThrRef: loc={0}, addr={1}, page={2}", __arglist(loc, addr, page)); PageType pageType = PageTable.Type(page); // if an object "spills" into a page that // is pinned, and the object is copied // during a collection, we will end up with // the first part of the object in a zombie page // the second part of the object in a GC page. // We need to find the start of the object and // use that to determine whether the object has // been moved. if (!PageTable.IsZombiePage(pageType) && !PageTable.IsGcPage(pageType)) { VTable.Assert(PageTable.IsNonGcPage(pageType) || PageTable.IsStackPage(pageType) || PageTable.IsSharedPage(pageType) || VTable.BuildC2Mods, "Semispace:ForwardThreadReference"); return; } UIntPtr objectPtr = InteriorPtrTable.Find(addr); if (objectPtr == addr) { generalReferenceVisitor.Visit(loc); } else { // we can check for the page type of // objectPtr here to see if it is zombie page. // If true we can just return. UIntPtr newObject = objectPtr; generalReferenceVisitor.Visit(&newObject); UIntPtr newAddr = newObject + (addr - objectPtr); Trace.Log(Trace.Area.Pointer, "FwdThrRef: {0} -> {1}", __arglist(addr, newAddr)); *loc = newAddr; } }
// BUGBUG: We are allocating an ArrayList while the collector // is running. If the ArrayList gets big enough to be // allocated in the older generation, then the RemSet has the // potential to overflow since the boxed integers will reside // in the young generation. We should eventually eliminate // the use of ArrayList in this class as well as avoid boxing // the page indices. internal unsafe override void Visit(UIntPtr *loc) { UIntPtr addr = *loc; UIntPtr page = PageTable.Page(addr); PageType pageType = PageTable.Type(page); if (!PageTable.IsZombiePage(pageType)) { VTable.Assert(PageTable.IsGcPage(pageType) || PageTable.IsNonGcPage(pageType) || PageTable.IsStackPage(pageType) || PageTable.IsSharedPage(pageType) || VTable.BuildC2Mods, "Semispace:RegisterPinnedReference:1"); return; } PageType gen = PageTable.ZombieToLive(pageType); UIntPtr pinnedObjectAddr = InteriorPtrTable.Find(addr); if (pinnedPageList == null) { pinnedPageList = new ArrayList(); comparer = new UIntPtrComparer(); } Object pinnedObject = Magic.fromAddress(pinnedObjectAddr); UIntPtr objectSize = ObjectLayout.ObjectSize(pinnedObjectAddr, pinnedObject.vtable); UIntPtr beforeObjectAddr = pinnedObjectAddr - PreHeader.Size; UIntPtr pastObjectAddr = beforeObjectAddr + objectSize; UIntPtr firstPage = PageTable.Page(beforeObjectAddr); UIntPtr lastPage = PageTable.Page(pastObjectAddr - 1); for (UIntPtr i = firstPage; i <= lastPage; i++) { if (!pinnedPageList.Contains(i)) { Trace.Log(Trace.Area.Pointer, "RegPin: ptr={0} page={1} gen={2}", __arglist(pinnedObjectAddr, i, gen)); GenerationalCollector.gcPromotedTable[(int)gen - 1] += PageTable.PageSize; pinnedPageList.Add(i); } } }
internal unsafe override void Visit(UIntPtr *loc) { UIntPtr addr = *loc; UIntPtr page = PageTable.Page(addr); PageType pageType = PageTable.Type(page); if (!PageTable.IsZombiePage(pageType)) { VTable.Assert(PageTable.IsGcPage(pageType) || PageTable.IsNonGcPage(pageType) || PageTable.IsStackPage(pageType) || PageTable.IsSharedPage(pageType)); return; } UIntPtr objectAddr = InteriorPtrTable.Find(addr); this.threadPtrQueue.Write(objectAddr); this.threadPtrQueue.Write(addr - objectAddr); }
internal unsafe override void Visit(UIntPtr *loc) { UIntPtr addr = *loc; UIntPtr page = PageTable.Page(addr); PageType pageType = PageTable.Type(page); if (!PageTable.IsZombiePage(pageType)) { VTable.Assert(PageTable.IsGcPage(pageType) || PageTable.IsNonGcPage(pageType) || PageTable.IsStackPage(pageType) || PageTable.IsSharedPage(pageType)); return; } UIntPtr objectAddr = InteriorPtrTable.Find(addr); registerThreadReferenceVisitor.threadPtrQueue.Write(objectAddr); registerThreadReferenceVisitor.threadPtrQueue.Write(addr - objectAddr); *Allocator.GetObjectVTableAddress(objectAddr) |= (UIntPtr)2U; }
internal override UIntPtr FindObjectAddr(UIntPtr interiorPtr) { return(InteriorPtrTable.Find(interiorPtr)); }