Beispiel #1
0
        public GCSimulation(ClrProfilerParser profiler)
        {
            m_clrProfiler = profiler;
            m_relocs      = new GrowableArray <Relocation>(256);
            Allocs        = new GrowableArray <AllocInfo>(100000);

            m_clrProfiler.GCStart               += new ClrProfilerParser.GCEventHandler(this.GCStart);
            m_clrProfiler.GCEnd                 += new ClrProfilerParser.GCEventHandler(this.GCEnd);
            m_clrProfiler.ObjectRangeLive       += new ClrProfilerParser.LiveObjectRangeHandler(this.ObjectRangeLive);
            m_clrProfiler.ObjectRangeRelocation += new ClrProfilerParser.RelocationEventHandler(this.ObjectRangeRelocation);

            // TODO expose the thread information
            AllocInfo info = new AllocInfo();

            m_clrProfiler.Allocation += delegate(ProfilerAllocID allocId, Address objectAddress, uint threadId)
            {
                Debug.Assert(allocId != ProfilerAllocID.Null);
                info.Size    = (int)m_clrProfiler.GetAllocSize(allocId);
                info.AllocId = allocId;

                var stackId = m_clrProfiler.GetAllocStack(allocId);
                info.MsecFromStart = CurrentTimeMSec;

                info.ObjectAddress = objectAddress;
                Allocs.Add(info);
                m_numAllocs++;
            };

            m_clrProfiler.Tick += delegate(int milliSecondsSinceStart)
            {
                CurrentTimeMSec = milliSecondsSinceStart;
            };
        }
Beispiel #2
0
        // Returns true if 'alloc' survivies.
        private bool ApplyRelocsToAlloc(ref AllocInfo alloc)
        {
            // You survive if your generation is large than the condemed generation.
            if (alloc.Generation > m_condemedGeneration)
            {
                return(true);
            }

            Debug.Assert(m_areRelocsSorted);

            // See if you survived.
            int idx = m_lastRelocIdx;                               // See if you can start where you left off.

            if (alloc.ObjectAddress < m_lastRelocRegionEnd)
            {
                idx = 0;                                            // Nope, start at the begining.
            }

            while (idx < m_relocs.Count)
            {
                if (alloc.ObjectAddress < m_relocs[idx].SourceStart)
                {
                    return(false);
                }

                if (alloc.ObjectAddress < m_relocs[idx].SourceEnd)
                {
                    alloc.ObjectAddress = alloc.ObjectAddress + m_relocs[idx].DiffToTarget;
                    alloc.Generation    = m_promotedToGeneration;
                    return(true);
                }
                m_lastRelocRegionEnd = m_relocs[idx].SourceEnd;
                idx++;
                m_lastRelocIdx = idx;
            }
            // TODO FIX NOW, not right when we have segments everywhere..

            // OK it did not survive the condemed generation, see if it is in a segment that was not condemed
            if (m_condemedGeneration < 2)
            {
                foreach (var gcSegment in m_gcSegments)
                {
                    if (gcSegment.rangeStart <= alloc.ObjectAddress &&
                        alloc.ObjectAddress < gcSegment.rangeStart + (ulong)gcSegment.rangeLength)
                    {
                        // Note rangeGeneration can == 3 for Large object heap, but this still works because we only even look
                        // for generations less than 2.
                        return(gcSegment.rangeGeneration > m_condemedGeneration);
                    }
                }
                Debug.Assert(false, "Object in no heap segment!");
            }
            return(false);
        }