Optimize free-threaded checks when metadata information is available#2255
Open
Sergio0694 wants to merge 10 commits intostaging/3.0from
Open
Optimize free-threaded checks when metadata information is available#2255Sergio0694 wants to merge 10 commits intostaging/3.0from
Sergio0694 wants to merge 10 commits intostaging/3.0from
Conversation
There was a problem hiding this comment.
Pull request overview
This PR optimizes the creation of Runtime Callable Wrappers (RCWs) for Windows Runtime objects by leveraging static metadata information about marshaling types. When the marshaling type is known from metadata (Agile or Standard), the runtime can skip up to 2 QueryInterface calls that would otherwise be needed to determine if an object is free-threaded. This is achieved by adding a new CreateObjectReferenceMarshalingType parameter throughout the object reference creation pipeline.
Changes:
- Introduced
CreateObjectReferenceMarshalingTypeenum to represent marshaling type information from metadata (Unknown, Agile, Standard) - Added optional validation feature (
EnableMarshalingTypeValidation) to verify that declared marshaling types match runtime behavior - Updated all
WindowsRuntimeObjectReferenceinitialization andWindowsRuntimeObjectconstructor signatures to accept marshaling type parameter - Maintained backward compatibility by providing overloads that default to
Unknownmarshaling type
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| CreateObjectReferenceMarshalingType.cs | New enum defining marshaling types (Unknown, Agile, Standard) aligned with Windows metadata |
| WindowsRuntimeFeatureSwitches.cs | Added feature switch to enable validation of marshaling type declarations (defaults to false) |
| ComObjectHelpers.cs | Added validation method to verify marshaling type matches runtime behavior via fail-fast |
| WindowsRuntimeObjectReference.Initialization.cs | Updated all initialization methods to accept marshaling type and use fast-path when type is known |
| WindowsRuntimeComWrappersMarshal.cs | Added overloads for CreateObjectReference methods accepting marshaling type parameter |
| WindowsRuntimeObject.cs | Updated all activation constructors to accept and forward marshaling type parameter; updated XML doc references |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/WinRT.Runtime2/InteropServices/ObjectReference/CreateObjectReferenceMarshalingType.cs
Outdated
Show resolved
Hide resolved
9704a1c to
d8acaa6
Compare
Introduce an internal enum CreateObjectReferenceMarshalingType to specify the marshaling behavior when creating WindowsRuntimeObjectReference instances. Defines Unknown, Agile, and Standard values and includes XML doc remarks linking to Windows.Foundation.Metadata.MarshalingType for clarity.
Add a marshalingType parameter to WindowsRuntimeObjectReference.InitializeObjectReference and InitializeObjectReferenceUnsafe to enable fast-path decisions (Agile/Standard) and avoid expensive runtime checks when metadata is available. Update free-threaded checks to use a boolean result derived from HRESULTs and adjust error handling and ownership semantics accordingly. Add overloads to WindowsRuntimeComWrappersMarshal that accept MarshalingType (mapped via CreateObjectReferenceMarshalingType.FromMetadata) and annotate platform support; update wrapperFlags assignment and XML docs. Also add required usings and pragmas to silence analyzer warnings.
Add a CreateObjectReferenceMarshalingType parameter to creation helpers and branch on it to avoid expensive runtime queries when possible. Fast-paths for Agile and Standard are used to set free-threaded semantics, while the default path calls ComObjectHelpers.IsFreeThreadedUnsafe and preserves previous failure handling (including releasing the inner unknown and throwing). Refactor uses a bool isFreeThreaded instead of HRESULT comparisons and clean up related comments and XML docs (including a small typo fix). This reduces runtime overhead for known marshaling annotations and centralizes the free-threaded decision logic.
Add a local CreateObjectReferenceMarshalingType enum (public but marked Obsolete and EditorBrowsable(Never)) to represent marshaling kinds and replace usages of Windows.Foundation.Metadata.MarshalingType. Update WindowsRuntimeComWrappersMarshal.CreateObjectReference/CreateObjectReferenceUnsafe to accept the new enum and pass it through to WindowsRuntimeObjectReference initialization. Propagate the marshalingType parameter through WindowsRuntimeObject constructors and activation paths so the value is forwarded when creating object references. Remove the direct dependency on Windows.Foundation.Metadata and adjust XML docs/links accordingly.
Introduce runtime validation for declared CreateObjectReferenceMarshalingType values. Adds ComObjectHelpers.ValidateMarshalingType (with aggressive inlining and a NoInlining helper) to check IsFreeThreadedUnsafe and FailFast on mismatches, and wire calls to this validator in WindowsRuntimeObjectReference initialization paths. Add a new feature switch (CSWINRT_ENABLE_MARSHALING_TYPE_VALIDATION / EnableMarshalingTypeValidation) to toggle the behavior (defaults to false) and add the required using for System.Runtime.CompilerServices.
Replace calls to hresult.Failed() with the hresult.Failed property in WindowsRuntimeObjectReference.Initialization.cs. Updated the failure checks around COM aggregation handling and the free-threaded interface release to match the HRESULT API change.
On initialization failure, explicitly release any acquired COM interface pointers to avoid leaking references: call ReleaseUnsafe on acquiredNewInstanceUnknown (if non-null) and on acquiredInnerInstanceUnknown. The previous long AddRef/Release commentary was moved and condensed below to clarify ownership semantics and that no AddRef is required in the common optimized paths. This change ensures proper cleanup on early returns and reduces lifetime-management complexity.
* Add helper to read MarshalingBehaviorAttribute from .winmd metadata Add get_marshaling_type_name() that reads the MarshalingBehaviorAttribute from a TypeDef and returns the corresponding C# CreateObjectReferenceMarshalingType enum value string for code generation. Maps MarshalingType.Agile (2) and MarshalingType.Standard (3) to their respective enum members, defaulting to Unknown for all other cases. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update factory constructor generation with marshalingType parameter Pass CreateObjectReferenceMarshalingType to base constructor calls in write_factory_constructors for both parameterized (callback-based) and parameterless (DerivedSealed) factory activation patterns. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update composable constructor generation with marshalingType parameter Pass CreateObjectReferenceMarshalingType to base constructor calls in write_composable_constructors for both parameterless (DerivedComposed) and parametered (callback-based) patterns. Also update all four protected pass-through constructors to accept and forward the marshalingType parameter. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update ComWrappers marshaller/callback with marshalingType parameter Pass CreateObjectReferenceMarshalingType to CreateObjectReference and CreateObjectReferenceUnsafe calls in write_class_comwrappers_marshaller_attribute and write_class_comwrappers_callback (sealed and unsealed paths, 4 call sites). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
6aef353 to
257c6a4
Compare
Remove explicit numeric assignments for Agile and Standard in CreateObjectReferenceMarshalingType so the enum uses default sequential values. This is a syntactic cleanup with no behavioral change; file also ends without a trailing newline.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Title. This can skip up to 2 QIs for every single RCW being created.