public static new void Initialize() { GenerationalCollector.Initialize(); SemispaceCollector.Initialize(); SlidingCollector.Initialize(); // instance = new AdaptiveCopyingCollector(); instance = (AdaptiveCopyingCollector ) BootstrapMemory.Allocate(typeof(AdaptiveCopyingCollector)); }
public static new void Initialize() { GenerationalCollector.Initialize(); // copyScanners = new CopyScan[MAX_GENERATION+1]; copyScanners = (CopyScan[]) BootstrapMemory.Allocate(typeof(CopyScan[]), (uint)MAX_GENERATION + 1); for (int i = (int)MIN_GENERATION; i <= (int)MAX_GENERATION; i++) { switch (GC.copyscanType) { case CopyScanType.CheneyScan: { copyScanners[i] = (CopyScan) BootstrapMemory.Allocate(typeof(CheneyScan)); break; } case CopyScanType.HierarchicalScan: { copyScanners[i] = (CopyScan) BootstrapMemory.Allocate(typeof(HierarchicalScan)); break; } case CopyScanType.NestedHierarchicalScan: { copyScanners[i] = (CopyScan) BootstrapMemory.Allocate(typeof(NestedHierarchicalScan)); break; } default: { VTable.NotReached("Unknown CopyScan type: " + GC.copyscanType); break; } } copyScanners[i].Initialize((PageType)i); } // SemispaceCollector.instance = new SemispaceCollector(); SemispaceCollector.instance = (SemispaceCollector) BootstrapMemory.Allocate(typeof(SemispaceCollector)); // generalReferenceVisitor = new ForwardReferenceVisitor(); SemispaceCollector.generalReferenceVisitor = (ForwardReferenceVisitor) BootstrapMemory.Allocate(typeof(ForwardReferenceVisitor)); // threadReferenceVisitor = new ForwardThreadReference(generalReferenceVisitor); SemispaceCollector.threadReferenceVisitor = (ForwardThreadReference) BootstrapMemory.Allocate(typeof(ForwardThreadReference)); // pinnedReferenceVisitor = new RegisterPinnedReference(); SemispaceCollector.pinnedReferenceVisitor = (RegisterPinnedReference) BootstrapMemory.Allocate(typeof(RegisterPinnedReference)); // forwardOnlyReferenceVisitor = new ForwardOnlyReferenceVisitor(); SemispaceCollector.forwardOnlyReferenceVisitor = (ForwardOnlyReferenceVisitor) BootstrapMemory.Allocate(typeof(ForwardOnlyReferenceVisitor)); }
private UIntPtr AllocateObjectMemorySlow(UIntPtr numBytes, uint alignment, Thread currentThread) { //Trace.Log(Trace.Area.Allocate, // "AllocateObjectMemorySlow numBytes={0}, alignment={1}, currentThread={2}", __arglist(numBytes, alignment, currentThread)); GC.CheckForNeededGCWork(currentThread); VTable.Assert(CurrentPhase != StopTheWorldPhase.SingleThreaded || currentThread.threadIndex == collectorThreadIndex); if (GenerationalCollector.IsLargeObjectSize(numBytes)) { return(AllocateBig(numBytes, alignment, currentThread)); } return(BumpAllocator.Allocate(currentThread, numBytes, alignment)); }
public static new void Initialize() { GenerationalCollector.Initialize(); // SlidingCollector.instance = new SlidingCollector(); SlidingCollector.instance = (SlidingCollector) BootstrapMemory.Allocate(typeof(SlidingCollector)); // markReferenceVisitor = new MarkReferenceVisitor(); markReferenceVisitor = (MarkReferenceVisitor) BootstrapMemory.Allocate(typeof(MarkReferenceVisitor)); // registerThreadReferenceVisitor = new RegisterThreadReference(); registerThreadReferenceVisitor = (RegisterThreadReference) BootstrapMemory.Allocate(typeof(RegisterThreadReference)); // registerPinnedReferenceVisitor = new RegisterPinnedReference(); registerPinnedReferenceVisitor = (RegisterPinnedReference) BootstrapMemory.Allocate(typeof(RegisterPinnedReference)); // updateThreadReferenceVisitor = new UpdateThreadReference(); updateThreadReferenceVisitor = (UpdateThreadReference) BootstrapMemory.Allocate(typeof(UpdateThreadReference)); // forwardReferenceVisitor = new ForwardReferenceVisitor(); forwardReferenceVisitor = (ForwardReferenceVisitor) BootstrapMemory.Allocate(typeof(ForwardReferenceVisitor)); }
// Reference updates and object relocation private unsafe UIntPtr ForwardReferences(PageType generation, out UIntPtr oldAllocPtr) { VTable.Assert(IsValidGeneration((int)generation)); UIntPtr destPage = UIntPtr.Zero; UIntPtr destCursor; UIntPtr destLimit; PageType destGeneration; if (generation < MAX_GENERATION) { destGeneration = generation + 1; } else { destGeneration = MAX_GENERATION; } destCursor = UIntPtr.Zero; destLimit = UIntPtr.Zero; oldAllocPtr = destCursor; UIntPtr runLength = UIntPtr.Zero; for (UIntPtr i = UIntPtr.Zero; i < PageTable.pageTableCount; i++) { if (!IsMyZombiePage(i)) { continue; } UIntPtr deltaBytes = (UIntPtr)0x80000000; UIntPtr sourceCursor = PageTable.PageAddr(i); do { i++; } while (i < PageTable.pageTableCount && IsMyZombiePage(i)); UIntPtr sourceLimit = PageTable.PageAddr(i); while (true) { if (sourceCursor >= sourceLimit) { break; } if (Allocator.IsAlignmentMarkerAddr(sourceCursor)) { sourceCursor += UIntPtr.Size; deltaBytes += UIntPtr.Size; continue; } if (BumpAllocator.IsUnusedMarkerAddr(sourceCursor)) { sourceCursor += UIntPtr.Size; sourceCursor = PageTable.PagePad(sourceCursor); deltaBytes = (UIntPtr)0x80000000; continue; } UIntPtr objectAddr = sourceCursor + PreHeader.Size; UIntPtr vtableOrMarker = Allocator.GetObjectVTable(objectAddr); if (vtableOrMarker == UIntPtr.Zero) { // We found the end of an allocation page sourceCursor = PageTable.PagePad(sourceCursor); deltaBytes = (UIntPtr)0x80000000; continue; } UIntPtr vtableAddr; if ((vtableOrMarker & 1) != 0) { UIntPtr temp = *(UIntPtr *)(vtableOrMarker - 1); while ((temp & 1) != 0) { temp = *(UIntPtr *)(temp - 1); } VTable.Assert(PageTable.IsNonGcPage(PageTable.Type(PageTable.Page(temp)))); vtableAddr = temp; if ((temp & 2) != 0) { // Found pinned object SkipDestinationAreas(ref destPage, destCursor, ref destLimit, sourceCursor); deltaBytes -= (sourceCursor - destCursor); destCursor = sourceCursor; vtableAddr -= 2; // Remove "pinned" bit } Allocator.SetObjectVTable(objectAddr, vtableAddr); } else { vtableAddr = vtableOrMarker; } VTable vtable = Magic.toVTable(Magic.fromAddress(vtableAddr)); UIntPtr objectSize = ObjectLayout.ObjectSize(objectAddr, vtable); VTable.Assert(objectSize > 0); if ((vtableOrMarker & 1) != 0) { if (GenerationalCollector.IsLargeObjectSize (objectSize)) { // Don't move large objects SkipDestinationAreas(ref destPage, destCursor, ref destLimit, sourceCursor); UIntPtr localDelta = sourceCursor - destCursor; deltaBytes -= localDelta; if (deltaBytes == UIntPtr.Zero && runLength != UIntPtr.Zero) { runLength += localDelta; } destCursor = sourceCursor; UIntPtr objLimit = sourceCursor + objectSize; UIntPtr pageEndAddr = PageTable.PagePad(objLimit); objectSize = (pageEndAddr - sourceCursor); } else if (destCursor + objectSize > destLimit) { UIntPtr oldDestCursor = destCursor; FindDestinationArea(ref destPage, ref destCursor, ref destLimit, objectSize, destGeneration); VTable.Assert(destCursor <= sourceCursor); VTable.Assert(destCursor + objectSize <= destLimit); deltaBytes -= (destCursor - oldDestCursor); } else if (vtable.baseAlignment > UIntPtr.Size) { uint alignmentMask = vtable.baseAlignment - 1; int offset = PreHeader.Size + UIntPtr.Size; while (((destCursor + offset) & alignmentMask) != 0) { destCursor += UIntPtr.Size; deltaBytes -= UIntPtr.Size; if (deltaBytes == UIntPtr.Zero && runLength != UIntPtr.Zero) { runLength += UIntPtr.Size; } } } if (runLength == UIntPtr.Zero || deltaBytes != UIntPtr.Zero) { if (runLength != UIntPtr.Zero) { RegisterRelocationEnd(runLength); } RegisterRelocationStart(sourceCursor, destCursor); deltaBytes = UIntPtr.Zero; runLength = UIntPtr.Zero; } UIntPtr newObjectAddr = destCursor + PreHeader.Size; do { UIntPtr *ptrAddr = (UIntPtr *)(vtableOrMarker - 1); vtableOrMarker = *ptrAddr; *ptrAddr = newObjectAddr; } while ((vtableOrMarker & 1) != 0); destCursor += objectSize; runLength += objectSize; } else { deltaBytes += objectSize; if (runLength != UIntPtr.Zero) { RegisterRelocationEnd(runLength); } runLength = UIntPtr.Zero; } sourceCursor += objectSize; } } if (runLength != UIntPtr.Zero) { RegisterRelocationEnd(runLength); } return(destCursor); }