Skip to content

Commit

Permalink
Skip QI and 'IObjectReference' allocation in IDIC fallback (#1833)
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergio0694 authored Oct 17, 2024
1 parent 938d95f commit 0a18c1f
Showing 1 changed file with 17 additions and 6 deletions.
23 changes: 17 additions & 6 deletions src/WinRT.Runtime/IWinRTObject.net5.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,17 +188,21 @@ internal sealed bool IsInterfaceImplementedFallback(RuntimeTypeHandle interfaceT
AdditionalTypeData.GetOrAdd(projectIEnum, (_) => new ABI.System.Collections.IEnumerable.AdaptiveFromAbiHelper(type, this));
}

using (objRef)
bool hasMovedObjRefOwnership = false;

try
{
var vftblType = helperType.FindVftblType();

// If there is no nested vftbl type, we want to add the object reference with the IID from the helper type
// to the cache. Rather than doing 'QueryInterface' again with the same IID, on the object reference we
// already have, we can just store that same instance in the cache, and suppress the 'objRef.Dispose()'
// call for it. This avoids that extra call, plus the overhead of allocating a new object reference.
// For all other cases, we dispose the object reference as usual at the end of this scope.
if (vftblType is null)
{
var qiObjRef = objRef.As<IUnknownVftbl>(GuidGenerator.GetIID(helperType));
if (!QueryInterfaceCache.TryAdd(interfaceType, qiObjRef))
{
qiObjRef.Dispose();
}
hasMovedObjRefOwnership = QueryInterfaceCache.TryAdd(interfaceType, objRef);

return true;
}

Expand Down Expand Up @@ -230,6 +234,13 @@ static IObjectReference GetObjectReferenceViaVftbl(IObjectReference objRef, Type

return true;
}
finally
{
if (!hasMovedObjRefOwnership)
{
objRef.Dispose();
}
}
}

#if NET8_0_OR_GREATER
Expand Down

0 comments on commit 0a18c1f

Please sign in to comment.