private void OnGCAllocationTick(GCAllocationTickTraceData data)
        {
            TraceThread thread = data.Thread();

            Debug.Assert(thread != null);
            if (null == thread)
            {
                return;
            }

            // Attempt to charge the allocation to a request.
            ScenarioThreadState scenarioThreadState = m_Configuration.ScenarioThreadState[(int)thread.ThreadIndex];

            CallStackIndex            traceLogCallStackIndex = data.CallStackIndex();
            StackSourceCallStackIndex callStackIndex         = scenarioThreadState.GetCallStackIndex(m_OutputStackSource, thread, data);

            // Add the thread.
            StackSourceFrameIndex threadFrameIndex = m_OutputStackSource.Interner.FrameIntern(thread.VerboseThreadName);

            callStackIndex = m_OutputStackSource.Interner.CallStackIntern(threadFrameIndex, callStackIndex);

            // Get the allocation call stack index.
            callStackIndex = m_OutputStackSource.GetCallStack(traceLogCallStackIndex, callStackIndex, null);

            // Add the type.
            string typeName = data.TypeName;

            if (typeName.Length > 0)
            {
                StackSourceFrameIndex nodeIndex = m_OutputStackSource.Interner.FrameIntern("Type " + data.TypeName);
                callStackIndex = m_OutputStackSource.Interner.CallStackIntern(nodeIndex, callStackIndex);
            }

            // Add a notification for large objects.
            if (data.AllocationKind == GCAllocationKind.Large)
            {
                StackSourceFrameIndex nodeIndex = m_OutputStackSource.Interner.FrameIntern("LargeObject");
                callStackIndex = m_OutputStackSource.Interner.CallStackIntern(nodeIndex, callStackIndex);
            }

            // Set the time.
            m_Sample.TimeRelativeMSec = data.TimeStampRelativeMSec;

            // Set the metric.
            bool seenBadAllocTick = false;

            m_Sample.Metric = data.GetAllocAmount(ref seenBadAllocTick);

            // Set the stack index.
            m_Sample.StackIndex = callStackIndex;

            // Add the sample.
            m_OutputStackSource.AddSample(m_Sample);
        }
Example #2
0
        internal void OnClrEvent(TraceEvent data)
        {
            TraceEventID eventID   = data.ID;
            HeapEvents   heapEvent = HeapEvents.Unknown;

            // TODO don't use IDs but use individual callbacks.
            const TraceEventID GCStartEventID                     = (TraceEventID)1;
            const TraceEventID GCStopEventID                      = (TraceEventID)2;
            const TraceEventID GCRestartEEStopEventID             = (TraceEventID)3;
            const TraceEventID GCHeapStatsEventID                 = (TraceEventID)4;
            const TraceEventID GCCreateSegmentEventID             = (TraceEventID)5;
            const TraceEventID GCFreeSegmentEventID               = (TraceEventID)6;
            const TraceEventID GCRestartEEStartEventID            = (TraceEventID)7;
            const TraceEventID GCSuspendEEStopEventID             = (TraceEventID)8;
            const TraceEventID GCSuspendEEStartEventID            = (TraceEventID)9;
            const TraceEventID GCAllocationTickEventID            = (TraceEventID)10;
            const TraceEventID GCCreateConcurrentThreadEventID    = (TraceEventID)11;
            const TraceEventID GCTerminateConcurrentThreadEventID = (TraceEventID)12;
            const TraceEventID GCFinalizersStopEventID            = (TraceEventID)13;
            const TraceEventID GCFinalizersStartEventID           = (TraceEventID)14;
            const TraceEventID ContentionStartEventID             = (TraceEventID)81;
            const TraceEventID ContentionStopEventID              = (TraceEventID)91;

            switch (eventID)
            {
            case GCStartEventID:
            {
                var mdata = data as Microsoft.Diagnostics.Tracing.Parsers.Clr.GCStartTraceData;
                if (mdata != null)
                {
                    GcEventExtra extra = GetGcEventExtra(mdata.Count);

                    extra.GCStartIndex  = data.EventIndex;
                    extra.GCStartThread = data.Thread();
                }
            }
                heapEvent = HeapEvents.GCStart;
                break;

            case GCStopEventID:
                heapEvent = HeapEvents.GCEnd;
                break;

            case GCRestartEEStartEventID:
                heapEvent = HeapEvents.GCRestartEEBegin;
                break;

            case GCRestartEEStopEventID:
                heapEvent = HeapEvents.GCRestartEEEnd;
                break;

            case GCHeapStatsEventID:
                heapEvent = HeapEvents.GCHeapStats;
                break;

            case GCCreateSegmentEventID:
                heapEvent = HeapEvents.GCCreateSegment;
                break;

            case GCFreeSegmentEventID:
                heapEvent = HeapEvents.GCFreeSegment;
                break;

            case GCSuspendEEStartEventID:
                heapEvent = HeapEvents.GCSuspendEEBegin;
                break;

            case GCSuspendEEStopEventID:
                heapEvent = HeapEvents.GCSuspendEEEnd;
                break;

            case GCAllocationTickEventID:
                heapEvent = HeapEvents.GCAllocationTick;
                {
                    GCAllocationTickTraceData mdata = data as GCAllocationTickTraceData;

                    AllocationTick(mdata, mdata.AllocationKind == GCAllocationKind.Large, mdata.GetAllocAmount(ref seenBadAlloc) / OneMBD);
                }
                break;

            case GCCreateConcurrentThreadEventID:
                heapEvent = HeapEvents.GCCreateConcurrentThread;
                break;

            case GCTerminateConcurrentThreadEventID:
                heapEvent = HeapEvents.GCTerminateConcurrentThread;
                break;

            case GCFinalizersStartEventID:
                heapEvent = HeapEvents.GCFinalizersBegin;
                break;

            case GCFinalizersStopEventID:
                heapEvent = HeapEvents.GCFinalizersEnd;
                break;

            case ContentionStartEventID:
                heapEvent = HeapEvents.ContentionStart;
                break;

            case ContentionStopEventID:
                heapEvent = HeapEvents.ContentionStop;
                break;

            default:
                break;
            }

            if (heapEvent != HeapEvents.Unknown)
            {
                ThreadMemoryInfo thread = GetThread(data.ThreadID);

                thread.AddEvent(heapEvent, data.TimeStampRelativeMSec);
            }
        }