public static void Add(Object obj) { if (freeHead == 0) { GC.Collect(); // GC may add object into the PLC buffer. } uint refState = obj.REF_STATE; if ((refState & DeferredReferenceCountingCollector.markFlagMask) != 0) { return; // GC may already put this object in ZCT } uint position = GetFreeEntry(); if ((refState & DeferredReferenceCountingCollector. acyclicFlagMask) == 0) { uint index = DeferredReferenceCountingCollector.GetPLCIndex(obj); if (index != 0) { DeferredReferenceCountingCollector. SetPLCIndex(obj, 0); DeferredReferenceCountingCollector. removeFromPLCBuffer(index); } } #if DEBUG else { uint index = DeferredReferenceCountingCollector.GetPLCIndex(obj); VTable.Assert(index == 0, @"index == 0"); } #endif // DEBUG zeroCountTable[position] = Magic.addressOf(obj); obj.REF_STATE = position | DeferredReferenceCountingCollector.markFlagMask | DeferredReferenceCountingCollector.countingONFlagMask | (refState & DeferredReferenceCountingCollector.acyclicFlagMask); }
internal override unsafe void Visit(UIntPtr *loc) { UIntPtr objAddr = *loc; Object obj = Magic.fromAddress(objAddr); // 1. remove from ZCT Remove(obj); // 2. decrement RC on objects retained via multiuseword MultiUseWord muw = MultiUseWord.GetForObject(obj); if (muw.IsMonitorOrInflatedTag()) { MultiUseWord.RefCountGCDeadObjHook(muw); } // 3. add to deallocation list DeferredReferenceCountingCollector.deallocateLazily(obj); }
public static unsafe void Initialize() { maxEntries = 1 << 16; VTable UIntPtrArrayVtable = ((RuntimeType)typeof(UIntPtr[])).classVtable; tableSize = ObjectLayout.ArraySize(UIntPtrArrayVtable, maxEntries); // Allocate a pool for ZCT BumpAllocator entryPool = new BumpAllocator(PageType.NonGC); UIntPtr memStart = MemoryManager.AllocateMemory(tableSize); entryPool.SetZeroedRange(memStart, tableSize); PageManager.SetStaticDataPages(memStart, tableSize); // Initialize ZCT zeroCountTable = (UIntPtr[]) DeferredReferenceCountingCollector. AllocateArray(ref entryPool, UIntPtrArrayVtable, tableSize); VTable.Assert(zeroCountTable != null, @"zeroCountTable != null"); *(uint *)(Magic.addressOf(zeroCountTable) + PostHeader.Size) = maxEntries; VTable.Assert(zeroCountTable.Length == maxEntries, @"zeroCountTable.Length == maxEntries"); // Build ZCT freeEntries list freeHead = 1; for (uint i = 1; i < maxEntries - 1; i++) { zeroCountTable[i] = (UIntPtr)(((i + 1) << 2) | 0x01); } zeroCountTable[maxEntries - 1] = (UIntPtr)0x01; zctGarbagePicker = (ZCTGarbagePicker)BootstrapMemory. Allocate(typeof(ZCTGarbagePicker)); }
static GC() // Class Constructor (cctor) { GC.Initialize(); switch (gcType) { #if !SINGULARITY || ADAPTIVE_COPYING_COLLECTOR case GCType.AdaptiveCopyingCollector: { AdaptiveCopyingCollector.Initialize(); GC.installedGC = AdaptiveCopyingCollector.instance; break; } #endif #if !SINGULARITY || MARK_SWEEP_COLLECTOR case GCType.MarkSweepCollector: { MarkSweepCollector.Initialize(); GC.installedGC = MarkSweepCollector.instance; break; } #endif #if !SINGULARITY || TABLE_MARK_SWEEP_COLLECTOR case GCType.TableMarkSweepCollector: { SimpleMarkSweepCollector.Initialize(); GC.installedGC = SimpleMarkSweepCollector.instance; break; } #endif #if !SINGULARITY || SEMISPACE_COLLECTOR case GCType.SemispaceCollector: { SemispaceCollector.Initialize(); GC.installedGC = SemispaceCollector.instance; break; } #endif #if !SINGULARITY || SLIDING_COLLECTOR case GCType.SlidingCollector: { SlidingCollector.Initialize(); GC.installedGC = SlidingCollector.instance; break; } #endif #if !SINGULARITY || CONCURRENT_MS_COLLECTOR case GCType.ConcurrentMSCollector: { ConcurrentMSCollector.Initialize(); GC.installedGC = ConcurrentMSCollector.instance; break; } #endif #if !SINGULARITY || ATOMIC_RC_COLLECTOR case GCType.AtomicRCCollector: { AtomicRCCollector.Initialize(); GC.installedGC = AtomicRCCollector.instance; break; } #endif #if !SINGULARITY case GCType.ReferenceCountingCollector: { ReferenceCountingCollector.Initialize(); GC.installedGC = ReferenceCountingCollector.instance; break; } #endif #if !SINGULARITY case GCType.DeferredReferenceCountingCollector: { DeferredReferenceCountingCollector.Initialize(); GC.installedGC = DeferredReferenceCountingCollector.instance; break; } #endif #if !SINGULARITY || NULL_COLLECTOR case GCType.NullCollector: { VTable.Assert(wbType == 0, "No need for a write barrier"); GC.installedGC = (NullCollector) BootstrapMemory.Allocate(typeof(NullCollector)); break; } #endif #if !SINGULARITY case GCType.CoCoMSCollector: { CoCoMSCollector.Initialize(); GC.installedGC = CoCoMSCollector.instance; break; } #endif default: { VTable.NotReached("Unknown GC type: " + gcType); break; } } GC.installedGC.NewThreadNotification(Thread.initialThread, true); GC.installedGC.ThreadStartNotification(Thread.initialThread.threadIndex); }