Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for ComWrappers-based RCWs to the special native WeakReference support. #35819

Merged
merged 23 commits into from
May 8, 2020

Conversation

jkoritzinsky
Copy link
Member

@jkoritzinsky jkoritzinsky commented May 4, 2020

Add support for ComWrappers-based RCWs to the special native WeakReference support.

Rename the WinRT weak reference handle to "native COM weak reference" handle.

Contributes to #35318

Fixes #35745

src/coreclr/src/vm/weakreferencenative.cpp Outdated Show resolved Hide resolved
src/coreclr/src/vm/weakreferencenative.cpp Outdated Show resolved Hide resolved
src/coreclr/src/vm/weakreferencenative.cpp Outdated Show resolved Hide resolved
// * be an RCW
// * respond to a QI for IWeakReferenceSource
// * succeed when asked for an IWeakReference*
//
// Note that *pObject should be GC protected on the way into this method
IWeakReference* GetWinRTWeakReference(OBJECTREF* pObject)
IWeakReference* GetComWeakReference(OBJECTREF* pObject)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this is non-pay for play API when called from WeakReference constructor. What is this change going to do to performance of WeakReference constructor when called on regular COM object?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When it's called by a regular COM object, it will go down the first if path and have basically the same performance characteristics as it did previously. Only non-builtin-COM objects will go down the else path that does the additional work.

{
return nullptr;
pWeakReferenceSource = reinterpret_cast<IWeakReferenceSource*>(GetComIPFromObjectRef(pObject, IID_IWeakReferenceSource, false /* throwIfNoComIP */));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this ever return non-null when the interopinfo on sync block is NULL? I am wondering whether we can have a short-circuit for null interopinfo up-front (potentially even in the caller of this method) and do this expensive COM related stuff only when the interop info is non-null.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe there are even better ways how to make this pay-for-play by e.g. having the types that should participate in this marked with a managed interface.

@jkotas
Copy link
Member

jkotas commented May 6, 2020

That should get back the lost performance.

Still seeing about 5% regression on the benchmark. Can we do better?

@AaronRobinsonMSFT
Copy link
Member

AaronRobinsonMSFT commented May 6, 2020

That should get back the lost performance.

Still seeing about 5% regression on the benchmark. Can we do better?

@jkoritzinsky Lets try keeping the SyncBlock query in weakreferencenative.cpp. This should avoid the call overhead and hopefully will get us down to noise in the normal managed object case. For example:

    IUnknown* unknown = nullptr;
    SyncBlock* syncBlock = (*pObject)->PassiveGetSyncBlock();
    if (syncBlock != nullptr)
    {
        unknown = ComWrappersNative::GetIdentityForObject(syncBlock, IID_IWeakReference);
    }

@jkotas
Copy link
Member

jkotas commented May 6, 2020

Would it be possible to use the sync block check to early our for the built-in COM interop as well?

@jkoritzinsky
Copy link
Member Author

I added a check before the call to GetComWeakReference and now we get a 9% average speed improvement on my local run of the posted benchmark.

…ition to and from pre-emptive when calling into the external QI.
@jkoritzinsky
Copy link
Member Author

@jkotas can you do another review pass when you have a chance?

@AaronRobinsonMSFT
Copy link
Member

@jkoritzinsky It seems like you have some unrelated changed in here.

@jkoritzinsky
Copy link
Member Author

jkoritzinsky commented May 8, 2020

@AaronRobinsonMSFT which changes are you referring to?

@AaronRobinsonMSFT
Copy link
Member

All the changes in ComWrappers.cs and any of the changes to g_IsGlobalComWrappersRegisteredForMarshalling; or g_IsGlobalComWrappersRegisteredForTrackerSupport;. It seems like these changes are being associated with this PR. Unsure how this happened though. Did you merge @elinor-fung's changes in before she squashed it?

@jkoritzinsky
Copy link
Member Author

There was no support on the native side for the “global ComWrappers for tracker support”. Only the global instance for marshalling was exposed in the runtime for the vm to use.

@AaronRobinsonMSFT
Copy link
Member

Ah. @elinor-fung only did the marshalling side. That is why it looked so familiar. Thanks.

@jkoritzinsky jkoritzinsky merged commit 16b7db2 into dotnet:master May 8, 2020
@jkoritzinsky jkoritzinsky deleted the comwrappers-weakreference branch May 8, 2020 02:20
@ghost ghost locked as resolved and limited conversation to collaborators Dec 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

WeakReference and WeakReference<T> should continue to support IWeakReference
4 participants