Skip to content

Commit a4d2139

Browse files
kgmatouskozak
authored andcommitted
[wasm] Improvements to startup performance of mono_wasm_get_assembly_exports (dotnet#99924)
Change generated JSImport/JSExport initializer to not rely on Environment.Version, for faster startup
1 parent 6194696 commit a4d2139

File tree

2 files changed

+34
-13
lines changed

2 files changed

+34
-13
lines changed

src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/Constants.cs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ internal static class Constants
1717
public const string ModuleInitializerAttributeGlobal = "global::System.Runtime.CompilerServices.ModuleInitializerAttribute";
1818
public const string CompilerGeneratedAttributeGlobal = "global::System.Runtime.CompilerServices.CompilerGeneratedAttribute";
1919
public const string DynamicDependencyAttributeGlobal = "global::System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute";
20+
public const string DynamicallyAccessedMemberTypesGlobal = "global::System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes";
2021
public const string ThreadStaticGlobal = "global::System.ThreadStaticAttribute";
2122
public const string TaskGlobal = "global::System.Threading.Tasks.Task";
2223
public const string SpanGlobal = "global::System.Span";

src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/JSExportGenerator.cs

+33-13
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ private static NamespaceDeclarationSyntax GenerateRegSource(
215215
const string generatedNamespace = "System.Runtime.InteropServices.JavaScript";
216216
const string initializerClass = "__GeneratedInitializer";
217217
const string initializerName = "__Register_";
218-
const string selfInitName = "__Net7SelfInit_";
218+
const string trimmingPreserveName = "__TrimmingPreserve_";
219219

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

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

244-
// 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
245-
// this also keeps the code protected from trimming
246-
MemberDeclarationSyntax initializerMethod = MethodDeclaration(PredefinedType(Token(SyntaxKind.VoidKeyword)), Identifier(selfInitName))
247-
.WithAttributeLists(List(new[]{
248-
AttributeList(SingletonSeparatedList(Attribute(IdentifierName(Constants.ModuleInitializerAttributeGlobal)))),
249-
}))
244+
// HACK: protect the code from trimming with DynamicDependency attached to a ModuleInitializer
245+
MemberDeclarationSyntax initializerMethod = MethodDeclaration(PredefinedType(Token(SyntaxKind.VoidKeyword)), Identifier(trimmingPreserveName))
246+
.WithAttributeLists(
247+
SingletonList<AttributeListSyntax>(
248+
AttributeList(
249+
SeparatedList<AttributeSyntax>(
250+
new SyntaxNodeOrToken[]{
251+
Attribute(
252+
IdentifierName(Constants.ModuleInitializerAttributeGlobal)),
253+
Token(SyntaxKind.CommaToken),
254+
Attribute(
255+
IdentifierName(Constants.DynamicDependencyAttributeGlobal))
256+
.WithArgumentList(
257+
AttributeArgumentList(
258+
SeparatedList<AttributeArgumentSyntax>(
259+
new SyntaxNodeOrToken[]{
260+
AttributeArgument(
261+
BinaryExpression(
262+
SyntaxKind.BitwiseOrExpression,
263+
MemberAccessExpression(
264+
SyntaxKind.SimpleMemberAccessExpression,
265+
IdentifierName(Constants.DynamicallyAccessedMemberTypesGlobal),
266+
IdentifierName("PublicMethods")),
267+
MemberAccessExpression(
268+
SyntaxKind.SimpleMemberAccessExpression,
269+
IdentifierName(Constants.DynamicallyAccessedMemberTypesGlobal),
270+
IdentifierName("NonPublicMethods")))),
271+
Token(SyntaxKind.CommaToken),
272+
AttributeArgument(
273+
TypeOfExpression(
274+
IdentifierName(initializerClass)))})))}))))
250275
.WithModifiers(TokenList(new[] {
251276
Token(SyntaxKind.StaticKeyword),
252277
Token(SyntaxKind.InternalKeyword)
253278
}))
254-
.WithBody(Block(
255-
IfStatement(BinaryExpression(SyntaxKind.EqualsExpression,
256-
IdentifierName("Environment.Version.Major"),
257-
LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(7))),
258-
Block(SingletonList<StatementSyntax>(
259-
ExpressionStatement(InvocationExpression(IdentifierName(initializerName))))))));
279+
.WithBody(Block());
260280

261281
var ns = NamespaceDeclaration(IdentifierName(generatedNamespace))
262282
.WithMembers(

0 commit comments

Comments
 (0)