Browse Source

Profiler:

- added translation for the profiler UI
- added functionality to control data collection (only profile parts)
- added new columns (Time spent (self); Time spent/call, Time spent (self)/call)
- added hot path indicators
- Top 20 tab is now sorted by TimeSpentSelf

* fixed bug in LocalizeExtension

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@4874 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Siegfried Pammer 16 years ago
parent
commit
566b84c281
  1. 5
      src/AddIns/Misc/Profiler/Controller/Data/IProfilingDataSet.cs
  2. 26
      src/AddIns/Misc/Profiler/Controller/Data/ProfilingDataSQLiteProvider.cs
  3. 6
      src/AddIns/Misc/Profiler/Controller/Data/ProfilingDataSQLiteWriter.cs
  4. 13
      src/AddIns/Misc/Profiler/Controller/Data/TempFileDatabase.cs
  5. 11
      src/AddIns/Misc/Profiler/Controller/Data/UnmanagedProfilingDataSet.cs
  6. 32
      src/AddIns/Misc/Profiler/Controller/Profiler.cs
  7. 15
      src/AddIns/Misc/Profiler/Controller/ProfilerOptions.cs
  8. 97
      src/AddIns/Misc/Profiler/Frontend/AddIn/AddIn.csproj
  9. 35
      src/AddIns/Misc/Profiler/Frontend/AddIn/ICSharpCode.Profiler.AddIn.addin
  10. 7
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Commands/CopyStacktrace.cs
  11. 11
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Commands/ProfileExecutable.cs
  12. 30
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Dialogs/ProfilerControlWindow.xaml
  13. 66
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Dialogs/ProfilerControlWindow.xaml.cs
  14. 29
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/OptionsPanels/General.cs
  15. 63
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/OptionsPanels/GeneralOptionsPanel.xaml
  16. 10
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/OptionsPanels/GeneralOptionsPanel.xaml.cs
  17. 12
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/ProfilerRunner.cs
  18. 7
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Views/ProfilerView.xaml.cs
  19. 2
      src/AddIns/Misc/Profiler/Frontend/Controls/CallTreeNodeViewModel.cs
  20. 2
      src/AddIns/Misc/Profiler/Frontend/Controls/Controls.csproj
  21. 22
      src/AddIns/Misc/Profiler/Frontend/Controls/ControlsTranslation.cs
  22. 6
      src/AddIns/Misc/Profiler/Frontend/Controls/QueryView.xaml.cs
  23. 31
      src/AddIns/Misc/Profiler/Frontend/Controls/TimeLineControl.cs
  24. 4
      src/Main/ICSharpCode.Core.Presentation/LocalizeExtension.cs

5
src/AddIns/Misc/Profiler/Controller/Data/IProfilingDataSet.cs

@ -27,6 +27,11 @@ namespace ICSharpCode.Profiler.Controller.Data
/// </summary> /// </summary>
double CpuUsage { get; } double CpuUsage { get; }
/// <summary>
/// Gets whether this dataset is the first dataset of a profiling run.
/// </summary>
bool IsFirst { get; }
/// <summary> /// <summary>
/// Gets the root node of the dataset. /// Gets the root node of the dataset.
/// </summary> /// </summary>

26
src/AddIns/Misc/Profiler/Controller/Data/ProfilingDataSQLiteProvider.cs

@ -173,14 +173,26 @@ namespace ICSharpCode.Profiler.Controller.Data
SQLiteCommand cmd; SQLiteCommand cmd;
using (LockAndCreateCommand(out cmd)) { using (LockAndCreateCommand(out cmd)) {
SQLiteDataReader reader;
bool isFirstAllowed = true;
try {
cmd.CommandText = @"SELECT id, cpuusage, isfirst
FROM DataSets
ORDER BY id;";
reader = cmd.ExecuteReader();
} catch (SQLiteException) {
cmd.CommandText = @"SELECT id, cpuusage cmd.CommandText = @"SELECT id, cpuusage
FROM DataSets FROM DataSets
ORDER BY id;"; ORDER BY id;";
SQLiteDataReader reader = cmd.ExecuteReader(); reader = cmd.ExecuteReader();
isFirstAllowed = false;
}
while (reader.Read()) { while (reader.Read()) {
list.Add(new SQLiteDataSet(this, reader.GetInt32(0), reader.GetDouble(1))); list.Add(new SQLiteDataSet(this, reader.GetInt32(0), reader.GetDouble(1), isFirstAllowed ? reader.GetBoolean(2) : false));
} }
} }
@ -212,12 +224,14 @@ namespace ICSharpCode.Profiler.Controller.Data
ProfilingDataSQLiteProvider provider; ProfilingDataSQLiteProvider provider;
int index; int index;
double cpuUsage; double cpuUsage;
bool isFirst;
public SQLiteDataSet(ProfilingDataSQLiteProvider provider, int index, double cpuUsage) public SQLiteDataSet(ProfilingDataSQLiteProvider provider, int index, double cpuUsage, bool isFirst)
{ {
this.provider = provider; this.provider = provider;
this.index = index; this.index = index;
this.cpuUsage = cpuUsage; this.cpuUsage = cpuUsage;
this.isFirst = isFirst;
} }
public double CpuUsage { public double CpuUsage {
@ -231,6 +245,12 @@ namespace ICSharpCode.Profiler.Controller.Data
return this.provider.GetRoot(index, index); return this.provider.GetRoot(index, index);
} }
} }
public bool IsFirst {
get {
return isFirst;
}
}
} }
/// <summary> /// <summary>

6
src/AddIns/Misc/Profiler/Controller/Data/ProfilingDataSQLiteWriter.cs

@ -106,10 +106,11 @@ namespace ICSharpCode.Profiler.Controller.Data
cmd.Parameters.Add(new SQLiteParameter("id", dataSetCount)); cmd.Parameters.Add(new SQLiteParameter("id", dataSetCount));
cmd.Parameters.Add(new SQLiteParameter("cpuuage", dataSet.CpuUsage.ToString(CultureInfo.InvariantCulture))); cmd.Parameters.Add(new SQLiteParameter("cpuuage", dataSet.CpuUsage.ToString(CultureInfo.InvariantCulture)));
cmd.Parameters.Add(new SQLiteParameter("isfirst", dataSet.IsFirst));
cmd.Parameters.Add(new SQLiteParameter("rootid", functionInfoCount)); cmd.Parameters.Add(new SQLiteParameter("rootid", functionInfoCount));
cmd.CommandText = "INSERT INTO DataSets(id, cpuusage, rootid)" + cmd.CommandText = "INSERT INTO DataSets(id, cpuusage, isfirst, rootid)" +
"VALUES(?,?,?);"; "VALUES(?,?,?,?);";
using (SQLiteCommand loopCommand = this.connection.CreateCommand()) { using (SQLiteCommand loopCommand = this.connection.CreateCommand()) {
CallTreeNode node = dataSet.RootNode; CallTreeNode node = dataSet.RootNode;
@ -208,6 +209,7 @@ namespace ICSharpCode.Profiler.Controller.Data
CREATE TABLE DataSets( CREATE TABLE DataSets(
id INTEGER NOT NULL PRIMARY KEY, id INTEGER NOT NULL PRIMARY KEY,
cpuusage REAL NOT NULL, cpuusage REAL NOT NULL,
isfirst INTEGER NOT NULL,
rootid INTEGER NOT NULL rootid INTEGER NOT NULL
); );

13
src/AddIns/Misc/Profiler/Controller/Data/TempFileDatabase.cs

@ -44,6 +44,7 @@ namespace ICSharpCode.Profiler.Controller.Data
public long StreamStartPosition { get; set; } public long StreamStartPosition { get; set; }
public long StreamLength { get; set; } public long StreamLength { get; set; }
public double CpuUsage { get; set; } public double CpuUsage { get; set; }
public bool IsFirst { get; set; }
} }
#region TempFileDatabase DataSet and DataWriter implementation #region TempFileDatabase DataSet and DataWriter implementation
@ -54,8 +55,8 @@ namespace ICSharpCode.Profiler.Controller.Data
public DataSet(TempFileDatabase database, UnmanagedMemory view, public DataSet(TempFileDatabase database, UnmanagedMemory view,
TargetProcessPointer nativeStartPosition, TargetProcessPointer nativeRootFuncInfoStartPosition, TargetProcessPointer nativeStartPosition, TargetProcessPointer nativeRootFuncInfoStartPosition,
double cpuUsage) double cpuUsage, bool isFirst)
: base(nativeStartPosition, nativeRootFuncInfoStartPosition, view.Pointer, view.Length, cpuUsage, database.is64Bit) : base(nativeStartPosition, nativeRootFuncInfoStartPosition, view.Pointer, view.Length, cpuUsage, isFirst, database.is64Bit)
{ {
this.database = database; this.database = database;
this.view = view; this.view = view;
@ -116,7 +117,7 @@ namespace ICSharpCode.Profiler.Controller.Data
if (dataSet == null) if (dataSet == null)
throw new InvalidOperationException("TempFileDatabase cannot write DataSets other than UnmanagedProfilingDataSet!"); throw new InvalidOperationException("TempFileDatabase cannot write DataSets other than UnmanagedProfilingDataSet!");
database.AddDataset((byte *)uDataSet.StartPtr.ToPointer(), uDataSet.Length, uDataSet.NativeStartPosition, uDataSet.NativeRootFuncInfoPosition, uDataSet.CpuUsage); database.AddDataset((byte *)uDataSet.StartPtr.ToPointer(), uDataSet.Length, uDataSet.NativeStartPosition, uDataSet.NativeRootFuncInfoPosition, uDataSet.CpuUsage, uDataSet.IsFirst);
this.database.is64Bit = uDataSet.Is64Bit; this.database.is64Bit = uDataSet.Is64Bit;
} }
@ -149,14 +150,14 @@ namespace ICSharpCode.Profiler.Controller.Data
this.file = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, FileOptions.Asynchronous | FileOptions.DeleteOnClose); this.file = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite, 4096, FileOptions.Asynchronous | FileOptions.DeleteOnClose);
} }
unsafe void AddDataset(byte *ptr, long length, TargetProcessPointer nativeStartPosition, TargetProcessPointer nativeRootFuncInfoStartPosition, double cpuUsage) unsafe void AddDataset(byte *ptr, long length, TargetProcessPointer nativeStartPosition, TargetProcessPointer nativeRootFuncInfoStartPosition, double cpuUsage, bool isFirst)
{ {
byte[] data = new byte[length]; byte[] data = new byte[length];
Marshal.Copy(new IntPtr(ptr), data, 0, (int)length); Marshal.Copy(new IntPtr(ptr), data, 0, (int)length);
if (this.currentWrite != null) if (this.currentWrite != null)
this.file.EndWrite(this.currentWrite); this.file.EndWrite(this.currentWrite);
this.streamInfos.Add(new StreamInfo { NativeStartPosition = nativeStartPosition, NativeRootFuncInfoStartPosition = nativeRootFuncInfoStartPosition, this.streamInfos.Add(new StreamInfo { NativeStartPosition = nativeStartPosition, NativeRootFuncInfoStartPosition = nativeRootFuncInfoStartPosition,
StreamStartPosition = this.file.Length, StreamLength = length, CpuUsage = cpuUsage }); StreamStartPosition = this.file.Length, StreamLength = length, CpuUsage = cpuUsage, IsFirst = isFirst });
this.currentWrite = this.file.BeginWrite(data, 0, (int)length, null, null); this.currentWrite = this.file.BeginWrite(data, 0, (int)length, null, null);
} }
@ -206,7 +207,7 @@ namespace ICSharpCode.Profiler.Controller.Data
return new DataSet(this, mmf.MapView(streamInfos[index].StreamStartPosition, streamInfos[index].StreamLength), streamInfos[index].NativeStartPosition, return new DataSet(this, mmf.MapView(streamInfos[index].StreamStartPosition, streamInfos[index].StreamLength), streamInfos[index].NativeStartPosition,
streamInfos[index].NativeRootFuncInfoStartPosition, streamInfos[index].NativeRootFuncInfoStartPosition,
streamInfos[index].CpuUsage); streamInfos[index].CpuUsage, streamInfos[index].IsFirst);
} }
/// <summary> /// <summary>

11
src/AddIns/Misc/Profiler/Controller/Data/UnmanagedProfilingDataSet.cs

@ -24,6 +24,7 @@ namespace ICSharpCode.Profiler.Controller.Data
TargetProcessPointer nativeRootFuncInfoPosition; TargetProcessPointer nativeRootFuncInfoPosition;
bool isDisposed; bool isDisposed;
double cpuUsage; double cpuUsage;
bool isFirst;
bool is64Bit; bool is64Bit;
/// <summary> /// <summary>
@ -82,12 +83,13 @@ namespace ICSharpCode.Profiler.Controller.Data
public abstract NameMapping GetMapping(int nameId); public abstract NameMapping GetMapping(int nameId);
internal UnmanagedProfilingDataSet(TargetProcessPointer nativeStartPosition, TargetProcessPointer nativeRootFuncInfoPosition, internal UnmanagedProfilingDataSet(TargetProcessPointer nativeStartPosition, TargetProcessPointer nativeRootFuncInfoPosition,
byte *startPtr, long length, double cpuUsage, bool is64Bit) byte *startPtr, long length, double cpuUsage, bool isFirst, bool is64Bit)
{ {
this.nativeStartPosition = nativeStartPosition; this.nativeStartPosition = nativeStartPosition;
this.cpuUsage = cpuUsage; this.cpuUsage = cpuUsage;
this.nativeRootFuncInfoPosition = nativeRootFuncInfoPosition; this.nativeRootFuncInfoPosition = nativeRootFuncInfoPosition;
this.is64Bit = is64Bit; this.is64Bit = is64Bit;
this.isFirst = isFirst;
this.startPtr = new IntPtr(startPtr); this.startPtr = new IntPtr(startPtr);
this.length = length; this.length = length;
} }
@ -140,5 +142,12 @@ namespace ICSharpCode.Profiler.Controller.Data
{ {
isDisposed = true; isDisposed = true;
} }
/// <inheritdoc/>
public bool IsFirst {
get {
return isFirst;
}
}
} }
} }

32
src/AddIns/Misc/Profiler/Controller/Profiler.cs

@ -48,6 +48,8 @@ namespace ICSharpCode.Profiler.Controller
bool is64Bit; bool is64Bit;
bool isRunning; bool isRunning;
volatile bool stopDC; volatile bool stopDC;
volatile bool enableDC;
volatile bool isFirstDC;
/// <summary> /// <summary>
/// Gets whether the profiler is running inside a 64-bit profilee process or not. /// Gets whether the profiler is running inside a 64-bit profilee process or not.
@ -198,6 +200,17 @@ namespace ICSharpCode.Profiler.Controller
get { return profilerOutput.ToString(); } get { return profilerOutput.ToString(); }
} }
public void EnableDataCollection()
{
this.enableDC = true;
}
public void DisableDataCollection()
{
this.enableDC = false;
this.isFirstDC = true;
}
/// <summary> /// <summary>
/// Creates a new profiler using the path to an executable to profile and a data writer. /// Creates a new profiler using the path to an executable to profile and a data writer.
/// </summary> /// </summary>
@ -302,8 +315,6 @@ namespace ICSharpCode.Profiler.Controller
this.Pause(); this.Pause();
this.threadListMutex.WaitOne(); this.threadListMutex.WaitOne();
Debug.Print("running DC " + (is64Bit ? "x64" : "x86"));
if (this.is64Bit) if (this.is64Bit)
CollectData64(); CollectData64();
else else
@ -342,13 +353,16 @@ namespace ICSharpCode.Profiler.Controller
item = (ThreadLocalData32*)TranslatePointer(item->Predecessor); item = (ThreadLocalData32*)TranslatePointer(item->Predecessor);
} }
if (this.enableDC) {
this.AddDataset(fullView.Pointer, this.AddDataset(fullView.Pointer,
memHeader32->NativeAddress + memHeader32->HeapOffset, memHeader32->NativeAddress + memHeader32->HeapOffset,
memHeader32->Allocator.startPos - memHeader32->NativeAddress, memHeader32->Allocator.startPos - memHeader32->NativeAddress,
memHeader32->Allocator.pos - memHeader32->Allocator.startPos, memHeader32->Allocator.pos - memHeader32->Allocator.startPos,
(cpuUsageCounter == null) ? 0 : cpuUsageCounter.NextValue(), (cpuUsageCounter == null) ? 0 : cpuUsageCounter.NextValue(),
isFirstDC,
memHeader32->RootFuncInfoAddress); memHeader32->RootFuncInfoAddress);
isFirstDC = false;
}
ZeroMemory(new IntPtr(TranslatePointer(memHeader32->Allocator.startPos)), new IntPtr(memHeader32->Allocator.pos - memHeader32->Allocator.startPos)); ZeroMemory(new IntPtr(TranslatePointer(memHeader32->Allocator.startPos)), new IntPtr(memHeader32->Allocator.pos - memHeader32->Allocator.startPos));
@ -388,9 +402,9 @@ namespace ICSharpCode.Profiler.Controller
} }
} }
unsafe void AddDataset(byte *ptr, TargetProcessPointer nativeStartPosition, long offset, long length, double cpuUsage, TargetProcessPointer nativeRootFuncInfoPosition) unsafe void AddDataset(byte *ptr, TargetProcessPointer nativeStartPosition, long offset, long length, double cpuUsage, bool isFirst, TargetProcessPointer nativeRootFuncInfoPosition)
{ {
using (DataSet dataSet = new DataSet(this, ptr + offset, length, nativeStartPosition, nativeRootFuncInfoPosition, cpuUsage, is64Bit)) { using (DataSet dataSet = new DataSet(this, ptr + offset, length, nativeStartPosition, nativeRootFuncInfoPosition, cpuUsage, isFirst, is64Bit)) {
lock (this.dataWriter) { lock (this.dataWriter) {
this.dataWriter.WriteDataSet(dataSet); this.dataWriter.WriteDataSet(dataSet);
} }
@ -492,6 +506,9 @@ namespace ICSharpCode.Profiler.Controller
this.profilee.StartInfo = this.psi; this.profilee.StartInfo = this.psi;
this.profilee.Exited += new EventHandler(ProfileeExited); this.profilee.Exited += new EventHandler(ProfileeExited);
this.enableDC = this.profilerOptions.EnableDCAtStart;
this.isFirstDC = true;
Debug.WriteLine("Launching profiler for " + this.psi.FileName + "..."); Debug.WriteLine("Launching profiler for " + this.psi.FileName + "...");
this.profilee.Start(); this.profilee.Start();
@ -578,6 +595,7 @@ namespace ICSharpCode.Profiler.Controller
// unload all counters to prevent exception during last collection! // unload all counters to prevent exception during last collection!
this.cpuUsageCounter = null; this.cpuUsageCounter = null;
this.performanceCounters = null; this.performanceCounters = null;
// Take last shot // Take last shot
if (this.is64Bit) if (this.is64Bit)
CollectData64(); CollectData64();
@ -796,8 +814,8 @@ namespace ICSharpCode.Profiler.Controller
public DataSet(Profiler profiler, byte *startPtr, long length, TargetProcessPointer nativeStartPosition, public DataSet(Profiler profiler, byte *startPtr, long length, TargetProcessPointer nativeStartPosition,
TargetProcessPointer nativeRootFuncInfoPosition, TargetProcessPointer nativeRootFuncInfoPosition,
double cpuUsage, bool is64Bit) double cpuUsage, bool isFirst, bool is64Bit)
: base(nativeStartPosition, nativeRootFuncInfoPosition, startPtr, length, cpuUsage, is64Bit) : base(nativeStartPosition, nativeRootFuncInfoPosition, startPtr, length, cpuUsage, isFirst, is64Bit)
{ {
this.profiler = profiler; this.profiler = profiler;
} }

15
src/AddIns/Misc/Profiler/Controller/ProfilerOptions.cs

@ -17,9 +17,10 @@ namespace ICSharpCode.Profiler.Controller
/// <summary> /// <summary>
/// Defines the default size of the shared memory. /// Defines the default size of the shared memory.
/// </summary> /// </summary>
public const int SHARED_MEMORY_SIZE = 64 * 1024 * 1024; // 64 mb public const int DefaultSharedMemorySize = 64 * 1024 * 1024; // 64 mb
bool enableDC; bool enableDC;
bool enableDCAtStart;
bool dotNotProfileDotNetInternals; bool dotNotProfileDotNetInternals;
bool combineRecursiveFunction; bool combineRecursiveFunction;
int sharedMemorySize; int sharedMemorySize;
@ -45,6 +46,13 @@ namespace ICSharpCode.Profiler.Controller
get { return enableDC; } get { return enableDC; }
} }
/// <summary>
/// Gets whether data collection is enabled at the start of the profiling session.
/// </summary>
public bool EnableDCAtStart {
get { return enableDCAtStart; }
}
/// <summary> /// <summary>
/// Gets the size of the shared memory. /// Gets the size of the shared memory.
/// </summary> /// </summary>
@ -55,19 +63,20 @@ namespace ICSharpCode.Profiler.Controller
/// <summary> /// <summary>
/// Creates new ProfilerOptions using the selected settings. /// Creates new ProfilerOptions using the selected settings.
/// </summary> /// </summary>
public ProfilerOptions(bool enableDC, int sharedMemorySize, bool profileDotNetInternals, bool combineRecursiveFunction) public ProfilerOptions(bool enableDC, int sharedMemorySize, bool profileDotNetInternals, bool combineRecursiveFunction, bool enableDCAtStart)
{ {
this.enableDC = enableDC; this.enableDC = enableDC;
this.sharedMemorySize = sharedMemorySize; this.sharedMemorySize = sharedMemorySize;
this.dotNotProfileDotNetInternals = profileDotNetInternals; this.dotNotProfileDotNetInternals = profileDotNetInternals;
this.combineRecursiveFunction = combineRecursiveFunction; this.combineRecursiveFunction = combineRecursiveFunction;
this.enableDCAtStart = enableDCAtStart;
} }
/// <summary> /// <summary>
/// Creates default ProfilerOptions. /// Creates default ProfilerOptions.
/// </summary> /// </summary>
public ProfilerOptions() public ProfilerOptions()
: this(true, SHARED_MEMORY_SIZE, false, false) : this(true, DefaultSharedMemorySize, false, false, true)
{ {
} }
} }

97
src/AddIns/Misc/Profiler/Frontend/AddIn/AddIn.csproj

@ -38,54 +38,6 @@
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<FileAlignment>4096</FileAlignment> <FileAlignment>4096</FileAlignment>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<Reference Include="ICSharpCode.Core">
<HintPath>..\..\..\..\..\..\bin\ICSharpCode.Core.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ICSharpCode.Core.Presentation">
<HintPath>..\..\..\..\..\..\bin\ICSharpCode.Core.Presentation.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ICSharpCode.SharpDevelop">
<HintPath>..\..\..\..\..\..\bin\ICSharpCode.SharpDevelop.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ICSharpCode.SharpDevelop.Dom">
<HintPath>..\..\..\..\..\..\bin\ICSharpCode.SharpDevelop.Dom.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Build.Engine" />
<Reference Include="Microsoft.Build.Framework" />
<Reference Include="PresentationCore">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="PresentationFramework">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Management" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Windows.Presentation">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="UIAutomationProvider">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="UnitTesting">
<HintPath>..\..\..\..\..\..\AddIns\AddIns\Misc\UnitTesting\UnitTesting.dll</HintPath>
</Reference>
<Reference Include="WindowsBase">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsFormsIntegration" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="ICSharpCode.Profiler.AddIn.addin"> <None Include="ICSharpCode.Profiler.AddIn.addin">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
@ -106,6 +58,10 @@
<Compile Include="Src\Dialogs\ProfileExecutableForm.xaml.cs"> <Compile Include="Src\Dialogs\ProfileExecutableForm.xaml.cs">
<DependentUpon>ProfileExecutableForm.xaml</DependentUpon> <DependentUpon>ProfileExecutableForm.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Src\Dialogs\ProfilerControlWindow.xaml.cs">
<DependentUpon>ProfilerControlWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Src\Extensions.cs" /> <Compile Include="Src\Extensions.cs" />
<Compile Include="Src\OptionsPanels\General.cs"> <Compile Include="Src\OptionsPanels\General.cs">
<SubType>UserControl</SubType> <SubType>UserControl</SubType>
@ -128,18 +84,63 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="Src\Dialogs\ProfilerControlWindow.xaml" />
<Page Include="Src\OptionsPanels\GeneralOptionsPanel.xaml" /> <Page Include="Src\OptionsPanels\GeneralOptionsPanel.xaml" />
<Page Include="Src\Views\ProfilerView.xaml"> <Page Include="Src\Views\ProfilerView.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
</ItemGroup>
<ItemGroup>
<Reference Include="ICSharpCode.Core">
<HintPath>..\..\..\..\..\..\bin\ICSharpCode.Core.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ICSharpCode.Core.Presentation">
<HintPath>..\..\..\..\..\..\bin\ICSharpCode.Core.Presentation.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ICSharpCode.SharpDevelop">
<HintPath>..\..\..\..\..\..\bin\ICSharpCode.SharpDevelop.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="ICSharpCode.SharpDevelop.Dom">
<HintPath>..\..\..\..\..\..\bin\ICSharpCode.SharpDevelop.Dom.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Build" />
<Reference Include="PresentationCore">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="PresentationFramework">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Windows.Forms" />
<Reference Include="UnitTesting">
<HintPath>..\..\..\..\..\..\AddIns\AddIns\Misc\UnitTesting\UnitTesting.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="WindowsBase">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsFormsIntegration">
<RequiredTargetFramework>3.0</RequiredTargetFramework>
</Reference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Controller\Controller.csproj"> <ProjectReference Include="..\..\Controller\Controller.csproj">
<Project>{72FFB35A-C9E2-4A31-B4FA-E3E3E28DED5F}</Project> <Project>{72FFB35A-C9E2-4A31-B4FA-E3E3E28DED5F}</Project>
<Name>Controller</Name> <Name>Controller</Name>
<Private>True</Private>
</ProjectReference> </ProjectReference>
<ProjectReference Include="..\Controls\Controls.csproj"> <ProjectReference Include="..\Controls\Controls.csproj">
<Project>{BDA49550-5ED1-4C6B-B648-657B2CACD8E0}</Project> <Project>{BDA49550-5ED1-4C6B-B648-657B2CACD8E0}</Project>
<Name>Controls</Name> <Name>Controls</Name>
<Private>True</Private>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />

35
src/AddIns/Misc/Profiler/Frontend/AddIn/ICSharpCode.Profiler.AddIn.addin

@ -22,13 +22,13 @@
<MenuItem <MenuItem
id="ProfileProject" id="ProfileProject"
class="ICSharpCode.Profiler.AddIn.Commands.ProfileProject" class="ICSharpCode.Profiler.AddIn.Commands.ProfileProject"
label="Profile current project" label="${res:AddIns.Profiler.ProfileCurrentProject}"
/> />
</ComplexCondition> </ComplexCondition>
<MenuItem <MenuItem
id="ProfileExecutable" id="ProfileExecutable"
class="ICSharpCode.Profiler.AddIn.Commands.ProfileExecutable" class="ICSharpCode.Profiler.AddIn.Commands.ProfileExecutable"
label="Select executable to profile" label="${res:AddIns.Profiler.ProfileExecutable}"
/> />
</MenuItem> </MenuItem>
</Path> </Path>
@ -37,58 +37,55 @@
<DisplayBinding id = "ProfilerDisplayBinding" <DisplayBinding id = "ProfilerDisplayBinding"
insertbefore="Text" insertbefore="Text"
fileNamePattern=".sdps" fileNamePattern=".sdps"
title = "Profiler View" title = "${res:AddIns.Profiler.ProfilingView.Title}"
class = "ICSharpCode.Profiler.AddIn.Views.ProfilerDisplayBinding"/> class = "ICSharpCode.Profiler.AddIn.Views.ProfilerDisplayBinding"/>
</Path> </Path>
<Path name="/AddIns/Profiler/QueryView/ContextMenu"> <Path name="/AddIns/Profiler/QueryView/ContextMenu">
<MenuItem <MenuItem
id="GoToDefinition" id="GoToDefinition"
label="Go to definition" label="{res:AddIns.Profiler.ProfilingView.ContextMenu.GoToDefinition}"
class="ICSharpCode.Profiler.AddIn.Commands.GoToDefinition" /> class="ICSharpCode.Profiler.AddIn.Commands.GoToDefinition" />
<MenuItem <MenuItem
id="FindReferences" id="FindReferences"
label="Find references" label="{res:SharpDevelop.Refactoring.FindReferences}"
class="ICSharpCode.Profiler.AddIn.Commands.FindReferences" /> class="ICSharpCode.Profiler.AddIn.Commands.FindReferences" />
<MenuItem type="Separator" id="Separator2" /> <MenuItem type="Separator" id="Separator2" />
<MenuItem <MenuItem
id="SetAsRoot" id="SetAsRoot"
label="Set as root/Merge" label="{res:AddIns.Profiler.ProfilingView.ContextMenu.SetAsRoot}"
class="ICSharpCode.Profiler.AddIn.Commands.SetAsRoot" /> class="ICSharpCode.Profiler.AddIn.Commands.SetAsRoot" />
<MenuItem <MenuItem
id="FindCallsOfSelected" id="FindCallsOfSelected"
label="Find calls of selected functions" label="{res:AddIns.Profiler.ProfilingView.ContextMenu.FindCallsOfSelected}"
class="ICSharpCode.Profiler.AddIn.Commands.FindCallsOfSelected" /> class="ICSharpCode.Profiler.AddIn.Commands.FindCallsOfSelected" />
<MenuItem <MenuItem
id="ShowFunctions" id="ShowFunctions"
label="Show functions" label="{res:AddIns.Profiler.ProfilingView.ContextMenu.ShowFunctions}"
class="ICSharpCode.Profiler.AddIn.Commands.ShowFunctions" /> class="ICSharpCode.Profiler.AddIn.Commands.ShowFunctions" />
<MenuItem type="Separator" id="Separator1" /> <MenuItem type="Separator" id="Separator1" />
<MenuItem <MenuItem
id="CopyStackTrace" id="CopyStacktrace"
label="Copy stacktrace" label="{res:AddIns.Profiler.ProfilingView.ContextMenu.CopyStacktrace}"
class="ICSharpCode.Profiler.AddIn.Commands.CopyStacktrace" /> class="ICSharpCode.Profiler.AddIn.Commands.CopyStacktrace" />
<MenuItem <MenuItem
id="CopySelectedData" id="CopySelectedData"
label="Copy selected data" label="{res:AddIns.Profiler.ProfilingView.ContextMenu.CopySelectedData}"
class="ICSharpCode.Profiler.AddIn.Commands.CopySelectedData" /> class="ICSharpCode.Profiler.AddIn.Commands.CopySelectedData" />
</Path> </Path>
<Path name="/SharpDevelop/Workbench/FileFilter"> <Path name="/SharpDevelop/Workbench/FileFilter">
<FileFilter id = "SharpDevelopProfingSession" <FileFilter id = "SharpDevelopProfingSession"
insertbefore="AllFiles" insertbefore="AllFiles"
name = "SharpDevelop Profiling Session" name = "{res:AddIns.Profiler.FileExtensionDescription}"
extensions = "*.sdps"/> extensions = "*.sdps"/>
</Path> </Path>
<Path name="/SharpDevelop/Dialogs/OptionsDialog"> <Path name="/SharpDevelop/Dialogs/OptionsDialog">
<DialogPanel id = "Profiling" <DialogPanel id = "Profiling"
label = "Profiling" label = "{res:AddIns.Profiler.Options.Title}"
insertbefore = "TextEditorOptions"> class = "ICSharpCode.Profiler.AddIn.OptionsPanels.General"
<DialogPanel id = "General" insertbefore = "TextEditorOptions" />
label = "General"
class = "ICSharpCode.Profiler.AddIn.OptionsPanels.General"/>
</DialogPanel>
</Path> </Path>
<Path name = "/SharpDevelop/Pads/UnitTestsPad/CommonTestCommands"> <Path name = "/SharpDevelop/Pads/UnitTestsPad/CommonTestCommands">
@ -100,7 +97,7 @@
</Not> </Not>
</And> </And>
<MenuItem id = "RunWithProfiler" <MenuItem id = "RunWithProfiler"
label = "Run with profiler" label = "{res:AddIns.Profiler.UnitTests.RunWithProfiler}"
class = "ICSharpCode.Profiler.AddIn.Commands.RunTestWithProfilerCommand"/> class = "ICSharpCode.Profiler.AddIn.Commands.RunTestWithProfilerCommand"/>
</ComplexCondition> </ComplexCondition>
</Path> </Path>

7
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Commands/CopyStacktrace.cs

@ -6,16 +6,9 @@
// </file> // </file>
using System; using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Shapes;
using ICSharpCode.Core;
using ICSharpCode.Profiler.Controller.Queries;
using ICSharpCode.Profiler.Controls;
namespace ICSharpCode.Profiler.AddIn.Commands namespace ICSharpCode.Profiler.AddIn.Commands
{ {

11
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Commands/ProfileExecutable.cs

@ -6,17 +6,8 @@
// </file> // </file>
using System; using System;
using System.IO;
using System.Windows.Forms;
using ICSharpCode.Core;
using ICSharpCode.Profiler.AddIn.Views;
using ICSharpCode.Profiler.Controller.Data;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
using Microsoft.Build.BuildEngine;
using System.Windows.Interop; using System.Windows.Interop;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.Profiler.AddIn.Commands namespace ICSharpCode.Profiler.AddIn.Commands
{ {

30
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Dialogs/ProfilerControlWindow.xaml

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<Window
x:Class="ICSharpCode.Profiler.AddIn.Dialogs.ProfilerControlWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sd="http://icsharpcode.net/sharpdevelop/core"
Title="{sd:Localize AddIns.Profiler.ProfilerControlWindow.Title}"
WindowStyle="ToolWindow" Closing="WindowClosing"
Topmost="True"
Height="60"
Width="170">
<Grid>
<Grid.RowDefinitions>
<RowDefinition
Height="*" />
</Grid.RowDefinitions>
<ToolBar
Grid.Column="0"
Grid.Row="0"
HorizontalAlignment="Left"
VerticalAlignment="Stretch">
<ToggleButton
Content="CollectData"
x:Name="collectData"
Checked="CollectDataChecked"
Unchecked="CollectDataUnchecked" />
<Button
Content="Shutdown"
x:Name="shutdown"
Click="ShutdownClick" />
</ToolBar>
</Grid>
</Window>

66
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Dialogs/ProfilerControlWindow.xaml.cs

@ -0,0 +1,66 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="siegfriedpammer@gmail.com"/>
// <version>$Revision$</version>
// </file>
using ICSharpCode.Core;
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.Profiler.Controller;
namespace ICSharpCode.Profiler.AddIn.Dialogs
{
/// <summary>
/// Interaction logic for ProfilerControlWindow.xaml
/// </summary>
public partial class ProfilerControlWindow : Window
{
ProfilerRunner runner;
public bool AllowClose { get; set; }
public ProfilerControlWindow(ProfilerRunner runner)
{
InitializeComponent();
this.runner = runner;
this.collectData.IsChecked = runner.Profiler.ProfilerOptions.EnableDCAtStart;
}
void CollectDataChecked(object sender, RoutedEventArgs e)
{
try {
this.runner.Profiler.EnableDataCollection();
} catch (Exception ex) {
MessageService.ShowError(ex);
}
}
void CollectDataUnchecked(object sender, RoutedEventArgs e)
{
try {
this.runner.Profiler.DisableDataCollection();
} catch (Exception ex) {
MessageService.ShowError(ex);
}
}
void ShutdownClick(object sender, RoutedEventArgs e)
{
this.AllowClose = true;
this.runner.Stop();
}
void WindowClosing(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = !AllowClose;
}
}
}

29
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/OptionsPanels/General.cs

@ -14,6 +14,7 @@ using ICSharpCode.Core;
using ICSharpCode.Profiler.Controller; using ICSharpCode.Profiler.Controller;
using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using System.Windows.Threading;
namespace ICSharpCode.Profiler.AddIn.OptionsPanels namespace ICSharpCode.Profiler.AddIn.OptionsPanels
{ {
@ -36,28 +37,42 @@ namespace ICSharpCode.Profiler.AddIn.OptionsPanels
public override void LoadPanelContents() public override void LoadPanelContents()
{ {
panel.SetOptionValue<bool>("EnableDC", !properties.Get("EnableDC", true)); try {
panel.SetOptionValue<double>("SharedMemorySize", properties.Get("SharedMemorySize", ProfilerOptions.SHARED_MEMORY_SIZE) / 1024 / 1024); panel.SetOptionValue("EnableDC", !properties.Get("EnableDC", true));
panel.SetOptionValue<bool>("DoNotProfileNetInternals", properties.Get("DoNotProfileNetInternals", false)); panel.SetOptionValue("SharedMemorySize", properties.Get("SharedMemorySize", ProfilerOptions.DefaultSharedMemorySize) / 1024 / 1024);
panel.SetOptionValue<bool>("CombineRecursiveFunction", properties.Get("CombineRecursiveFunction", false)); panel.SetOptionValue("DoNotProfileNetInternals", properties.Get("DoNotProfileNetInternals", false));
panel.SetOptionValue("CombineRecursiveFunction", properties.Get("CombineRecursiveFunction", false));
panel.SetOptionValue("EnableDCAtStart", properties.Get("EnableDCAtStart", true));
base.LoadPanelContents(); base.LoadPanelContents();
} catch (Exception e) {
MessageService.ShowError(e);
}
} }
public override bool StorePanelContents() public override bool StorePanelContents()
{ {
try {
properties.Set("EnableDC", !panel.GetOptionValue<bool>("EnableDC")); properties.Set("EnableDC", !panel.GetOptionValue<bool>("EnableDC"));
properties.Set("SharedMemorySize", (int)panel.GetOptionValue<double>("SharedMemorySize") * 1024 * 1024); properties.Set("SharedMemorySize", (int)panel.GetOptionValue<double>("SharedMemorySize") * 1024 * 1024);
properties.Set("DoNotProfileNetInternals", panel.GetOptionValue<bool>("DoNotProfileNetInternals")); properties.Set("DoNotProfileNetInternals", panel.GetOptionValue<bool>("DoNotProfileNetInternals"));
properties.Set("CombineRecursiveFunction", panel.GetOptionValue<bool>("CombineRecursiveFunction")); properties.Set("CombineRecursiveFunction", panel.GetOptionValue<bool>("CombineRecursiveFunction"));
properties.Set("EnableDCAtStart", panel.GetOptionValue<bool>("EnableDCAtStart"));
return base.StorePanelContents(); return base.StorePanelContents();
} catch (Exception e) {
MessageService.ShowError(e);
}
return false;
} }
public static ProfilerOptions CreateProfilerOptions() public static ProfilerOptions CreateProfilerOptions()
{ {
return new ProfilerOptions(properties.Get("EnableDC", true), return new ProfilerOptions(
properties.Get("SharedMemorySize", ProfilerOptions.SHARED_MEMORY_SIZE), properties.Get("EnableDC", true),
properties.Get("SharedMemorySize", ProfilerOptions.DefaultSharedMemorySize),
properties.Get("DoNotProfileNetInternals", false), properties.Get("DoNotProfileNetInternals", false),
properties.Get("CombineRecursiveFunction", false) properties.Get("CombineRecursiveFunction", false),
properties.Get("EnableDCAtStart", true)
); );
} }
} }

63
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/OptionsPanels/GeneralOptionsPanel.xaml

@ -1,16 +1,51 @@
<UserControl x:Class="ICSharpCode.Profiler.AddIn.OptionsPanels.GeneralOptionsPanel" <?xml version="1.0" encoding="utf-8"?>
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" <UserControl
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="418" Height="300"> x:Class="ICSharpCode.Profiler.AddIn.OptionsPanels.GeneralOptionsPanel" xmlns:sd="http://icsharpcode.net/sharpdevelop/core" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid> <StackPanel
<GroupBox Header="Data Collection" Margin="0,0,0,0" Name="groupBox1"> Orientation="Vertical">
<Grid> <GroupBox
<CheckBox Height="14" Margin="6,6,6,0" Name="chkEnableDC" VerticalAlignment="Top">Only collect data at the end of the session.</CheckBox> Header="{sd:Localize AddIns.Profiler.Options.General.DataCollection.Header}">
<Slider Margin="170,26,94,0" Name="slSharedMemorySize" IsDirectionReversed="False" TickPlacement="Both" Minimum="64" Maximum="512" TickFrequency="64" SmallChange="64" LargeChange="128" IsSnapToTickEnabled="True" Height="34" VerticalAlignment="Top" /> <StackPanel
<Label Margin="1,26,0,0" Name="label1" Height="24" HorizontalAlignment="Left" VerticalAlignment="Top" Width="163">Size of temporary storage file:</Label> Orientation="Vertical">
<TextBlock HorizontalAlignment="Right" Margin="0,34,38,0" Width="50" Text="{Binding Value, ElementName=slSharedMemorySize, StringFormat=\{0\} MB}" Height="16" VerticalAlignment="Top" /> <CheckBox Margin="3"
<CheckBox Margin="6,66,6,0" Name="chkDoNotProfileNetInternals" Height="15" VerticalAlignment="Top">Do not profile .NET internal calls.</CheckBox> Name="chkEnableDC"
<CheckBox Margin="6,87,6,0" Name="chkCombineRecursiveCalls" Height="16.723" VerticalAlignment="Top">Combine recursive calls.</CheckBox> VerticalAlignment="Top"
</Grid> Content="{sd:Localize AddIns.Profiler.Options.General.DataCollection.EnableDC}" />
<CheckBox Margin="3"
Name="chkEnableDCAtStartup"
VerticalAlignment="Top"
Content="{sd:Localize AddIns.Profiler.Options.General.DataCollection.EnableDCAtStartup}" />
<StackPanel Margin="3"
Orientation="Horizontal">
<Label Margin="3"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Content="{sd:Localize AddIns.Profiler.Options.General.DataCollection.SizeOfStorageDescription}" />
<Slider Margin="3" Width="150"
Name="slSharedMemorySize"
IsDirectionReversed="False"
TickPlacement="Both"
Minimum="64"
Maximum="512"
TickFrequency="64"
SmallChange="64"
LargeChange="128"
IsSnapToTickEnabled="True"
VerticalAlignment="Top" />
<TextBlock Margin="3"
HorizontalAlignment="Right"
Text="{Binding Value, ElementName=slSharedMemorySize, StringFormat=\{0\} MB}"
VerticalAlignment="Top" />
</StackPanel>
<CheckBox Margin="3"
Name="chkDoNotProfileNetInternals"
VerticalAlignment="Top"
Content="{sd:Localize AddIns.Profiler.Options.General.DataCollection.DoNotProfileNetInternals}" />
<CheckBox Margin="3"
Name="chkCombineRecursiveCalls"
VerticalAlignment="Top"
Content="{sd:Localize AddIns.Profiler.Options.General.DataCollection.CombineRecursiveCalls}" />
</StackPanel>
</GroupBox> </GroupBox>
</Grid> </StackPanel>
</UserControl> </UserControl>

10
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/OptionsPanels/GeneralOptionsPanel.xaml.cs

@ -28,7 +28,7 @@ namespace ICSharpCode.Profiler.AddIn.OptionsPanels
public T GetOptionValue<T>(string name) public T GetOptionValue<T>(string name)
{ {
object o; object o = null;
switch (name) { switch (name) {
case "SharedMemorySize": case "SharedMemorySize":
@ -43,6 +43,9 @@ namespace ICSharpCode.Profiler.AddIn.OptionsPanels
case "CombineRecursiveFunction": case "CombineRecursiveFunction":
o = this.chkCombineRecursiveCalls.IsChecked; o = this.chkCombineRecursiveCalls.IsChecked;
break; break;
case "EnableDCAtStart":
o = this.chkEnableDCAtStartup.IsChecked;
break;
default: default:
throw new NotSupportedException("value '" + name + "' is not supported!"); throw new NotSupportedException("value '" + name + "' is not supported!");
} }
@ -56,7 +59,7 @@ namespace ICSharpCode.Profiler.AddIn.OptionsPanels
switch (name) { switch (name) {
case "SharedMemorySize": case "SharedMemorySize":
this.slSharedMemorySize.Value = (double)o; this.slSharedMemorySize.Value = (int)o;
break; break;
case "EnableDC": case "EnableDC":
this.chkEnableDC.IsChecked = (bool)o; this.chkEnableDC.IsChecked = (bool)o;
@ -67,6 +70,9 @@ namespace ICSharpCode.Profiler.AddIn.OptionsPanels
case "CombineRecursiveFunction": case "CombineRecursiveFunction":
this.chkCombineRecursiveCalls.IsChecked = (bool)o; this.chkCombineRecursiveCalls.IsChecked = (bool)o;
break; break;
case "EnableDCAtStart":
this.chkEnableDCAtStartup.IsChecked = (bool)o;
break;
default: default:
throw new NotSupportedException("value '" + name + "' is not supported!"); throw new NotSupportedException("value '" + name + "' is not supported!");
} }

12
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/ProfilerRunner.cs

@ -7,12 +7,17 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.Profiler.AddIn.Dialogs;
using ICSharpCode.Profiler.AddIn.OptionsPanels; using ICSharpCode.Profiler.AddIn.OptionsPanels;
using ICSharpCode.Profiler.Controller.Data; using ICSharpCode.Profiler.Controller.Data;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project; using ICSharpCode.SharpDevelop.Project;
using System.IO;
namespace ICSharpCode.Profiler.AddIn namespace ICSharpCode.Profiler.AddIn
{ {
@ -22,6 +27,7 @@ namespace ICSharpCode.Profiler.AddIn
public class ProfilerRunner public class ProfilerRunner
{ {
public event EventHandler RunFinished; public event EventHandler RunFinished;
ProfilerControlWindow controlWindow;
protected virtual void OnRunFinished(EventArgs e) protected virtual void OnRunFinished(EventArgs e)
{ {
@ -80,6 +86,8 @@ namespace ICSharpCode.Profiler.AddIn
{ {
using (AsynchronousWaitDialog dlg = AsynchronousWaitDialog.ShowWaitDialog("Preparing for analysis", true)) { using (AsynchronousWaitDialog dlg = AsynchronousWaitDialog.ShowWaitDialog("Preparing for analysis", true)) {
profiler.Dispose(); profiler.Dispose();
WorkbenchSingleton.SafeThreadAsyncCall(() => { controlWindow.AllowClose = true; this.controlWindow.Close(); });
if (database != null) { if (database != null) {
database.WriteTo(writer, progress => !dlg.IsCancelled); database.WriteTo(writer, progress => !dlg.IsCancelled);
writer.Close(); writer.Close();
@ -96,7 +104,9 @@ namespace ICSharpCode.Profiler.AddIn
public void Run() public void Run()
{ {
WorkbenchSingleton.Workbench.GetPad(typeof(CompilerMessageView)).BringPadToFront(); WorkbenchSingleton.Workbench.GetPad(typeof(CompilerMessageView)).BringPadToFront();
this.controlWindow = new ProfilerControlWindow(this);
profiler.Start(); profiler.Start();
this.controlWindow.Show();
} }
public void Stop() public void Stop()

7
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Views/ProfilerView.xaml.cs

@ -29,7 +29,7 @@ namespace ICSharpCode.Profiler.AddIn.Views
this.timeLine.IsEnabled = true; this.timeLine.IsEnabled = true;
this.timeLine.ValuesList.Clear(); this.timeLine.ValuesList.Clear();
this.timeLine.ValuesList.AddRange(this.provider.DataSets.Select(i => i.CpuUsage / 100)); this.timeLine.ValuesList.AddRange(this.provider.DataSets.Select(i => new TimeLineInfo() { value = i.CpuUsage / 100, displayMarker = i.IsFirst }));
this.timeLine.SelectedStartIndex = 0; this.timeLine.SelectedStartIndex = 0;
this.timeLine.SelectedEndIndex = this.timeLine.ValuesList.Count; this.timeLine.SelectedEndIndex = this.timeLine.ValuesList.Count;
@ -98,11 +98,14 @@ namespace ICSharpCode.Profiler.AddIn.Views
void UpdateErrorList(IEnumerable<CompilerError> errors) void UpdateErrorList(IEnumerable<CompilerError> errors)
{ {
Dispatcher.Invoke( Dispatcher.Invoke(
(Action)(
() => { () => {
WorkbenchSingleton.Workbench.GetPad(typeof(ErrorListPad)).BringPadToFront(); WorkbenchSingleton.Workbench.GetPad(typeof(ErrorListPad)).BringPadToFront();
TaskService.ClearExceptCommentTasks(); TaskService.ClearExceptCommentTasks();
TaskService.AddRange(errors.Select(error => new Task("", error.ErrorText, error.Column, error.Line, (error.IsWarning) ? TaskType.Warning : TaskType.Error))); TaskService.AddRange(errors.Select(error => new Task("", error.ErrorText, error.Column, error.Line, (error.IsWarning) ? TaskType.Warning : TaskType.Error)));
}); }
)
);
} }
void tabView_SelectionChanged(object sender, SelectionChangedEventArgs e) void tabView_SelectionChanged(object sender, SelectionChangedEventArgs e)

2
src/AddIns/Misc/Profiler/Frontend/Controls/CallTreeNodeViewModel.cs

@ -135,7 +135,7 @@ namespace ICSharpCode.Profiler.Controls
{ {
if (level == 0) if (level == 0)
return null; // no tooltip for root return null; // no tooltip for root
if (level == 1) if (node.IsThread)
return Name; return Name;
TextBlock text = new TextBlock { TextBlock text = new TextBlock {

2
src/AddIns/Misc/Profiler/Frontend/Controls/Controls.csproj

@ -61,6 +61,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="CallTreeNodeViewModel.cs" /> <Compile Include="CallTreeNodeViewModel.cs" />
<Compile Include="ControlsTranslation.cs" />
<Compile Include="EventLine.cs" /> <Compile Include="EventLine.cs" />
<Compile Include="ExtendedTimeLineControl.xaml.cs"> <Compile Include="ExtendedTimeLineControl.xaml.cs">
<DependentUpon>ExtendedTimeLineControl.xaml</DependentUpon> <DependentUpon>ExtendedTimeLineControl.xaml</DependentUpon>
@ -98,6 +99,7 @@
<ProjectReference Include="..\..\Controller\Controller.csproj"> <ProjectReference Include="..\..\Controller\Controller.csproj">
<Project>{72FFB35A-C9E2-4A31-B4FA-E3E3E28DED5F}</Project> <Project>{72FFB35A-C9E2-4A31-B4FA-E3E3E28DED5F}</Project>
<Name>Controller</Name> <Name>Controller</Name>
<Private>False</Private>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
</Project> </Project>

22
src/AddIns/Misc/Profiler/Frontend/Controls/ControlsTranslation.cs

@ -0,0 +1,22 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="siegfriedpammer@gmail.com"/>
// <version>$Revision$</version>
// </file>
using System;
namespace ICSharpCode.Profiler.Controls
{
/// <summary>
/// Description of ControlsTranslation.
/// </summary>
public class ControlsTranslation
{
public virtual string WaitBarText {
get {
return "Refreshing view, please wait ...";
}
}
}
}

6
src/AddIns/Misc/Profiler/Frontend/Controls/QueryView.xaml.cs

@ -69,6 +69,8 @@ namespace ICSharpCode.Profiler.Controls
set { SetValue(ShowQueryItemsProperty, value); } set { SetValue(ShowQueryItemsProperty, value); }
get { return (bool)GetValue(ShowQueryItemsProperty); } get { return (bool)GetValue(ShowQueryItemsProperty); }
} }
public ControlsTranslation Translation { get; set; }
#endregion #endregion
void txtSearchKeyDown(object sender, KeyEventArgs e) void txtSearchKeyDown(object sender, KeyEventArgs e)
@ -82,7 +84,7 @@ namespace ICSharpCode.Profiler.Controls
AdornerLayer layer = AdornerLayer.GetAdornerLayer(this); AdornerLayer layer = AdornerLayer.GetAdornerLayer(this);
OverlayAdorner ad = new OverlayAdorner(this); OverlayAdorner ad = new OverlayAdorner(this);
WaitBar bar = new WaitBar("Refreshing view, please wait ..."); WaitBar bar = new WaitBar();
ad.Child = bar; ad.Child = bar;
layer.Add(ad); layer.Add(ad);
@ -155,6 +157,8 @@ namespace ICSharpCode.Profiler.Controls
this.task = new SingleTask(this.Dispatcher); this.task = new SingleTask(this.Dispatcher);
this.searchTask = new SingleTask(this.Dispatcher); this.searchTask = new SingleTask(this.Dispatcher);
this.Translation = new ControlsTranslation();
this.treeView.SizeChanged += delegate(object sender, SizeChangedEventArgs e) { this.treeView.SizeChanged += delegate(object sender, SizeChangedEventArgs e) {
if (e.NewSize.Width > 0 && e.PreviousSize.Width > 0 && if (e.NewSize.Width > 0 && e.PreviousSize.Width > 0 &&
(nameColumn.Width + (e.NewSize.Width - e.PreviousSize.Width)) > 0) { (nameColumn.Width + (e.NewSize.Width - e.PreviousSize.Width)) > 0) {

31
src/AddIns/Misc/Profiler/Frontend/Controls/TimeLineControl.cs

@ -16,9 +16,14 @@ using System.Windows.Media;
namespace ICSharpCode.Profiler.Controls namespace ICSharpCode.Profiler.Controls
{ {
public struct TimeLineInfo {
public double value;
public bool displayMarker;
}
public class TimeLineControl : FrameworkElement public class TimeLineControl : FrameworkElement
{ {
ObservableCollection<double> valuesList; ObservableCollection<TimeLineInfo> valuesList;
int selectedStartIndex, selectedEndIndex; int selectedStartIndex, selectedEndIndex;
double pieceWidth; double pieceWidth;
@ -54,14 +59,14 @@ namespace ICSharpCode.Profiler.Controls
} }
} }
public ObservableCollection<double> ValuesList public ObservableCollection<TimeLineInfo> ValuesList
{ {
get { return valuesList; } get { return valuesList; }
} }
public TimeLineControl() public TimeLineControl()
{ {
this.valuesList = new ObservableCollection<double>(); this.valuesList = new ObservableCollection<TimeLineInfo>();
this.valuesList.CollectionChanged += delegate { this.InvalidateMeasure(); this.InvalidateVisual(); }; this.valuesList.CollectionChanged += delegate { this.InvalidateMeasure(); this.InvalidateVisual(); };
} }
@ -94,7 +99,7 @@ namespace ICSharpCode.Profiler.Controls
for (int i = 0; i < this.valuesList.Count; i++) for (int i = 0; i < this.valuesList.Count; i++)
{ {
double x = this.pieceWidth / 2.0 + this.pieceWidth * i + offset; double x = this.pieceWidth / 2.0 + this.pieceWidth * i + offset;
double y = this.RenderSize.Height - this.valuesList[i] * (this.RenderSize.Height - offset) - offset; double y = this.RenderSize.Height - this.valuesList[i].value * (this.RenderSize.Height - offset) - offset;
points.Add(new Point(x, y)); points.Add(new Point(x, y));
@ -115,12 +120,28 @@ namespace ICSharpCode.Profiler.Controls
drawingContext.DrawLine(new Pen(Brushes.Black, 1), new Point(offset / 2, this.RenderSize.Height - offset / 2), new Point(this.RenderSize.Width - offset, this.RenderSize.Height - offset / 2)); drawingContext.DrawLine(new Pen(Brushes.Black, 1), new Point(offset / 2, this.RenderSize.Height - offset / 2), new Point(this.RenderSize.Width - offset, this.RenderSize.Height - offset / 2));
drawingContext.DrawLine(new Pen(Brushes.Black, 1), new Point(offset / 2, 0), new Point(offset / 2, this.RenderSize.Height - offset / 2)); drawingContext.DrawLine(new Pen(Brushes.Black, 1), new Point(offset / 2, 0), new Point(offset / 2, this.RenderSize.Height - offset / 2));
for (int i = 0; i < this.valuesList.Count; i++) var p = new Pen(Brushes.DarkRed, 2);
for (int i = 0; i < this.valuesList.Count; i++) {
drawingContext.DrawLine(new Pen(Brushes.Black, 1), drawingContext.DrawLine(new Pen(Brushes.Black, 1),
new Point(offset + pieceWidth / 2 + pieceWidth * i, this.RenderSize.Height - offset / 4), new Point(offset + pieceWidth / 2 + pieceWidth * i, this.RenderSize.Height - offset / 4),
new Point(offset + pieceWidth / 2 + pieceWidth * i, this.RenderSize.Height - (offset / 4 * 3 + 3))); new Point(offset + pieceWidth / 2 + pieceWidth * i, this.RenderSize.Height - (offset / 4 * 3 + 3)));
if (this.valuesList[i].displayMarker) {
drawingContext.DrawLine(p, new Point(offset + pieceWidth * i, 0),
new Point(offset + pieceWidth * i, this.RenderSize.Height - offset));
}
}
drawingContext.DrawGeometry(b, new Pen(b, 3), geometry); drawingContext.DrawGeometry(b, new Pen(b, 3), geometry);
for (int i = 0; i < this.valuesList.Count; i++) {
if (this.valuesList[i].displayMarker)
drawingContext.DrawLine(p, new Point(offset + pieceWidth * i, 0),
new Point(offset + pieceWidth * i, this.RenderSize.Height - offset));
}
drawingContext.DrawRectangle( drawingContext.DrawRectangle(
new SolidColorBrush(Color.FromArgb(64, Colors.CornflowerBlue.R, new SolidColorBrush(Color.FromArgb(64, Colors.CornflowerBlue.R,
Colors.CornflowerBlue.G, Colors.CornflowerBlue.B)), Colors.CornflowerBlue.G, Colors.CornflowerBlue.B)),

4
src/Main/ICSharpCode.Core.Presentation/LocalizeExtension.cs

@ -24,7 +24,11 @@ namespace ICSharpCode.Core.Presentation
public override object ProvideValue(IServiceProvider serviceProvider) public override object ProvideValue(IServiceProvider serviceProvider)
{ {
try {
return ResourceService.GetString(key); return ResourceService.GetString(key);
} catch (ResourceNotFoundException) {
return "{Localize:" + key + "}";
}
} }
} }
} }

Loading…
Cancel
Save