Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mcs/class/Mono.Profiler.Log/Mono.Profiler.Log/LogProcessor.cs173
-rw-r--r--mcs/class/Mono.Profiler.Log/Mono.Profiler.Log/LogReader.cs86
2 files changed, 126 insertions, 133 deletions
diff --git a/mcs/class/Mono.Profiler.Log/Mono.Profiler.Log/LogProcessor.cs b/mcs/class/Mono.Profiler.Log/Mono.Profiler.Log/LogProcessor.cs
index 71bdca3f0dc..7e9871efa63 100644
--- a/mcs/class/Mono.Profiler.Log/Mono.Profiler.Log/LogProcessor.cs
+++ b/mcs/class/Mono.Profiler.Log/Mono.Profiler.Log/LogProcessor.cs
@@ -12,7 +12,7 @@ namespace Mono.Profiler.Log {
public sealed class LogProcessor {
- public LogReader Reader { get; }
+ public LogStream Stream { get; }
public LogEventVisitor ImmediateVisitor { get; }
@@ -20,18 +20,20 @@ namespace Mono.Profiler.Log {
public LogStreamHeader StreamHeader { get; private set; }
+ LogReader _reader;
+
LogBufferHeader _bufferHeader;
ulong _time;
bool _used;
- public LogProcessor (LogReader reader, LogEventVisitor immediateVisitor, LogEventVisitor sortedVisitor)
+ public LogProcessor (LogStream stream, LogEventVisitor immediateVisitor, LogEventVisitor sortedVisitor)
{
- if (reader == null)
- throw new ArgumentNullException (nameof (reader));
+ if (stream == null)
+ throw new ArgumentNullException (nameof (stream));
- Reader = reader;
+ Stream = stream;
ImmediateVisitor = immediateVisitor;
SortedVisitor = sortedVisitor;
}
@@ -66,29 +68,44 @@ namespace Mono.Profiler.Log {
throw new InvalidOperationException ("This log processor cannot be reused.");
_used = true;
- StreamHeader = new LogStreamHeader (Reader);
+ _reader = new LogReader (Stream, true);
+
+ StreamHeader = new LogStreamHeader (_reader);
var events = new List<LogEvent> (Environment.ProcessorCount * 1000);
- while (!Reader.BaseStream.EndOfStream) {
+ while (!Stream.EndOfStream) {
token.ThrowIfCancellationRequested ();
- _bufferHeader = new LogBufferHeader (StreamHeader, Reader);
+ _bufferHeader = new LogBufferHeader (StreamHeader, _reader);
+
+ // Read the entire buffer into a MemoryStream ahead of time to
+ // reduce the amount of I/O system calls we do. This should be
+ // fine since the profiler tries to keep buffers small and
+ // flushes them every second at minimum. This also has the
+ // advantage that we can use the Position and Length properties
+ // even if the stream we read the buffer from is actually
+ // non-seekable.
+ var stream = new MemoryStream (_reader.ReadBytes (_bufferHeader.Length), false);
- // Use the manual position tracking in LogReader so we're
- // compatible with non-seekable streams.
- var goal = Reader.Position + _bufferHeader.Length;
+ using (var reader = new LogReader (stream, false)) {
+ var oldReader = _reader;
- while (Reader.Position < goal) {
- token.ThrowIfCancellationRequested ();
+ _reader = reader;
- var ev = ReadEvent ();
+ while (stream.Position < stream.Length) {
+ token.ThrowIfCancellationRequested ();
- ProcessEvent (ImmediateVisitor, ev);
- events.Add (ev);
+ var ev = ReadEvent ();
+
+ ProcessEvent (ImmediateVisitor, ev);
+ events.Add (ev);
+
+ if (ev is SynchronizationPointEvent)
+ ProcessEvents (events, token);
+ }
- if (ev is SynchronizationPointEvent)
- ProcessEvents (events, token);
+ _reader = oldReader;
}
}
@@ -97,7 +114,7 @@ namespace Mono.Profiler.Log {
LogEvent ReadEvent ()
{
- var type = Reader.ReadByte ();
+ var type = _reader.ReadByte ();
var basicType = (LogEventType) (type & 0xf);
var extType = (LogEventType) (type & 0xf0);
@@ -112,7 +129,7 @@ namespace Mono.Profiler.Log {
ev = new AllocationEvent {
ClassPointer = ReadPointer (),
ObjectPointer = ReadObject (),
- ObjectSize = (long) Reader.ReadULeb128 (),
+ ObjectSize = (long) _reader.ReadULeb128 (),
Backtrace = ReadBacktrace (extType == LogEventType.AllocationBacktrace),
};
break;
@@ -124,17 +141,17 @@ namespace Mono.Profiler.Log {
switch (extType) {
case LogEventType.GCEvent:
ev = new GCEvent {
- Type = (LogGCEvent) Reader.ReadByte (),
- Generation = Reader.ReadByte (),
+ Type = (LogGCEvent) _reader.ReadByte (),
+ Generation = _reader.ReadByte (),
};
break;
case LogEventType.GCResize:
ev = new GCResizeEvent {
- NewSize = (long) Reader.ReadULeb128 (),
+ NewSize = (long) _reader.ReadULeb128 (),
};
break;
case LogEventType.GCMove: {
- var list = new long [(int) Reader.ReadULeb128 ()];
+ var list = new long [(int) _reader.ReadULeb128 ()];
for (var i = 0; i < list.Length; i++)
list [i] = ReadObject ();
@@ -148,8 +165,8 @@ namespace Mono.Profiler.Log {
case LogEventType.GCHandleCreationNoBacktrace:
case LogEventType.GCHandleCreationBacktrace:
ev = new GCHandleCreationEvent {
- Type = (LogGCHandleType) Reader.ReadULeb128 (),
- Handle = (long) Reader.ReadULeb128 (),
+ Type = (LogGCHandleType) _reader.ReadULeb128 (),
+ Handle = (long) _reader.ReadULeb128 (),
ObjectPointer = ReadObject (),
Backtrace = ReadBacktrace (extType == LogEventType.GCHandleCreationBacktrace),
};
@@ -157,8 +174,8 @@ namespace Mono.Profiler.Log {
case LogEventType.GCHandleDeletionNoBacktrace:
case LogEventType.GCHandleDeletionBacktrace:
ev = new GCHandleDeletionEvent {
- Type = (LogGCHandleType) Reader.ReadULeb128 (),
- Handle = (long) Reader.ReadULeb128 (),
+ Type = (LogGCHandleType) _reader.ReadULeb128 (),
+ Handle = (long) _reader.ReadULeb128 (),
Backtrace = ReadBacktrace (extType == LogEventType.GCHandleDeletionBacktrace),
};
break;
@@ -199,7 +216,7 @@ namespace Mono.Profiler.Log {
throw new LogException ($"Invalid extended event type ({extType}).");
}
- var metadataType = (LogMetadataType) Reader.ReadByte ();
+ var metadataType = (LogMetadataType) _reader.ReadByte ();
switch (metadataType) {
case LogMetadataType.Class:
@@ -207,7 +224,7 @@ namespace Mono.Profiler.Log {
ev = new ClassLoadEvent {
ClassPointer = ReadPointer (),
ImagePointer = ReadPointer (),
- Name = Reader.ReadCString (),
+ Name = _reader.ReadCString (),
};
} else
throw new LogException ("Invalid class metadata event.");
@@ -216,12 +233,12 @@ namespace Mono.Profiler.Log {
if (load) {
ev = new ImageLoadEvent {
ImagePointer = ReadPointer (),
- Name = Reader.ReadCString (),
+ Name = _reader.ReadCString (),
};
} else if (unload) {
ev = new ImageUnloadEvent {
ImagePointer = ReadPointer (),
- Name = Reader.ReadCString (),
+ Name = _reader.ReadCString (),
};
} else
throw new LogException ("Invalid image metadata event.");
@@ -231,13 +248,13 @@ namespace Mono.Profiler.Log {
ev = new AssemblyLoadEvent {
AssemblyPointer = ReadPointer (),
ImagePointer = StreamHeader.FormatVersion >= 14 ? ReadPointer () : 0,
- Name = Reader.ReadCString (),
+ Name = _reader.ReadCString (),
};
} else if (unload) {
ev = new AssemblyUnloadEvent {
AssemblyPointer = ReadPointer (),
ImagePointer = StreamHeader.FormatVersion >= 14 ? ReadPointer () : 0,
- Name = Reader.ReadCString (),
+ Name = _reader.ReadCString (),
};
} else
throw new LogException ("Invalid assembly metadata event.");
@@ -254,7 +271,7 @@ namespace Mono.Profiler.Log {
} else {
ev = new AppDomainNameEvent {
AppDomainId = ReadPointer (),
- Name = Reader.ReadCString (),
+ Name = _reader.ReadCString (),
};
}
break;
@@ -270,7 +287,7 @@ namespace Mono.Profiler.Log {
} else {
ev = new ThreadNameEvent {
ThreadId = ReadPointer (),
- Name = Reader.ReadCString (),
+ Name = _reader.ReadCString (),
};
}
break;
@@ -314,8 +331,8 @@ namespace Mono.Profiler.Log {
ev = new JitEvent {
MethodPointer = ReadMethod (),
CodePointer = ReadPointer (),
- CodeSize = (long) Reader.ReadULeb128 (),
- Name = Reader.ReadCString (),
+ CodeSize = (long) _reader.ReadULeb128 (),
+ Name = _reader.ReadCString (),
};
break;
default:
@@ -333,8 +350,8 @@ namespace Mono.Profiler.Log {
break;
case LogEventType.ExceptionClause:
ev = new ExceptionClauseEvent {
- Type = (LogExceptionClause) Reader.ReadByte (),
- Index = (long) Reader.ReadULeb128 (),
+ Type = (LogExceptionClause) _reader.ReadByte (),
+ Index = (long) _reader.ReadULeb128 (),
MethodPointer = ReadMethod (),
ObjectPointer = StreamHeader.FormatVersion >= 14 ? ReadObject () : 0,
};
@@ -356,7 +373,7 @@ namespace Mono.Profiler.Log {
case LogEventType.MonitorBacktrace:
ev = new MonitorEvent {
Event = StreamHeader.FormatVersion >= 14 ?
- (LogMonitorEvent) Reader.ReadByte () :
+ (LogMonitorEvent) _reader.ReadByte () :
(LogMonitorEvent) ((((byte) type & 0xf0) >> 4) & 0x3),
ObjectPointer = ReadObject (),
Backtrace = ReadBacktrace (extType == LogEventType.MonitorBacktrace),
@@ -378,14 +395,14 @@ namespace Mono.Profiler.Log {
HeapObjectEvent hoe = new HeapObjectEvent {
ObjectPointer = ReadObject (),
ClassPointer = ReadPointer (),
- ObjectSize = (long) Reader.ReadULeb128 (),
+ ObjectSize = (long) _reader.ReadULeb128 (),
};
- var list = new HeapObjectEvent.HeapObjectReference [(int) Reader.ReadULeb128 ()];
+ var list = new HeapObjectEvent.HeapObjectReference [(int) _reader.ReadULeb128 ()];
for (var i = 0; i < list.Length; i++) {
list [i] = new HeapObjectEvent.HeapObjectReference {
- Offset = (long) Reader.ReadULeb128 (),
+ Offset = (long) _reader.ReadULeb128 (),
ObjectPointer = ReadObject (),
};
}
@@ -399,15 +416,15 @@ namespace Mono.Profiler.Log {
case LogEventType.HeapRoots: {
// TODO: This entire event makes no sense.
var hre = new HeapRootsEvent ();
- var list = new HeapRootsEvent.HeapRoot [(int) Reader.ReadULeb128 ()];
+ var list = new HeapRootsEvent.HeapRoot [(int) _reader.ReadULeb128 ()];
- hre.MaxGenerationCollectionCount = (long) Reader.ReadULeb128 ();
+ hre.MaxGenerationCollectionCount = (long) _reader.ReadULeb128 ();
for (var i = 0; i < list.Length; i++) {
list [i] = new HeapRootsEvent.HeapRoot {
ObjectPointer = ReadObject (),
- Attributes = StreamHeader.FormatVersion == 13 ? (LogHeapRootAttributes) Reader.ReadByte () : (LogHeapRootAttributes) Reader.ReadULeb128 (),
- ExtraInfo = (long) Reader.ReadULeb128 (),
+ Attributes = StreamHeader.FormatVersion == 13 ? (LogHeapRootAttributes) _reader.ReadByte () : (LogHeapRootAttributes) _reader.ReadULeb128 (),
+ ExtraInfo = (long) _reader.ReadULeb128 (),
};
}
@@ -425,7 +442,7 @@ namespace Mono.Profiler.Log {
case LogEventType.SampleHit:
if (StreamHeader.FormatVersion < 14) {
// Read SampleType (always set to .Cycles) for versions < 14
- Reader.ReadByte ();
+ _reader.ReadByte ();
}
ev = new SampleHitEvent {
ThreadId = ReadPointer (),
@@ -436,33 +453,33 @@ namespace Mono.Profiler.Log {
case LogEventType.SampleUnmanagedSymbol:
ev = new UnmanagedSymbolEvent {
CodePointer = ReadPointer (),
- CodeSize = (long) Reader.ReadULeb128 (),
- Name = Reader.ReadCString (),
+ CodeSize = (long) _reader.ReadULeb128 (),
+ Name = _reader.ReadCString (),
};
break;
case LogEventType.SampleUnmanagedBinary:
ev = new UnmanagedBinaryEvent {
- SegmentPointer = StreamHeader.FormatVersion >= 14 ? ReadPointer () : Reader.ReadSLeb128 (),
- SegmentOffset = (long) Reader.ReadULeb128 (),
- SegmentSize = (long) Reader.ReadULeb128 (),
- FileName = Reader.ReadCString (),
+ SegmentPointer = StreamHeader.FormatVersion >= 14 ? ReadPointer () : _reader.ReadSLeb128 (),
+ SegmentOffset = (long) _reader.ReadULeb128 (),
+ SegmentSize = (long) _reader.ReadULeb128 (),
+ FileName = _reader.ReadCString (),
};
break;
case LogEventType.SampleCounterDescriptions: {
var cde = new CounterDescriptionsEvent ();
- var list = new CounterDescriptionsEvent.CounterDescription [(int) Reader.ReadULeb128 ()];
+ var list = new CounterDescriptionsEvent.CounterDescription [(int) _reader.ReadULeb128 ()];
for (var i = 0; i < list.Length; i++) {
- var section = (LogCounterSection) Reader.ReadULeb128 ();
+ var section = (LogCounterSection) _reader.ReadULeb128 ();
list [i] = new CounterDescriptionsEvent.CounterDescription {
Section = section,
- SectionName = section == LogCounterSection.User ? Reader.ReadCString () : string.Empty,
- CounterName = Reader.ReadCString (),
- Type = (LogCounterType) Reader.ReadByte (),
- Unit = (LogCounterUnit) Reader.ReadByte (),
- Variance = (LogCounterVariance) Reader.ReadByte (),
- Index = (long) Reader.ReadULeb128 (),
+ SectionName = section == LogCounterSection.User ? _reader.ReadCString () : string.Empty,
+ CounterName = _reader.ReadCString (),
+ Type = (LogCounterType) _reader.ReadByte (),
+ Unit = (LogCounterUnit) _reader.ReadByte (),
+ Variance = (LogCounterVariance) _reader.ReadByte (),
+ Index = (long) _reader.ReadULeb128 (),
};
}
@@ -476,31 +493,31 @@ namespace Mono.Profiler.Log {
var list = new List<CounterSamplesEvent.CounterSample> ();
while (true) {
- var index = (long) Reader.ReadULeb128 ();
+ var index = (long) _reader.ReadULeb128 ();
if (index == 0)
break;
- var counterType = (LogCounterType) Reader.ReadByte ();
+ var counterType = (LogCounterType) _reader.ReadByte ();
object value = null;
switch (counterType) {
case LogCounterType.String:
- value = Reader.ReadByte () == 1 ? Reader.ReadCString () : null;
+ value = _reader.ReadByte () == 1 ? _reader.ReadCString () : null;
break;
case LogCounterType.Int32:
case LogCounterType.Word:
case LogCounterType.Int64:
case LogCounterType.Interval:
- value = Reader.ReadSLeb128 ();
+ value = _reader.ReadSLeb128 ();
break;
case LogCounterType.UInt32:
case LogCounterType.UInt64:
- value = Reader.ReadULeb128 ();
+ value = _reader.ReadULeb128 ();
break;
case LogCounterType.Double:
- value = Reader.ReadDouble ();
+ value = _reader.ReadDouble ();
break;
default:
throw new LogException ($"Invalid counter type ({counterType}).");
@@ -525,13 +542,13 @@ namespace Mono.Profiler.Log {
case LogEventType.Runtime:
switch (extType) {
case LogEventType.RuntimeJitHelper: {
- var helperType = (LogJitHelper) Reader.ReadByte ();
+ var helperType = (LogJitHelper) _reader.ReadByte ();
ev = new JitHelperEvent {
Type = helperType,
BufferPointer = ReadPointer (),
- BufferSize = (long) Reader.ReadULeb128 (),
- Name = helperType == LogJitHelper.SpecificTrampoline ? Reader.ReadCString () : string.Empty,
+ BufferSize = (long) _reader.ReadULeb128 (),
+ Name = helperType == LogJitHelper.SpecificTrampoline ? _reader.ReadCString () : string.Empty,
};
break;
}
@@ -543,7 +560,7 @@ namespace Mono.Profiler.Log {
switch (extType) {
case LogEventType.MetaSynchronizationPoint:
ev = new SynchronizationPointEvent {
- Type = (LogSynchronizationPoint) Reader.ReadByte (),
+ Type = (LogSynchronizationPoint) _reader.ReadByte (),
};
break;
default:
@@ -562,24 +579,24 @@ namespace Mono.Profiler.Log {
long ReadPointer ()
{
- var ptr = Reader.ReadSLeb128 () + _bufferHeader.PointerBase;
+ var ptr = _reader.ReadSLeb128 () + _bufferHeader.PointerBase;
return StreamHeader.PointerSize == sizeof (long) ? ptr : ptr & 0xffffffffL;
}
long ReadObject ()
{
- return Reader.ReadSLeb128 () + _bufferHeader.ObjectBase << 3;
+ return _reader.ReadSLeb128 () + _bufferHeader.ObjectBase << 3;
}
long ReadMethod ()
{
- return _bufferHeader.CurrentMethod += Reader.ReadSLeb128 ();
+ return _bufferHeader.CurrentMethod += _reader.ReadSLeb128 ();
}
ulong ReadTime ()
{
- return _bufferHeader.CurrentTime += Reader.ReadULeb128 ();
+ return _bufferHeader.CurrentTime += _reader.ReadULeb128 ();
}
IReadOnlyList<long> ReadBacktrace (bool actuallyRead, bool managed = true)
@@ -587,7 +604,7 @@ namespace Mono.Profiler.Log {
if (!actuallyRead)
return Array.Empty<long> ();
- var list = new long [(int) Reader.ReadULeb128 ()];
+ var list = new long [(int) _reader.ReadULeb128 ()];
for (var i = 0; i < list.Length; i++)
list [i] = managed ? ReadMethod () : ReadPointer ();
diff --git a/mcs/class/Mono.Profiler.Log/Mono.Profiler.Log/LogReader.cs b/mcs/class/Mono.Profiler.Log/Mono.Profiler.Log/LogReader.cs
index 4b241ba155d..a58211a1510 100644
--- a/mcs/class/Mono.Profiler.Log/Mono.Profiler.Log/LogReader.cs
+++ b/mcs/class/Mono.Profiler.Log/Mono.Profiler.Log/LogReader.cs
@@ -3,27 +3,22 @@
// See the LICENSE file in the project root for more information.
using System;
-using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Mono.Profiler.Log {
- public sealed class LogReader : IDisposable {
+ sealed class LogReader : IDisposable {
- public static Encoding Encoding { get; } = Encoding.UTF8;
-
- public LogStream BaseStream => (LogStream) _reader.BaseStream;
-
- public long Position { get; private set; }
+ static readonly Encoding _encoding = Encoding.UTF8;
readonly BinaryReader _reader;
byte[] _stringBuffer = new byte [1024];
- public LogReader (LogStream stream, bool leaveOpen)
+ public LogReader (Stream stream, bool leaveOpen)
{
- _reader = new BinaryReader (stream, Encoding, leaveOpen);
+ _reader = new BinaryReader (stream, _encoding, leaveOpen);
}
public void Dispose ()
@@ -31,73 +26,54 @@ namespace Mono.Profiler.Log {
_reader.Dispose ();
}
- internal byte ReadByte ()
+ public byte[] ReadBytes (int count)
{
- var b = _reader.ReadByte ();
+ var bytes = new byte [count];
- Position += sizeof (byte);
+ // BinaryReader.ReadBytes doesn't necessarily read the specified
+ // amount of bytes, so just do it this way.
+ for (var i = 0; i < bytes.Length; i++)
+ bytes [i] = ReadByte ();
- return b;
+ return bytes;
}
- internal ushort ReadUInt16 ()
+ public byte ReadByte ()
{
- var i = _reader.ReadUInt16 ();
-
- Position += sizeof (ushort);
-
- return i;
+ return _reader.ReadByte ();
}
- internal int ReadInt32 ()
+ public ushort ReadUInt16 ()
{
- var i = _reader.ReadInt32 ();
-
- Position += sizeof (int);
-
- return i;
+ return _reader.ReadUInt16 ();
}
- internal long ReadInt64 ()
+ public int ReadInt32 ()
{
- var i = _reader.ReadInt64 ();
-
- Position += sizeof (long);
-
- return i;
+ return _reader.ReadInt32 ();
}
- internal ulong ReadUInt64 ()
+ public long ReadInt64 ()
{
- var i = _reader.ReadUInt64 ();
-
- Position += sizeof (ulong);
-
- return i;
+ return _reader.ReadInt64 ();
}
- internal double ReadDouble ()
+ public ulong ReadUInt64 ()
{
- var d = _reader.ReadDouble ();
-
- Position += sizeof (double);
-
- return d;
+ return _reader.ReadUInt64 ();
}
- internal string ReadHeaderString ()
+ public double ReadDouble ()
{
- var bytes = new byte [ReadInt32 ()];
-
- // ReadBytes doesn't necessarily read the specified amount of
- // bytes, so just do it this way.
- for (var i = 0; i < bytes.Length; i++)
- bytes [i] = ReadByte ();
+ return _reader.ReadDouble ();
+ }
- return Encoding.GetString (bytes);
+ public string ReadHeaderString ()
+ {
+ return _encoding.GetString (ReadBytes (ReadInt32 ()));
}
- internal string ReadCString ()
+ public string ReadCString ()
{
var pos = 0;
@@ -110,10 +86,10 @@ namespace Mono.Profiler.Log {
_stringBuffer [pos++] = val;
}
- return Encoding.GetString (_stringBuffer, 0, pos);
+ return _encoding.GetString (_stringBuffer, 0, pos);
}
- internal long ReadSLeb128 ()
+ public long ReadSLeb128 ()
{
long result = 0;
var shift = 0;
@@ -135,7 +111,7 @@ namespace Mono.Profiler.Log {
return result;
}
- internal ulong ReadULeb128 ()
+ public ulong ReadULeb128 ()
{
ulong result = 0;
var shift = 0;