Skip to content

Commit

Permalink
Fix benchmarks and optimizations to CreateObject code path
Browse files Browse the repository at this point in the history
  • Loading branch information
manodasanW committed Oct 6, 2021
1 parent bd25372 commit f16d9c4
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 45 deletions.
7 changes: 4 additions & 3 deletions src/Benchmarks/Benchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
<PackageReference Include="BenchmarkDotNet" Version="0.13.1" />
<PackageReference Include="BenchmarkDotNet.Diagnostics.Windows" Version="0.13.1" />
<PackageReference Include="Microsoft.Windows.SDK.Contracts" Version="10.0.18362.2005" Condition="$(UseWinmd) == true"/>
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="4.5.3" Condition="$(UseWinmd) == false"/>
</ItemGroup>

<ItemGroup>
<Reference Include="$(MSBuildThisFileDirectory)..\Projections\Windows\bin\x64\Release\$(BenchmarkTargetFramework)\Microsoft.Windows.SDK.NET.dll"></Reference>
<Reference Include="$(MSBuildThisFileDirectory)..\Projections\Benchmark\bin\x64\Release\$(BenchmarkTargetFramework)\Benchmark.dll"></Reference>
<Reference Include="$(MSBuildThisFileDirectory)..\Projections\Windows\bin\x64\Release\$(BenchmarkTargetFramework)\Microsoft.Windows.SDK.NET.dll" Condition="$(UseWinmd) == false"></Reference>
<Reference Include="$(MSBuildThisFileDirectory)..\Projections\Benchmark\bin\x64\Release\$(BenchmarkTargetFramework)\Benchmark.dll" Condition="$(UseWinmd) == false"></Reference>

<ProjectReference Include="..\Projections\Windows\Windows.csproj" Condition="$(UseWinmd) == false And $(IsDotnetBuild) == false" />
<ProjectReference Include="..\Projections\Benchmark\Benchmark.csproj" Condition="$(UseWinmd) == false And $(IsDotnetBuild) == false" />
Expand Down
67 changes: 33 additions & 34 deletions src/WinRT.Runtime/ComWrappersSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,49 +63,48 @@ public static IObjectReference GetObjectReferenceForInterface(IntPtr externalCom
return null;
}

using var unknownRef = ObjectReference<IUnknownVftbl>.FromAbi(externalComObject);
var unknownRef = ObjectReference<IUnknownVftbl>.FromAbi(externalComObject);

if (IsFreeThreaded())
if (IsFreeThreaded(unknownRef))
{
return unknownRef.As<IUnknownVftbl>();
return unknownRef;
}
else
{
return new ObjectReferenceWithContext<IUnknownVftbl>(
unknownRef.GetRef(),
Context.GetContextCallback(),
Context.GetContextToken());
using (unknownRef)
{
return new ObjectReferenceWithContext<IUnknownVftbl>(
unknownRef.GetRef(),
Context.GetContextCallback(),
Context.GetContextToken());
}
}

// If we are free threaded, we do not need to keep track of context.
// This can either be if the object implements IAgileObject or the free threaded marshaler.
unsafe bool IsFreeThreaded()
{
if (unknownRef.TryAs<IUnknownVftbl>(typeof(ABI.WinRT.Interop.IAgileObject.Vftbl).GUID, out var agileRef) >= 0)
{
agileRef.Dispose();
return true;
}
else if (unknownRef.TryAs<ABI.WinRT.Interop.IMarshal.Vftbl>(out var marshalRef) >= 0)
{
try
{
Guid iid_IUnknown = typeof(IUnknownVftbl).GUID;
Guid iid_unmarshalClass;
var marshaler = new ABI.WinRT.Interop.IMarshal(marshalRef);
marshaler.GetUnmarshalClass(&iid_IUnknown, IntPtr.Zero, MSHCTX.InProc, IntPtr.Zero, MSHLFLAGS.Normal, &iid_unmarshalClass);
if (iid_unmarshalClass == ABI.WinRT.Interop.IMarshal.IID_InProcFreeThreadedMarshaler.Value)
{
return true;
}
}
finally
{
marshalRef.Dispose();
}
}
return false;
}
unsafe static bool IsFreeThreaded(IObjectReference unknownRef)
{
if (unknownRef.TryAs(ABI.WinRT.Interop.IAgileObject.IID, out var agilePtr) >= 0)
{
Marshal.Release(agilePtr);
return true;
}
else if (unknownRef.TryAs<ABI.WinRT.Interop.IMarshal.Vftbl>(out var marshalRef) >= 0)
{
using (marshalRef)
{
Guid iid_IUnknown = typeof(IUnknownVftbl).GUID;
Guid iid_unmarshalClass;
Marshal.ThrowExceptionForHR(marshalRef.Vftbl.GetUnmarshalClass_0(
marshalRef.ThisPtr, &iid_IUnknown, IntPtr.Zero, MSHCTX.InProc, IntPtr.Zero, MSHLFLAGS.Normal, &iid_unmarshalClass));
if (iid_unmarshalClass == ABI.WinRT.Interop.IMarshal.IID_InProcFreeThreadedMarshaler.Value)
{
return true;
}
}
}
return false;
}
}

public static void RegisterProjectionAssembly(Assembly assembly) => TypeNameSupport.RegisterProjectionAssembly(assembly);
Expand Down
16 changes: 10 additions & 6 deletions src/WinRT.Runtime/ExceptionHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,17 @@ static ExceptionHelpers()
setRestrictedErrorInfo = Platform.GetProcAddress<SetRestrictedErrorInfo>(winRTErrorModule);
}
}
}

public static void ThrowExceptionForHR(int hr)
{
if (hr < 0)
{
ThrowExceptionForHRInternal(hr);
}
}

public static void ThrowExceptionForHR(int hr)
private static void ThrowExceptionForHRInternal(int hr)
{
Exception ex = GetExceptionForHR(hr, useGlobalErrorState: true, out bool restoredExceptionFromGlobalState);
if (restoredExceptionFromGlobalState)
Expand All @@ -71,15 +79,11 @@ public static void ThrowExceptionForHR(int hr)
}
}

public static Exception GetExceptionForHR(int hr) => GetExceptionForHR(hr, false, out _);
public static Exception GetExceptionForHR(int hr) => hr >= 0 ? null : GetExceptionForHR(hr, false, out _);

private static Exception GetExceptionForHR(int hr, bool useGlobalErrorState, out bool restoredExceptionFromGlobalState)
{
restoredExceptionFromGlobalState = false;
if (hr >= 0)
{
return null;
}

ObjectReference<ABI.WinRT.Interop.IErrorInfo.Vftbl> iErrorInfo = null;
IObjectReference restrictedErrorInfoToSave = null;
Expand Down
6 changes: 4 additions & 2 deletions src/WinRT.Runtime/Interop/IAgileReference.netstandard2.0.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal interface IAgileReference
[WindowsRuntimeType]
[Guid("94ea2b94-e9cc-49e0-c0ff-ee64ca8f5b90")]
public interface IAgileObject
{
{
}

[WindowsRuntimeType]
Expand Down Expand Up @@ -113,7 +113,9 @@ public IObjectReference Resolve(Guid riid)

[Guid("94ea2b94-e9cc-49e0-c0ff-ee64ca8f5b90")]
public class IAgileObject : global::WinRT.Interop.IAgileObject
{
{
internal static readonly Guid IID = Guid.Parse("94ea2b94-e9cc-49e0-c0ff-ee64ca8f5b90");

[Guid("94ea2b94-e9cc-49e0-c0ff-ee64ca8f5b90")]
public struct Vftbl
{
Expand Down

0 comments on commit f16d9c4

Please sign in to comment.