Skip to content

Commit

Permalink
ILMarshaler Refactor (dotnet#21227)
Browse files Browse the repository at this point in the history
* Add support for fields to ILStubMarshalHome objects.

* Make the specific code streams in the ILMarshaler private members.

* Make home members private.

* Move the IL code stream members back to being protected for the marshalers that override EmitMarshalArgumentCLRToNative instead of EmitMarshalArgumentContents/Space.

* Convert virtual specifiers in overrides to override specifiers.

* Remove unused and undefined member.

* Cleanup a few missed virtual/override specifiers.

* Refactor setup methods. Refactor some of the overrides to duplicate less code.

* Refactor the setup stream and add some comments around how the ArgumentOverride/ReturnOverride marshalling system works.

* Use the cleanup work list in SafeHandle marshalling since the work list is now implemented entirely in managed code.

* Generalize DelegateCleanupWorkListElement -> KeepAliveCleanupWorkListElement and rename the managed entry point to match.

* Refactor direct usage of the cleanup code stream in non-overridden marshalers to use the cleanup work list instead.

* Refactor AsAny marshalling to fit into the regular ILMarshaler code-paths.

* Move ILArgIteratorMarshaler over to the full ILMarshaler infrastructure.

* Port ILBlittablePtrMarshaler over to not directly reference m_pcsMarshal.

* Make the specific code streams private and have ILNativeArrayMarshaler fetch the one it needs from the NDirectStubLinker.

* Devirtualize a method on ILMarshaler.

* Fix broken metasig

* Revert "Use the cleanup work list in SafeHandle marshalling since the work list is now implemented entirely in managed code."

This reverts commit aedcdfb.

* Fix ILArgIteratorMarshaler.

* Take 2 on using the cleanup work list for SafeHandles

* Remove unused field

* SafeHandleMarshaler doesn't need to have extra cleanup code when using the CleanupWorkList.

* Move the rest of the SafeHandle marshalling into ArgumentOverride.

* Moved Pinned Native Array special case into an ArgumentOverride.

* Devirtualize

* Remove invalid field hometype.

* Make ILMarshaler::m_pslNDirect private.

* Native Array marshalling fixes.

* Fix STLOC->LDLOC mistakes.

* Add override hook to allow a marshaler to request that byval contents are always converted to native even when not marked as In (i.e. explicitly marked only as Out). Used in AsAny for byval arrays.

* PR Feedback.

* Add explicit pinning path to ilmarshalers.

* Move implementation of ILNativeArrayMarshaler::CanMarshalViaPinning to ilmarshalers.cpp.

* Add missing override specifier.

* Don't create a managed marshaler if we are able to marshal via pinning. Remove extraneous checks against pinning.

* Convert ILWSTRMarshaler to use the MarshalViaPinning functions for its pinning fast-path.

* Enable LPWSTR marshalling to fall back to allocating on the heap for large strings when stack-allocating for native space (byref in-only semantics).

* PR Feedback.
  • Loading branch information
jkoritzinsky committed Jun 19, 2019
1 parent eafa864 commit 70febba
Show file tree
Hide file tree
Showing 7 changed files with 908 additions and 1,013 deletions.
16 changes: 8 additions & 8 deletions src/System.Private.CoreLib/src/System/StubHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1485,21 +1485,21 @@ public static void AddToCleanupList(ref CleanupWorkListElement list, CleanupWork
}
}

// Keeps a Delegate instance alive across the full Managed->Native call.
// Keeps an object instance alive across the full Managed->Native call.
// This ensures that users don't have to call GC.KeepAlive after passing a struct or class
// that has a delegate field to native code.
internal sealed class DelegateCleanupWorkListElement : CleanupWorkListElement
internal sealed class KeepAliveCleanupWorkListElement : CleanupWorkListElement
{
public DelegateCleanupWorkListElement(Delegate del)
public KeepAliveCleanupWorkListElement(object obj)
{
m_del = del;
m_obj = obj;
}

private Delegate m_del;
private object m_obj;

protected override void DestroyCore()
{
GC.KeepAlive(m_del);
GC.KeepAlive(m_obj);
}
}

Expand Down Expand Up @@ -1562,9 +1562,9 @@ internal static IntPtr AddToCleanupList(ref CleanupWorkListElement pCleanupWorkL
return element.AddRef();
}

internal static void AddToCleanupList(ref CleanupWorkListElement pCleanupWorkList, Delegate del)
internal static void KeepAliveViaCleanupList(ref CleanupWorkListElement pCleanupWorkList, object obj)
{
DelegateCleanupWorkListElement element = new DelegateCleanupWorkListElement(del);
KeepAliveCleanupWorkListElement element = new KeepAliveCleanupWorkListElement(obj);
CleanupWorkListElement.AddToCleanupList(ref pCleanupWorkList, element);
}

Expand Down
2 changes: 1 addition & 1 deletion src/vm/fieldmarshaler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3064,7 +3064,7 @@ VOID FieldMarshaler_Delegate::UpdateNativeImpl(OBJECTREF* pCLRValue, LPVOID pNat
if (*pCLRValue != NULL && ppCleanupWorkListOnStack != NULL)
{
// Call StubHelpers.AddToCleanupList to ensure the delegate is kept alive across the full native call.
MethodDescCallSite AddToCleanupList(METHOD__STUBHELPERS__ADD_TO_CLEANUP_LIST_DELEGATE);
MethodDescCallSite AddToCleanupList(METHOD__STUBHELPERS__KEEP_ALIVE_VIA_CLEANUP_LIST);

ARG_SLOT args[] =
{
Expand Down
Loading

0 comments on commit 70febba

Please sign in to comment.