Esempio n. 1
0
        void Read(TextReader reader)
        {
            // TODO this is relatively inefficient.
            var regEx = new Regex(@"^\s*(\d+)\s*(\d+)\s*\[\s*(\d+)\s*\]\s*(\S*?)!?(.*)");

            var         stack = new GrowableArray <WTStackElem>();
            WTStackElem elem  = new WTStackElem();
            long        time  = 0;

            for (; ;)
            {
                var line = reader.ReadLine();
                if (line == null)
                {
                    break;
                }
                var match = regEx.Match(line);
                if (match.Success)
                {
                    int    excInstrSoFar = int.Parse(match.Groups[1].Value);
                    int    depth         = int.Parse(match.Groups[3].Value);
                    string module        = match.Groups[4].Value;
                    string method        = match.Groups[5].Value;

                    var moduleIndex = ModuleIntern(module);
                    var frameIndex  = FrameIntern(method, moduleIndex);

                    var parent = StackSourceCallStackIndex.Invalid;
                    if (depth > 0)
                    {
                        parent = stack[depth - 1].FirstCallStackIndex;    // TODO handle out of range
                    }
                    var callStackIndex = CallStackIntern(frameIndex, parent);

                    int extra = stack.Count - depth;
                    int exclInstr;
                    if (extra > 0)
                    {
                        elem = stack[depth];

                        if (callStackIndex == elem.CallStackIndex)
                        {
                            exclInstr = excInstrSoFar - elem.ExclInstrSoFar;
                        }
                        else
                        {
                            exclInstr           = excInstrSoFar;
                            elem.CallStackIndex = callStackIndex;
                        }
                        Debug.Assert(exclInstr >= 0);
                        stack.RemoveRange(depth, extra);
                    }
                    else
                    {
                        elem.CallStackIndex      = callStackIndex;
                        elem.FirstCallStackIndex = callStackIndex;
                        Debug.Assert(extra == 0);
                        exclInstr = excInstrSoFar;
                    }
                    elem.ExclInstrSoFar = excInstrSoFar;
                    stack.Add(elem);

                    time += exclInstr;

                    var sample = new StackSourceSample(this);
                    sample.SampleIndex = (StackSourceSampleIndex)m_samples.Count;
                    sample.Metric      = exclInstr;
                    sample.TimeRelMSec = time - exclInstr;
                    sample.StackIndex  = elem.FirstCallStackIndex;

                    // Break long sequences of instructions into individual samples.   This
                    // makes timeline work well.
                    // TODO this bloats the data, not clear if this is the right tradeoff ....
                    const int maxSize = 20;
                    while (sample.Metric > maxSize)
                    {
                        var subSample = new StackSourceSample(sample);
                        subSample.Metric    = maxSize;
                        sample.Metric      -= maxSize;
                        sample.TimeRelMSec += maxSize;
                        m_samples.Add(subSample);
                        sample.SampleIndex = (StackSourceSampleIndex)m_samples.Count;
                    }

                    m_samples.Add(sample);
#if DEBUG
                    var sampleStr = this.ToString(sample);
                    Debug.WriteLine(sampleStr);
#endif
                }
            }
            m_sampleTimeRelMSecLimit = time;
            CompletedReading();
        }
Esempio n. 2
0
        void Read(TextReader reader)
        {
            // TODO this is relatively inefficient.
            var regEx = new Regex(@"^\s*(\d+)\s*(\d+)\s*\[\s*(\d+)\s*\]\s*(\S*?)!?(.*)");

            var         stack  = new GrowableArray <WTStackElem>();
            WTStackElem elem   = new WTStackElem();
            long        time   = 0;
            var         sample = new StackSourceSample(this);

            for (; ;)
            {
                var line = reader.ReadLine();
                if (line == null)
                {
                    break;
                }
                var match = regEx.Match(line);
                if (match.Success)
                {
                    // Parse the line.
                    int    excInstrSoFar = int.Parse(match.Groups[1].Value);
                    int    depth         = int.Parse(match.Groups[3].Value);
                    string module        = match.Groups[4].Value;
                    string method        = match.Groups[5].Value;

                    // Form the name for this line
                    var moduleIndex = Interner.ModuleIntern(module);
                    var frameIndex  = Interner.FrameIntern(method, moduleIndex);

                    // Get the parent stack for this line
                    var parent = StackSourceCallStackIndex.Invalid;
                    if (depth > 0)
                    {
                        parent = stack[depth - 1].FirstCallStackIndex;    // TODO handle out of range
                    }
                    // Form the stack for this entry
                    var callStackIndex = Interner.CallStackIntern(frameIndex, parent);

                    int exclInstr;                              // Number of instructions executed on this line
                    int extra = stack.Count - depth;            // The number of frames we need to pop off (including me)
                    if (extra > 0)
                    {
                        // We returned from one or more methods OR we have not left the current method
                        //
                        elem = stack[depth];

                        // We expect to return to the same method we were at at this depth.
                        if (callStackIndex == elem.CallStackIndex)
                        {
                            exclInstr = excInstrSoFar - elem.ExclInstrSoFar;    // We are continuing the function
                        }
                        else
                        {
                            // We are tail-calling to another routine.
                            exclInstr           = excInstrSoFar;
                            elem.CallStackIndex = callStackIndex;
                        }

                        // Pop off all the frames we returned from
                        Debug.Assert(exclInstr >= 0);
                        stack.RemoveRange(depth, extra);
                    }
                    else
                    {
                        // Means we are adding a new frame (we called someone)
                        Debug.Assert(extra == 0);       // We always add only one more frame (e.g. we never go from depth 2 to 4)
                        elem.CallStackIndex      = callStackIndex;
                        elem.FirstCallStackIndex = callStackIndex;
                        exclInstr = excInstrSoFar;
                    }
                    elem.ExclInstrSoFar = excInstrSoFar;
                    stack.Add(elem);

                    time += exclInstr;

                    sample.Metric           = exclInstr;
                    sample.TimeRelativeMSec = time - exclInstr;
                    sample.StackIndex       = elem.FirstCallStackIndex;
                    AddSample(sample);
                }
            }
            Interner.DoneInterning();
        }