Esempio n. 1
0
        // this is _just_ a notification - it doesn't pin the object, it's just
        // what we do if an object ends up being pinned.
        internal static void NotifyPin(UIntPtr objAddr)
        {
            UIntPtr page = PageTable.Page(objAddr);

            if (PageTable.Type(page) != SegregatedFreeList.SMALL_OBJ_PAGE)
            {
                return;
            }
            SegregatedFreeList.PageHeader *ph =
                (SegregatedFreeList.PageHeader *)PageTable.PageAddr(page);
            CoCoPageUserValue v = new CoCoPageUserValue(ph->userValue);

            if (v.Marked)
            {
                v.Pinned = true;
            }
            ph->userValue = v.Bits;
        }
            VisitPage(UIntPtr page,
                      SegregatedFreeList.PageHeader *ph,
                      int cells)
            {
                if (fDebugPage)
                {
                    VTable.DebugPrint("      $$ visiting page.\n");
                }
                CoCoPageUserValue v = new CoCoPageUserValue(ph->userValue);

                if (inFixUp && v.Marked)
                {
                    unmarkedCnt++;
                    v.Marked = false;
                    if (v.Pinned)
                    {
                        v.Pinned  = false;
                        v.Version = pinPenalty; /* use the Version to delay
                                                 * any future evacuation
                                                 * attempts for this page */
                    }
                }
                else if (!doingCoCo && !delay)
                {
                    if (v.Version >= 1)
                    {
                        // this page has a non-zero Version - this means
                        // that any attempts to evacuate it should be delayed.
                        v.Version--;
                        delayedCnt++;
                        if (fDebugPage)
                        {
                            VTable.DebugPrint("      $$ page had non-zero version.\n");
                        }
                    }
                    else
                    {
                        if (fDebugPage)
                        {
                            VTable.DebugPrint("      $$ cnt = ");
                            VTable.DebugPrint((ulong)cnt);
                            VTable.DebugPrint(", lastSmallPagesRecycle = ");
                            VTable.DebugPrint((ulong)lastSmallPagesRecycle);
                            VTable.DebugPrint(", sizeFracLim = ");
                            VTable.DebugPrint((ulong)sizeFracLim);
                            VTable.DebugPrint(", sizeLim = ");
                            VTable.DebugPrint((ulong)sizeLim);
                            VTable.DebugPrint(", PageSize = ");
                            VTable.DebugPrint((ulong)PageTable.PageSize);
                            VTable.DebugPrint(", freeCount = ");
                            VTable.DebugPrint((ulong)ph->freeCount);
                            VTable.DebugPrint(", pageFragThres = ");
                            VTable.DebugPrint((ulong)pageFragThres);
                            VTable.DebugPrint(", cells = ");
                            VTable.DebugPrint((ulong)cells);
                            VTable.DebugPrint("\n");
                        }
                        if ((long)cnt < ((long)lastSmallPagesRecycle
                                         / (long)sizeFracLim) &&
                            (sizeLim < 0 ||
                             cnt * PageTable.PageSize < (UIntPtr)sizeLim) &&
                            ph->freeCount * pageFragThres >= cells)
                        {
                            cnt++;
                            v.Marked = true;
                        }
                    }
                }
                else
                {
                    if (fDebugPage)
                    {
                        VTable.DebugPrint("      $$ not doing anything about page.\n");
                    }
                }
                ph->userValue = v.Bits;
                if (v.Marked)
                {
                    return(SegregatedFreeList.PartialPageAction.CommitFull);
                }
                else
                {
                    return(SegregatedFreeList.PartialPageAction.CommitFree);
                }
            }