internal Enumerator(ref UIntPtrQueue queue) { this.pageEnumerator = new UnmanagedPageList.Enumerator(ref queue.pageList); this.lastPageLimit = queue.writeCursor.cursor; this.lastPageStart = PageTable.PageAlign((UIntPtr)lastPageLimit); this.currentCursor = new PageCursor(null, null); if (this.pageEnumerator.MoveNext()) { UIntPtr currentPage = this.pageEnumerator.Current; this.SetCursor(currentPage); } }
private static unsafe void processPLCList() { int startTicks = 0; bool enableGCTiming = VTable.enableGCTiming; if (enableGCTiming) { VTable.enableGCTiming = false; startTicks = Environment.TickCount; } if (VTable.enableGCWatermarks) { MemoryAccounting.RecordHeapWatermarks(); } #if DEBUG VTable.Assert(firstPLCLink->objAddr == UIntPtr.Zero, @"firstPLCLink->objAddr == UIntPtr.Zero"); #endif // DEBUG // Let S be the subgraph of heap objects reachable from // the PLC list. Decrement counts due to references in S. for (PLCLink *link = firstPLCLink->next; link != null; link = link->next) { UIntPtr objAddr = link->objAddr; VTable.Assert(objAddr != UIntPtr.Zero, @"objAddr != UIntPtr.Zero"); Object obj = Magic.fromAddress(objAddr); VTable.Assert((obj.REF_STATE & countingONFlagMask) != 0, @"(obj.REF_STATE & countingONFlagMask) != 0"); uint refState = obj.REF_STATE; if ((refState & markFlagMask) == 0) { obj.REF_STATE = refState | markFlagMask; internalDecrementer.Traverse(objAddr); } } // Objects that now have non-zero counts are those that // have references external to S incident on them. // Recompute counts due to reachability from such objects. for (PLCLink *link = firstPLCLink->next; link != null; link = link->next) { UIntPtr objAddr = link->objAddr; internalScanner.Traverse(objAddr); } // String together objects with reference count // of zero for reclamation. internalReclaimer.Initialize(); for (PLCLink *link = firstPLCLink->next; link != null; link = link->next) { UIntPtr objAddr = link->objAddr; internalReclaimer.Traverse(objAddr); } ulong reclaimedBytes = 0; Object reclaimedObj = internalReclaimer.ReclaimedObjects; while (reclaimedObj != null) { if (VTable.enableGCProfiling) { UIntPtr size = ObjectLayout.Sizeof(reclaimedObj); reclaimedBytes += (ulong)size; } Object nextReclaimedObj = getNextLink(reclaimedObj); SegregatedFreeList.Free(reclaimedObj); reclaimedObj = nextReclaimedObj; } // Recycle the PLC list. if (firstPLCLink->next != null) { PLCLink *lastPLCLink = firstPLCLink; do { lastPLCLink = lastPLCLink->next; } while (lastPLCLink->next != null); lastPLCLink->next = plcListChunk; plcListChunk = firstPLCLink->next; firstPLCLink->next = null; } // Release the memory used up by work lists. UIntPtrQueue.ReleaseStandbyPages(null); SegregatedFreeList.RecycleGlobalPages(); SegregatedFreeList.CommitFreedData(); GC.newBytesSinceGC = UIntPtr.Zero; if (enableGCTiming) { int elapsedTicks = Environment.TickCount - startTicks; System.GC.gcTotalTime += elapsedTicks; if (System.GC.maxPauseTime < elapsedTicks) { System.GC.maxPauseTime = elapsedTicks; } System.GC.pauseCount++; VTable.enableGCTiming = true; } if (VTable.enableGCProfiling) { if (maxCyclicGarbage < reclaimedBytes) { maxCyclicGarbage = reclaimedBytes; } totalCyclicGarbage += reclaimedBytes; cycleCollections++; } }
internal override void Initialize(PageType pageType) { base.Initialize(pageType); this.workList = new UIntPtrQueue(); }