Skip to content

JsonSerializerOptions.MemberAccessorStrategy shouldn't use Reflection.Emit when IsDynamicCodeCompiled is false #38693

Description

@eerhardt

When trimming a Blazor WASM app, the last usage of Reflection.Emit (after fixing #38678) is coming from System.Text.Json.Serialization.JsonSerializerOptions:

internalMemberAccessorMemberAccessorStrategy
{
get
{
if(_memberAccessorStrategy==null)
{
#if NETFRAMEWORK||NETCOREAPP
_memberAccessorStrategy=newReflectionEmitMemberAccessor();
#else
_memberAccessorStrategy=newReflectionMemberAccessor();
#endif
}
return_memberAccessorStrategy;
}
}

However, on Mono WASM, RuntimeFeature.IsDynamicCodeCompiled is always false, so using Reflection.Emit is probably a waste, and it brings in a decent amount of code. In my investigations I find it removing ~50KB of IL if we trim this usage of Reflection.Emit.

We should change this code to something more like:

internalMemberAccessorMemberAccessorStrategy{get{if(_memberAccessorStrategy==null){
#if NETFRAMEWORK||NETCOREAPPif(RuntimeFeature.IsDynamicCodeCompiled){_memberAccessorStrategy=newReflectionEmitMemberAccessor();}else{_memberAccessorStrategy=newReflectionMemberAccessor();}
#else
_memberAccessorStrategy=newReflectionMemberAccessor();
#endif
}return_memberAccessorStrategy;}}

With changing the code to the above, on a default template Blazor WASM app, I am seeing size savings of:

BuildSize
master3,366,912 bytes
#387293,039,232 bytes
#38729 + this change2,990,080 bytes

So almost a 50 KB savings by allowing the removing all usages of System.Reflection.Emit.

cc @steveharter@layomia@vitek-karas@marek-safar

Metadata

Metadata

Assignees

Labels

arch-wasmWebAssembly architecturearea-System.Text.Jsonin-prThere is an active PR which will close this issue when it is mergedsize-reductionIssues impacting final app size primary for size sensitive workloads

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions