internal static bool NoObjectPtrToTheCard(UIntPtr c) { VTable.Assert(CardTable.IsValidCardNo(c), "NoObjectPtrToTheCard: invalid card no"); return(GetCompressedBiasedOffset(c) == NoObjPtrToCard); }
internal static UIntPtr FirstObjPtrWithFieldInCard(UIntPtr c) { VTable.Assert(CardTable.IsValidCardNo(c), "Not valid card no"); VTable.Assert(CardTable.IsMyLiveGcCard(c), "Not my live GC card"); UIntPtr cardAddr = CardTable.CardAddr(c); UIntPtr nextCardAddr = CardTable.NextCardAddr(c); // Scan backward. May go to zombie areas UIntPtr cardBefore = c - 1; while (cardBefore >= CardTable.FirstCardNo && OffsetTable.NoObjectPtrToTheCard(cardBefore) && CardTable.IsMyGcCard(cardBefore)) { cardBefore--; } UIntPtr ptr; if (cardBefore < CardTable.FirstCardNo || !CardTable.IsMyGcCard(cardBefore)) { // this case happens when c is the first live card that has an object. VTable.Assert(CardTable.IsMyGcCard(cardBefore + 1), "The next card must be a GC card"); VTable.Assert(CardTable.CardAddr(cardBefore + 1) == CardTable.PageAddrOfCard(cardBefore + 1), "The next card must be at the boundary of a page"); UIntPtr pageAddr = CardTable.PageAddrOfCard(cardBefore + 1); ptr = PtrToNextObject(pageAddr, (UIntPtr)PreHeader.Size, nextCardAddr); } else { VTable.Assert(!OffsetTable.NoObjectPtrToTheCard(cardBefore), "A card with an object must have been found"); ptr = CardTable.CardAddr(cardBefore) + OffsetTable.GetOffset(cardBefore); } VTable.Assert(ptr < nextCardAddr, "No objptr in this card"); // Scan forward. Update offset table in the course. UIntPtr currentPtr = ptr; while (currentPtr < cardAddr) { UIntPtr size = OffsetTable.ObjectSize(currentPtr); if (currentPtr + size - PreHeader.Size > cardAddr) { VTable.Assert(CardTable.CardGeneration(CardTable.CardNo(currentPtr)) == CardTable.CardGeneration(c), "The whole object must be in the same generation"); break; } else { ptr = currentPtr; currentPtr = PtrToNextObject(currentPtr, size, nextCardAddr); VTable.Assert(CardTable.CardNo(ptr) <= CardTable.CardNo(currentPtr), "Previous ptr should be before current ptr"); if (CardTable.CardNo(ptr) < CardTable.CardNo(currentPtr)) { UIntPtr ptrC = CardTable.CardNo(ptr); UIntPtr offsetC = ptr - CardTable.CardAddr(ptrC); if (offsetC > GetOffset(ptrC)) { SetOffset(ptrC, offsetC); } } } } VTable.Assert(currentPtr != UIntPtr.Zero, "current ptr is zero"); VTable.Assert(currentPtr < nextCardAddr, "No objptr found in this card"); #if DEBUG_OFFSETTABLE UIntPtr temp = OffsetTable.FirstPtrFromInteriorTable(c); if (temp != currentPtr) { VTable.DebugPrint("Found ptr ({0:x8}) inconsistent with first ptr from interior table({1:x8})\n", __arglist(currentPtr, temp)); VTable.Assert(false); } #endif return(currentPtr); }
private static void SetNoObjPtrToCard(UIntPtr c) { VTable.Assert(CardTable.IsValidCardNo(c), "SetNoObjPtrToCard: invalid card no"); SetCompressedBiasedOffset(c, NoObjPtrToCard); }