Imported Upstream version 5.8.0.22

Former-commit-id: df344e34b07851d296efb3e6604c8db42b6f7aa3
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-10-19 20:04:20 +00:00
parent 5f4a27cc8a
commit 7d05485754
5020 changed files with 114082 additions and 186061 deletions

View File

@@ -0,0 +1,21 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Reflection;
using System.Resources;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle ("Mono.Profiler.Log")]
[assembly: AssemblyDescription ("Mono Log Profiler API Library")]
[assembly: AssemblyCompany (Consts.MonoCompany)]
[assembly: AssemblyProduct (Consts.MonoProduct)]
[assembly: AssemblyCopyright (Consts.MonoCopyright)]
[assembly: AssemblyVersion (Consts.FxVersion)]
[assembly: SatelliteContractVersion (Consts.FxVersion)]
[assembly: AssemblyInformationalVersion (Consts.FxFileVersion)]
[assembly: AssemblyFileVersion (Consts.FxFileVersion)]
[assembly: ComVisible (false)]

View File

@@ -0,0 +1,13 @@
thisdir = class/Mono.Profiler.Log
include ../../build/rules.make
LIBRARY = Mono.Profiler.Log.dll
LIBRARY_SNK = ../mono.snk
LIB_REFS = System System.Core
KEYFILE = $(LIBRARY_SNK)
LIB_MCS_FLAGS = /unsafe /publicsign
NO_TEST = yes
include ../../build/library.make

View File

@@ -0,0 +1,14 @@
Assembly/AssemblyInfo.cs
../../build/common/Consts.cs
../../build/common/Locale.cs
Mono.Profiler.Log/LogBufferHeader.cs
Mono.Profiler.Log/LogEnums.cs
Mono.Profiler.Log/LogEvent.cs
Mono.Profiler.Log/LogEventVisitor.cs
Mono.Profiler.Log/LogEvents.cs
Mono.Profiler.Log/LogException.cs
Mono.Profiler.Log/LogProcessor.cs
Mono.Profiler.Log/LogProfiler.cs
Mono.Profiler.Log/LogReader.cs
Mono.Profiler.Log/LogStream.cs
Mono.Profiler.Log/LogStreamHeader.cs

View File

@@ -0,0 +1,46 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Mono.Profiler.Log {
public sealed class LogBufferHeader {
const int Id = 0x4d504c01;
public LogStreamHeader StreamHeader { get; }
public int Length { get; }
public ulong TimeBase { get; }
public long PointerBase { get; }
public long ObjectBase { get; }
public long ThreadId { get; }
public long MethodBase { get; }
internal ulong CurrentTime { get; set; }
internal long CurrentMethod { get; set; }
internal LogBufferHeader (LogStreamHeader streamHeader, LogReader reader)
{
StreamHeader = streamHeader;
var id = reader.ReadInt32 ();
if (id != Id)
throw new LogException ($"Invalid buffer header ID (0x{id:X}).");
Length = reader.ReadInt32 ();
TimeBase = CurrentTime = reader.ReadUInt64 ();
PointerBase = reader.ReadInt64 ();
ObjectBase = reader.ReadInt64 ();
ThreadId = reader.ReadInt64 ();
MethodBase = CurrentMethod = reader.ReadInt64 ();
}
}
}

View File

@@ -0,0 +1,217 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Mono.Profiler.Log {
// mono/profiler/log.h : TYPE_*
enum LogEventType {
Allocation = 0,
GC = 1,
Metadata = 2,
Method = 3,
Exception = 4,
Monitor = 5,
Heap = 6,
Sample = 7,
Runtime = 8,
Meta = 10,
AllocationNoBacktrace = 0 << 4,
AllocationBacktrace = 1 << 4,
GCEvent = 1 << 4,
GCResize = 2 << 4,
GCMove = 3 << 4,
GCHandleCreationNoBacktrace = 4 << 4,
GCHandleDeletionNoBacktrace = 5 << 4,
GCHandleCreationBacktrace = 6 << 4,
GCHandleDeletionBacktrace = 7 << 4,
GCFinalizeBegin = 8 << 4,
GCFinalizeEnd = 9 << 4,
GCFinalizeObjectBegin = 10 << 4,
GCFinalizeObjectEnd = 11 << 4,
MetadataExtra = 0 << 4,
MetadataEndLoad = 2 << 4,
MetadataEndUnload = 4 << 4,
MethodLeave = 1 << 4,
MethodEnter = 2 << 4,
MethodLeaveExceptional = 3 << 4,
MethodJit = 4 << 4,
ExceptionThrowNoBacktrace = 0 << 7,
ExceptionThrowBacktrace = 1 << 7,
ExceptionClause = 1 << 4,
MonitorNoBacktrace = 0 << 7,
MonitorBacktrace = 1 << 7,
HeapBegin = 0 << 4,
HeapEnd = 1 << 4,
HeapObject = 2 << 4,
HeapRoots = 3 << 4,
SampleHit = 0 << 4,
SampleUnmanagedSymbol = 1 << 4,
SampleUnmanagedBinary = 2 << 4,
SampleCounterDescriptions = 3 << 4,
SampleCounters = 4 << 4,
RuntimeJitHelper = 1 << 4,
MetaSynchronizationPoint = 0 << 4,
}
// mono/profiler/log.h : TYPE_*
enum LogMetadataType {
Class = 1,
Image = 2,
Assembly = 3,
AppDomain = 4,
Thread = 5,
Context = 6,
}
// mono/utils/mono-counters.h : MONO_COUNTER_*
public enum LogCounterType {
Int32 = 0,
UInt32 = 1,
Word = 2,
Int64 = 3,
UInt64 = 4,
Double = 5,
String = 6,
Interval = 7,
}
// mono/utils/mono-counters.h : MONO_COUNTER_*
public enum LogCounterSection {
Jit = 1 << 8,
GC = 1 << 9,
Metadata = 1 << 10,
Generics = 1 << 11,
Security = 1 << 12,
Runtime = 1 << 13,
System = 1 << 14,
User = 1 << 15,
Profiler = 1 << 16,
}
// mono/utils/mono-counters.h : MONO_COUNTER_*
public enum LogCounterUnit {
Raw = 0 << 24,
Bytes = 1 << 24,
Time = 2 << 24,
Count = 3 << 24,
Percentage = 4 << 24,
}
// mono/utils/mono-counters.h : MONO_COUNTER_*
public enum LogCounterVariance {
Monotonic = 1 << 28,
Constant = 1 << 29,
Variable = 1 << 30,
}
// mono/metadata/profiler.h : MonoProfilerCodeBufferType
public enum LogJitHelper {
Unknown = 0,
Method = 1,
MethodTrampoline = 2,
UnboxTrampoline = 3,
ImtTrampoline = 4,
GenericsTrampoline = 5,
SpecificTrampoline = 6,
Helper = 7,
Monitor = 8,
DelegateInvoke = 9,
ExceptionHandling = 10,
}
// mono/metadata/profiler.h : MonoProfilerGCRootType
[Flags]
public enum LogHeapRootAttributes {
Pinning = 1 << 8,
WeakReference = 2 << 8,
Interior = 4 << 8,
Stack = 0,
Finalizer = 1,
Handle = 2,
Other = 3,
Miscellaneous = 4,
TypeMask = 0xff,
}
// mono/profiler/log.h : MonoProfilerMonitorEvent
public enum LogMonitorEvent {
Contention = 1,
Done = 2,
Fail = 3,
}
// mono/metadata/metadata.h : MonoExceptionEnum
public enum LogExceptionClause {
Catch = 0,
Filter = 1,
Finally = 2,
Fault = 4,
}
// mono/metadata/profiler.h : MonoProfilerGCEvent
public enum LogGCEvent {
PreStopWorld = 6,
PreStopWorldLocked = 10,
PostStopWorld = 7,
Begin = 0,
End = 5,
PreStartWorld = 8,
PostStartWorld = 9,
PostStartWorldUnlocked = 11,
// Following are v13 and older only
[Obsolete ("This event is no longer produced.")]
MarkBegin = 1,
[Obsolete ("This event is no longer produced.")]
MarkEnd = 2,
[Obsolete ("This event is no longer produced.")]
ReclaimBegin = 3,
[Obsolete ("This event is no longer produced.")]
ReclaimEnd = 4
}
// mono/metadata/mono-gc.h : MonoGCHandleType
public enum LogGCHandleType {
Weak = 0,
WeakTrackResurrection = 1,
Normal = 2,
Pinned = 3,
}
// mono/profiler/log.h : MonoProfilerSyncPointType
public enum LogSynchronizationPoint {
Periodic = 0,
WorldStop = 1,
WorldStart = 2,
}
// mono/metadata/profiler.h : MonoProfilerSampleMode
public enum LogSampleMode {
None = 0,
Process = 1,
Real = 2,
}
// mono/profiler/log.h : MonoProfilerHeapshotMode
public enum LogHeapshotMode {
None = 0,
EveryMajor = 1,
OnDemand = 2,
Milliseconds = 3,
Collections = 4,
}
}

View File

@@ -0,0 +1,75 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections;
using System.Linq;
using System.Reflection;
using System.Text;
namespace Mono.Profiler.Log {
public abstract class LogEvent {
const BindingFlags PropertyFlags = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public;
const string Indent = " ";
internal LogEvent ()
{
}
public LogBufferHeader Buffer { get; internal set; }
public ulong Timestamp { get; internal set; }
public override string ToString ()
{
var sb = new StringBuilder ();
ToString (this, sb, string.Empty, GetType ().Name, 0);
return sb.ToString ();
}
static void ToString (object source, StringBuilder result, string indent, string header, int level)
{
result.AppendLine ($"{indent}{header} {{");
foreach (var prop in source.GetType ().GetProperties (PropertyFlags).OrderBy (p => p.MetadataToken)) {
var name = prop.Name;
var propIndent = indent + Indent;
var value = prop.GetValue (source);
if (value is IList list) {
result.AppendLine ($"{propIndent}{name} = [{list.Count}] {{");
for (var i = 0; i < list.Count; i++) {
var elem = list [i];
var type = elem.GetType ();
var elemIndent = propIndent + Indent;
var elemHeader = $"[{i}] = ";
if (type.IsClass && type != typeof (string))
ToString (elem, result, elemIndent, $"{elemHeader}{type.Name}", level + 1);
else
result.AppendLine ($"{elemIndent}{elemHeader}{elem}");
}
result.AppendLine ($"{propIndent}}}");
} else
result.AppendLine ($"{propIndent}{name} = {value}");
}
var end = $"{indent}}}";
if (level == 0)
result.Append (end);
else
result.AppendLine (end);
}
internal abstract void Accept (LogEventVisitor visitor);
}
}

View File

@@ -0,0 +1,181 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
namespace Mono.Profiler.Log {
public abstract class LogEventVisitor {
public virtual void VisitBefore (LogEvent ev)
{
}
public virtual void VisitAfter (LogEvent ev)
{
}
public virtual void Visit (AppDomainLoadEvent ev)
{
}
public virtual void Visit (AppDomainUnloadEvent ev)
{
}
public virtual void Visit (AppDomainNameEvent ev)
{
}
public virtual void Visit (ContextLoadEvent ev)
{
}
public virtual void Visit (ContextUnloadEvent ev)
{
}
public virtual void Visit (ThreadStartEvent ev)
{
}
public virtual void Visit (ThreadEndEvent ev)
{
}
public virtual void Visit (ThreadNameEvent ev)
{
}
public virtual void Visit (ImageLoadEvent ev)
{
}
public virtual void Visit (ImageUnloadEvent ev)
{
}
public virtual void Visit (AssemblyLoadEvent ev)
{
}
public virtual void Visit (AssemblyUnloadEvent ev)
{
}
public virtual void Visit (ClassLoadEvent ev)
{
}
public virtual void Visit (JitEvent ev)
{
}
public virtual void Visit (JitHelperEvent ev)
{
}
public virtual void Visit (AllocationEvent ev)
{
}
public virtual void Visit (HeapBeginEvent ev)
{
}
public virtual void Visit (HeapEndEvent ev)
{
}
public virtual void Visit (HeapObjectEvent ev)
{
}
public virtual void Visit (HeapRootsEvent ev)
{
}
public virtual void Visit (GCEvent ev)
{
}
public virtual void Visit (GCResizeEvent ev)
{
}
public virtual void Visit (GCMoveEvent ev)
{
}
public virtual void Visit (GCHandleCreationEvent ev)
{
}
public virtual void Visit (GCHandleDeletionEvent ev)
{
}
public virtual void Visit (GCFinalizeBeginEvent ev)
{
}
public virtual void Visit (GCFinalizeEndEvent ev)
{
}
public virtual void Visit (GCFinalizeObjectBeginEvent ev)
{
}
public virtual void Visit (GCFinalizeObjectEndEvent ev)
{
}
public virtual void Visit (ThrowEvent ev)
{
}
public virtual void Visit (ExceptionClauseEvent ev)
{
}
public virtual void Visit (EnterEvent ev)
{
}
public virtual void Visit (LeaveEvent ev)
{
}
public virtual void Visit (ExceptionalLeaveEvent ev)
{
}
public virtual void Visit (MonitorEvent ev)
{
}
public virtual void Visit (SampleHitEvent ev)
{
}
public virtual void Visit (CounterSamplesEvent ev)
{
}
public virtual void Visit (CounterDescriptionsEvent ev)
{
}
public virtual void Visit (UnmanagedBinaryEvent ev)
{
}
public virtual void Visit (UnmanagedSymbolEvent ev)
{
}
public virtual void Visit (SynchronizationPointEvent ev)
{
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Mono.Profiler.Log {
public sealed class LogException : Exception {
public LogException (string message)
: base (message)
{
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,262 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security;
namespace Mono.Profiler.Log {
public static class LogProfiler {
static bool? _attached;
public static bool IsAttached {
get {
if (_attached != null)
return (bool) _attached;
try {
GetMaxStackTraceFrames ();
return (bool) (_attached = true);
} catch (Exception e) when (e is MissingMethodException || e is SecurityException) {
return (bool) (_attached = false);
}
}
}
[MethodImpl (MethodImplOptions.InternalCall)]
extern static int GetMaxStackTraceFrames ();
public static int MaxStackTraceFrames {
get { return GetMaxStackTraceFrames (); }
}
[MethodImpl (MethodImplOptions.InternalCall)]
extern static int GetStackTraceFrames ();
[MethodImpl (MethodImplOptions.InternalCall)]
extern static void SetStackTraceFrames (int value);
public static int StackTraceFrames {
get { return GetStackTraceFrames (); }
set {
var max = MaxStackTraceFrames;
if (value < 0 || value > max)
throw new ArgumentOutOfRangeException (nameof (value), value, $"Value must be between 0 and {max}.");
SetStackTraceFrames (value);
}
}
[MethodImpl (MethodImplOptions.InternalCall)]
extern static LogHeapshotMode GetHeapshotMode ();
[MethodImpl (MethodImplOptions.InternalCall)]
extern static void SetHeapshotMode (LogHeapshotMode value);
public static LogHeapshotMode HeapshotMode {
get { return GetHeapshotMode (); }
set {
if (!Enum.IsDefined (typeof (LogHeapshotMode), value))
throw new ArgumentException ("Invalid heapshot mode.", nameof (value));
SetHeapshotMode (value);
}
}
[MethodImpl (MethodImplOptions.InternalCall)]
extern static int GetHeapshotMillisecondsFrequency ();
[MethodImpl (MethodImplOptions.InternalCall)]
extern static void SetHeapshotMillisecondsFrequency (int value);
public static int HeapshotMillisecondsFrequency {
get { return GetHeapshotMillisecondsFrequency (); }
set {
if (value < 0)
throw new ArgumentOutOfRangeException (nameof (value), value, "Value must be non-negative.");
SetHeapshotMillisecondsFrequency (value);
}
}
[MethodImpl (MethodImplOptions.InternalCall)]
extern static int GetHeapshotCollectionsFrequency ();
[MethodImpl (MethodImplOptions.InternalCall)]
extern static void SetHeapshotCollectionsFrequency (int value);
public static int HeapshotCollectionsFrequency {
get { return GetHeapshotCollectionsFrequency (); }
set {
if (value < 0)
throw new ArgumentOutOfRangeException (nameof (value), value, "Value must be non-negative.");
SetHeapshotCollectionsFrequency (value);
}
}
[MethodImpl (MethodImplOptions.InternalCall)]
extern static int GetCallDepth ();
[MethodImpl (MethodImplOptions.InternalCall)]
extern static void SetCallDepth (int value);
public static int CallDepth {
get { return GetCallDepth (); }
set {
if (value < 0)
throw new ArgumentOutOfRangeException (nameof (value), value, "Value must be non-negative.");
SetCallDepth (value);
}
}
[MethodImpl (MethodImplOptions.InternalCall)]
extern static void GetSampleMode (out LogSampleMode mode, out int frequency);
[MethodImpl (MethodImplOptions.InternalCall)]
extern static bool SetSampleMode (LogSampleMode value, int frequency);
public static LogSampleMode SampleMode {
get {
GetSampleMode (out var mode, out var _);
return mode;
}
}
public static int SampleFrequency {
get {
GetSampleMode (out var _, out var frequency);
return frequency;
}
}
public static bool SetSampleParameters (LogSampleMode mode, int frequency)
{
if (!Enum.IsDefined (typeof (LogSampleMode), mode))
throw new ArgumentException ("Invalid sample mode.", nameof (mode));
if (frequency < 1)
throw new ArgumentOutOfRangeException (nameof (frequency), frequency, "Frequency must be positive.");
return SetSampleMode (mode, frequency);
}
[MethodImpl (MethodImplOptions.InternalCall)]
extern static bool GetExceptionEvents ();
[MethodImpl (MethodImplOptions.InternalCall)]
extern static void SetExceptionEvents (bool value);
public static bool ExceptionEventsEnabled {
get { return GetExceptionEvents (); }
set { SetExceptionEvents (value); }
}
[MethodImpl (MethodImplOptions.InternalCall)]
extern static bool GetMonitorEvents ();
[MethodImpl (MethodImplOptions.InternalCall)]
extern static void SetMonitorEvents (bool value);
public static bool MonitorEventsEnabled {
get { return GetMonitorEvents (); }
set { SetMonitorEvents (value); }
}
[MethodImpl (MethodImplOptions.InternalCall)]
extern static bool GetGCEvents ();
[MethodImpl (MethodImplOptions.InternalCall)]
extern static void SetGCEvents (bool value);
public static bool GCEventsEnabled {
get { return GetGCEvents (); }
set { SetGCEvents (value); }
}
[MethodImpl (MethodImplOptions.InternalCall)]
extern static bool GetGCAllocationEvents ();
[MethodImpl (MethodImplOptions.InternalCall)]
extern static void SetGCAllocationEvents (bool value);
public static bool GCAllocationEventsEnabled {
get { return GetGCAllocationEvents (); }
set { SetGCAllocationEvents (value); }
}
[MethodImpl (MethodImplOptions.InternalCall)]
extern static bool GetGCMoveEvents ();
[MethodImpl (MethodImplOptions.InternalCall)]
extern static void SetGCMoveEvents (bool value);
public static bool GCMoveEventsEnabled {
get { return GetGCMoveEvents (); }
set { SetGCMoveEvents (value); }
}
[MethodImpl (MethodImplOptions.InternalCall)]
extern static bool GetGCRootEvents ();
[MethodImpl (MethodImplOptions.InternalCall)]
extern static void SetGCRootEvents (bool value);
public static bool GCRootEventsEnabled {
get { return GetGCRootEvents (); }
set { SetGCRootEvents (value); }
}
[MethodImpl (MethodImplOptions.InternalCall)]
extern static bool GetGCHandleEvents ();
[MethodImpl (MethodImplOptions.InternalCall)]
extern static void SetGCHandleEvents (bool value);
public static bool GCHandleEventsEnabled {
get { return GetGCHandleEvents (); }
set { SetGCHandleEvents (value); }
}
[MethodImpl (MethodImplOptions.InternalCall)]
extern static bool GetGCFinalizationEvents ();
[MethodImpl (MethodImplOptions.InternalCall)]
extern static void SetGCFinalizationEvents (bool value);
public static bool GCFinalizationEventsEnabled {
get { return GetGCFinalizationEvents (); }
set { SetGCFinalizationEvents (value); }
}
[MethodImpl (MethodImplOptions.InternalCall)]
extern static bool GetCounterEvents ();
[MethodImpl (MethodImplOptions.InternalCall)]
extern static void SetCounterEvents (bool value);
public static bool CounterEventsEnabled {
get { return GetCounterEvents (); }
set { SetCounterEvents (value); }
}
[MethodImpl (MethodImplOptions.InternalCall)]
extern static bool GetJitEvents ();
[MethodImpl (MethodImplOptions.InternalCall)]
extern static void SetJitEvents (bool value);
public static bool JitEventsEnabled {
get { return GetJitEvents (); }
set { SetJitEvents (value); }
}
}
}

View File

@@ -0,0 +1,133 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.IO;
using System.Text;
namespace Mono.Profiler.Log {
sealed class LogReader : IDisposable {
static readonly Encoding _encoding = Encoding.UTF8;
readonly BinaryReader _reader;
byte[] _stringBuffer = new byte [1024];
public LogReader (Stream stream, bool leaveOpen)
{
_reader = new BinaryReader (stream, _encoding, leaveOpen);
}
public void Dispose ()
{
_reader.Dispose ();
}
public byte[] ReadBytes (int count)
{
var bytes = new byte [count];
// 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 bytes;
}
public byte ReadByte ()
{
return _reader.ReadByte ();
}
public ushort ReadUInt16 ()
{
return _reader.ReadUInt16 ();
}
public int ReadInt32 ()
{
return _reader.ReadInt32 ();
}
public long ReadInt64 ()
{
return _reader.ReadInt64 ();
}
public ulong ReadUInt64 ()
{
return _reader.ReadUInt64 ();
}
public double ReadDouble ()
{
return _reader.ReadDouble ();
}
public string ReadHeaderString ()
{
return _encoding.GetString (ReadBytes (ReadInt32 ()));
}
public string ReadCString ()
{
var pos = 0;
byte val;
while ((val = ReadByte ()) != 0) {
if (pos == _stringBuffer.Length)
Array.Resize (ref _stringBuffer, System.Math.Max (_stringBuffer.Length * 2, pos + 1));
_stringBuffer [pos++] = val;
}
return _encoding.GetString (_stringBuffer, 0, pos);
}
public long ReadSLeb128 ()
{
long result = 0;
var shift = 0;
while (true) {
var b = ReadByte ();
result |= (long) (b & 0x7f) << shift;
shift += 7;
if ((b & 0x80) != 0x80) {
if (shift < sizeof (long) * 8 && (b & 0x40) == 0x40)
result |= -(1L << shift);
break;
}
}
return result;
}
public ulong ReadULeb128 ()
{
ulong result = 0;
var shift = 0;
while (true) {
var b = ReadByte ();
result |= (ulong) (b & 0x7f) << shift;
if ((b & 0x80) != 0x80)
break;
shift += 7;
}
return result;
}
}
}

View File

@@ -0,0 +1,81 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.IO;
namespace Mono.Profiler.Log {
public class LogStream : Stream {
public Stream BaseStream { get; }
public virtual bool EndOfStream => BaseStream.Position == BaseStream.Length;
public override bool CanRead => true;
public override bool CanSeek => false;
public override bool CanWrite => false;
public override long Length => throw new NotSupportedException ();
public override long Position {
get => throw new NotSupportedException ();
set => throw new NotSupportedException ();
}
readonly byte[] _byteBuffer = new byte [1];
public LogStream (Stream baseStream)
{
if (baseStream == null)
throw new ArgumentNullException (nameof (baseStream));
if (!baseStream.CanRead)
throw new ArgumentException ("Stream does not support reading.", nameof (baseStream));
BaseStream = baseStream;
}
protected override void Dispose (bool disposing)
{
if (disposing)
BaseStream.Dispose ();
}
public override void Flush ()
{
throw new NotSupportedException ();
}
public override int ReadByte ()
{
// The base method on Stream is extremely inefficient in that it
// allocates a 1-byte array for every call. Simply use a private
// buffer instead.
return Read (_byteBuffer, 0, sizeof (byte)) == 0 ? -1 : _byteBuffer [0];
}
public override int Read (byte[] buffer, int offset, int count)
{
return BaseStream.Read (buffer, offset, count);
}
public override long Seek (long offset, SeekOrigin origin)
{
throw new NotSupportedException ();
}
public override void SetLength (long value)
{
throw new NotSupportedException ();
}
public override void Write (byte[] buffer, int offset, int count)
{
throw new NotSupportedException ();
}
}
}

View File

@@ -0,0 +1,62 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Mono.Profiler.Log {
public sealed class LogStreamHeader {
const int MinVersion = 13;
const int MaxVersion = 14;
const int Id = 0x4d505a01;
public Version Version { get; }
public int FormatVersion { get; }
public byte PointerSize { get; }
public ulong StartupTime { get; }
public int TimerOverhead { get; }
public int Flags { get; }
public int ProcessId { get; }
public int Port { get; }
public string Arguments { get; }
public string Architecture { get; }
public string OperatingSystem { get; }
internal LogStreamHeader (LogReader reader)
{
var id = reader.ReadInt32 ();
if (id != Id)
throw new LogException ($"Invalid stream header ID (0x{id:X}).");
Version = new Version (reader.ReadByte (), reader.ReadByte ());
FormatVersion = reader.ReadByte ();
if (FormatVersion < MinVersion || FormatVersion > MaxVersion)
throw new LogException ($"Unsupported MLPD version {FormatVersion}. Should be >= {MinVersion} and <= {MaxVersion}.");
PointerSize = reader.ReadByte ();
StartupTime = reader.ReadUInt64 ();
TimerOverhead = reader.ReadInt32 ();
Flags = reader.ReadInt32 ();
ProcessId = reader.ReadInt32 ();
Port = reader.ReadUInt16 ();
Arguments = reader.ReadHeaderString ();
Architecture = reader.ReadHeaderString ();
OperatingSystem = reader.ReadHeaderString ();
}
}
}