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

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

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

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

@ -0,0 +1,20 @@ @@ -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 @@ -142,31 +142,47 @@ namespace ICSharpCode.Profiler.Controller.Data
cmd.CommandText = @"
CREATE TABLE NameMapping(
id INTEGER NOT NULL PRIMARY KEY,
returntype VARCHAR2(100) NOT NULL,
name VARCHAR2(255) NOT NULL,
parameters VARCHAR2(1000) NOT NULL);
id INTEGER NOT NULL PRIMARY KEY,
returntype VARCHAR2(100) NOT NULL,
name VARCHAR2(255) NOT NULL,
parameters VARCHAR2(1000) NOT NULL
);
CREATE TABLE FunctionData(
datasetid INTEGER NOT NULL,
id INTEGER NOT NULL PRIMARY KEY,
endid INTEGER NOT NULL,
parentid INTEGER NOT NULL,
nameid INTEGER NOT NULL,
timespent INT8 NOT NULL,
isactiveatstart INTEGER NOT NULL,
callcount INTEGER NOT NULL);
datasetid INTEGER NOT NULL,
id INTEGER NOT NULL PRIMARY KEY,
endid INTEGER NOT NULL,
parentid INTEGER NOT NULL,
nameid INTEGER NOT NULL,
timespent INT8 NOT NULL,
isactiveatstart INTEGER NOT NULL,
callcount INTEGER NOT NULL
);
CREATE TABLE DataSets(
id INTEGER NOT NULL PRIMARY KEY,
cpuusage REAL NOT NULL,
rootid INTEGER NOT NULL);
id INTEGER NOT NULL PRIMARY KEY,
cpuusage REAL NOT NULL,
rootid INTEGER NOT NULL
);
CREATE TABLE Properties(
name VARCHAR2(100) NOT NULL PRIMARY KEY,
value VARCHAR2(100) NOT NULL);
name VARCHAR2(100) NOT NULL PRIMARY KEY,
value VARCHAR2(100) NOT NULL
);
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();

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

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

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

@ -55,7 +55,7 @@ namespace ICSharpCode.Profiler.Controller.Queries @@ -55,7 +55,7 @@ namespace ICSharpCode.Profiler.Controller.Queries
/// Creates a new instance of the QueryCompiler.
/// </summary>
/// <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)
{
if (reporter == null)
@ -100,11 +100,13 @@ namespace ICSharpCode.Profiler.Controller.Queries @@ -100,11 +100,13 @@ namespace ICSharpCode.Profiler.Controller.Queries
/// <returns>The result of the query.</returns>
public IEnumerable<CallTreeNode> ExecuteQuery(ProfilingDataProvider provider, int startIndex, int endIndex)
{
if (provider == null)
throw new ArgumentNullException("provider");
Assembly assembly;
lock (queryCache)
assembly = queryCache[this.currentQuery];
QueryBase queryContainer = assembly.CreateInstance("Query") as QueryBase;
CallTreeNode root = provider.GetRoot(startIndex, endIndex);
queryContainer.Provider = provider;
queryContainer.StartDataSetIndex = startIndex;

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

@ -47,12 +47,9 @@ namespace ICSharpCode.Profiler.AddIn.Commands @@ -47,12 +47,9 @@ namespace ICSharpCode.Profiler.AddIn.Commands
if (runner != null) {
runner.RunFinished += delegate {
string title = Path.GetFileName(path);
ProfilingDataProvider provider = new ProfilingDataSQLiteProvider(path);
Action updater = () => {
WorkbenchSingleton.Workbench.ShowView(new WpfViewer(provider, title));
FileProjectItem file = new FileProjectItem(currentProj, ItemType.Content, "ProfilingSessions\\" + title);
FileService.OpenFile(path);
FileProjectItem file = new FileProjectItem(currentProj, ItemType.Content, "ProfilingSessions\\" + Path.GetFileName(path));
ProjectService.AddProjectItem(currentProj, file);
ProjectBrowserPad.Instance.ProjectBrowserControl.RefreshView();
currentProj.Save();
@ -73,8 +70,14 @@ namespace ICSharpCode.Profiler.AddIn.Commands @@ -73,8 +70,14 @@ namespace ICSharpCode.Profiler.AddIn.Commands
return null;
if (!currentProj.IsStartable) {
MessageService.ShowError("This project cannot be started, please select a startable project for Profiling!");
return null;
if (MessageService.AskQuestion("This project cannot be started. Do you want to profile the solution's StartUp project instead?")) {
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)) {
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 @@ @@ -1,4 +1,4 @@
using ICSharpCode.Profiler.Controller;
using ICSharpCode.SharpDevelop;
using System;
using System.Diagnostics;
using System.Globalization;
@ -7,6 +7,7 @@ using System.Windows; @@ -7,6 +7,7 @@ using System.Windows;
using ICSharpCode.Core;
using ICSharpCode.Profiler.AddIn.OptionsPanels;
using ICSharpCode.Profiler.AddIn.Views;
using ICSharpCode.Profiler.Controller;
using ICSharpCode.Profiler.Controller.Data;
using ICSharpCode.SharpDevelop.Gui;
using Microsoft.Win32;
@ -48,9 +49,7 @@ namespace ICSharpCode.Profiler.AddIn.Dialogs @@ -48,9 +49,7 @@ namespace ICSharpCode.Profiler.AddIn.Dialogs
if (runner != null) {
runner.RunFinished += delegate {
string title = Path.GetFileName(outputPath);
ProfilingDataProvider provider = new ProfilingDataSQLiteProvider(outputPath);
WorkbenchSingleton.SafeThreadCall(() => WorkbenchSingleton.Workbench.ShowView(new WpfViewer(provider, title)));
WorkbenchSingleton.SafeThreadCall(() => FileService.OpenFile(outputPath));
};
runner.Run();

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

@ -29,7 +29,7 @@ namespace ICSharpCode.Profiler.AddIn.Views @@ -29,7 +29,7 @@ namespace ICSharpCode.Profiler.AddIn.Views
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 @@ -173,8 +173,10 @@ namespace ICSharpCode.Profiler.AddIn.Views
view.CurrentQuery = query;
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); };
header.Text = title;

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

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

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

@ -318,43 +318,6 @@ namespace ICSharpCode.Profiler.Controls @@ -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 {
get {

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

@ -61,6 +61,11 @@ @@ -61,6 +61,11 @@
</ItemGroup>
<ItemGroup>
<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="CustomGridView.cs" />
<Compile Include="ExtensionMethods.cs" />
@ -85,6 +90,7 @@ @@ -85,6 +90,7 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Themes" />
<Page Include="ExtendedTimeLineControl.xaml" />
<Page Include="QueryView.xaml" />
<Page Include="Themes\Generic.xaml" />
<ProjectReference Include="..\..\Controller\Controller.csproj">

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

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

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

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

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

@ -13,9 +13,8 @@ @@ -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>
<TextBox Margin="10,39,12,4" Name="txtOutput" VerticalScrollBarVisibility="Visible" />
<GridSplitter Height="2" VerticalAlignment="Bottom" Grid.Row="1" />
<ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
<y:TimeLineControl x:Name="timeLine" RangeChanged="timeLine_RangeChanged" />
</ScrollViewer>
<!-- <y:TimeLineControl x:Name="timeLine" RangeChanged="timeLine_RangeChanged" /> -->
<y:ExtendedTimeLineControl x:Name="timeLine" Grid.Row="1" />
<TabControl Name="tabView" HorizontalAlignment="Stretch" Grid.Row="2">
<TabItem Header="Overview">
<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 @@ -44,7 +44,7 @@ namespace ICSharpCode.Profiler.Frontend
string path = dlg.FileName;
// remove UI before disposing profiler
this.timeLine.ValuesList.Clear();
//this.timeLine.ValuesList.Clear();
if (this.provider != null)
this.provider.Close();
@ -101,8 +101,8 @@ namespace ICSharpCode.Profiler.Frontend @@ -101,8 +101,8 @@ namespace ICSharpCode.Profiler.Frontend
this.treeView.Provider = this.provider;
RefreshUI(0, 0);
this.timeLine.IsEnabled = true;
this.timeLine.ValuesList.Clear();
this.timeLine.ValuesList.AddRange(this.provider.DataSets.Select(i => i.CpuUsage));
//this.timeLine.ValuesList.Clear();
//this.timeLine.ValuesList.AddRange(this.provider.DataSets.Select(i => i.CpuUsage));
} catch (Exception ex) {
Debug.WriteLine(ex.ToString());
MessageBox.Show(ex.ToString());
@ -145,7 +145,7 @@ namespace ICSharpCode.Profiler.Frontend @@ -145,7 +145,7 @@ namespace ICSharpCode.Profiler.Frontend
InitializeComponent();
this.btnStop.IsEnabled = false;
this.timeLine.IsEnabled = false;
//this.timeLine.IsEnabled = false;
this.treeView.Reporter = new ErrorReporter(HandleError);
this.CommandBindings.Add(new CommandBinding(ApplicationCommands.SelectAll, ExecuteSelectAll, CanExecuteSelectAll));
@ -154,15 +154,15 @@ namespace ICSharpCode.Profiler.Frontend @@ -154,15 +154,15 @@ namespace ICSharpCode.Profiler.Frontend
void ExecuteSelectAll(object sender, ExecutedRoutedEventArgs e)
{
if (this.timeLine.IsEnabled) {
this.timeLine.SelectedStartIndex = 0;
this.timeLine.SelectedEndIndex = this.timeLine.ValuesList.Count;
//this.timeLine.SelectedStartIndex = 0;
//this.timeLine.SelectedEndIndex = this.timeLine.ValuesList.Count;
}
e.Handled = true;
}
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;
}
@ -194,8 +194,8 @@ namespace ICSharpCode.Profiler.Frontend @@ -194,8 +194,8 @@ namespace ICSharpCode.Profiler.Frontend
this.treeView.CurrentQuery = "from t in Threads select t";
treeView.SetRange(0, this.provider.DataSets.Count);
this.timeLine.IsEnabled = true;
this.timeLine.ValuesList.Clear();
this.timeLine.ValuesList.AddRange(provider.DataSets.Select(i => i.CpuUsage));
//this.timeLine.ValuesList.Clear();
//this.timeLine.ValuesList.AddRange(provider.DataSets.Select(i => i.CpuUsage));
}
internal void LogString(string text, bool clear)

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

@ -150,9 +150,8 @@ ASSEMBLER_CALLBACK FunctionLeaveGlobal() @@ -150,9 +150,8 @@ ASSEMBLER_CALLBACK FunctionLeaveGlobal()
ASSEMBLER_CALLBACK 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();
// TODO: handle tail calls A->B as enter B, ..., leave B, leave A
// 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) @@ -559,21 +559,7 @@ bool SignatureReader::IsNetInternal(FunctionID fid)
ULONG assemblyNameLength;
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;
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)
return true;

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

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

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

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

Loading…
Cancel
Save