#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

242 lines
6.2 KiB

// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Globalization;
using System.Runtime.InteropServices;
namespace ICSharpCode.Profiler.Controller
{
/// <summary>
/// Contains general fields for verification, synchronisation and important addresses and offsets.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
struct SharedMemoryHeader32
{
public int Magic; // Verfication value, always '~SM1'
public volatile int ExclusiveAccess;
public int TotalLength;
public int NativeToManagedBufferOffset;
public int ThreadDataOffset;
public int ThreadDataLength;
public int HeapOffset;
public int HeapLength;
public TargetProcessPointer32 NativeAddress;
public TargetProcessPointer32 RootFuncInfoAddress;
public TargetProcessPointer32 LastThreadListItem;
public int ProcessorFrequency;
public bool DoNotProfileDotnetInternals;
public bool CombineRecursiveFunction;
public bool TrackEvents;
public Allocator32 Allocator;
}
/// <summary>
/// The representation of the unmanaged allocator used by the Hook.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
unsafe struct Allocator32
{
public TargetProcessPointer32 startPos;
public TargetProcessPointer32 pos;
public TargetProcessPointer32 endPos;
public fixed UInt32 freeList[32]; // Need UInt32 instead of TargetProcessPointer32
// because of fixed
public static void ClearFreeList(Allocator32 *a)
{
for (int i = 0; i < 32; i++) {
a->freeList[i] = 0;
}
}
}
/// <summary>
/// 32bit pointer used when a 32bit executable is profiled.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
struct TargetProcessPointer32
{
public UInt32 Pointer;
public override string ToString()
{
return "0x" + Pointer.ToString("x", CultureInfo.InvariantCulture);
}
public static implicit operator TargetProcessPointer(TargetProcessPointer32 p)
{
return new TargetProcessPointer(p);
}
public static TargetProcessPointer32 operator +(TargetProcessPointer32 p, Int32 offset)
{
unchecked { p.Pointer += (UInt32)offset; }
return p;
}
public static TargetProcessPointer32 operator -(TargetProcessPointer32 p, Int32 offset)
{
unchecked { p.Pointer -= (UInt32)offset; }
return p;
}
public static Int32 operator -(TargetProcessPointer32 ptr1, TargetProcessPointer32 ptr2)
{
unchecked { return (Int32)(ptr1.Pointer - ptr2.Pointer); }
}
}
/// <summary>
/// A pointer that can be both 64 and 32 bit.
/// </summary>
struct TargetProcessPointer
{
TargetProcessPointer64 pointer;
internal TargetProcessPointer(TargetProcessPointer32 p)
{
this.pointer.Pointer = p.Pointer;
}
internal TargetProcessPointer(TargetProcessPointer64 p)
{
this.pointer = p;
}
internal TargetProcessPointer32 To32()
{
TargetProcessPointer32 p = new TargetProcessPointer32();
p.Pointer = (uint)pointer.Pointer;
return p;
}
internal TargetProcessPointer64 To64()
{
return pointer;
}
public override string ToString()
{
return pointer.ToString();
}
public override bool Equals(object obj)
{
if (obj is TargetProcessPointer) {
return ((TargetProcessPointer)obj).pointer.Pointer == pointer.Pointer;
}
return false;
}
public override int GetHashCode()
{
return pointer.Pointer.GetHashCode();
}
public static bool operator ==(TargetProcessPointer ptr, int number)
{
return (ptr.pointer.Pointer == (ulong)number);
}
public static bool operator !=(TargetProcessPointer ptr, int number)
{
return (ptr.pointer.Pointer != (ulong)number);
}
public static bool operator ==(TargetProcessPointer ptr, TargetProcessPointer ptr2)
{
return (ptr.pointer.Pointer == ptr2.pointer.Pointer);
}
public static bool operator !=(TargetProcessPointer ptr, TargetProcessPointer ptr2)
{
return (ptr.pointer.Pointer != ptr2.pointer.Pointer);
}
public static int operator -(TargetProcessPointer ptr, TargetProcessPointer ptr2)
{
return (int)(ptr.pointer.Pointer - ptr2.pointer.Pointer);
}
public static int operator +(TargetProcessPointer ptr, TargetProcessPointer ptr2)
{
return (int)(ptr.pointer.Pointer + ptr2.pointer.Pointer);
}
public static int operator +(TargetProcessPointer ptr, int num)
{
return (int)(ptr.pointer.Pointer + (ulong)num);
}
}
/// <summary>
/// The managed version of the FunctionInfo
/// </summary>
[StructLayout(LayoutKind.Sequential)]
unsafe partial struct FunctionInfo
{
public int Id;
public int CallCount;
public ulong TimeSpent;
public int FillCount;
public int LastChildIndex;
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes")]
public static TargetProcessPointer32* GetChildren32(FunctionInfo* f)
{
if (f == null)
throw new NullReferenceException();
return (TargetProcessPointer32*)(f + 1);
}
public static void AddOrUpdateChild32(FunctionInfo* parent, FunctionInfo* child, Profiler profiler)
{
int slot = child->Id;
while (true)
{
slot &= parent->LastChildIndex;
FunctionInfo* slotContent = (FunctionInfo*)profiler.TranslatePointer(GetChildren32(parent)[slot]);
if (slotContent == null || slotContent->Id == child->Id)
{
GetChildren32(parent)[slot] = profiler.TranslatePointerBack32(child);
break;
}
slot++;
}
}
}
/// <summary>
/// The managed version of the ThreadLocalData
/// </summary>
[StructLayout(LayoutKind.Sequential)]
unsafe struct ThreadLocalData32
{
public int ThreadID;
public volatile int InLock;
public volatile bool Active;
public TargetProcessPointer32 Predecessor;
public TargetProcessPointer32 Follower;
public LightweightStack32 Stack;
}
[StructLayout(LayoutKind.Sequential)]
unsafe struct LightweightStack32
{
public TargetProcessPointer32 Array;
public TargetProcessPointer32 TopPointer;
public TargetProcessPointer32 ArrayEnd;
}
[StructLayout(LayoutKind.Sequential)]
unsafe struct StackEntry32
{
public TargetProcessPointer32 Function;
public ulong StartTime;
public int FrameCount;
}
}