Skip to content

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

@eerhardt

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:

internal MemberAccessor MemberAccessorStrategy
{
get
{
if (_memberAccessorStrategy == null)
{
#if NETFRAMEWORK || NETCOREAPP
_memberAccessorStrategy = new ReflectionEmitMemberAccessor();
#else
_memberAccessorStrategy = new ReflectionMemberAccessor();
#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:

        internal MemberAccessor MemberAccessorStrategy
        {
            get
            {
                if (_memberAccessorStrategy == null)
                {
#if NETFRAMEWORK || NETCOREAPP
                    if (RuntimeFeature.IsDynamicCodeCompiled)
                    {
                        _memberAccessorStrategy = new ReflectionEmitMemberAccessor();
                    }
                    else
                    {
                        _memberAccessorStrategy = new ReflectionMemberAccessor();
                    }
#else
                    _memberAccessorStrategy = new ReflectionMemberAccessor();
#endif
                }

                return _memberAccessorStrategy;
            }
        }

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

Build Size
master 3,366,912 bytes
#38729 3,039,232 bytes
#38729 + this change 2,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

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions