Skip to content

Commit

Permalink
[wasm] Improvements to startup performance of mono_wasm_get_assembly_…
Browse files Browse the repository at this point in the history
…exports (dotnet#99924)

Change generated JSImport/JSExport initializer to not rely on Environment.Version, for faster startup
  • Loading branch information
kg authored and matouskozak committed Apr 30, 2024
1 parent 6194696 commit a4d2139
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ internal static class Constants
public const string ModuleInitializerAttributeGlobal = "global::System.Runtime.CompilerServices.ModuleInitializerAttribute";
public const string CompilerGeneratedAttributeGlobal = "global::System.Runtime.CompilerServices.CompilerGeneratedAttribute";
public const string DynamicDependencyAttributeGlobal = "global::System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute";
public const string DynamicallyAccessedMemberTypesGlobal = "global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes";
public const string ThreadStaticGlobal = "global::System.ThreadStaticAttribute";
public const string TaskGlobal = "global::System.Threading.Tasks.Task";
public const string SpanGlobal = "global::System.Span";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ private static NamespaceDeclarationSyntax GenerateRegSource(
const string generatedNamespace = "System.Runtime.InteropServices.JavaScript";
const string initializerClass = "__GeneratedInitializer";
const string initializerName = "__Register_";
const string selfInitName = "__Net7SelfInit_";
const string trimmingPreserveName = "__TrimmingPreserve_";

if (methods.IsEmpty) return NamespaceDeclaration(IdentifierName(generatedNamespace));

Expand All @@ -241,22 +241,42 @@ private static NamespaceDeclarationSyntax GenerateRegSource(
.WithModifiers(TokenList(new[] { Token(SyntaxKind.StaticKeyword) }))
.WithBody(Block(registerStatements));

// when we are running code generated by .NET8 on .NET7 runtime we need to auto initialize the assembly, because .NET7 doesn't call the registration from JS
// this also keeps the code protected from trimming
MemberDeclarationSyntax initializerMethod = MethodDeclaration(PredefinedType(Token(SyntaxKind.VoidKeyword)), Identifier(selfInitName))
.WithAttributeLists(List(new[]{
AttributeList(SingletonSeparatedList(Attribute(IdentifierName(Constants.ModuleInitializerAttributeGlobal)))),
}))
// HACK: protect the code from trimming with DynamicDependency attached to a ModuleInitializer
MemberDeclarationSyntax initializerMethod = MethodDeclaration(PredefinedType(Token(SyntaxKind.VoidKeyword)), Identifier(trimmingPreserveName))
.WithAttributeLists(
SingletonList<AttributeListSyntax>(
AttributeList(
SeparatedList<AttributeSyntax>(
new SyntaxNodeOrToken[]{
Attribute(
IdentifierName(Constants.ModuleInitializerAttributeGlobal)),
Token(SyntaxKind.CommaToken),
Attribute(
IdentifierName(Constants.DynamicDependencyAttributeGlobal))
.WithArgumentList(
AttributeArgumentList(
SeparatedList<AttributeArgumentSyntax>(
new SyntaxNodeOrToken[]{
AttributeArgument(
BinaryExpression(
SyntaxKind.BitwiseOrExpression,
MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
IdentifierName(Constants.DynamicallyAccessedMemberTypesGlobal),
IdentifierName("PublicMethods")),
MemberAccessExpression(
SyntaxKind.SimpleMemberAccessExpression,
IdentifierName(Constants.DynamicallyAccessedMemberTypesGlobal),
IdentifierName("NonPublicMethods")))),
Token(SyntaxKind.CommaToken),
AttributeArgument(
TypeOfExpression(
IdentifierName(initializerClass)))})))}))))
.WithModifiers(TokenList(new[] {
Token(SyntaxKind.StaticKeyword),
Token(SyntaxKind.InternalKeyword)
}))
.WithBody(Block(
IfStatement(BinaryExpression(SyntaxKind.EqualsExpression,
IdentifierName("Environment.Version.Major"),
LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(7))),
Block(SingletonList<StatementSyntax>(
ExpressionStatement(InvocationExpression(IdentifierName(initializerName))))))));
.WithBody(Block());

var ns = NamespaceDeclaration(IdentifierName(generatedNamespace))
.WithMembers(
Expand Down

0 comments on commit a4d2139

Please sign in to comment.