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

Cache parameterized ctor delegates in class info rather than converter #34248

Merged
merged 3 commits into from
Mar 31, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ namespace System.Text.Json.Serialization.Converters
/// </summary>
internal sealed class LargeObjectWithParameterizedConstructorConverter<T> : ObjectWithParameterizedConstructorConverter<T> where T : notnull
{
internal override void CreateConstructorDelegate(JsonClassInfo classInfo, JsonSerializerOptions options)
{
classInfo.CreateObjectWithParameterizedCtor = options.MemberAccessorStrategy.CreateParameterizedConstructor<T>(ConstructorInfo)!;
}

protected override bool ReadAndCacheConstructorArgument(ref ReadStack state, ref Utf8JsonReader reader, JsonParameterInfo jsonParameterInfo)
{
bool success = jsonParameterInfo.ReadJson(ref state, ref reader, out object? arg0);
Expand Down Expand Up @@ -49,8 +44,15 @@ protected override object CreateObject(ref ReadStackFrame frame)

protected override void InitializeConstructorArgumentCaches(ref ReadStack state, JsonSerializerOptions options)
{
object[] arguments = ArrayPool<object>.Shared.Rent(state.Current.JsonClassInfo.ParameterCount);
foreach (JsonParameterInfo jsonParameterInfo in state.Current.JsonClassInfo.ParameterCache!.Values)
JsonClassInfo classInfo = state.Current.JsonClassInfo;

if (classInfo.CreateObjectWithParameterizedCtor == null)
{
classInfo.CreateObjectWithParameterizedCtor = options.MemberAccessorStrategy.CreateParameterizedConstructor<T>(ConstructorInfo)!;
}

object[] arguments = ArrayPool<object>.Shared.Rent(classInfo.ParameterCount);
foreach (JsonParameterInfo jsonParameterInfo in classInfo.ParameterCache!.Values)
{
if (jsonParameterInfo.ShouldDeserialize)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ namespace System.Text.Json.Serialization.Converters
/// </summary>
internal sealed class SmallObjectWithParameterizedConstructorConverter<T, TArg0, TArg1, TArg2, TArg3> : ObjectWithParameterizedConstructorConverter<T> where T : notnull
{
internal override void CreateConstructorDelegate(JsonClassInfo classInfo, JsonSerializerOptions options)
{
classInfo.CreateObjectWithParameterizedCtor = options.MemberAccessorStrategy.CreateParameterizedConstructor<T, TArg0, TArg1, TArg2, TArg3>(ConstructorInfo)!;
}

protected override object CreateObject(ref ReadStackFrame frame)
{
var createObject = (JsonClassInfo.ParameterizedConstructorDelegate<T, TArg0, TArg1, TArg2, TArg3>)
Expand Down Expand Up @@ -72,9 +67,17 @@ protected override bool ReadAndCacheConstructorArgument(ref ReadStack state, ref

protected override void InitializeConstructorArgumentCaches(ref ReadStack state, JsonSerializerOptions options)
{
JsonClassInfo classInfo = state.Current.JsonClassInfo;

if (classInfo.CreateObjectWithParameterizedCtor == null)
{
classInfo.CreateObjectWithParameterizedCtor =
options.MemberAccessorStrategy.CreateParameterizedConstructor<T, TArg0, TArg1, TArg2, TArg3>(ConstructorInfo)!;
}

var arguments = new Arguments<TArg0, TArg1, TArg2, TArg3>();

foreach (JsonParameterInfo parameterInfo in state.Current.JsonClassInfo.ParameterCache!.Values)
foreach (JsonParameterInfo parameterInfo in classInfo.ParameterCache!.Values)
{
if (parameterInfo.ShouldDeserialize)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,6 @@ public JsonClassInfo(Type type, JsonSerializerOptions options)

if (converter.ConstructorIsParameterized)
{
// Create and cache the constructor delegate for this type.
// We depend on the first converter created for this type to perform the initialization.
// Subsequent instances of the converter will not perform this initialization since we will
// not go down this code path (as the type will already be in the JsonClassInfo cache).
// The converter is used because it has generic type support.
converter.CreateConstructorDelegate(this, options);

InitializeConstructorParameters(converter.ConstructorInfo);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,5 @@ internal bool ShouldFlush(Utf8JsonWriter writer, ref WriteStack state)
internal virtual bool ConstructorIsParameterized => false;

internal ConstructorInfo ConstructorInfo { get; set; } = null!;
layomia marked this conversation as resolved.
Show resolved Hide resolved

internal virtual void CreateConstructorDelegate(JsonClassInfo classInfo, JsonSerializerOptions options) { }
}
}