Пример #1
0
            internal override unsafe void Visit(UIntPtr *loc)
            {
                UIntPtr objAddr = *loc;
                Object  obj     = Magic.fromAddress(objAddr);

                // 1. remove from ZCT
                Remove(obj);
                // 2. decrement RC on objects retained via multiuseword
                MultiUseWord muw = MultiUseWord.GetForObject(obj);

                if (muw.IsMonitorOrInflatedTag())
                {
                    MultiUseWord.RefCountGCDeadObjHook(muw);
                }
                // 3. add to deallocation list
                DeferredReferenceCountingCollector.deallocateLazily(obj);
            }
Пример #2
0
        internal static void ReportHeapDetails()
        {
            VTable.DebugPrint("\nHeap details:\n");
            uint pageCount = 0;

            for (UIntPtr i = UIntPtr.Zero; i < PageTable.pageTableCount;
                 i++)
            {
                if (PageTable.IsMyGcPage(i))
                {
                    pageCount++;
                }
            }
            VTable.DebugPrint("\tTotal number of heap pages: {0}",
                              __arglist(pageCount));

            // The following obtains counts of heap objects against types.
            UIntPtr lowPage  = UIntPtr.Zero;
            UIntPtr highPage = PageTable.pageTableCount;

            assertRuntimeTypeHeaders(lowPage, highPage);

            // First count the RuntimeType instances for heap objects.
            runtimeTypeReckoner.Initialize(true);
            visitAllObjects(forGCRuntimeTypeReckoner, lowPage, highPage);

            // Next, create a table for RuntimeType instance accounting.
            // NOTE: Storage for the table is marked "non-GC". Since
            // static data accounting is done before this, it's okay.
            int numSlots = runtimeTypeReckoner.Count;

            if (numSlots > TABLE_SIZE)
            {
                VTable.DebugPrint("Need {0} slots, have {1}\n",
                                  __arglist(numSlots, TABLE_SIZE));
                VTable.NotReached("MemoryAccounting table not large enough");
            }

            // Associate a table slot for each RuntimeType instance.
            runtimeTypeMapper.Initialize(false, MemoryAccounting.table);
            visitAllObjects(forGCRuntimeTypeMapper, lowPage, highPage);

            // Map each relevant RuntimeType instance to its table slot.
            for (uint i = 0; i < numSlots; i++)
            {
                RuntimeType rType = MemoryAccounting.table[i].RuntimeTypeObject;
                VTable.Assert(!MultiUseWord.IsMarked(rType),
                              @"!MultiUseWord.IsMarked(rType)");
                MemoryAccounting.table[i].SavedMUW =
                    MultiUseWord.GetForObject(rType);
                MultiUseWord.SetValForObject(rType, (UIntPtr)i);
            }

            // Count heap object instances by RuntimeType using table.
            instanceReckoner.Initialize(MemoryAccounting.table);
            visitAllObjects(forGCInstanceReckoner, lowPage, highPage);

            // Bubble sort the table in decreasing order of total size.
            for (int i = 0; i < numSlots; i++)
            {
                for (int j = numSlots - 1; j > i; j--)
                {
                    if (MemoryAccounting.table[j].TotalSize
                        > MemoryAccounting.table[j - 1].TotalSize)
                    {
                        // Swap contents.
                        RuntimeTypeAccounting temp = MemoryAccounting.table[j];
                        MemoryAccounting.table[j]     = MemoryAccounting.table[j - 1];
                        MemoryAccounting.table[j - 1] = temp;
                    }
                }
            }

            // Display table.
            VTable.DebugPrint("\n\tCounts of objects against types:\n");
            for (uint i = 0; i < numSlots; i++)
            {
                if ((uint)MemoryAccounting.table[i].TotalSize < 1024)
                {
                    continue;
                }
                VTable.DebugPrint
                    ("\t\t{0,36} instances: {1,6}, bytes: {2,10}\n",
                    __arglist(MemoryAccounting.table[i].RuntimeTypeObject.Name,
                              (uint)MemoryAccounting.table[i].Count,
                              (uint)MemoryAccounting.table[i].TotalSize));
            }

            // Reset book-keeping information maintained in headers and the global
            // table.
            for (uint i = 0; i < numSlots; i++)
            {
                RuntimeType rType = MemoryAccounting.table[i].RuntimeTypeObject;
                MultiUseWord.SetForObject
                    (rType, MemoryAccounting.table[i].SavedMUW);
                VTable.Assert(!MultiUseWord.IsMarked(rType),
                              "@!MultiUseWord.IsMarked(rType)");

                MemoryAccounting.table[i].RuntimeTypeObject = null;
                MemoryAccounting.table[i].SavedMUW          =
                    new MultiUseWord(new UIntPtr(0));
                MemoryAccounting.table[i].TotalSize = new UIntPtr(0);
                MemoryAccounting.table[i].Count     = 0;
            }
        }