Browse Source

Added an Expression cache

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2876 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
David Srbecký 18 years ago
parent
commit
9ea3fb9980
  1. 1
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/LocalVarPad.cs
  2. 5
      src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/Util.cs
  3. 2
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/Ast/ThisReferenceExpression.cs
  4. 39
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/Expression.cs
  5. 11
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/StackFrame.cs
  6. 4
      src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs

1
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/Pads/LocalVarPad.cs

@ -221,6 +221,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads @@ -221,6 +221,7 @@ namespace ICSharpCode.SharpDevelop.Gui.Pads
public override void RefreshPad()
{
Debugger.AddIn.TreeModel.Util.ResetDoEventsStartTime();
DateTime start = Debugger.Util.HighPrecisionTimer.Now;
try {
if (debuggedProcess != null && debuggedProcess.SelectedStackFrame != null) {

5
src/AddIns/Misc/Debugger/Debugger.AddIn/Project/Src/TreeModel/Util.cs

@ -22,6 +22,11 @@ namespace Debugger.AddIn.TreeModel @@ -22,6 +22,11 @@ namespace Debugger.AddIn.TreeModel
const double maxFPS = 30; // this prevents too much drawing on good machine
const double maxWorkTime = 250; // ms this ensures minimal response on bad machine
public static void ResetDoEventsStartTime()
{
nextDoEventsTime = Debugger.Util.HighPrecisionTimer.Now.AddMilliseconds(1000 / maxFPS);
}
public static void DoEvents()
{
if (Debugger.Util.HighPrecisionTimer.Now > nextDoEventsTime) {

2
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/Ast/ThisReferenceExpression.cs

@ -34,7 +34,7 @@ namespace Debugger.Expressions @@ -34,7 +34,7 @@ namespace Debugger.Expressions
public override bool Equals(object obj)
{
return obj is EmptyExpression;
return obj is ThisReferenceExpression;
}
#endregion

39
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Expressions/Expression.cs

@ -16,6 +16,11 @@ namespace Debugger.Expressions @@ -16,6 +16,11 @@ namespace Debugger.Expressions
/// </summary>
public abstract partial class Expression: DebuggerObject
{
static Dictionary<Expression, Value> expressionCache;
static DebugeeState expressionCache_debuggerState;
static Thread expressionCache_thread;
static int expressionCache_stackDepth;
public abstract string Code {
get;
}
@ -31,12 +36,42 @@ namespace Debugger.Expressions @@ -31,12 +36,42 @@ namespace Debugger.Expressions
return this.Code;
}
Value GetFromCache(StackFrame context)
{
if (expressionCache == null ||
expressionCache_debuggerState != context.Process.DebugeeState ||
expressionCache_thread != context.Thread ||
expressionCache_stackDepth != context.Depth)
{
expressionCache = new Dictionary<Expression, Value>();
expressionCache_debuggerState = context.Process.DebugeeState;
expressionCache_thread = context.Thread;
expressionCache_stackDepth = context.Depth;
context.Process.TraceMessage("Expression cache cleared");
}
if (expressionCache.ContainsKey(this)) {
Value cachedResult = expressionCache[this];
if (!cachedResult.HasExpired) {
return cachedResult;
}
}
return null;
}
public Value Evaluate(StackFrame context)
{
if (context == null) throw new ArgumentNullException("context");
if (context.HasExpired) throw new DebuggerException("Context is expired StackFrame");
Value result;
result = GetFromCache(context);
if (result != null) {
context.Process.TraceMessage(string.Format("Cached: {0,-12} ({1})", this.Code, this.GetType().Name));
return result;
}
DateTime start = Debugger.Util.HighPrecisionTimer.Now;
try {
result = EvaluateInternal(context);
} catch (GetValueException e) {
@ -45,8 +80,10 @@ namespace Debugger.Expressions @@ -45,8 +80,10 @@ namespace Debugger.Expressions
}
throw;
}
DateTime end = Debugger.Util.HighPrecisionTimer.Now;
expressionCache[this] = result;
context.Process.TraceMessage("Evaluated " + this.GetType().Name + ": "+ this.Code);
context.Process.TraceMessage(string.Format("Evaluated: {0,-12} ({1}) ({2} ms)", this.Code, this.GetType().Name, (end - start).TotalMilliseconds));
return result;
}

11
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/StackFrame.cs

@ -30,6 +30,7 @@ namespace Debugger @@ -30,6 +30,7 @@ namespace Debugger
ICorDebugFunction corFunction;
MethodInfo methodInfo;
int depth;
/// <summary> The process in which this stack frame is executed </summary>
[Debugger.Tests.Ignore]
@ -52,6 +53,13 @@ namespace Debugger @@ -52,6 +53,13 @@ namespace Debugger
}
}
/// <summary>
/// The depth of this frame. First frame has depth of 0.
/// </summary>
public int Depth {
get { return depth; }
}
/// <summary> True if the stack frame has symbols defined.
/// (That is has accesss to the .pdb file) </summary>
public bool HasSymbols {
@ -67,13 +75,14 @@ namespace Debugger @@ -67,13 +75,14 @@ namespace Debugger
}
}
internal StackFrame(Thread thread, ICorDebugILFrame corILFrame)
internal StackFrame(Thread thread, ICorDebugILFrame corILFrame, int depth)
{
this.process = thread.Process;
this.thread = thread;
this.corILFrame = corILFrame;
this.corILFramePauseSession = process.PauseSession;
this.corFunction = corILFrame.Function;
this.depth = depth;
DebugType debugType = DebugType.Create(
this.Process,

4
src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Thread.cs

@ -245,13 +245,15 @@ namespace Debugger @@ -245,13 +245,15 @@ namespace Debugger
get {
process.AssertPaused();
int depth = 0;
foreach(ICorDebugChain corChain in CorThread.EnumerateChains().Enumerator) {
if (corChain.IsManaged == 0) continue; // Only managed ones
foreach(ICorDebugFrame corFrame in corChain.EnumerateFrames().Enumerator) {
if (corFrame.Is<ICorDebugILFrame>()) {
StackFrame stackFrame;
try {
stackFrame = new StackFrame(this, corFrame.CastTo<ICorDebugILFrame>());
stackFrame = new StackFrame(this, corFrame.CastTo<ICorDebugILFrame>(), depth);
depth++;
} catch (COMException) { // TODO
continue;
};

Loading…
Cancel
Save