Просмотр исходного кода

Merge pull request #1028 from DavidKarlas/sdbTypesCaching

[Mono.Debugger.Soft] Caching Assemblies and Types
Zoltan Varga 11 лет назад
Родитель
Сommit
3f8134d3fd

+ 23 - 7
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/AppDomainMirror.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Threading;
 
 namespace Mono.Debugger.Soft
 {
@@ -6,6 +7,9 @@ namespace Mono.Debugger.Soft
 	{
 		string friendly_name;
 		AssemblyMirror entry_assembly, corlib;
+		AssemblyMirror[] assemblies;
+		bool assembliesCacheIsInvalid = true;
+		object assembliesCacheLocker = new object ();
 
 		internal AppDomainMirror (VirtualMachine vm, long id) : base (vm, id) {
 		}
@@ -19,15 +23,27 @@ namespace Mono.Debugger.Soft
 			}
 	    }
 
-		// Not cached
+		internal void InvalidateAssembliesCache ()
+		{
+			assembliesCacheIsInvalid = true;
+		}
+
 		public AssemblyMirror[] GetAssemblies () {
-			long[] ids = vm.conn.Domain_GetAssemblies (id);
-			AssemblyMirror[] assemblies = new AssemblyMirror [ids.Length];
-			// FIXME: Uniqueness
-			for (int i = 0; i < ids.Length; ++i)
-				assemblies [i] = vm.GetAssembly (ids [i]);
+			if (assembliesCacheIsInvalid) {
+				lock (assembliesCacheLocker) {
+					if (assembliesCacheIsInvalid) {
+						long[] ids = vm.conn.Domain_GetAssemblies (id);
+						assemblies = new AssemblyMirror [ids.Length];
+						// FIXME: Uniqueness
+						for (int i = 0; i < ids.Length; ++i)
+							assemblies [i] = vm.GetAssembly (ids [i]);
+						Thread.MemoryBarrier ();
+						assembliesCacheIsInvalid = false;
+					}
+				}
+			}
 			return assemblies;
-	    }
+		}
 
 		// This returns null when called before the first AssemblyLoad event
 		public AssemblyMirror GetEntryAssembly () {

+ 22 - 2
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/AssemblyMirror.cs

@@ -2,6 +2,7 @@ using System;
 using System.Reflection;
 using Mono.Debugger;
 using Mono.Cecil;
+using System.Collections.Generic;
 
 namespace Mono.Debugger.Soft
 {
@@ -13,6 +14,8 @@ namespace Mono.Debugger.Soft
 		ModuleMirror main_module;
 		AssemblyName aname;
 		AssemblyDefinition meta;
+		Dictionary<string, long> typeCacheIgnoreCase = new Dictionary<string, long> (StringComparer.InvariantCultureIgnoreCase);
+		Dictionary<string, long> typeCache = new Dictionary<string, long> ();
 
 		internal AssemblyMirror (VirtualMachine vm, long id) : base (vm, id) {
 		}
@@ -62,13 +65,30 @@ namespace Mono.Debugger.Soft
 		public TypeMirror GetType (string name, bool throwOnError, bool ignoreCase)
 		{
 			if (name == null)
-				throw new ArgumentNullException (name);
+				throw new ArgumentNullException ("name");
 			if (name.Length == 0)
 				throw new ArgumentException ("name", "Name cannot be empty");
 
 			if (throwOnError)
 				throw new NotImplementedException ();
-			return vm.GetType (vm.conn.Assembly_GetType (id, name, ignoreCase));
+			long typeId;
+			if (ignoreCase) {
+				if (!typeCacheIgnoreCase.TryGetValue (name, out typeId)) {
+					typeId = vm.conn.Assembly_GetType (id, name, ignoreCase);
+					typeCacheIgnoreCase.Add (name, typeId);
+					var type = vm.GetType (typeId);
+					if (type != null) {
+						typeCache.Add (type.FullName, typeId);
+					}
+					return type;
+				}
+			} else {
+				if (!typeCache.TryGetValue (name, out typeId)) {
+					typeId = vm.conn.Assembly_GetType (id, name, ignoreCase);
+					typeCache.Add (name, typeId);
+				}
+			}
+			return vm.GetType (typeId);
 		}
 
 		public TypeMirror GetType (String name, Boolean throwOnError)

+ 2 - 0
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs

@@ -655,9 +655,11 @@ namespace Mono.Debugger.Soft
 					break;
 				case EventType.AssemblyLoad:
 					l.Add (new AssemblyLoadEvent (vm, req_id, thread_id, id));
+					vm.GetThread (thread_id).Domain.InvalidateAssembliesCache ();
 					break;
 				case EventType.AssemblyUnload:
 					l.Add (new AssemblyUnloadEvent (vm, req_id, thread_id, id));
+					vm.GetThread (thread_id).Domain.InvalidateAssembliesCache ();
 					break;
 				case EventType.TypeLoad:
 					l.Add (new TypeLoadEvent (vm, req_id, thread_id, id));