Skip to content

Commit

Permalink
Make default comparers a removable feature
Browse files Browse the repository at this point in the history
Adding to make it possible to work around current problems in dotnet#7208 when reflection is disabled.

Comparers also root the entire type loader, so making this optional puts as on a path where we can make type loader optional too. Type loader is about 500 kB of junk. If we can remove it, our Hello world size becomes competitive with Go. People who are willing to walk the extra mile to make their code compatible with this get very small deployment sizes that are especially important for e.g. the WASM target.
  • Loading branch information
MichalStrehovsky committed Mar 24, 2019
1 parent 3302cd3 commit 5b78379
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/ILCompiler/src/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,8 @@ private int Run(string[] args)
removedFeatures |= RemovedFeature.FrameworkResources;
else if (feature == "Globalization")
removedFeatures |= RemovedFeature.Globalization;
else if (feature == "Comparers")
removedFeatures |= RemovedFeature.Comparers;
}

ILProvider ilProvider = _isReadyToRunCodeGen ? (ILProvider)new ReadyToRunILProvider() : new CoreRTILProvider();
Expand Down
40 changes: 39 additions & 1 deletion src/ILCompiler/src/RemovingILProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ public RemovingILProvider(ILProvider baseILProvider, RemovedFeature feature)

public override MethodIL GetMethodIL(MethodDesc method)
{
switch (GetAction(method))
RemoveAction action = GetAction(method);
switch (action)
{
case RemoveAction.Nothing:
return _baseILProvider.GetMethodIL(method);
Expand All @@ -48,6 +49,26 @@ public override MethodIL GetMethodIL(MethodDesc method)
case RemoveAction.ConvertToThrow:
return new ILStubMethodIL(method, new byte[] { (byte)ILOpcode.ldnull, (byte)ILOpcode.throw_ }, Array.Empty<LocalVariableDefinition>(), null);

case RemoveAction.ConvertToGetKnownObjectComparer:
case RemoveAction.ConvertToGetKnownObjectEqualityComparer:
{
TypeSystemContext context = method.Context;
MetadataType comparerType =
action == RemoveAction.ConvertToGetKnownObjectComparer ?
context.SystemModule.GetType("System.Collections.Generic", "ObjectComparer`1") :
context.SystemModule.GetType("System.Collections.Generic", "ObjectEqualityComparer`1");

MethodDesc methodDef = method.GetTypicalMethodDefinition();

ILEmitter emitter = new ILEmitter();
ILCodeStream codeStream = emitter.NewCodeStream();
codeStream.Emit(ILOpcode.newobj, emitter.NewToken(comparerType.MakeInstantiatedType(context.GetSignatureVariable(0, method: false)).GetDefaultConstructor()));
codeStream.Emit(ILOpcode.dup);
codeStream.Emit(ILOpcode.stsfld, emitter.NewToken(methodDef.OwningType.InstantiateAsOpen().GetField("_default")));
codeStream.Emit(ILOpcode.ret);
return new InstantiatedMethodIL(method, emitter.Link(methodDef));
}

default:
throw new NotImplementedException();
}
Expand Down Expand Up @@ -131,6 +152,20 @@ owningType is Internal.TypeSystem.Ecma.EcmaType mdType &&
}
}

if ((_removedFeature & RemovedFeature.Comparers) != 0)
{
if (owningType.GetTypeDefinition() is Internal.TypeSystem.Ecma.EcmaType mdType
&& mdType.Module == method.Context.SystemModule
&& method.Name == "Create"
&& mdType.Namespace == "System.Collections.Generic")
{
if (mdType.Name == "EqualityComparer`1")
return RemoveAction.ConvertToGetKnownObjectEqualityComparer;
else if (mdType.Name == "Comparer`1")
return RemoveAction.ConvertToGetKnownObjectComparer;
}
}

return RemoveAction.Nothing;
}

Expand Down Expand Up @@ -170,6 +205,8 @@ private enum RemoveAction

ConvertToTrueStub,
ConvertToGetResourceStringStub,
ConvertToGetKnownObjectComparer,
ConvertToGetKnownObjectEqualityComparer,
}
}

Expand All @@ -179,5 +216,6 @@ public enum RemovedFeature
Etw = 0x1,
FrameworkResources = 0x2,
Globalization = 0x4,
Comparers = 0x8,
}
}

0 comments on commit 5b78379

Please sign in to comment.