예제 #1
0
 internal void RecordGc(int tickIndex, SampleObjectTable sampleObjectTable, bool simpleForm)
 {
     if (simpleForm && nullRelocationsSeen || newLiveRoot != null)
     {
         // in this case assume anything not reported is dead
         updateRoot = SortIntervals(updateRoot);
         ulong prevHiAddr = 0;
         for (Interval i = updateRoot; i != null; i = i.next)
         {
             if (prevHiAddr < i.loAddr)
             {
                 RemoveRange(prevHiAddr, i.loAddr, tickIndex, sampleObjectTable);
             }
             if (prevHiAddr < i.hiAddr)
                 prevHiAddr = i.hiAddr;
         }
         RemoveRange(prevHiAddr, ulong.MaxValue, tickIndex, sampleObjectTable);
         updateRoot = null;
         if (newLiveRoot != null)
         {
             liveRoot = newLiveRoot;
             newLiveRoot = null;
         }
     }
     else
     {
         for (Interval i = liveRoot; i != null; i = i.next)
             i.justHadGc = true;
     }
     nullRelocationsSeen = false;
 }
예제 #2
0
 internal bool AddObject(ulong id, uint size, int allocTickIndex, SampleObjectTable sampleObjectTable)
 {
     size = (size + 3) & (uint.MaxValue - 3);
     Interval prevInterval = null;
     Interval bestInterval = null;
     Interval prevI = null;
     bool emptySpace = false;
     // look for the best interval to put this object in.
     for (Interval i = liveRoot; i != null; i = i.next)
     {
         if (i.loAddr < id + size && id <= i.hiAddr + allowableGap)
         {
             if (bestInterval == null || bestInterval.loAddr < i.loAddr)
             {
                 bestInterval = i;
                 prevInterval = prevI;
             }
         }
         prevI = i;
     }
     if (bestInterval != null)
     {
         if (bestInterval.loAddr > id)
         {
             bestInterval.loAddr = id;
         }
         if (id < bestInterval.hiAddr)
         {
             if (bestInterval.hadRelocations && bestInterval.justHadGc)
             {
                 // Interval gets shortened
                 liveObjectTable.RemoveObjectRange(id, bestInterval.hiAddr - id, allocTickIndex, sampleObjectTable);
                 bestInterval.hiAddr = id + size;
                 bestInterval.justHadGc = false;
             }
         }
         else
         {
             bestInterval.hiAddr = id + size;
             emptySpace = true;
         }
         if (prevInterval != null)
         {
             // Move to front to speed up future searches.
             prevInterval.next = bestInterval.next;
             bestInterval.next = liveRoot;
             liveRoot = bestInterval;
         }
         if (OverlappingInterval(bestInterval) != null)
             MergeInterval(bestInterval);
         return emptySpace;
     }
     liveRoot = new Interval(id, id + size, -1, liveRoot);
     //Debug.Assert(OverlappingInterval(liveRoot) == null);
     return emptySpace;
 }
예제 #3
0
 private void RemoveRange(ulong loAddr, ulong hiAddr, int tickIndex, SampleObjectTable sampleObjectTable)
 {
     Interval next;
     for (Interval i = liveRoot; i != null; i = next)
     {
         next = i.next;
         ulong lo = Math.Max(loAddr, i.loAddr);
         ulong hi = Math.Min(hiAddr, i.hiAddr);
         if (lo >= hi)
             continue;
         liveObjectTable.RemoveObjectRange(lo, hi - lo, tickIndex, sampleObjectTable);
         if (i.hiAddr == hi)
         {
             if (i.loAddr == lo)
                 DeleteInterval(i);
             else
                 i.hiAddr = lo;
         }
     }
 }
예제 #4
0
        internal void RecordGc(int tickIndex, int gcGen0Count, int gcGen1Count, int gcGen2Count, SampleObjectTable sampleObjectTable)
        {
            int gen = 0;
            if (gcGen2Count != lastGcGen2Count)
                gen = 2;
            else if (gcGen1Count != lastGcGen1Count)
                gen = 1;

            RecordGc(tickIndex, gen, sampleObjectTable, false);

            lastGcGen0Count = gcGen0Count;
            lastGcGen1Count = gcGen1Count;
            lastGcGen2Count = gcGen2Count;
        }
예제 #5
0
        internal void RecordGc(int tickIndex, int gen, SampleObjectTable sampleObjectTable, bool simpleForm)
        {
            lastTickIndex = tickIndex;

            if (sampleObjectTable != null)
                sampleObjectTable.AddGcTick(tickIndex, gen);

            intervalTable.RecordGc(tickIndex, sampleObjectTable, simpleForm);

            if (gen >= 1)
                gen2LimitTickIndex = gen1LimitTickIndex;
            gen1LimitTickIndex = tickIndex;

            lastGcGen0Count++;
            if (gen > 0)
            {
                lastGcGen1Count++;
                if (gen > 1)
                    lastGcGen2Count++;
            }
        }
예제 #6
0
        internal void UpdateObjects(Histogram relocatedHistogram, ulong oldId, 
            ulong newId, uint length, int tickIndex, SampleObjectTable sampleObjectTable)
        {
            if (lastPos >= readNewLog.pos)
                return;
            lastPos = readNewLog.pos;

            lastTickIndex = tickIndex;
            intervalTable.Relocate(oldId, newId, length);

            if (oldId == newId)
                return;

            ulong nextId;
            ulong lastId = oldId + length;
            LiveObject o;
            for (GetNextObject(oldId, lastId, out o); o.id < lastId; GetNextObject(nextId, lastId, out o))
            {
                nextId = o.id + o.size;
                ulong offset = o.id - oldId;
                if (sampleObjectTable != null)
                    sampleObjectTable.Delete(o.id, o.id + o.size, tickIndex);
                Zero(o.id, o.size);
                InsertObject(newId + offset, o.typeSizeStacktraceIndex, o.allocTickIndex, tickIndex, false, sampleObjectTable);
                if (relocatedHistogram != null)
                    relocatedHistogram.AddObject(o.typeSizeStacktraceIndex, 1);
            }
        }
예제 #7
0
        void RemoveObjectRange(ulong firstId, ulong length, int tickIndex, SampleObjectTable sampleObjectTable)
        {
            ulong lastId = firstId + length;

            if (sampleObjectTable != null)
                sampleObjectTable.Delete(firstId, lastId, tickIndex);

            Zero(firstId, length);
        }
예제 #8
0
        internal void InsertObject(ulong id, int typeSizeStacktraceIndex, int allocTickIndex, int nowTickIndex, bool newAlloc, SampleObjectTable sampleObjectTable)
        {
            if (lastPos >= readNewLog.pos && newAlloc)
                return;
            lastPos = readNewLog.pos;

            lastTickIndex = nowTickIndex;
            int[] stacktrace = readNewLog.stacktraceTable.IndexToStacktrace(typeSizeStacktraceIndex);
            int typeIndex = stacktrace[0];
            uint size = (uint)stacktrace[1];
            bool emptySpace = false;
            if (newAlloc)
            {
                emptySpace = intervalTable.AddObject(id, size, allocTickIndex, sampleObjectTable);
            }
            if (!emptySpace)
            {
                ulong prevId = FindObjectBackward(id - 4);
                LiveObject o;
                GetNextObject(prevId, id, out o);
                if (o.id < id && (o.id + o.size > id || o.id + 12 > id))
                {
                    Zero(o.id, id - o.id);
                }
            }
            //Debug.Assert(FindObjectBackward(id - 4) + 12 <= id);
            if (size >= 12)
            {
                ushort u1 = (ushort)(typeSizeStacktraceIndex | 0x8000);
                ushort u2 = (ushort)((typeSizeStacktraceIndex >> 15) | ((allocTickIndex & 0xff) << 7));
                ushort u3 = (ushort)(allocTickIndex >> 8);
                Write3WordsAt(id, u1, u2, u3);
                if (!emptySpace)
                    Zero(id + 12, size - 12);
                //Debug.Assert(CanReadObjectBackCorrectly(id, size, typeSizeStacktraceIndex, allocTickIndex));
            }
            if (sampleObjectTable != null)
                sampleObjectTable.Insert(id, id + size, nowTickIndex, allocTickIndex, typeIndex);
        }