Exemple #1
0
        private StackSourceFrameIndex GetSourceLocation(CallTreeNodeBase node, string cellText, out Dictionary <StackSourceFrameIndex, float> retVal)
        {
            var m = Regex.Match(cellText, "<<(.*!.*)>>");

            if (m.Success)
            {
                cellText = m.Groups[1].Value;
            }

            var frameIndexCounts = new Dictionary <StackSourceFrameIndex, float>();

            node.GetSamples(false, sampleIdx =>
            {
                var matchingFrameIndex = StackSourceFrameIndex.Invalid;
                var sample             = this.callTree.StackSource.GetSampleByIndex(sampleIdx);
                var callStackIdx       = sample.StackIndex;

                while (callStackIdx != StackSourceCallStackIndex.Invalid)
                {
                    var frameIndex = this.callTree.StackSource.GetFrameIndex(callStackIdx);
                    var frameName  = this.callTree.StackSource.GetFrameName(frameIndex, false);

                    if (frameName == cellText)
                    {
                        matchingFrameIndex = frameIndex;
                    }

                    callStackIdx = this.callTree.StackSource.GetCallerIndex(callStackIdx);
                }

                if (matchingFrameIndex != StackSourceFrameIndex.Invalid)
                {
                    frameIndexCounts.TryGetValue(matchingFrameIndex, out float count);
                    frameIndexCounts[matchingFrameIndex] = count + sample.Metric;
                }

                return(true);
            });

            var   maxFrameIdx      = StackSourceFrameIndex.Invalid;
            float maxFrameIdxCount = -1;

            foreach (var keyValue in frameIndexCounts)
            {
                if (keyValue.Value >= maxFrameIdxCount)
                {
                    maxFrameIdxCount = keyValue.Value;
                    maxFrameIdx      = keyValue.Key;
                }
            }

            retVal = frameIndexCounts;

            return(maxFrameIdx);
        }
        private SourceLocation GetSourceLocation(CallTreeNodeBase asCallTreeNodeBase, string cellText, out SortedDictionary <int, float> metricOnLine)
        {
            metricOnLine = null;
            var m = Regex.Match(cellText, "<<(.*!.*)>>");

            if (m.Success)
            {
                cellText = m.Groups[1].Value;
            }

            var frameIndexCounts = new Dictionary <StackSourceFrameIndex, float>();

            asCallTreeNodeBase.GetSamples(false, delegate(StackSourceSampleIndex sampleIdx)
            {
                var matchingFrameIndex = StackSourceFrameIndex.Invalid;
                var sample             = this.stacksource.GetSampleByIndex(sampleIdx);
                var callStackIdx       = sample.StackIndex;
                while (callStackIdx != StackSourceCallStackIndex.Invalid)
                {
                    var frameIndex = this.stacksource.GetFrameIndex(callStackIdx);
                    var frameName  = this.stacksource.GetFrameName(frameIndex, false);
                    if (frameName == cellText)
                    {
                        matchingFrameIndex = frameIndex;        // We keep overwriting it, so we get the entry closest to the root.
                    }
                    callStackIdx = this.stacksource.GetCallerIndex(callStackIdx);
                }
                if (matchingFrameIndex != StackSourceFrameIndex.Invalid)
                {
                    float count = 0;
                    frameIndexCounts.TryGetValue(matchingFrameIndex, out count);
                    frameIndexCounts[matchingFrameIndex] = count + sample.Metric;
                }
                return(true);
            });

            var   maxFrameIdx      = StackSourceFrameIndex.Invalid;
            float maxFrameIdxCount = -1;

            foreach (var keyValue in frameIndexCounts)
            {
                if (keyValue.Value >= maxFrameIdxCount)
                {
                    maxFrameIdxCount = keyValue.Value;
                    maxFrameIdx      = keyValue.Key;
                }
            }

            if (maxFrameIdx == StackSourceFrameIndex.Invalid)
            {
                return(null);
            }

            // Find the most primitive TraceEventStackSource
            TraceEventStackSource asTraceEventStackSource = GetTraceEventStackSource(this.stacksource);

            if (asTraceEventStackSource == null)
            {
                return(null);
            }

            var frameToLine = new Dictionary <StackSourceFrameIndex, int>();

            var sourceLocation = asTraceEventStackSource.GetSourceLine(maxFrameIdx, this.reader);

            if (sourceLocation != null)
            {
                var filePathForMax = sourceLocation.SourceFile.BuildTimeFilePath;
                metricOnLine = new SortedDictionary <int, float>();

                // Accumulate the counts on a line basis
                foreach (StackSourceFrameIndex frameIdx in frameIndexCounts.Keys)
                {
                    var loc = asTraceEventStackSource.GetSourceLine(frameIdx, this.reader);
                    if (loc != null && loc.SourceFile.BuildTimeFilePath == filePathForMax)
                    {
                        frameToLine[frameIdx] = loc.LineNumber;
                        float metric;
                        metricOnLine.TryGetValue(loc.LineNumber, out metric);
                        metric += frameIndexCounts[frameIdx];
                        metricOnLine[loc.LineNumber] = metric;
                    }
                }
            }

            bool        commonMethodIdxSet = false;
            MethodIndex commonMethodIdx    = MethodIndex.Invalid;

            var nativeAddressFreq = new SortedDictionary <ulong, Tuple <int, float> >();

            foreach (var keyValue in frameIndexCounts)
            {
                var codeAddr = asTraceEventStackSource.GetFrameCodeAddress(keyValue.Key);
                if (codeAddr != CodeAddressIndex.Invalid)
                {
                    var methodIdx = asTraceEventStackSource.TraceLog.CodeAddresses.MethodIndex(codeAddr);
                    if (methodIdx != MethodIndex.Invalid)
                    {
                        if (!commonMethodIdxSet)
                        {
                            commonMethodIdx = methodIdx;            // First time, set it as the common method.
                        }
                        else if (methodIdx != commonMethodIdx)
                        {
                            methodIdx = MethodIndex.Invalid;        // More than one method, give up.
                        }
                        commonMethodIdxSet = true;
                    }

                    var nativeAddr = asTraceEventStackSource.TraceLog.CodeAddresses.Address(codeAddr);
                    var lineNum    = 0;
                    frameToLine.TryGetValue(keyValue.Key, out lineNum);
                    nativeAddressFreq[nativeAddr] = new Tuple <int, float>(lineNum, keyValue.Value);
                }
            }

            foreach (var keyValue in nativeAddressFreq)
            {
                Console.WriteLine("    {0,12:x} : {1,6} {2,10:f1}", keyValue.Key, keyValue.Value.Item1, keyValue.Value.Item2);
            }

            if (sourceLocation == null)
            {
                return(null);
            }

            foreach (var keyVal in metricOnLine)
            {
                Console.WriteLine("    Line {0,5}:  Metric {1,5:n1}", keyVal.Key, keyVal.Value);
            }

            return(sourceLocation);
        }