internal override void Scan(NonNullReferenceVisitor ptrVisitor,
                             PageType genToCollect)
 {
     for (int i = 0; i < writeBufferIndex; i++)
     {
         UIntPtr tag = *(writeBuffer + i);
         if (tag != UIntPtr.Zero)
         {
             if ((tag & 0x1) == 0)
             {
                 UIntPtr *fieldLoc = (UIntPtr *)tag;
                 if (*fieldLoc != UIntPtr.Zero)
                 {
                     ptrVisitor.Visit(fieldLoc);
                 }
             }
             else
             {
                 UIntPtr objectPtr = (UIntPtr)(tag - 1);
                 Object  obj       = Magic.fromAddress(objectPtr);
                 ptrVisitor.VisitReferenceFields(obj);
             }
         }
     }
     // Handle the overflow in the thread objects
     for (int i = 0; i < Thread.threadTable.Length; i++)
     {
         Thread t = Thread.threadTable[i];
         if (t != null)
         {
             UIntPtr tag = MixinThread(t).ssb.overflowValue;
             if (tag != UIntPtr.Zero)
             {
                 if ((tag & 0x1) == 0)
                 {
                     UIntPtr *fieldLoc = (UIntPtr *)tag;
                     if (*fieldLoc != UIntPtr.Zero)
                     {
                         ptrVisitor.Visit(fieldLoc);
                     }
                 }
                 else
                 {
                     UIntPtr objectPtr = (UIntPtr)(tag - 1);
                     Object  obj       = Magic.fromAddress(objectPtr);
                     ptrVisitor.VisitReferenceFields(obj);
                 }
             }
         }
     }
 }
Example #2
0
 protected static void UpdateReferentRefCounts
     (UIntPtr objAddr,
     VTable vtable,
     NonNullReferenceVisitor updater)
 {
     updater.VisitReferenceFields(objAddr, vtable);
 }
Example #3
0
        internal override bool Scan(NonNullReferenceVisitor visitor)
        {
            bool globalRepeat = false;

            while (true)
            {
                UIntPtr lowAddr, highAddr;
                if (this.destinationLow != this.allocator.AllocPtr)
                {
                    lowAddr             = this.destinationLow;
                    highAddr            = this.allocator.AllocPtr;
                    this.destinationLow = highAddr;
                }
                else if (!this.HaveWork)
                {
                    // No more work to do
                    break;
                }
                else
                {
                    lowAddr = this.GetWork(out highAddr);
                }
                globalRepeat    = true;
                this.sourceHigh = highAddr;
                lowAddr        += PreHeader.Size;
                lowAddr         =
                    BumpAllocator.SkipNonObjectData(lowAddr, highAddr);
                while (lowAddr < this.sourceHigh)
                {
                    Object obj = Magic.fromAddress(lowAddr);
                    lowAddr += visitor.VisitReferenceFields(obj);
                    lowAddr  =
                        BumpAllocator.SkipNonObjectData(lowAddr, highAddr);
                }
                if (lowAddr < highAddr)
                {
                    // The scanning must have been aborted early due to
                    // overflow into a new page.  Put the rest of the
                    // range on the work list.
                    this.AddWork(lowAddr - PreHeader.Size, highAddr);
                }
            }
            return(globalRepeat);
        }
Example #4
0
        internal override bool Scan(NonNullReferenceVisitor visitor)
        {
            bool localRepeat  = false;
            bool globalRepeat = false;

            while (true)
            {
                while (this.HaveWork)
                {
                    localRepeat = true;
                    UIntPtr lowAddr, highAddr;
                    lowAddr  = this.GetWork(out highAddr);
                    lowAddr += PreHeader.Size;
                    lowAddr  =
                        BumpAllocator.SkipNonObjectData(lowAddr, highAddr);
                    while (lowAddr < highAddr)
                    {
                        Object obj = Magic.fromAddress(lowAddr);
                        lowAddr += visitor.VisitReferenceFields(obj);
                        lowAddr  =
                            BumpAllocator.SkipNonObjectData(lowAddr, highAddr);
                    }
                }
                if (this.destinationLow != this.allocator.AllocPtr)
                {
                    localRepeat = true;
                    UIntPtr lowAddr  = this.destinationLow;
                    UIntPtr highAddr = this.allocator.AllocPtr;
                    this.destinationLow = highAddr;
                    this.AddWork(lowAddr, highAddr);
                }
                if (!localRepeat)
                {
                    // Exit the loop if we have done nothing this time around
                    break;
                }
                globalRepeat = true;
                localRepeat  = false;
            }
            return(globalRepeat);
        }
Example #5
0
        private static void VisitObjectsInCards(NonNullReferenceVisitor ptrVisitor,
                                                UIntPtr first, UIntPtr last)
        {
            UIntPtr objectPtr = OffsetTable.FirstObjPtrWithFieldInCard(first);

            VTable.Assert(objectPtr != UIntPtr.Zero, "No first obj ptr");

            // TODO: in semispace.Visit, update cards in visiting promoted objects.
            // So far, since we have only two generations, and after scanning, all nursery
            // objects are promoted to mature generation,  thus there is no inter-generational
            // pointers anymore, and we do not need to update cards during visit. But we
            // need to do that once we have more than two generations.

            UIntPtr limit = NextCardAddr(last);

            while (objectPtr != UIntPtr.Zero && objectPtr < limit)
            {
#if DEBUG_CARDS
                VTable.DebugPrint("     visiting obj ptr {0:x8}\n", __arglist(objectPtr));
#endif
                Object  obj           = Magic.fromAddress(objectPtr);
                UIntPtr objSize       = ptrVisitor.VisitReferenceFields(obj);
                UIntPtr nextObjectPtr = OffsetTable.PtrToNextObject(objectPtr, objSize, limit);
                VTable.Assert(CardNo(objectPtr) <= CardNo(nextObjectPtr),
                              "Next object should be below the current one");
                if (CardNo(objectPtr) < CardNo(nextObjectPtr))
                {
                    UIntPtr c      = CardNo(objectPtr);
                    UIntPtr offset = objectPtr - CardAddr(c);
                    if (offset > OffsetTable.GetOffset(c))
                    {
                        OffsetTable.SetOffset(c, offset);
                    }
                }
                objectPtr = nextObjectPtr;
            }
        }
Example #6
0
        protected static unsafe uint incrementalDecrement
            (UIntPtr objAddr,
            VTable vtable,
            NonNullReferenceVisitor decrementer)
        {
            uint pointerTracking = (uint)vtable.pointerTrackingMask;
            uint objTag          = pointerTracking & 0xf;
            uint workDone        = 0;

            switch (objTag)
            {
            case ObjectLayout.SPARSE_TAG: {
                UIntPtr *sparseObject        = (UIntPtr *)objAddr;
                uint     lastPointerTracking = getLastTracked(objAddr);
                for (pointerTracking = lastPointerTracking;
                     pointerTracking != 0 &&
                     workDone < decrementSpan; workDone++)
                {
                    uint index = pointerTracking & 0xf;
                    pointerTracking >>= 4;
                    UIntPtr *loc  = sparseObject + (int)index;
                    UIntPtr  addr = *loc;
                    if (addr != UIntPtr.Zero)
                    {
                        decrementer.Visit(addr);
                    }
                }
                setLastTracked(objAddr, pointerTracking);
                break;
            }

            case ObjectLayout.DENSE_TAG: {
                UIntPtr *denseObject = (UIntPtr *)
                                       (objAddr + PostHeader.Size);
                int lastIndex =
                    unchecked ((int)getLastTracked(objAddr));
                pointerTracking >>= lastIndex + 4;
                for (denseObject += lastIndex; pointerTracking != 0 &&
                     workDone < decrementSpan; workDone++,
                     lastIndex++, denseObject++)
                {
                    if ((pointerTracking & 0x1) != 0 &&
                        *denseObject != UIntPtr.Zero)
                    {
                        decrementer.Visit(denseObject);
                    }
                    pointerTracking >>= 1;
                }
                setLastTracked(objAddr, unchecked ((uint)lastIndex));
                break;
            }

            case ObjectLayout.PTR_VECTOR_TAG: {
                uint     length      = *(uint *)(objAddr + PostHeader.Size);
                UIntPtr *elemAddress = (UIntPtr *)
                                       (objAddr + vtable.baseLength - PreHeader.Size);
                uint lastIndex = getLastTracked(objAddr);
                for (elemAddress += lastIndex; lastIndex < length &&
                     workDone < decrementSpan; workDone++,
                     lastIndex++, elemAddress++)
                {
                    if (*elemAddress != UIntPtr.Zero)
                    {
                        decrementer.Visit(elemAddress);
                    }
                }
                setLastTracked(objAddr, lastIndex);
                break;
            }

            case ObjectLayout.OTHER_VECTOR_TAG: {
                if (vtable.arrayOf == StructuralType.Struct)
                {
                    uint    length      = *(uint *)(objAddr + PostHeader.Size);
                    UIntPtr elemAddress = objAddr + vtable.baseLength -
                                          PreHeader.Size - PostHeader.Size;
                    VTable elemVTable = vtable.arrayElementClass;
                    int    elemSize   = vtable.arrayElementSize;
                    uint   lastIndex  = getLastTracked(objAddr);
                    for (elemAddress += (UIntPtr)(elemSize * lastIndex);
                         lastIndex < length &&
                         workDone < decrementSpan; workDone++,
                         lastIndex++, elemAddress += elemSize)
                    {
                        decrementer.VisitReferenceFields(elemAddress,
                                                         elemVTable);
                    }
                    setLastTracked(objAddr, lastIndex);
                }
                break;
            }

            case ObjectLayout.PTR_ARRAY_TAG: {
                uint length =
                    *(uint *)(objAddr + PostHeader.Size + sizeof(uint));
                UIntPtr *elemAddress = (UIntPtr *)
                                       (objAddr + vtable.baseLength - PreHeader.Size);
                uint lastIndex = getLastTracked(objAddr);
                for (elemAddress += lastIndex; lastIndex < length &&
                     workDone < decrementSpan; workDone++,
                     lastIndex++, elemAddress++)
                {
                    if (*elemAddress != UIntPtr.Zero)
                    {
                        decrementer.Visit(elemAddress);
                    }
                }
                setLastTracked(objAddr, lastIndex);
                break;
            }

            case ObjectLayout.OTHER_ARRAY_TAG: {
                if (vtable.arrayOf == StructuralType.Struct)
                {
                    uint length =
                        *(uint *)(objAddr +
                                  PostHeader.Size + sizeof(uint));
                    UIntPtr elemAddress = objAddr + vtable.baseLength -
                                          PreHeader.Size - PostHeader.Size;
                    VTable elemVTable = vtable.arrayElementClass;
                    int    elemSize   = vtable.arrayElementSize;
                    uint   lastIndex  = getLastTracked(objAddr);
                    for (elemAddress += (UIntPtr)(elemSize * lastIndex);
                         lastIndex < length &&
                         workDone < decrementSpan; workDone++,
                         lastIndex++, elemAddress += elemSize)
                    {
                        decrementer.VisitReferenceFields(elemAddress,
                                                         elemVTable);
                    }
                    setLastTracked(objAddr, lastIndex);
                }
                break;
            }

            case ObjectLayout.STRING_TAG: {
                break;
            }

            default: {
                VTable.Assert((objTag & 0x1) == 0,
                              @"(objTag & 0x1) == 0");

                UIntPtr *largeObject        = (UIntPtr *)objAddr;
                int *    pointerDescription =
                    (int *)vtable.pointerTrackingMask;
                int lastCount =
                    unchecked ((int)getLastTracked(objAddr));
                for (int count = *pointerDescription;
                     lastCount <= count && workDone < decrementSpan;
                     workDone++, lastCount++)
                {
                    UIntPtr *loc = largeObject +
                                   *(pointerDescription + lastCount);
                    if (*loc != UIntPtr.Zero)
                    {
                        decrementer.Visit(loc);
                    }
                }
                setLastTracked(objAddr, unchecked ((uint)lastCount));
                break;
            }
            }

            return(workDone);
        }
Example #7
0
        protected static unsafe void UpdateReferentRefCounts
            (UIntPtr objAddr,
            VTable vtable,
            int start,
            int span,
            NonNullReferenceVisitor updater)
        {
            uint pointerTracking = (uint)vtable.pointerTrackingMask;
            uint objTag          = pointerTracking & 0xf;

            switch (objTag)
            {
            case ObjectLayout.PTR_VECTOR_TAG: {
                uint length = *(uint *)(objAddr + PostHeader.Size);
                VTable.Assert(span <= length,
                              @"span <= length");

                UIntPtr *elemAddress = (UIntPtr *)(objAddr +
                                                   vtable.baseLength - PreHeader.Size) + start;
                for (int i = 0; i < span; i++, elemAddress++)
                {
                    updater.Visit(elemAddress);
                }
                break;
            }

            case ObjectLayout.OTHER_VECTOR_TAG: {
                uint length = *(uint *)(objAddr + PostHeader.Size);
                VTable.Assert(span <= length,
                              @"span <= length");

                if (vtable.arrayOf == StructuralType.Struct)
                {
                    int     elemSize    = vtable.arrayElementSize;
                    UIntPtr elemAddress = objAddr + vtable.baseLength -
                                          PreHeader.Size - PostHeader.Size + elemSize * start;
                    VTable elemVTable = vtable.arrayElementClass;
                    for (int i = 0; i < span; i++,
                         elemAddress += elemSize)
                    {
                        updater.VisitReferenceFields(elemAddress,
                                                     elemVTable);
                    }
                }
                break;
            }

            case ObjectLayout.PTR_ARRAY_TAG: {
                uint length =
                    *(uint *)(objAddr + PostHeader.Size + sizeof(uint));
                VTable.Assert(span <= length,
                              @"span <= length");

                UIntPtr *elemAddress = (UIntPtr *)
                                       (objAddr + vtable.baseLength - PreHeader.Size) + start;
                for (int i = 0; i < span; i++, elemAddress++)
                {
                    updater.Visit(elemAddress);
                }
                break;
            }

            case ObjectLayout.OTHER_ARRAY_TAG: {
                uint length =
                    *(uint *)(objAddr + PostHeader.Size + sizeof(uint));
                VTable.Assert(span <= length,
                              @"span <= length");

                if (vtable.arrayOf == StructuralType.Struct)
                {
                    int     elemSize    = vtable.arrayElementSize;
                    UIntPtr elemAddress = objAddr + vtable.baseLength -
                                          PreHeader.Size - PostHeader.Size + elemSize * start;
                    VTable elemVTable = vtable.arrayElementClass;
                    for (int i = 0; i < span; i++,
                         elemAddress += elemSize)
                    {
                        updater.VisitReferenceFields(elemAddress,
                                                     elemVTable);
                    }
                }
                break;
            }

            case ObjectLayout.STRING_TAG: {
                break;
            }

            default: {
                VTable.NotReached("An unsupported tag found!");
                break;
            }
            }
        }