diff --git a/src/AddIns/Debugger/Debugger.Core/Eval.cs b/src/AddIns/Debugger/Debugger.Core/Eval.cs
index 136cfba8da..0675c415e7 100644
--- a/src/AddIns/Debugger/Debugger.Core/Eval.cs
+++ b/src/AddIns/Debugger/Debugger.Core/Eval.cs
@@ -187,12 +187,15 @@ namespace Debugger
 		/// <summary> Synchronously calls a function and returns its return value </summary>
 		public static Value InvokeMethod(Thread evalThread, IMethod method, Value thisValue, Value[] args)
 		{
-			#warning Fast property eval
-//			var field = Value.GetBackingField(method);
-//			if (field != null) {
-//				evalThread.Process.TraceMessage("Using backing field for " + method.FullName);
-//				return Value.GetMemberValue(evalThread, thisValue, field, args);
-//			}
+			Module module = method.DeclaringTypeDefinition.ParentAssembly.GetModule();
+			uint fieldToken = module.GetBackingFieldToken(method.ToCorFunction());
+			if (fieldToken != 0) {
+				var field = method.DeclaringType.ImportField(fieldToken);
+				if (field != null) {
+					evalThread.Process.TraceMessage("Using backing field for " + method.FullName);
+					return Value.GetMemberValue(evalThread, thisValue, field, args);
+				}
+			}
 			return AsyncInvokeMethod(evalThread, method, thisValue, args).WaitForResult();
 		}
 		
diff --git a/src/AddIns/Debugger/Debugger.Core/Module.cs b/src/AddIns/Debugger/Debugger.Core/Module.cs
index 92abd7198c..dddc3efae0 100644
--- a/src/AddIns/Debugger/Debugger.Core/Module.cs
+++ b/src/AddIns/Debugger/Debugger.Core/Module.cs
@@ -356,5 +356,71 @@ namespace Debugger
 			}
 			return jcf;
 		}
+		
+		Dictionary<ICorDebugFunction, uint> backingFieldCache = new Dictionary<ICorDebugFunction, uint>();
+		
+		/// <summary> Is this method in form 'return this.field;'? </summary>
+		internal uint GetBackingFieldToken(ICorDebugFunction corFunction)
+		{
+			uint token;
+			if (backingFieldCache.TryGetValue(corFunction, out token)) {
+				return token;
+			}
+			
+			ICorDebugCode corCode;
+			try {
+				corCode = corFunction.GetILCode();
+			} catch (COMException) {
+				backingFieldCache[corFunction] = 0;
+				return 0;
+			}
+			
+			if (corCode == null || corCode.IsIL() == 0 || corCode.GetSize() > 12) {
+				backingFieldCache[corFunction] = 0;
+				return 0;
+			}
+			
+			List<byte> code = new List<byte>(corCode.GetCode());
+			
+			bool success =
+				(Read(code, 0x00) || true) &&                     // nop || nothing
+				(Read(code, 0x02, 0x7B) || Read(code, 0x7E)) &&   // ldarg.0; ldfld || ldsfld
+				ReadToken(code, ref token) &&                     //   <field token>
+				(Read(code, 0x0A, 0x2B, 0x00, 0x06) || true) &&   // stloc.0; br.s; offset+00; ldloc.0 || nothing
+				Read(code, 0x2A);                                 // ret
+			
+			if (!success) {
+				backingFieldCache[corFunction] = 0;
+				return 0;
+			}
+			
+			backingFieldCache[corFunction] = token;
+			return token;
+		}
+		
+		// Read expected sequence of bytes
+		static bool Read(List<byte> code, params byte[] expected)
+		{
+			if (code.Count < expected.Length)
+				return false;
+			for(int i = 0; i < expected.Length; i++) {
+				if (code[i] != expected[i])
+					return false;
+			}
+			code.RemoveRange(0, expected.Length);
+			return true;
+		}
+		
+		// Read field token
+		static bool ReadToken(List<byte> code, ref uint token)
+		{
+			if (code.Count < 4)
+				return false;
+			if (code[3] != 0x04) // field token
+				return false;
+			token = ((uint)code[0]) + ((uint)code[1] << 8) + ((uint)code[2] << 16) + ((uint)code[3] << 24);
+			code.RemoveRange(0, 4);
+			return true;
+		}
 	}
 }
diff --git a/src/AddIns/Debugger/Debugger.Core/StackFrame.cs b/src/AddIns/Debugger/Debugger.Core/StackFrame.cs
index 2afc57eb28..86aa48dad1 100644
--- a/src/AddIns/Debugger/Debugger.Core/StackFrame.cs
+++ b/src/AddIns/Debugger/Debugger.Core/StackFrame.cs
@@ -391,7 +391,7 @@ namespace Debugger
 					if (this.MethodInfo.IsAccessor) return true;
 				}
 				if (opt.StepOverFieldAccessProperties) {
-					if (this.MethodInfo.IsAccessor && Value.GetBackingFieldToken(this.MethodInfo) != 0) return true;
+					if (this.MethodInfo.IsAccessor && this.Module.GetBackingFieldToken(this.CorFunction) != 0) return true;
 				}
 				return false;
 			}
diff --git a/src/AddIns/Debugger/Debugger.Core/TypeSystemExtensions.cs b/src/AddIns/Debugger/Debugger.Core/TypeSystemExtensions.cs
index e7065d7d41..9a936ba16b 100644
--- a/src/AddIns/Debugger/Debugger.Core/TypeSystemExtensions.cs
+++ b/src/AddIns/Debugger/Debugger.Core/TypeSystemExtensions.cs
@@ -522,5 +522,12 @@ namespace Debugger
 			}
 			return unresolvedMethod.Resolve(new SimpleTypeResolveContext(module.Assembly));
 		}
+		
+		public static IField ImportField(this IType declaringType, uint fieldToken)
+		{
+			var module = declaringType.GetDefinition().ParentAssembly.GetModule();
+			var info = GetInfo(module.Assembly);
+			return declaringType.GetFields(f => info.GetMetadataToken(f) == fieldToken, GetMemberOptions.IgnoreInheritedMembers).SingleOrDefault();
+		}
 	}
 }
diff --git a/src/AddIns/Debugger/Debugger.Core/Value.cs b/src/AddIns/Debugger/Debugger.Core/Value.cs
index 90dbff8302..b1753b7f3e 100644
--- a/src/AddIns/Debugger/Debugger.Core/Value.cs
+++ b/src/AddIns/Debugger/Debugger.Core/Value.cs
@@ -602,63 +602,6 @@ namespace Debugger
 		
 		#endregion
 		
-		/// <summary> Is this method in form 'return this.field;'? </summary>
-		internal static uint GetBackingFieldToken(IMethod method)
-		{
-			ICorDebugFunction corFunction = method.ToCorFunction();
-			
-			ICorDebugCode corCode;
-			try {
-				corCode = corFunction.GetILCode();
-			} catch (COMException) {
-				return 0;
-			}
-			
-			if (corCode == null || corCode.IsIL() == 0 || corCode.GetSize() > 12)
-				return 0;
-			
-			List<byte> code = new List<byte>(corCode.GetCode());
-			
-			uint token = 0;
-			
-			bool success =
-				(Read(code, 0x00) || true) &&                     // nop || nothing
-				(Read(code, 0x02, 0x7B) || Read(code, 0x7E)) &&   // ldarg.0; ldfld || ldsfld
-				ReadToken(code, ref token) &&                     //   <field token>
-				(Read(code, 0x0A, 0x2B, 0x00, 0x06) || true) &&   // stloc.0; br.s; offset+00; ldloc.0 || nothing
-				Read(code, 0x2A);                                 // ret
-			
-			if (!success)
-				return 0;
-			
-			return token;
-		}
-		
-		// Read expected sequence of bytes
-		static bool Read(List<byte> code, params byte[] expected)
-		{
-			if (code.Count < expected.Length)
-				return false;
-			for(int i = 0; i < expected.Length; i++) {
-				if (code[i] != expected[i])
-					return false;
-			}
-			code.RemoveRange(0, expected.Length);
-			return true;
-		}
-		
-		// Read field token
-		static bool ReadToken(List<byte> code, ref uint token)
-		{
-			if (code.Count < 4)
-				return false;
-			if (code[3] != 0x04) // field token
-				return false;
-			token = ((uint)code[0]) + ((uint)code[1] << 8) + ((uint)code[2] << 16) + ((uint)code[3] << 24);
-			code.RemoveRange(0, 4);
-			return true;
-		}
-		
 		public override string ToString()
 		{
 			return this.AsString();