示例#1
0
            public static AllocationRanges New(UInt16 snapshotId, UInt32 tracebackId, UInt32 size, UInt32 overhead)
            {
                var ranges = ImmutableArrayPool <Range> .Allocate(1);

                ranges.Array[ranges.Offset] = new Range(snapshotId, tracebackId, size, overhead);
                return(new AllocationRanges(ranges));
            }
示例#2
0
        public bool ReadKey(BTreeValue *pEntry, ushort keyType, out TangleKey key)
        {
            if (keyType == 0)
            {
                key = default(TangleKey);
                return(false);
            }

            var buffer = ImmutableArrayPool <byte> .Allocate(pEntry->KeyLength);

            if (pEntry->KeyLength <= BTreeValue.KeyPrefixSize)
            {
                fixed(byte *pBuffer = buffer.Array)
                Native.memmove(pBuffer + buffer.Offset, pEntry->KeyPrefix, new UIntPtr(pEntry->KeyLength));
            }
            else
            {
                using (var keyRange = KeyStream.AccessRange(
                           pEntry->KeyOffset, pEntry->KeyLength, MemoryMappedFileAccess.Read
                           ))
                    Unsafe.ReadBytes(keyRange.Pointer, 0, buffer.Array, buffer.Offset, pEntry->KeyLength);
            }

            key = new TangleKey(buffer, keyType);
            return(true);
        }
示例#3
0
            static unsafe void Deserialize(ref DeserializationContext context, out AllocationRanges output)
            {
                if (context.SourceLength < 4)
                {
                    throw new InvalidDataException();
                }

                int count = *(int *)(context.Source + 0);
                var array = ImmutableArrayPool <Range> .Allocate(count);

                uint offset   = 4;
                uint itemSize = BlittableSerializer <Range> .Size;

                if (context.SourceLength < (4 + (itemSize * count)))
                {
                    throw new InvalidDataException();
                }

                for (int i = 0; i < count; i++)
                {
                    context.DeserializeValue(
                        BlittableSerializer <Range> .Deserialize,
                        offset, itemSize, out array.Array[array.Offset + i]
                        );

                    offset += itemSize;
                }

                output = new AllocationRanges(array);
            }
示例#4
0
            public AllocationRanges Update(UInt16 snapshotId, UInt32 tracebackId, UInt32 size, UInt32 overhead)
            {
                ArraySegment <Range> result;

                var a = Ranges.Array;

                for (int i = 0, c = Ranges.Count, o = Ranges.Offset; i < c; i++)
                {
                    var range = a[i + o];

                    if ((range.TracebackID != tracebackId) || (range.Size != size) || (range.Overhead != overhead))
                    {
                        continue;
                    }

                    if (range.Last == snapshotId - 1)
                    {
                        result = ImmutableArrayPool <Range> .Allocate(Ranges.Count);

                        Array.Copy(Ranges.Array, Ranges.Offset, result.Array, result.Offset, Ranges.Count);
                        result.Array[result.Offset + i] = new Range(range.First, snapshotId, tracebackId, size, overhead);
                        return(new AllocationRanges(result));
                    }
                }

                result = ImmutableArrayPool <Range> .Allocate(Ranges.Count + 1);

                Array.Copy(Ranges.Array, Ranges.Offset, result.Array, result.Offset, Ranges.Count);
                result.Array[result.Offset + result.Count - 1] = new Range(snapshotId, tracebackId, size, overhead);
                return(new AllocationRanges(result));
            }
示例#5
0
        private FunctionAnalysis1stPass.NodeIndices GetParentNodeIndices()
        {
            var count  = NodeIndexStack.Count;
            var buffer = ImmutableArrayPool <int> .Allocate(count);

            NodeIndexStack.CopyTo(buffer.Array, buffer.Offset);
            return(new FunctionAnalysis1stPass.NodeIndices(buffer));
        }
示例#6
0
        static unsafe void _Serialize(ref SerializationContext context, ref T input)
        {
            var buffer = ImmutableArrayPool <byte> .Allocate((int)Size);

            fixed(byte *pBuffer = buffer.Array)
            Unsafe <T> .StructureToPtr(ref input, pBuffer + buffer.Offset, Size);

            context.Stream.Write(buffer.Array, buffer.Offset, (int)Size);
        }
示例#7
0
        public static TracebackInfo ConstructTracebackInfo(UInt32 tracebackID, ArraySegment <UInt32> rawFrames, IDictionary <UInt32, TracebackFrame> symbols)
        {
            var tracebackFunctions = new NameTable(StringComparer.Ordinal);
            var tracebackModules   = new NameTable(StringComparer.Ordinal);
            var tracebackFrames    = ImmutableArrayPool <TracebackFrame> .Allocate(rawFrames.Count);

            for (int i = 0, o = tracebackFrames.Offset, c = tracebackFrames.Count; i < c; i++)
            {
                var rawFrame = rawFrames.Array[rawFrames.Offset + i];
                var symbol   = symbols[rawFrame];

                if ((symbol.Offset == 0) && (!symbol.Offset2.HasValue))
                {
                    tracebackFrames.Array[i + o] = new TracebackFrame(rawFrame);
                }
                else
                {
                    tracebackFrames.Array[i + o] = symbol;
                }

                if (symbol.Function != null)
                {
                    tracebackFunctions.Add(symbol.Function);
                }
                if (symbol.Module != null)
                {
                    tracebackModules.Add(symbol.Module);
                }
            }

            return(new TracebackInfo {
                Frames = tracebackFrames,
                Functions = tracebackFunctions,
                Modules = tracebackModules,
                TraceId = tracebackID
            });
        }
示例#8
0
            static unsafe void Deserialize(ref DeserializationContext context, out Traceback output)
            {
                if (context.SourceLength < 8)
                {
                    throw new InvalidDataException();
                }

                var id    = *(UInt32 *)(context.Source + 0);
                var count = *(int *)(context.Source + 4);

                if (context.SourceLength < 8 + (count * 4))
                {
                    throw new InvalidDataException();
                }

                var array = ImmutableArrayPool <UInt32> .Allocate(count);

                fixed(uint *pFrames = array.Array)
                Squared.Data.Mangler.Internal.Native.memmove(
                    (byte *)(&pFrames[array.Offset]), context.Source + 8, new UIntPtr((uint)(count * 4))
                    );

                output = new Traceback(id, array);
            }
示例#9
0
        public static IEnumerator <object> FromFile(string filename, IProgressListener progress)
        {
            progress.Status = "Loading diff...";

            Future <string> fText;

            // We could stream the lines in from the IO thread while we parse them, but this
            //  part of the load is usually pretty quick even on a regular hard disk, and
            //  loading the whole diff at once eliminates some context switches
            using (var fda = new FileDataAdapter(
                       filename, FileMode.Open,
                       FileAccess.Read, FileShare.Read, 1024 * 128
                       )) {
                var fBytes = fda.ReadToEnd();
                yield return(fBytes);

                fText = Future.RunInThread(
                    () => Encoding.ASCII.GetString(fBytes.Result)
                    );
                yield return(fText);
            }

            yield return(fText);

            var lr = new LineReader(fText.Result);

            LineReader.Line line;

            progress.Status = "Parsing diff...";

            var frames        = new List <TracebackFrame>();
            var moduleNames   = new NameTable(StringComparer.Ordinal);
            var symbolTypes   = new NameTable(StringComparer.Ordinal);
            var functionNames = new NameTable(StringComparer.Ordinal);
            var deltas        = new List <DeltaInfo>();
            var tracebacks    = new Dictionary <UInt32, TracebackInfo>();

            var regexes = new Regexes();

            // Regex.Groups[string] does an inefficient lookup, so we do that lookup once here
            int groupModule            = regexes.DiffModule.GroupNumberFromName("module");
            int groupSymbolType        = regexes.DiffModule.GroupNumberFromName("symbol_type");
            int groupTraceId           = regexes.BytesDelta.GroupNumberFromName("trace_id");
            int groupType              = regexes.BytesDelta.GroupNumberFromName("type");
            int groupDeltaBytes        = regexes.BytesDelta.GroupNumberFromName("delta_bytes");
            int groupNewBytes          = regexes.BytesDelta.GroupNumberFromName("new_bytes");
            int groupOldBytes          = regexes.BytesDelta.GroupNumberFromName("old_bytes");
            int groupNewCount          = regexes.BytesDelta.GroupNumberFromName("new_count");
            int groupOldCount          = regexes.CountDelta.GroupNumberFromName("old_count");
            int groupCountDelta        = regexes.CountDelta.GroupNumberFromName("delta_count");
            int groupTracebackModule   = regexes.TracebackFrame.GroupNumberFromName("module");
            int groupTracebackFunction = regexes.TracebackFrame.GroupNumberFromName("function");
            int groupTracebackOffset   = regexes.TracebackFrame.GroupNumberFromName("offset");
            int groupTracebackOffset2  = regexes.TracebackFrame.GroupNumberFromName("offset2");
            int groupTracebackPath     = regexes.TracebackFrame.GroupNumberFromName("path");
            int groupTracebackLine     = regexes.TracebackFrame.GroupNumberFromName("line");

            var delay = new Sleep(0.01);
            int i     = 0;

            while (lr.ReadLine(out line))
            {
retryFromHere:
                i += 1;
                if (i % ProgressInterval == 0)
                {
                    progress.Maximum  = lr.Length;
                    progress.Progress = lr.Position;

                    // Suspend processing for a bit
                    yield return(delay);
                }

                Match m;
                if (regexes.DiffModule.TryMatch(ref line, out m))
                {
                    moduleNames.Add(m.Groups[groupModule].Value);
                }
                else if (regexes.BytesDelta.TryMatch(ref line, out m))
                {
                    var added   = (m.Groups[groupType].Value == "+");
                    var traceId = UInt32.Parse(m.Groups[groupTraceId].Value, NumberStyles.HexNumber);
                    var info    = new DeltaInfo {
                        BytesDelta = int.Parse(m.Groups[groupDeltaBytes].Value, NumberStyles.HexNumber) *
                                     (added ? 1 : -1),
                        NewBytes = int.Parse(m.Groups[groupNewBytes].Value, NumberStyles.HexNumber),
                        OldBytes = int.Parse(m.Groups[groupOldBytes].Value, NumberStyles.HexNumber),
                        NewCount = int.Parse(m.Groups[groupNewCount].Value, NumberStyles.HexNumber),
                    };

                    if (lr.ReadLine(out line))
                    {
                        if (regexes.CountDelta.TryMatch(ref line, out m))
                        {
                            info.OldCount   = int.Parse(m.Groups[groupOldCount].Value, NumberStyles.HexNumber);
                            info.CountDelta = int.Parse(m.Groups[groupCountDelta].Value, NumberStyles.HexNumber) *
                                              (added ? 1 : -1);
                        }
                    }

                    bool readingLeadingWhitespace = true, doRetry = false;

                    frames.Clear();
                    var itemModules = new NameTable(StringComparer.Ordinal);
                    var itemFunctions = new NameTable(StringComparer.Ordinal);

                    while (lr.ReadLine(out line))
                    {
                        if (line.ToString().Trim().Length == 0)
                        {
                            if (readingLeadingWhitespace)
                            {
                                continue;
                            }
                            else
                            {
                                break;
                            }
                        }
                        else if (regexes.TracebackFrame.TryMatch(ref line, out m))
                        {
                            readingLeadingWhitespace = false;

                            var moduleName = moduleNames[m.Groups[groupTracebackModule].Value];
                            itemModules.Add(moduleName);

                            var functionName = functionNames[m.Groups[groupTracebackFunction].Value];
                            itemFunctions.Add(functionName);

                            var frame = new TracebackFrame {
                                Module   = moduleName,
                                Function = functionName,
                                Offset   = UInt32.Parse(m.Groups[groupTracebackOffset].Value, NumberStyles.HexNumber)
                            };
                            if (m.Groups[groupTracebackOffset2].Success)
                            {
                                frame.Offset2 = UInt32.Parse(m.Groups[groupTracebackOffset2].Value, NumberStyles.HexNumber);
                            }

                            if (m.Groups[groupTracebackPath].Success)
                            {
                                frame.SourceFile = m.Groups[groupTracebackPath].Value;
                            }

                            if (m.Groups[groupTracebackLine].Success)
                            {
                                frame.SourceLine = int.Parse(m.Groups[groupTracebackLine].Value);
                            }

                            frames.Add(frame);
                        }
                        else
                        {
                            // We hit the beginning of a new allocation, so make sure it gets parsed
                            doRetry = true;
                            break;
                        }
                    }

                    if (tracebacks.ContainsKey(traceId))
                    {
                        info.Traceback = tracebacks[traceId];
                        Program.ErrorList.ReportError("Duplicate traceback for id {0}!", traceId);
                    }
                    else
                    {
                        var frameArray = ImmutableArrayPool <TracebackFrame> .Allocate(frames.Count);

                        frames.CopyTo(frameArray.Array, frameArray.Offset);

                        info.Traceback = tracebacks[traceId] = new TracebackInfo {
                            TraceId   = traceId,
                            Frames    = frameArray,
                            Modules   = itemModules,
                            Functions = itemFunctions
                        };
                    }

                    deltas.Add(info);

                    if (doRetry)
                    {
                        goto retryFromHere;
                    }
                }
                else if (line.StartsWith("//"))
                {
                    // Comment, ignore it
                }
                else if (line.StartsWith("Total increase") || line.StartsWith("Total decrease"))
                {
                    // Ignore this too
                }
                else if (line.StartsWith("         ") && (line.EndsWith(".pdb")))
                {
                    // Symbol path for a module, ignore it
                }
                else
                {
                    Program.ErrorList.ReportError("Unrecognized diff content: {0}", line.ToString());
                }
            }

            var result = new HeapDiff(
                filename, moduleNames, functionNames, deltas, tracebacks
                );

            yield return(new Result(result));
        }