Skip to content
This repository has been archived by the owner on Dec 15, 2020. It is now read-only.

Commit

Permalink
Add support for new profiler events
Browse files Browse the repository at this point in the history
  • Loading branch information
slluis committed Oct 21, 2015
1 parent b9e760e commit 84033f7
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 25 deletions.
179 changes: 158 additions & 21 deletions HeapShot.Reader/Event.cs
@@ -1,4 +1,4 @@
//
//
// Event.cs
//
// Authors:
Expand Down Expand Up @@ -46,7 +46,8 @@ public enum EventType
Monitor = 5,
Heap = 6,
Sample = 7,
Runtime = 8
Runtime = 8,
Coverage = 9
}

public class Backtrace
Expand Down Expand Up @@ -83,7 +84,9 @@ public abstract class Event
public const byte TYPE_GC_MOVE = 3 << 4;
public const byte TYPE_GC_HANDLE_CREATED = 4 << 4;
public const byte TYPE_GC_HANDLE_DESTROYED = 5 << 4;

public const byte TYPE_GC_HANDLE_CREATED_BT = 6 << 4;
public const byte TYPE_GC_HANDLE_DESTROYED_BT = 7 << 4;

public static Event CreateEvent (LogFileReader reader, EventType type, byte extendedInfo)
{
switch (type) {
Expand All @@ -100,15 +103,17 @@ public static Event CreateEvent (LogFileReader reader, EventType type, byte exte
case TYPE_GC_MOVE:
return MoveGcEvent.Read (reader);
case TYPE_GC_HANDLE_CREATED:
return HandleCreatedGcEvent.Read (reader);
case TYPE_GC_HANDLE_CREATED_BT:
return HandleCreatedGcEvent.Read (reader, extendedInfo);
case TYPE_GC_HANDLE_DESTROYED:
return HandleDestroyedGcEvent.Read (reader);
case TYPE_GC_HANDLE_DESTROYED_BT:
return HandleDestroyedGcEvent.Read (reader, extendedInfo);
}
throw new InvalidOperationException ("unknown gc type:" + extendedInfo);
case EventType.Heap:
return HeapEvent.Read (reader, extendedInfo);
case EventType.Metadata:
return MetadataEvent.Read (reader);
return MetadataEvent.Read (reader, extendedInfo);
case EventType.Method:
return MethodEvent.Read (reader, extendedInfo);
case EventType.Monitor:
Expand All @@ -117,6 +122,8 @@ public static Event CreateEvent (LogFileReader reader, EventType type, byte exte
return SampleEvent.Read (reader, extendedInfo);
case EventType.Runtime:
return RuntimeEvent.Read (reader, extendedInfo);
case EventType.Coverage:
return CoverageEvent.Read (reader, extendedInfo);
}
throw new InvalidOperationException ("invalid event type " + type);
}
Expand Down Expand Up @@ -250,18 +257,20 @@ public class HandleCreatedGcEvent : Event
public readonly ulong HandleType; // GC handle type (System.Runtime.InteropServices.GCHandleType)
public readonly ulong Handle; // GC handle value
public readonly long ObjAddr; // object pointer differences from obj_base
HandleCreatedGcEvent (LogFileReader reader)

HandleCreatedGcEvent (LogFileReader reader, byte exinfo)
{
TimeDiff = reader.ReadULeb128 ();
HandleType = reader.ReadULeb128 ();
Handle = reader.ReadULeb128 ();
ObjAddr = reader.ReadSLeb128 ();
if (exinfo == TYPE_GC_HANDLE_CREATED_BT)
new Backtrace (reader);
}

public static new Event Read (LogFileReader reader)
public static Event Read (LogFileReader reader, byte exinfo)
{
return new HandleCreatedGcEvent (reader);
return new HandleCreatedGcEvent (reader, exinfo);
}

public override object Accept (EventVisitor visitor)
Expand All @@ -275,16 +284,18 @@ public class HandleDestroyedGcEvent : Event
public readonly ulong HandleType; // GC handle type (System.Runtime.InteropServices.GCHandleType)
public readonly ulong Handle; // GC handle value

HandleDestroyedGcEvent (LogFileReader reader)
HandleDestroyedGcEvent (LogFileReader reader, byte exinfo)
{
TimeDiff = reader.ReadULeb128 ();
HandleType = reader.ReadULeb128 ();
Handle = reader.ReadULeb128 ();
if (exinfo == TYPE_GC_HANDLE_DESTROYED_BT)
new Backtrace (reader);
}

public static new Event Read (LogFileReader reader)
public static Event Read (LogFileReader reader, byte exinfo)
{
return new HandleDestroyedGcEvent (reader);
return new HandleDestroyedGcEvent (reader, exinfo);
}

public override object Accept (EventVisitor visitor)
Expand All @@ -302,18 +313,20 @@ public enum MetaDataType : byte
Image = 2,
Assembly = 3,
Domain = 4,
Thread = 5
Thread = 5,
Context = 6
}

public readonly MetaDataType MType; // metadata type, one of: TYPE_CLASS, TYPE_IMAGE, TYPE_ASSEMBLY, TYPE_DOMAINTYPE_THREAD
public readonly long Pointer; // pointer of the metadata type depending on mtype

public readonly long Domain; // domain id as a pointer

public readonly ulong Flags; // must be 0
public readonly string Name; // full class/image file or thread name

public readonly long Image; // MonoImage* as a pointer difference from ptr_base

MetadataEvent (LogFileReader reader)
MetadataEvent (LogFileReader reader, byte extendedInfo)
{
TimeDiff = reader.ReadULeb128 ();
MType = (MetaDataType)reader.ReadByte ();
Expand All @@ -328,16 +341,33 @@ public enum MetaDataType : byte
Flags = reader.ReadULeb128 ();
Name = reader.ReadNullTerminatedString ();
break;
case MetaDataType.Thread:
case MetaDataType.Assembly:
Flags = reader.ReadULeb128 ();
Name = reader.ReadNullTerminatedString ();
break;
case MetaDataType.Thread:
Flags = reader.ReadULeb128 ();
if (reader.Header.Format < 11 || (reader.Header.Format > 10 && extendedInfo == 0)) {
Name = reader.ReadNullTerminatedString ();
}
break;
case MetaDataType.Domain:
Flags = reader.ReadULeb128 ();
if (extendedInfo == 0)
Name = reader.ReadNullTerminatedString ();
break;
case MetaDataType.Context:
Flags = reader.ReadULeb128 ();
Domain = reader.ReadSLeb128 ();
break;
default:
throw new ArgumentException ("Unknown metadata type: " + MType);
}
}

public static new Event Read (LogFileReader reader)
public static Event Read (LogFileReader reader, byte extendedInfo)
{
return new MetadataEvent (reader);
return new MetadataEvent (reader, extendedInfo);
}

public override object Accept (EventVisitor visitor)
Expand Down Expand Up @@ -406,7 +436,7 @@ public class ExceptionEvent : Event
ExceptionEvent (LogFileReader reader, byte exinfo)
{
TimeDiff = reader.ReadULeb128 ();
byte subtype = (byte)(exinfo & 0x70);
byte subtype = (byte)(exinfo & ~TYPE_EXCEPTION_BT);
if (subtype == TYPE_CLAUSE) {
ClauseType = reader.ReadULeb128 ();
ClauseNum = reader.ReadULeb128 ();
Expand All @@ -415,7 +445,8 @@ public class ExceptionEvent : Event
Object = reader.ReadSLeb128 ();
if ((exinfo & TYPE_EXCEPTION_BT) == TYPE_EXCEPTION_BT)
Backtrace = new Backtrace (reader);
}
} else
throw new InvalidOperationException ("Unknown exception event type:" + (exinfo & ~TYPE_EXCEPTION_BT));
}

public static Event Read (LogFileReader reader, byte exinfo)
Expand Down Expand Up @@ -823,4 +854,110 @@ enum MonoProfilerCodeBufferType {
MONO_PROFILER_CODE_BUFFER_LAST
}
}

public abstract class CoverageEvent : Event
{
public const byte TYPE_COVERAGE_ASSEMBLY = 0 << 4;
public const byte TYPE_COVERAGE_METHOD = 1 << 4;
public const byte TYPE_COVERAGE_STATEMENT = 2 << 4;
public const byte TYPE_COVERAGE_CLASS = 3 << 4;

public static Event Read (LogFileReader reader, byte extendedInfo)
{
switch (extendedInfo) {
case TYPE_COVERAGE_ASSEMBLY: return new CoverageAssemblyEvent (reader);
case TYPE_COVERAGE_METHOD: return new CoverageMethodEvent (reader);
case TYPE_COVERAGE_STATEMENT: return new CoverageStatementEvent (reader);
case TYPE_COVERAGE_CLASS: return new CoverageClassEvent (reader);
}
throw new ArgumentException ("Unknown `CoverageEventType`: " + extendedInfo);
}

public override object Accept (EventVisitor visitor)
{
return visitor.Visit (this);
}
}

class CoverageAssemblyEvent: CoverageEvent
{
public readonly string Name;
public readonly string Guid;
public readonly string Filename;
public readonly ulong NumberOfMethods;
public readonly ulong FullyCovered;
public readonly ulong PartiallyCovered;

public CoverageAssemblyEvent (LogFileReader reader)
{
Name = reader.ReadNullTerminatedString ();
Guid = reader.ReadNullTerminatedString ();
Filename = reader.ReadNullTerminatedString ();
NumberOfMethods = reader.ReadULeb128 ();
FullyCovered = reader.ReadULeb128 ();
PartiallyCovered = reader.ReadULeb128 ();
}
}

class CoverageMethodEvent: CoverageEvent
{
public readonly string Assembly;
public readonly string Class;
public readonly string Name;
public readonly string Signature;
public readonly string Filename;
public readonly ulong Token;
public readonly ulong MethodId;
public readonly ulong Len;

public CoverageMethodEvent (LogFileReader reader)
{
Assembly = reader.ReadNullTerminatedString ();
Class = reader.ReadNullTerminatedString ();
Name = reader.ReadNullTerminatedString ();
Signature =reader.ReadNullTerminatedString ();
Filename = reader.ReadNullTerminatedString ();
Token = reader.ReadULeb128 ();
MethodId = reader.ReadULeb128 ();
Len = reader.ReadULeb128 ();
}
}

class CoverageClassEvent: CoverageEvent
{
public readonly string Name;
public readonly string Class;
public readonly ulong NumberOfMethods;
public readonly ulong FullyCovered;
public readonly ulong PartiallyCovered;

public CoverageClassEvent (LogFileReader reader)
{
Name = reader.ReadNullTerminatedString ();
Class = reader.ReadNullTerminatedString ();
NumberOfMethods = reader.ReadULeb128 ();
FullyCovered = reader.ReadULeb128 ();
PartiallyCovered = reader.ReadULeb128 ();

}
}

public class CoverageStatementEvent : CoverageEvent
{
public readonly ulong MethodId;
public readonly ulong Offset;
public readonly ulong Counter;
public readonly ulong Line;
public readonly ulong Column;

public CoverageStatementEvent (LogFileReader reader)
{
MethodId = reader.ReadULeb128 ();
Offset = reader.ReadULeb128 ();
Counter = reader.ReadULeb128 ();
Line = reader.ReadULeb128 ();
Column = reader.ReadULeb128 ();
}
}

}
7 changes: 6 additions & 1 deletion HeapShot.Reader/EventVisitor.cs
@@ -1,4 +1,4 @@
//
//
// EventVisitor.cs
//
// Author:
Expand Down Expand Up @@ -118,6 +118,11 @@ public virtual object Visit (RuntimeJitHelperEvent heapEvent)
{
return null;
}

public virtual object Visit (CoverageEvent heapEvent)
{
return null;
}
}
}

5 changes: 4 additions & 1 deletion HeapShot.Reader/LogFileReader.cs
@@ -1,4 +1,4 @@
//
//
// LogFileReader.cs
//
// Authors:
Expand Down Expand Up @@ -26,6 +26,7 @@

using System;
using System.IO;
using MonoDevelop.Profiler;

namespace HeapShot.Reader
{
Expand All @@ -35,6 +36,8 @@ public class LogFileReader : IDisposable
byte [] buffer = new byte [ushort.MaxValue];
int buffered_size;
int position;

public Header Header { get; set; }

public LogFileReader (string filename)
{
Expand Down
5 changes: 3 additions & 2 deletions HeapShot.Reader/ObjectMapFileReader.cs
@@ -1,4 +1,4 @@
//
//
// ObjectMapFileReader.cs
//
// Copyright (C) 2005 Novell, Inc.
Expand Down Expand Up @@ -176,6 +176,8 @@ private void ReadLogFile (IProgressListener progress)
header = Header.Read (reader);
if (header == null)
return;

reader.Header = header;

while (!reader.IsEof) {
// We check if we must cancel before reading more data (and after processing all the data we've read).
Expand Down Expand Up @@ -208,7 +210,6 @@ private void ReadLogFile (IProgressListener progress)
GcEvent ge;

Event e = Event.Read (reader);
//Console.WriteLine ("Event: {0}", e);
if ((me = e as MetadataEvent) != null)
ReadLogFileChunk_Type (me);
else if ((he = e as HeapEvent) != null)
Expand Down

0 comments on commit 84033f7

Please sign in to comment.