From 4632b7aba4ca19e26f339df6d32f6effe66a7a28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Srbeck=C3=BD?= Date: Tue, 26 Dec 2006 17:58:53 +0000 Subject: [PATCH] Load debuggee metadata only once and cache it git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2214 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Project/Src/Threads/Process.cs | 12 --- .../Project/Src/Variables/Types/DebugType.cs | 102 +++++++++++------- 2 files changed, 65 insertions(+), 49 deletions(-) diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Process.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Process.cs index 515dfc606d..6d4e5c1752 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Process.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Threads/Process.cs @@ -22,8 +22,6 @@ namespace Debugger Thread selectedThread; PauseSession pauseSession; - Dictionary debugTypeCache = new Dictionary(); - bool hasExpired = false; public event EventHandler Expired; @@ -251,15 +249,5 @@ namespace Debugger } } } - - internal DebugType GetDebugType(ICorDebugType corType) - { - DebugType type; - if (!debugTypeCache.TryGetValue(corType.WrappedObject, out type)) { - type = new DebugType(this, corType); - debugTypeCache.Add(corType.WrappedObject, type); - } - return type; - } } } diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/DebugType.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/DebugType.cs index a0d2344cd4..1778d8ea0d 100644 --- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/DebugType.cs +++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Variables/Types/DebugType.cs @@ -14,8 +14,9 @@ namespace Debugger { /// /// Represents a type in a debugee. That is, a class, array, value type or a primitive type. - /// This class mimics the class. + /// This class mimics the class. /// + /// If two types are identical, the references to DebugType will also be identical public partial class DebugType: DebuggerObject { Process process; @@ -36,6 +37,9 @@ namespace Debugger List methods = new List(); List properties = new List(); + // Stores all DebugType instances. FullName is the key + static Dictionary> loadedTypes = new Dictionary>(); + void AssertClassOrValueType() { if(!IsClass && !IsValueType) { @@ -213,7 +217,7 @@ namespace Debugger } } - internal DebugType(Process process, ICorDebugType corType) + DebugType(Process process, ICorDebugType corType) { if (corType == null) throw new ArgumentNullException("corType"); @@ -225,8 +229,6 @@ namespace Debugger this.corClass = corType.Class; this.module = process.GetModule(corClass.Module); this.classProps = module.MetaData.GetTypeDefProps(corClass.Token); - - LoadType(); } if (this.IsClass || this.IsValueType || this.IsArray) { @@ -238,12 +240,41 @@ namespace Debugger this.fullName = GetFullName(); } - /// - /// Obtains instance of DebugType using process cache - /// + /// Obtains instance of DebugType. Same types will return identical instance. static internal DebugType Create(Process process, ICorDebugType corType) { - return process.GetDebugType(corType); + DateTime startTime = Util.HighPrecisionTimer.Now; + + DebugType type = new DebugType(process, corType); + + // Get types with matching names from cache + List typesWithMatchingName; + if (!loadedTypes.TryGetValue(type.FullName, out typesWithMatchingName)) { + // No types with such name - create a new list + typesWithMatchingName = new List(1); + loadedTypes.Add(type.FullName, typesWithMatchingName); + } + + // Try to find the type + foreach(DebugType loadedType in typesWithMatchingName) { + if (loadedType.Equals(type)) { + TimeSpan totalTime = Util.HighPrecisionTimer.Now - startTime; + //process.TraceMessage("Type " + type.FullName + " was loaded already (" + totalTime.TotalMilliseconds + " ms)"); + return loadedType; // Type was loaded before + } + } + + // The type is not in the cache, finish loading it and add it to the cache + if (type.IsClass || type.IsValueType) { + type.LoadMemberInfo(); + } + typesWithMatchingName.Add(type); + type.Process.Expired += delegate { typesWithMatchingName.Remove(type); }; + + TimeSpan totalTime2 = Util.HighPrecisionTimer.Now - startTime; + process.TraceMessage("Loaded type " + type.FullName + " (" + totalTime2.TotalMilliseconds + " ms)"); + + return type; } string GetFullName() @@ -269,31 +300,8 @@ namespace Debugger } } - /// Determines whether the current type is sublass of - /// the the given type. That is, it derives from the given type. - /// Returns false if the given type is same as the current type - public bool IsSubclassOf(DebugType superType) - { - DebugType type = this.BaseType; - while (type != null) { - if (type.Equals(superType)) return true; - type = type.BaseType; - } - return false; - } - - /// Determines whether the given object is instance of the - /// current type or can be implicitly cast to it - public bool IsInstanceOfType(Value objectInstance) + void LoadMemberInfo() { - return objectInstance.Type.Equals(this) || - objectInstance.Type.IsSubclassOf(this); - } - - void LoadType() - { - DateTime startTime = Util.HighPrecisionTimer.Now; - // Load fields foreach(FieldProps field in module.MetaData.EnumFields(this.MetadataToken)) { if (field.IsStatic && field.IsLiteral) continue; // Skip static literals TODO: Why? @@ -324,9 +332,27 @@ namespace Debugger accessors.TryGetValue("set_" + kvp.Key, out setter); properties.Add(new PropertyInfo(this, getter, setter)); } - - TimeSpan totalTime = Util.HighPrecisionTimer.Now - startTime; - process.TraceMessage("Loaded type " + this.FullName + " (" + totalTime.TotalMilliseconds + " ms)"); + } + + /// Determines whether the current type is sublass of + /// the the given type. That is, it derives from the given type. + /// Returns false if the given type is same as the current type + public bool IsSubclassOf(DebugType superType) + { + DebugType type = this.BaseType; + while (type != null) { + if (type.Equals(superType)) return true; + type = type.BaseType; + } + return false; + } + + /// Determines whether the given object is instance of the + /// current type or can be implicitly cast to it + public bool IsInstanceOfType(Value objectInstance) + { + return objectInstance.Type.Equals(this) || + objectInstance.Type.IsSubclassOf(this); } /// Return all public fields. @@ -369,9 +395,11 @@ namespace Debugger public override bool Equals(object obj) { DebugType other = obj as DebugType; - if (other != null) { + if (other != null && this.Process == other.Process) { if (this.IsArray) { - throw new NotImplementedException(); // TODO + return other.IsArray && + other.GetArrayRank() == this.GetArrayRank() && + other.GetElementType().Equals(this.GetElementType()); } if (this.IsPrimitive) { return other.IsPrimitive &&