Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Wrighton <davidwr@microsoft.com>2017-07-03 20:15:05 +0300
committerDavid Wrighton <davidwr@microsoft.com>2017-07-03 20:15:05 +0300
commit6ed0b6c9feb5dc6c2b3819abde41b3946b5efa1f (patch)
treeb58e13f79cde49594604048d0e195565e77a50ec /src/Runtime.Base
parent090d7b4424fd66fa17d4c4e50214b9b8e6f898ae (diff)
Improve performance of interface casting
- Primary improvement is to the performance of failed interface casting (the is case where null is returned). - Change checking ICastable flag from needing access to the RareFlags to being examinable directly from EEType - Remove unused existing RuntimeAllocated flag and move ICastable flag to be directly on EEType - Secondary improvement - Micro-optimize use of assignability cache by removing an if statement from the assignability cache lookup function and force inline it into its caller. Removal of the extra function prolog/epilog/removal of the if statement is worth about 300ms. - This will improve performance of all interface cast checks by a small but measurable amount. [tfs-changeset: 1664305]
Diffstat (limited to 'src/Runtime.Base')
-rw-r--r--src/Runtime.Base/src/System/Runtime/EEType.Runtime.cs2
-rw-r--r--src/Runtime.Base/src/System/Runtime/TypeCast.cs22
2 files changed, 21 insertions, 3 deletions
diff --git a/src/Runtime.Base/src/System/Runtime/EEType.Runtime.cs b/src/Runtime.Base/src/System/Runtime/EEType.Runtime.cs
index 475b77568..09a6c8bef 100644
--- a/src/Runtime.Base/src/System/Runtime/EEType.Runtime.cs
+++ b/src/Runtime.Base/src/System/Runtime/EEType.Runtime.cs
@@ -77,7 +77,7 @@ namespace Internal.Runtime
{
fixed (EEType* pThis = &this)
{
- if (!IsRuntimeAllocated && !IsDynamicType)
+ if (!IsDynamicType)
return (IntPtr)pThis;
// There are currently four types of runtime allocated EETypes, arrays, pointers, byrefs, and generic types.
diff --git a/src/Runtime.Base/src/System/Runtime/TypeCast.cs b/src/Runtime.Base/src/System/Runtime/TypeCast.cs
index 62dea8448..db68ac4a4 100644
--- a/src/Runtime.Base/src/System/Runtime/TypeCast.cs
+++ b/src/Runtime.Base/src/System/Runtime/TypeCast.cs
@@ -268,7 +268,7 @@ namespace System.Runtime
EEType* pTargetType = (EEType*)pvTargetType;
EEType* pObjType = obj.EEType;
- if (CastCache.AreTypesAssignableInternal(pObjType, pTargetType, AssignmentVariation.BoxedSource))
+ if (CastCache.AreTypesAssignableInternal_SourceNotTarget_BoxedSource(pObjType, pTargetType))
return obj;
// If object type implements ICastable then there's one more way to check whether it implements
@@ -744,7 +744,7 @@ namespace System.Runtime
EEType* pTargetType = (EEType*)pvTargetEEType;
EEType* pObjType = obj.EEType;
- if (CastCache.AreTypesAssignableInternal(pObjType, pTargetType, AssignmentVariation.BoxedSource))
+ if (CastCache.AreTypesAssignableInternal_SourceNotTarget_BoxedSource(pObjType, pTargetType))
return obj;
Exception castError = null;
@@ -1116,6 +1116,24 @@ namespace System.Runtime
return entry.Result;
}
+ // This method is an optimized and customized version of AreTypesAssignable that achieves better performance
+ // than AreTypesAssignableInternal through 2 significant changes
+ // 1. Removal of sourceType to targetType check (This propery must be known before calling this function. At time
+ // of writing, this is true as its is only used if sourceType is from an object, and targetType is an interface.)
+ // 2. Force inlining (This particular variant is only used in a small number of dispatch scenarios that are particularly
+ // high in performance impact.)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static unsafe bool AreTypesAssignableInternal_SourceNotTarget_BoxedSource(EEType* pSourceType, EEType* pTargetType)
+ {
+ Debug.Assert(pSourceType != pTargetType, "target is source");
+ Key key = new Key(pSourceType, pTargetType, AssignmentVariation.BoxedSource);
+ Entry entry = LookupInCache(s_cache, ref key);
+ if (entry == null)
+ return CacheMiss(ref key);
+
+ return entry.Result;
+ }
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Entry LookupInCache(Entry[] cache, ref Key key)
{