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

[mono][wasm] marshal-ilgen is dropped when not required #86035

Merged
merged 33 commits into from
Jun 14, 2023

Conversation

jandupej
Copy link
Member

@jandupej jandupej commented May 10, 2023

A new analyzer MarshlingPInvokeScanner is added, that scans all assemblies for constructs incompatible with the lightweight marshaller. This is essentially every P/Invoke that uses a nonblittable type as argument or returns it. The analyzer uses System.Reflection.Metadata to remain compatible with .NET Framework.

Additionally, the wasm toolchain uses this analyzer to decide whether marshal-ilgen is needed. If it is not, the full marshaller is dropped in favor of the lightweight one.

EDIT: The reduction in dotnet.native.wasm is approx. 74 KB when marshal-ilgen is dropped in favor of its stub.

@jandupej jandupej added the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label May 10, 2023
@jandupej jandupej requested a review from lambdageek May 10, 2023 12:58
@jandupej jandupej self-assigned this May 10, 2023
@dotnet-issue-labeler dotnet-issue-labeler bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label May 10, 2023
@teo-tsirpanis teo-tsirpanis added area-Build-mono and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels May 13, 2023
Copy link
Member

@lambdageek lambdageek left a comment

Choose a reason for hiding this comment

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

I wonder if the stub emit method can assert in a few places.

src/mono/mono/component/marshal-ilgen-stub.c Outdated Show resolved Hide resolved
src/mono/mono/component/marshal-ilgen-stub.c Outdated Show resolved Hide resolved
src/mono/mono/component/marshal-ilgen-stub.c Outdated Show resolved Hide resolved
src/mono/mono/component/marshal-ilgen-stub.c Show resolved Hide resolved
@jandupej jandupej marked this pull request as ready for review June 2, 2023 09:22
@jandupej jandupej removed the NO-MERGE The PR is not ready for merge yet (see discussion for detailed reasons) label Jun 2, 2023
Copy link
Member

@lambdageek lambdageek left a comment

Choose a reason for hiding this comment

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

native code changes lgtm. I have a couple of suggestions for the build task - the biggest one being whether we can use the type system from NativeAOT instead of building our own signature provider. if we use our own, then I think we need some comments to explain what is going on. It is not obvious.

Also check the weird ECMA edge-case of "generic" enum types that arise from nested types.

lambdageek

This comment was marked as duplicate.

@@ -3,9 +3,11 @@

<UsingTask TaskName="Microsoft.WebAssembly.Build.Tasks.ManagedToNativeGenerator" AssemblyFile="$(WasmAppBuilderTasksAssemblyPath)" />
<UsingTask TaskName="Microsoft.WebAssembly.Build.Tasks.EmccCompile" AssemblyFile="$(WasmAppBuilderTasksAssemblyPath)" />
<UsingTask TaskName="MarshalingPInvokeScanner" AssemblyFile="$(MonoTargetsTasksAssemblyPath)" />
Copy link
Member

Choose a reason for hiding this comment

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

Add namespace for the task

Comment on lines 238 to 239


Copy link
Member

Choose a reason for hiding this comment

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

Suggested change



}

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change



#pragma warning disable CS0649
internal sealed class PInvokeCallback
Copy link
Member

Choose a reason for hiding this comment

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

This could be a record like:

internal sealed record PInvokeCallback(MethodInfo method, string? EntryName = null);

Comment on lines 55 to 57



Copy link
Member

Choose a reason for hiding this comment

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

Suggested change


internal sealed class PInvokeCollector {
private readonly Dictionary<Assembly, bool> _assemblyDisableRuntimeMarshallingAttributeCache = new();
private TaskLoggingHelper Log { get; set; }
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
private TaskLoggingHelper Log { get; set; }
private readonly TaskLoggingHelper Log { get; init; }

if(mdtReader.GetString(td.Name) == "DisableRuntimeMarshallingAttribute")
return false;
}
catch(InvalidCastException)
Copy link
Member

Choose a reason for hiding this comment

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

Which part can throw this exception?

TypeDefinitionHandle tdh = md.GetDeclaringType();
TypeDefinition td = mdtReader.GetTypeDefinition(tdh);

if(mdtReader.GetString(td.Name) == "DisableRuntimeMarshallingAttribute")
Copy link
Member

Choose a reason for hiding this comment

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

.. and check namespace

Comment on lines 284 to 285
SignatureDecoder<Compatibility, object> decoder = new SignatureDecoder<Compatibility, object>(
mmtcp, mdtReader, null!);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
SignatureDecoder<Compatibility, object> decoder = new SignatureDecoder<Compatibility, object>(
mmtcp, mdtReader, null!);
SignatureDecoder<Compatibility, object> decoder = new(mmtcp, mdtReader, null!);

MethodSignature<Compatibility> sgn = decoder.DecodeMethodSignature(ref sgnBlobReader);
if(sgn.ReturnType == Compatibility.Incompatible || sgn.ParameterTypes.Any(p => p == Compatibility.Incompatible))
{
Log.LogMessage(MessageImportance.Low, string.Format("Assebly {0} requires marhsal-ilgen for method {1}.{2}:{3} (first pass).",
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Log.LogMessage(MessageImportance.Low, string.Format("Assebly {0} requires marhsal-ilgen for method {1}.{2}:{3} (first pass).",
Log.LogMessage(MessageImportance.Low, string.Format("Assembly {0} requires marhsal-ilgen for method {1}.{2}:{3} (first pass).",

@@ -35,6 +35,8 @@ public IEnumerable<string> Generate(string[] pinvokeModules, IEnumerable<string>
var pinvokes = new List<PInvoke>();
var callbacks = new List<PInvokeCallback>();

PInvokeCollector pinvokeCollector = new PInvokeCollector(Log);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
PInvokeCollector pinvokeCollector = new PInvokeCollector(Log);
PInvokeCollector pinvokeCollector = new(Log);

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.

5 participants