Browse Source

- Bug fixes in Profiler and enhancements in GUI

- improved TaskListPad

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@4003 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Siegfried Pammer 17 years ago
parent
commit
59672ddadb
  1. 1
      src/AddIns/Misc/Profiler/Controller/Controller.csproj
  2. 1
      src/AddIns/Misc/Profiler/Controller/Data/IProfilingDataWriter.cs
  3. 20
      src/AddIns/Misc/Profiler/Controller/Data/PerformanceCounterDescriptor.cs
  4. 50
      src/AddIns/Misc/Profiler/Controller/Data/ProfilingDataSQLiteWriter.cs
  5. 37
      src/AddIns/Misc/Profiler/Controller/ExtensionMethods.cs
  6. 22
      src/AddIns/Misc/Profiler/Controller/Profiler.cs
  7. 6
      src/AddIns/Misc/Profiler/Controller/Queries/QueryCompiler.cs
  8. 17
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Commands/ProfileProject.cs
  9. 7
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Dialogs/ProfileExecutableForm.xaml.cs
  10. 2
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Views/ProfilerDisplayBinding.cs
  11. 6
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Views/ProfilerView.xaml.cs
  12. 11
      src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Views/WpfViewer.cs
  13. 37
      src/AddIns/Misc/Profiler/Frontend/Controls/CallTreeNodeViewModel.cs
  14. 6
      src/AddIns/Misc/Profiler/Frontend/Controls/Controls.csproj
  15. 28
      src/AddIns/Misc/Profiler/Frontend/Controls/EventLine.cs
  16. 48
      src/AddIns/Misc/Profiler/Frontend/Controls/ExtendedTimeLineControl.xaml
  17. 28
      src/AddIns/Misc/Profiler/Frontend/Controls/ExtendedTimeLineControl.xaml.cs
  18. 66
      src/AddIns/Misc/Profiler/Frontend/Controls/QueryView.xaml.cs
  19. 1
      src/AddIns/Misc/Profiler/Frontend/Controls/RingDiagramControl.cs
  20. 5
      src/AddIns/Misc/Profiler/Frontend/Gui/Window1.xaml
  21. 18
      src/AddIns/Misc/Profiler/Frontend/Gui/Window1.xaml.cs
  22. 3
      src/AddIns/Misc/Profiler/Hook/Profiler.cpp
  23. 14
      src/AddIns/Misc/Profiler/Hook/ProfilerMetaData.cpp
  24. 1
      src/AddIns/Misc/Profiler/TODO.txt
  25. 9
      src/Main/Base/Project/Src/Gui/Pads/TaskList/TaskListPad.cs

1
src/AddIns/Misc/Profiler/Controller/Controller.csproj

@ -66,6 +66,7 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Data\PerformanceCounterDescriptor.cs" />
<Compile Include="Data\ProfilingDataProvider.cs" /> <Compile Include="Data\ProfilingDataProvider.cs" />
<Compile Include="Data\CallTreeNode.cs" /> <Compile Include="Data\CallTreeNode.cs" />
<Compile Include="Data\IProfilingDataSet.cs" /> <Compile Include="Data\IProfilingDataSet.cs" />

1
src/AddIns/Misc/Profiler/Controller/Data/IProfilingDataWriter.cs

@ -8,6 +8,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics;
namespace ICSharpCode.Profiler.Controller.Data namespace ICSharpCode.Profiler.Controller.Data
{ {

20
src/AddIns/Misc/Profiler/Controller/Data/PerformanceCounterDescriptor.cs

@ -0,0 +1,20 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
// <version>$Revision$</version>
// </file>
using System;
namespace ICSharpCode.Profiler.Controller.Data
{
public class PerformanceCounterDescriptor
{
public PerformanceCounterDescriptor()
{
}
}
}

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

@ -142,31 +142,47 @@ namespace ICSharpCode.Profiler.Controller.Data
cmd.CommandText = @" cmd.CommandText = @"
CREATE TABLE NameMapping( CREATE TABLE NameMapping(
id INTEGER NOT NULL PRIMARY KEY, id INTEGER NOT NULL PRIMARY KEY,
returntype VARCHAR2(100) NOT NULL, returntype VARCHAR2(100) NOT NULL,
name VARCHAR2(255) NOT NULL, name VARCHAR2(255) NOT NULL,
parameters VARCHAR2(1000) NOT NULL); parameters VARCHAR2(1000) NOT NULL
);
CREATE TABLE FunctionData( CREATE TABLE FunctionData(
datasetid INTEGER NOT NULL, datasetid INTEGER NOT NULL,
id INTEGER NOT NULL PRIMARY KEY, id INTEGER NOT NULL PRIMARY KEY,
endid INTEGER NOT NULL, endid INTEGER NOT NULL,
parentid INTEGER NOT NULL, parentid INTEGER NOT NULL,
nameid INTEGER NOT NULL, nameid INTEGER NOT NULL,
timespent INT8 NOT NULL, timespent INT8 NOT NULL,
isactiveatstart INTEGER NOT NULL, isactiveatstart INTEGER NOT NULL,
callcount INTEGER NOT NULL); callcount INTEGER NOT NULL
);
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,
rootid INTEGER NOT NULL); rootid INTEGER NOT NULL
);
CREATE TABLE Properties( CREATE TABLE Properties(
name VARCHAR2(100) NOT NULL PRIMARY KEY, name VARCHAR2(100) NOT NULL PRIMARY KEY,
value VARCHAR2(100) NOT NULL); value VARCHAR2(100) NOT NULL
);
INSERT INTO Properties(name, value) VALUES('version', '1.0'); INSERT INTO Properties(name, value) VALUES('version', '1.0');
CREATE TABLE PerformanceCounter(
id INTEGER NOT NULL PRIMARY KEY,
name VARCHAR2(100) NOT NULL
);
CREATE TABLE CounterData(
datasetid INTEGER NOT NULL,
counterid INTEGER NOT NULL,
value INTEGER NOT NULL,
CONSTRAINT PK_couterdata PRIMARY KEY (datasetid, counterid)
);
"; ";
cmd.ExecuteNonQuery(); cmd.ExecuteNonQuery();

37
src/AddIns/Misc/Profiler/Controller/ExtensionMethods.cs

@ -133,5 +133,42 @@ namespace ICSharpCode.Profiler.Controller
} }
return result; return result;
} }
public static bool Search(this CallTreeNode item, string search, bool recursive, out CallTreeNode result)
{
if (recursive)
return SearchRecursive(search, item, out result);
else
return SearchInternal(item, search, out result);
}
static bool SearchInternal(CallTreeNode item, string search, out CallTreeNode result)
{
foreach (var child in item.Children) {
if (child.Name.IndexOf(search, StringComparison.Ordinal) > -1) {
result = item;
return true;
}
}
result = null;
return false;
}
static bool SearchRecursive(string search, CallTreeNode current, out CallTreeNode result)
{
foreach (var item in current.Children) {
if (item.Name.IndexOf(search, StringComparison.Ordinal) > -1) {
result = item;
return true;
}
if (SearchRecursive(search, item, out result))
return true;
}
result = null;
return false;
}
} }
} }

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

@ -97,6 +97,7 @@ namespace ICSharpCode.Profiler.Controller
EventWaitHandle accessEventHandle; EventWaitHandle accessEventHandle;
Thread logger; Thread logger;
Thread dataCollector; Thread dataCollector;
Thread counterCollector;
UnmanagedCircularBuffer nativeToManagedBuffer; UnmanagedCircularBuffer nativeToManagedBuffer;
IProfilingDataWriter dataWriter; IProfilingDataWriter dataWriter;
@ -259,6 +260,10 @@ namespace ICSharpCode.Profiler.Controller
this.dataCollector = new Thread(new ThreadStart(DataCollection)); this.dataCollector = new Thread(new ThreadStart(DataCollection));
this.dataCollector.Name = "DataCollector"; this.dataCollector.Name = "DataCollector";
this.dataCollector.IsBackground = true; this.dataCollector.IsBackground = true;
this.counterCollector = new Thread(new ThreadStart(CounterCollection));
this.counterCollector.Name = "CounterCollector";
this.counterCollector.IsBackground = true;
} }
void InitializeHeader32() void InitializeHeader32()
@ -292,6 +297,11 @@ namespace ICSharpCode.Profiler.Controller
throw new ArgumentException("The Processor Frequency could not be read!"); throw new ArgumentException("The Processor Frequency could not be read!");
return freq; return freq;
} }
void CounterCollection()
{
}
void DataCollection() void DataCollection()
{ {
@ -499,8 +509,10 @@ namespace ICSharpCode.Profiler.Controller
this.logger.Start(nativeToManagedBuffer.CreateReadingStream()); this.logger.Start(nativeToManagedBuffer.CreateReadingStream());
// GC references currentSession // GC references currentSession
if (this.profilerOptions.EnableDC) if (this.profilerOptions.EnableDC) {
this.dataCollector.Start(); this.dataCollector.Start();
this.counterCollector.Start();
}
OnSessionStarted(EventArgs.Empty); OnSessionStarted(EventArgs.Empty);
return profilee; return profilee;
@ -570,8 +582,10 @@ namespace ICSharpCode.Profiler.Controller
Debug.WriteLine("Joining logger thread..."); Debug.WriteLine("Joining logger thread...");
this.logger.Join(); this.logger.Join();
Debug.WriteLine("Logger thread joined!"); Debug.WriteLine("Logger thread joined!");
if (this.profilerOptions.EnableDC) if (this.profilerOptions.EnableDC) {
this.dataCollector.Join(); this.dataCollector.Join();
this.counterCollector.Join();
}
// Take last shot // Take last shot
if (this.is64Bit) if (this.is64Bit)
@ -769,6 +783,10 @@ namespace ICSharpCode.Profiler.Controller
if (dataCollector != null && dataCollector.IsAlive) { if (dataCollector != null && dataCollector.IsAlive) {
this.dataCollector.Join(); this.dataCollector.Join();
} }
if (counterCollector != null && counterCollector.IsAlive) {
this.counterCollector.Join();
}
this.fullView.Dispose(); this.fullView.Dispose();
this.file.Close(); this.file.Close();

6
src/AddIns/Misc/Profiler/Controller/Queries/QueryCompiler.cs

@ -55,7 +55,7 @@ namespace ICSharpCode.Profiler.Controller.Queries
/// Creates a new instance of the QueryCompiler. /// Creates a new instance of the QueryCompiler.
/// </summary> /// </summary>
/// <param name="reporter">A delegate to report any errors to an upper layer.</param> /// <param name="reporter">A delegate to report any errors to an upper layer.</param>
/// <param name="query">The query to c</param> /// <param name="query">The query to compile.</param>
public QueryCompiler(ErrorReporter reporter, string query) public QueryCompiler(ErrorReporter reporter, string query)
{ {
if (reporter == null) if (reporter == null)
@ -100,11 +100,13 @@ namespace ICSharpCode.Profiler.Controller.Queries
/// <returns>The result of the query.</returns> /// <returns>The result of the query.</returns>
public IEnumerable<CallTreeNode> ExecuteQuery(ProfilingDataProvider provider, int startIndex, int endIndex) public IEnumerable<CallTreeNode> ExecuteQuery(ProfilingDataProvider provider, int startIndex, int endIndex)
{ {
if (provider == null)
throw new ArgumentNullException("provider");
Assembly assembly; Assembly assembly;
lock (queryCache) lock (queryCache)
assembly = queryCache[this.currentQuery]; assembly = queryCache[this.currentQuery];
QueryBase queryContainer = assembly.CreateInstance("Query") as QueryBase; QueryBase queryContainer = assembly.CreateInstance("Query") as QueryBase;
CallTreeNode root = provider.GetRoot(startIndex, endIndex);
queryContainer.Provider = provider; queryContainer.Provider = provider;
queryContainer.StartDataSetIndex = startIndex; queryContainer.StartDataSetIndex = startIndex;

17
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Commands/ProfileProject.cs

@ -47,12 +47,9 @@ namespace ICSharpCode.Profiler.AddIn.Commands
if (runner != null) { if (runner != null) {
runner.RunFinished += delegate { runner.RunFinished += delegate {
string title = Path.GetFileName(path);
ProfilingDataProvider provider = new ProfilingDataSQLiteProvider(path);
Action updater = () => { Action updater = () => {
WorkbenchSingleton.Workbench.ShowView(new WpfViewer(provider, title)); FileService.OpenFile(path);
FileProjectItem file = new FileProjectItem(currentProj, ItemType.Content, "ProfilingSessions\\" + title); FileProjectItem file = new FileProjectItem(currentProj, ItemType.Content, "ProfilingSessions\\" + Path.GetFileName(path));
ProjectService.AddProjectItem(currentProj, file); ProjectService.AddProjectItem(currentProj, file);
ProjectBrowserPad.Instance.ProjectBrowserControl.RefreshView(); ProjectBrowserPad.Instance.ProjectBrowserControl.RefreshView();
currentProj.Save(); currentProj.Save();
@ -73,8 +70,14 @@ namespace ICSharpCode.Profiler.AddIn.Commands
return null; return null;
if (!currentProj.IsStartable) { if (!currentProj.IsStartable) {
MessageService.ShowError("This project cannot be started, please select a startable project for Profiling!"); if (MessageService.AskQuestion("This project cannot be started. Do you want to profile the solution's StartUp project instead?")) {
return null; currentProj = ProjectService.OpenSolution.StartupProject as AbstractProject;
if (currentProj == null) {
MessageService.ShowError("No startable project was found. Aborting ...");
return null;
}
} else
return null;
} }
if (!File.Exists(currentProj.OutputAssemblyFullPath)) { if (!File.Exists(currentProj.OutputAssemblyFullPath)) {
MessageService.ShowError("This project cannot be started because the executable file was not found, " + MessageService.ShowError("This project cannot be started because the executable file was not found, " +

7
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Dialogs/ProfileExecutableForm.xaml.cs

@ -1,4 +1,4 @@
using ICSharpCode.Profiler.Controller; using ICSharpCode.SharpDevelop;
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
@ -7,6 +7,7 @@ using System.Windows;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.Profiler.AddIn.OptionsPanels; using ICSharpCode.Profiler.AddIn.OptionsPanels;
using ICSharpCode.Profiler.AddIn.Views; using ICSharpCode.Profiler.AddIn.Views;
using ICSharpCode.Profiler.Controller;
using ICSharpCode.Profiler.Controller.Data; using ICSharpCode.Profiler.Controller.Data;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using Microsoft.Win32; using Microsoft.Win32;
@ -48,9 +49,7 @@ namespace ICSharpCode.Profiler.AddIn.Dialogs
if (runner != null) { if (runner != null) {
runner.RunFinished += delegate { runner.RunFinished += delegate {
string title = Path.GetFileName(outputPath); WorkbenchSingleton.SafeThreadCall(() => FileService.OpenFile(outputPath));
ProfilingDataProvider provider = new ProfilingDataSQLiteProvider(outputPath);
WorkbenchSingleton.SafeThreadCall(() => WorkbenchSingleton.Workbench.ShowView(new WpfViewer(provider, title)));
}; };
runner.Run(); runner.Run();

2
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Views/ProfilerDisplayBinding.cs

@ -29,7 +29,7 @@ namespace ICSharpCode.Profiler.AddIn.Views
public ICSharpCode.SharpDevelop.Gui.IViewContent CreateContentForFile(OpenedFile file) public ICSharpCode.SharpDevelop.Gui.IViewContent CreateContentForFile(OpenedFile file)
{ {
return new WpfViewer(ProfilingDataSQLiteProvider.FromFile(file.FileName), Path.GetFileName(file.FileName)); return new WpfViewer(file);
} }
} }
} }

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

@ -173,8 +173,10 @@ namespace ICSharpCode.Profiler.AddIn.Views
view.CurrentQuery = query; view.CurrentQuery = query;
view.ShowQueryItems = true; view.ShowQueryItems = true;
//view.TreeViewContextMenu = ; view.ContextMenuOpening += delegate(object sender, ContextMenuEventArgs e) {
object source = (e.OriginalSource is Shape) ? e.OriginalSource : view;
MenuService.CreateContextMenu(source, "/AddIns/Profiler/QueryView/ContextMenu").IsOpen = true;
};
view.CurrentQueryChanged += delegate { ViewCurrentQueryChanged(header, view); }; view.CurrentQueryChanged += delegate { ViewCurrentQueryChanged(header, view); };
header.Text = title; header.Text = title;

11
src/AddIns/Misc/Profiler/Frontend/AddIn/Src/Views/WpfViewer.cs

@ -6,12 +6,14 @@
// </file> // </file>
using System; using System;
using System.IO;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Forms.Integration; using System.Windows.Forms.Integration;
using ICSharpCode.Core.Presentation;
using ICSharpCode.Profiler.Controller.Data; using ICSharpCode.Profiler.Controller.Data;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.Core.Presentation;
namespace ICSharpCode.Profiler.AddIn.Views namespace ICSharpCode.Profiler.AddIn.Views
{ {
@ -38,10 +40,11 @@ namespace ICSharpCode.Profiler.AddIn.Views
/// <summary> /// <summary>
/// Creates a new WpfViewer object /// Creates a new WpfViewer object
/// </summary> /// </summary>
public WpfViewer(ProfilingDataProvider provider, string title) public WpfViewer(OpenedFile file)
{ {
this.provider = provider; this.Files.Add(file);
this.TabPageText = title; this.provider = ProfilingDataSQLiteProvider.FromFile(file.FileName);
this.TabPageText = Path.GetFileName(file.FileName);
this.TitleName = this.TabPageText; this.TitleName = this.TabPageText;
this.host = new SharpDevelopElementHost(dataView = new ProfilerView(this.provider)); this.host = new SharpDevelopElementHost(dataView = new ProfilerView(this.provider));
// HACK : Make host.Child visible // HACK : Make host.Child visible

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

@ -318,43 +318,6 @@ namespace ICSharpCode.Profiler.Controls
} }
} }
} }
public bool Search(string search, bool recursive, out CallTreeNodeViewModel result)
{
if (recursive)
return SearchRecursive(search, this, out result);
else
return SearchInternal(search, out result);
}
bool SearchInternal(string search, out CallTreeNodeViewModel result)
{
foreach (CallTreeNodeViewModel item in this.Children) {
if (item.Name.IndexOf(search, StringComparison.Ordinal) > -1) {
result = item;
return true;
}
}
result = null;
return false;
}
bool SearchRecursive(string search, CallTreeNodeViewModel current, out CallTreeNodeViewModel result)
{
foreach (CallTreeNodeViewModel item in current.Children) {
if (item.Name.IndexOf(search, StringComparison.Ordinal) > -1) {
result = item;
return true;
}
if (SearchRecursive(search, item, out result))
return true;
}
result = null;
return false;
}
public string TimeSpent { public string TimeSpent {
get { get {

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

@ -61,6 +61,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="CallTreeNodeViewModel.cs" /> <Compile Include="CallTreeNodeViewModel.cs" />
<Compile Include="EventLine.cs" />
<Compile Include="ExtendedTimeLineControl.xaml.cs">
<DependentUpon>ExtendedTimeLineControl.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="SingleTask.cs" /> <Compile Include="SingleTask.cs" />
<Compile Include="CustomGridView.cs" /> <Compile Include="CustomGridView.cs" />
<Compile Include="ExtensionMethods.cs" /> <Compile Include="ExtensionMethods.cs" />
@ -85,6 +90,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Themes" /> <Folder Include="Themes" />
<Page Include="ExtendedTimeLineControl.xaml" />
<Page Include="QueryView.xaml" /> <Page Include="QueryView.xaml" />
<Page Include="Themes\Generic.xaml" /> <Page Include="Themes\Generic.xaml" />
<ProjectReference Include="..\..\Controller\Controller.csproj"> <ProjectReference Include="..\..\Controller\Controller.csproj">

28
src/AddIns/Misc/Profiler/Frontend/Controls/EventLine.cs

@ -0,0 +1,28 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Siegfried Pammer" email="sie_pam@gmx.at"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Windows.Controls;
namespace ICSharpCode.Profiler.Controls
{
/// <summary>
/// Description of EventLine.
/// </summary>
public class EventLine : Grid
{
public EventLine()
{
}
}
class EventItem
{
int dataSet;
}
}

48
src/AddIns/Misc/Profiler/Frontend/Controls/ExtendedTimeLineControl.xaml

@ -0,0 +1,48 @@
<UserControl x:Class="ICSharpCode.Profiler.Controls.ExtendedTimeLineControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:y="clr-namespace:ICSharpCode.Profiler.Controls">
<DockPanel>
<DockPanel Margin="3,0">
<TextBlock Text="Performance Counters" DockPanel.Dock="Top" />
<ListBox>
<ListBoxItem>Test1</ListBoxItem>
<ListBoxItem>Test2</ListBoxItem>
<ListBoxItem>Test3</ListBoxItem>
<ListBoxItem>Test4</ListBoxItem>
<ListBoxItem>Test5</ListBoxItem>
</ListBox>
</DockPanel>
<Grid Margin="3,0">
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="20" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Time" />
<TextBlock Grid.Row="1" Text="Events" />
<TextBlock Grid.Row="2" Text="Graph" />
</Grid>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled" Margin="3,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="20" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<TextBlock Text="Test" />
<TextBlock Text="a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaa" />
<TextBlock Text="a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaa" />
<TextBlock Text="a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaa" />
<TextBlock Text="a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaa" />
<TextBlock Text="a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaa" />
<TextBlock Text="a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaa" />
<TextBlock Text="a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaa" />
</StackPanel>
<y:TimeLineControl x:Name="t1" Grid.Row="1" />
<TextBlock Grid.Row="2" Text="Test" />
</Grid>
</ScrollViewer>
</DockPanel>
</UserControl>

28
src/AddIns/Misc/Profiler/Frontend/Controls/ExtendedTimeLineControl.xaml.cs

@ -0,0 +1,28 @@
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 System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace ICSharpCode.Profiler.Controls
{
/// <summary>
/// Interaction logic for ExtendedTimeLineControl.xaml
/// </summary>
public partial class ExtendedTimeLineControl : UserControl
{
public ExtendedTimeLineControl()
{
InitializeComponent();
}
}
}

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

@ -18,13 +18,15 @@ namespace ICSharpCode.Profiler.Controls
/// </summary> /// </summary>
public partial class QueryView : UserControl public partial class QueryView : UserControl
{ {
#region Properties
/// <remarks> /// <remarks>
/// Provider should only be changed once! /// Provider should only be changed once!
/// </remarks> /// </remarks>
public ProfilingDataProvider Provider { get; set; } public ProfilingDataProvider Provider { get; set; }
HierarchyList<CallTreeNodeViewModel> list; HierarchyList<CallTreeNodeViewModel> list;
CallTreeNodeViewModel searchRoot, oldSearchResult; CallTreeNodeViewModel oldSearchResult;
SingleTask task; SingleTask task;
SingleTask searchTask;
bool isQueryModifiable = true; bool isQueryModifiable = true;
@ -67,20 +69,49 @@ namespace ICSharpCode.Profiler.Controls
set { SetValue(ShowQueryItemsProperty, value); } set { SetValue(ShowQueryItemsProperty, value); }
get { return (bool)GetValue(ShowQueryItemsProperty); } get { return (bool)GetValue(ShowQueryItemsProperty); }
} }
#endregion
void txtSearchKeyDown(object sender, KeyEventArgs e) void txtSearchKeyDown(object sender, KeyEventArgs e)
{ {
if (!string.IsNullOrEmpty(txtSearch.Text) && list.Count > 0) { if (!string.IsNullOrEmpty(txtSearch.Text) && list.Count > 0) {
CallTreeNodeViewModel result; // searchTask.Cancel();
// TODO: should we perform search in background? // string text = txtSearch.Text;
// int start = this.RangeStart;
if (list.First().Search(txtSearch.Text, true, out result)) { // int end = this.RangeEnd;
result.IsSelected = true; // var provider = this.Provider;
if (oldSearchResult != null) //
oldSearchResult.IsSelected = false; // AdornerLayer layer = AdornerLayer.GetAdornerLayer(this);
oldSearchResult = result; // OverlayAdorner ad = new OverlayAdorner(this);
// WaitBar bar = new WaitBar("Refreshing view, please wait ...");
// ad.Child = bar;
// layer.Add(ad);
//
// searchTask.Execute(
// () => DoSearchInBackground(provider, start, end, text, true),
// result => SearchCompleted(result, layer, ad),
// delegate { layer.Remove(ad); });
}
}
static CallTreeNode DoSearchInBackground(ProfilingDataProvider provider, int startIndex, int endIndex, string text, bool recursive)
{
CallTreeNode result;
foreach (var item in provider.GetRoot(startIndex, endIndex).Children) {
if (item.Search(text, true, out result)) {
return result;
} }
} }
return null;
}
void SearchCompleted(CallTreeNode result, AdornerLayer layer, OverlayAdorner ad)
{
// var root = Provider.GetRoot(RangeStart, RangeEnd);
// result.IsSelected = true;
// if (oldSearchResult != null)
// oldSearchResult.IsSelected = false;
// oldSearchResult = result;
// layer.Remove(ad);
} }
public QueryView() public QueryView()
@ -89,6 +120,8 @@ namespace ICSharpCode.Profiler.Controls
this.IsVisibleChanged += delegate { this.ExecuteQuery(); }; this.IsVisibleChanged += delegate { this.ExecuteQuery(); };
this.DataContext = this; this.DataContext = this;
this.task = new SingleTask(this.Dispatcher); this.task = new SingleTask(this.Dispatcher);
this.searchTask = new SingleTask(this.Dispatcher);
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) {
@ -108,7 +141,6 @@ namespace ICSharpCode.Profiler.Controls
this.RangeStart = start; this.RangeStart = start;
this.RangeEnd = end; this.RangeEnd = end;
this.searchRoot = new CallTreeNodeViewModel(this.Provider.GetRoot(start, end), null);
this.Invalidate(); this.Invalidate();
this.InvalidateArrange(); this.InvalidateArrange();
} }
@ -122,7 +154,7 @@ namespace ICSharpCode.Profiler.Controls
void ExecuteQuery() void ExecuteQuery()
{ {
if (!this.isDirty) if (!this.isDirty || this.Provider == null)
return; return;
if (RangeStart > RangeEnd) { if (RangeStart > RangeEnd) {
@ -170,10 +202,14 @@ namespace ICSharpCode.Profiler.Controls
static HierarchyList<CallTreeNodeViewModel> LoadWorker(ProfilingDataProvider provider, QueryCompiler compiler, int rangeStart, int rangeEnd) static HierarchyList<CallTreeNodeViewModel> LoadWorker(ProfilingDataProvider provider, QueryCompiler compiler, int rangeStart, int rangeEnd)
{ {
if (compiler.Compile()) { try {
var data = compiler.ExecuteQuery(provider, rangeStart, rangeEnd - 1); if (compiler.Compile()) {
var nodes = data.Select(i => new CallTreeNodeViewModel(i, null)).ToList(); var data = compiler.ExecuteQuery(provider, rangeStart, rangeEnd - 1);
return new HierarchyList<CallTreeNodeViewModel>(nodes); var nodes = data.Select(i => new CallTreeNodeViewModel(i, null)).ToList();
return new HierarchyList<CallTreeNodeViewModel>(nodes);
}
} catch (ObjectDisposedException) {
return null;
} }
return null; return null;

1
src/AddIns/Misc/Profiler/Frontend/Controls/RingDiagramControl.cs

@ -196,7 +196,6 @@ namespace ICSharpCode.Profiler.Controls
return p; return p;
} }
} }
class PiePieceDescriptor class PiePieceDescriptor
{ {

5
src/AddIns/Misc/Profiler/Frontend/Gui/Window1.xaml

@ -13,9 +13,8 @@
<Button Height="23" HorizontalAlignment="Left" Margin="118,9,0,0" Name="btnStop" VerticalAlignment="Top" Width="111" Click="btnStop_Click">Stop and Shutdown</Button> <Button Height="23" HorizontalAlignment="Left" Margin="118,9,0,0" Name="btnStop" VerticalAlignment="Top" Width="111" Click="btnStop_Click">Stop and Shutdown</Button>
<TextBox Margin="10,39,12,4" Name="txtOutput" VerticalScrollBarVisibility="Visible" /> <TextBox Margin="10,39,12,4" Name="txtOutput" VerticalScrollBarVisibility="Visible" />
<GridSplitter Height="2" VerticalAlignment="Bottom" Grid.Row="1" /> <GridSplitter Height="2" VerticalAlignment="Bottom" Grid.Row="1" />
<ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled"> <!-- <y:TimeLineControl x:Name="timeLine" RangeChanged="timeLine_RangeChanged" /> -->
<y:TimeLineControl x:Name="timeLine" RangeChanged="timeLine_RangeChanged" /> <y:ExtendedTimeLineControl x:Name="timeLine" Grid.Row="1" />
</ScrollViewer>
<TabControl Name="tabView" HorizontalAlignment="Stretch" Grid.Row="2"> <TabControl Name="tabView" HorizontalAlignment="Stretch" Grid.Row="2">
<TabItem Header="Overview"> <TabItem Header="Overview">
<y:QueryView x:Name="treeView" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ShowQueryItems="False" CurrentQuery="from t in Threads select t" /> <y:QueryView x:Name="treeView" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ShowQueryItems="False" CurrentQuery="from t in Threads select t" />

18
src/AddIns/Misc/Profiler/Frontend/Gui/Window1.xaml.cs

@ -44,7 +44,7 @@ namespace ICSharpCode.Profiler.Frontend
string path = dlg.FileName; string path = dlg.FileName;
// remove UI before disposing profiler // remove UI before disposing profiler
this.timeLine.ValuesList.Clear(); //this.timeLine.ValuesList.Clear();
if (this.provider != null) if (this.provider != null)
this.provider.Close(); this.provider.Close();
@ -101,8 +101,8 @@ namespace ICSharpCode.Profiler.Frontend
this.treeView.Provider = this.provider; this.treeView.Provider = this.provider;
RefreshUI(0, 0); RefreshUI(0, 0);
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)); //this.timeLine.ValuesList.AddRange(this.provider.DataSets.Select(i => i.CpuUsage));
} catch (Exception ex) { } catch (Exception ex) {
Debug.WriteLine(ex.ToString()); Debug.WriteLine(ex.ToString());
MessageBox.Show(ex.ToString()); MessageBox.Show(ex.ToString());
@ -145,7 +145,7 @@ namespace ICSharpCode.Profiler.Frontend
InitializeComponent(); InitializeComponent();
this.btnStop.IsEnabled = false; this.btnStop.IsEnabled = false;
this.timeLine.IsEnabled = false; //this.timeLine.IsEnabled = false;
this.treeView.Reporter = new ErrorReporter(HandleError); this.treeView.Reporter = new ErrorReporter(HandleError);
this.CommandBindings.Add(new CommandBinding(ApplicationCommands.SelectAll, ExecuteSelectAll, CanExecuteSelectAll)); this.CommandBindings.Add(new CommandBinding(ApplicationCommands.SelectAll, ExecuteSelectAll, CanExecuteSelectAll));
@ -154,15 +154,15 @@ namespace ICSharpCode.Profiler.Frontend
void ExecuteSelectAll(object sender, ExecutedRoutedEventArgs e) void ExecuteSelectAll(object sender, ExecutedRoutedEventArgs e)
{ {
if (this.timeLine.IsEnabled) { if (this.timeLine.IsEnabled) {
this.timeLine.SelectedStartIndex = 0; //this.timeLine.SelectedStartIndex = 0;
this.timeLine.SelectedEndIndex = this.timeLine.ValuesList.Count; //this.timeLine.SelectedEndIndex = this.timeLine.ValuesList.Count;
} }
e.Handled = true; e.Handled = true;
} }
void CanExecuteSelectAll(object sender, CanExecuteRoutedEventArgs e) void CanExecuteSelectAll(object sender, CanExecuteRoutedEventArgs e)
{ {
e.CanExecute = this.timeLine.IsEnabled && this.timeLine.ValuesList.Count > 0; e.CanExecute = this.timeLine.IsEnabled;// && this.timeLine.ValuesList.Count > 0;
e.Handled = true; e.Handled = true;
} }
@ -194,8 +194,8 @@ namespace ICSharpCode.Profiler.Frontend
this.treeView.CurrentQuery = "from t in Threads select t"; this.treeView.CurrentQuery = "from t in Threads select t";
treeView.SetRange(0, this.provider.DataSets.Count); treeView.SetRange(0, this.provider.DataSets.Count);
this.timeLine.IsEnabled = true; this.timeLine.IsEnabled = true;
this.timeLine.ValuesList.Clear(); //this.timeLine.ValuesList.Clear();
this.timeLine.ValuesList.AddRange(provider.DataSets.Select(i => i.CpuUsage)); //this.timeLine.ValuesList.AddRange(provider.DataSets.Select(i => i.CpuUsage));
} }
internal void LogString(string text, bool clear) internal void LogString(string text, bool clear)

3
src/AddIns/Misc/Profiler/Hook/Profiler.cpp

@ -150,9 +150,8 @@ ASSEMBLER_CALLBACK FunctionLeaveGlobal()
ASSEMBLER_CALLBACK FunctionTailcallGlobal() ASSEMBLER_CALLBACK FunctionTailcallGlobal()
{ {
DebugWriteLine(L"FunctionTailcallGlobal"); DebugWriteLine(L"FunctionTailcallGlobal");
// For now, handle tail calls A->B as leave A, enter B, ... // handle tail calls A->B as leave A, enter B, ...
FunctionLeaveGlobal(); FunctionLeaveGlobal();
// TODO: handle tail calls A->B as enter B, ..., leave B, leave A
// FunctionTailcallGlobal call will be followed by FunctionEnterGlobal for new function // FunctionTailcallGlobal call will be followed by FunctionEnterGlobal for new function
} }

14
src/AddIns/Misc/Profiler/Hook/ProfilerMetaData.cpp

@ -559,21 +559,7 @@ bool SignatureReader::IsNetInternal(FunctionID fid)
ULONG assemblyNameLength; ULONG assemblyNameLength;
hr = asmMetaData->GetAssemblyProps(assembly, &publicKey, &pKLength, nullptr, assemblyName, NAME_BUFFER_SIZE, &assemblyNameLength, nullptr, nullptr); hr = asmMetaData->GetAssemblyProps(assembly, &publicKey, &pKLength, nullptr, assemblyName, NAME_BUFFER_SIZE, &assemblyNameLength, nullptr, nullptr);
DebugWriteLine(L"assembly: %s", assemblyName);
const byte *b = (const byte *)publicKey; const byte *b = (const byte *)publicKey;
WCHAR tmp[8];
std::wstring s(L"{ ");
for (ULONG i = 0; i < pKLength; i++) {
memset(tmp, 0, 16);
swprintf_s(tmp, L"0x%02X, ", (int) b[i]);
s.append(tmp);
}
s.append(L" }");
DebugWriteLine(L"assembly: PK: %s", s.c_str());
if (pKLength == sizeof(mscorlibkey) && memcmp(mscorlibkey, b, sizeof(mscorlibkey)) == 0) if (pKLength == sizeof(mscorlibkey) && memcmp(mscorlibkey, b, sizeof(mscorlibkey)) == 0)
return true; return true;

1
src/AddIns/Misc/Profiler/TODO.txt

@ -3,7 +3,6 @@ TODO list:
HIGH PRIORITY HIGH PRIORITY
LOW PRIORITY LOW PRIORITY
- handle Tailcalls differently
NEW FEATURES NEW FEATURES
- Implement an exception tracer - Implement an exception tracer

9
src/Main/Base/Project/Src/Gui/Pads/TaskList/TaskListPad.cs

@ -84,10 +84,17 @@ namespace ICSharpCode.SharpDevelop.Gui
ProjectService.SolutionLoaded += OnSolutionOpen; ProjectService.SolutionLoaded += OnSolutionOpen;
ProjectService.SolutionClosed += OnSolutionClosed; ProjectService.SolutionClosed += OnSolutionClosed;
ProjectService.CurrentProjectChanged += ProjectServiceCurrentProjectChanged;
this.isInitialized = true; this.isInitialized = true;
} }
void ProjectServiceCurrentProjectChanged(object sender, ProjectEventArgs e)
{
if (isInitialized)
UpdateItems();
}
void WorkbenchActiveViewContentChanged(object sender, EventArgs e) void WorkbenchActiveViewContentChanged(object sender, EventArgs e)
{ {
if (WorkbenchSingleton.Workbench.ActiveViewContent == null) if (WorkbenchSingleton.Workbench.ActiveViewContent == null)
@ -121,7 +128,7 @@ namespace ICSharpCode.SharpDevelop.Gui
UpdateItems(); UpdateItems();
} }
private void InitializeToolStrip() void InitializeToolStrip()
{ {
taskView.CreateControl(); taskView.CreateControl();

Loading…
Cancel
Save