示例#1
0
 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));
        }
示例#3
0
 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);
        }