Merge pull request #8541 from rolfbjarne/linker-no-constructor

[linker] Don't pass information to linker steps by selectively creating them or using constructors.

Instead use the built-in logic to determine if a linker step should light up,
and use information available in the LinkContext to determine how steps should
behave.

This is required for .NET, where linker steps can't have custom constructors.

Several steps have not been modified, because they're not all required in .NET.
This commit is contained in:
Rolf Bjarne Kvinge 2020-05-07 18:18:57 +02:00 коммит произвёл GitHub
Родитель 0511006ec2 d884c2a2c7
Коммит 0e03a929e4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
10 изменённых файлов: 64 добавлений и 77 удалений

Просмотреть файл

@ -23,13 +23,10 @@ namespace Xamarin.Linker.Steps {
public class CoreHttpMessageHandler : ExceptionalSubStep {
public CoreHttpMessageHandler (LinkerOptions options)
public CoreHttpMessageHandler ()
{
Options = options;
}
public LinkerOptions Options { get; private set; }
public override SubStepTargets Targets {
get { return SubStepTargets.Type; }
}
@ -39,11 +36,7 @@ namespace Xamarin.Linker.Steps {
Application App {
get {
#if MONOMAC
return Driver.App;
#else
return Options.Application;
#endif
return LinkContext.App;
}
}
@ -72,7 +65,7 @@ namespace Xamarin.Linker.Steps {
MethodDefinition method = type.Methods.First (x => x.Name == "GetHttpMessageHandler" && !x.HasParameters);
AssemblyDefinition systemNetHTTPAssembly = context.GetAssemblies ().First (x => x.Name.Name == "System.Net.Http");
TypeDefinition handler = RuntimeOptions.GetHttpMessageHandler (App, Options.RuntimeOptions, systemNetHTTPAssembly.MainModule, type.Module);
TypeDefinition handler = RuntimeOptions.GetHttpMessageHandler (App, LinkContext.Target.LinkerOptions.RuntimeOptions, systemNetHTTPAssembly.MainModule, type.Module);
MethodReference handler_ctor = handler.Methods.First (x => x.IsConstructor && !x.HasParameters && !x.IsStatic);
// HttpClientHandler is defined in System.Net.Http.dll so we need to import

Просмотреть файл

@ -26,19 +26,17 @@ namespace Xamarin.Linker {
protected bool HasOptimizableCode { get; private set; }
protected bool IsExtensionType { get; private set; }
protected LinkerOptions Options { get; set; }
public bool IsDualBuild {
get { return Options.Application.IsDualBuild; }
get { return LinkContext.App.IsDualBuild; }
}
public int Arch {
get { return Options.Target.Is64Build ? 8 : 4; }
get { return LinkContext.Target.Is64Build ? 8 : 4; }
}
protected Optimizations Optimizations {
get {
return Options.Application.Optimizations;
return LinkContext.App.Optimizations;
}
}
@ -47,14 +45,15 @@ namespace Xamarin.Linker {
bool? is_arm64_calling_convention;
public CoreOptimizeGeneratedCode (LinkerOptions options)
public override void Initialize (LinkContext context)
{
Options = options;
base.Initialize (context);
if (Optimizations.InlineIsARM64CallingConvention == true) {
if (options.Target.Abis.Count == 1) {
if (Optimizations.InlineIsARM64CallingConvention == true) {
var target = LinkContext.Target;
if (target.Abis.Count == 1) {
// We can usually inline Runtime.InlineIsARM64CallingConvention if the generated code will execute on a single architecture
switch ((options.Target.Abis [0] & Abi.ArchMask)) {
switch ((target.Abis [0] & Abi.ArchMask)) {
case Abi.i386:
case Abi.ARMv7:
case Abi.ARMv7s:
@ -70,10 +69,10 @@ namespace Xamarin.Linker {
// ARMv7k binaries can run on ARM64_32, so this can't be inlined :/
break;
default:
options.LinkContext.Exceptions.Add (ErrorHelper.CreateWarning (99, Errors.MX0099, $"unknown abi: {options.Target.Abis[0]}"));
LinkContext.Exceptions.Add (ErrorHelper.CreateWarning (99, Errors.MX0099, $"unknown abi: {target.Abis[0]}"));
break;
}
} else if (options.Target.Abis.Count == 2 && options.Target.Is32Build && options.Target.Abis.Contains (Abi.ARMv7) && options.Target.Abis.Contains (Abi.ARMv7s)) {
} else if (target.Abis.Count == 2 && target.Is32Build && target.Abis.Contains (Abi.ARMv7) && target.Abis.Contains (Abi.ARMv7s)) {
// We know we won't be running on arm64 if we're building for armv7+armv7s.
is_arm64_calling_convention = false;
}
@ -839,10 +838,10 @@ namespace Xamarin.Linker {
prev = prev.Previous; // Skip any nops.
if (prev.OpCode.StackBehaviourPush != StackBehaviour.Push1) {
//todo: localize mmp error 2106
ErrorHelper.Show (ErrorHelper.CreateWarning (Options.Application, 2106, caller, ins, Errors.MM2106, caller, ins.Offset, mr.Name, prev));
ErrorHelper.Show (ErrorHelper.CreateWarning (LinkContext.App, 2106, caller, ins, Errors.MM2106, caller, ins.Offset, mr.Name, prev));
return 0;
} else if (prev.OpCode.StackBehaviourPop != StackBehaviour.Pop0) {
ErrorHelper.Show (ErrorHelper.CreateWarning (Options.Application, 2106, caller, ins, Errors.MM2106, caller, ins.Offset, mr.Name, prev));
ErrorHelper.Show (ErrorHelper.CreateWarning (LinkContext.App, 2106, caller, ins, Errors.MM2106, caller, ins.Offset, mr.Name, prev));
return 0;
}
@ -853,12 +852,12 @@ namespace Xamarin.Linker {
// Then find the type of the previous instruction (the first argument to SetupBlock[Unsafe])
var trampolineDelegateType = GetPushedType (caller, loadTrampolineInstruction);
if (trampolineDelegateType == null) {
ErrorHelper.Show (ErrorHelper.CreateWarning (Options.Application, 2106, caller, ins, Errors.MM2106_A, caller, ins.Offset, mr.Name, loadTrampolineInstruction));
ErrorHelper.Show (ErrorHelper.CreateWarning (LinkContext.App, 2106, caller, ins, Errors.MM2106_A, caller, ins.Offset, mr.Name, loadTrampolineInstruction));
return 0;
}
if (trampolineDelegateType.Is ("System", "Delegate") || trampolineDelegateType.Is ("System", "MulticastDelegate")) {
ErrorHelper.Show (ErrorHelper.CreateWarning (Options.Application, 2106, caller, ins, Errors.MM2106_B, caller, trampolineDelegateType.FullName, mr.Name));
ErrorHelper.Show (ErrorHelper.CreateWarning (LinkContext.App, 2106, caller, ins, Errors.MM2106_B, caller, trampolineDelegateType.FullName, mr.Name));
return 0;
}
@ -881,7 +880,7 @@ namespace Xamarin.Linker {
// No luck finding the signature, so give up.
if (userMethod == null) {
ErrorHelper.Show (ErrorHelper.CreateWarning (Options.Application, 2106, caller, ins, Errors.MM2106_C, caller, ins.Offset, trampolineDelegateType.FullName));
ErrorHelper.Show (ErrorHelper.CreateWarning (LinkContext.App, 2106, caller, ins, Errors.MM2106_C, caller, ins.Offset, trampolineDelegateType.FullName));
return 0;
}
@ -890,7 +889,7 @@ namespace Xamarin.Linker {
parameters [p] = userMethod.Parameters [p].ParameterType;
signature = LinkContext.Target.StaticRegistrar.ComputeSignature (userMethod.DeclaringType, false, userMethod.ReturnType, parameters, userMethod.Resolve (), isBlockSignature: blockSignature);
} catch (Exception e) {
ErrorHelper.Show (ErrorHelper.CreateWarning (Options.Application, 2106, e, caller, ins, Errors.MM2106_D, caller, ins.Offset, e.Message));
ErrorHelper.Show (ErrorHelper.CreateWarning (LinkContext.App, 2106, e, caller, ins, Errors.MM2106_D, caller, ins.Offset, e.Message));
return 0;
}
@ -1031,7 +1030,7 @@ namespace Xamarin.Linker {
break;
}
if (setupblock_def == null)
throw ErrorHelper.CreateError (Options.Application, 99, caller, ins, Errors.MX0099, $"could not find the method {Namespaces.ObjCRuntime}.BlockLiteral.SetupBlockImpl");
throw ErrorHelper.CreateError (LinkContext.App, 99, caller, ins, Errors.MX0099, $"could not find the method {Namespaces.ObjCRuntime}.BlockLiteral.SetupBlockImpl");
}
return caller.Module.ImportReference (setupblock_def);
}

Просмотреть файл

@ -15,6 +15,13 @@ namespace Xamarin.Linker {
}
}
public override bool IsActiveFor (AssemblyDefinition assembly)
{
if (LinkContext.App.Optimizations.CustomAttributesRemoval != true)
return false;
return base.IsActiveFor (assembly);
}
protected override bool IsRemovedAttribute (CustomAttribute attribute)
{
// note: this also avoid calling FullName (which allocates a string)

Просмотреть файл

@ -4,12 +4,27 @@ using Mono.Linker;
using Mono.Cecil;
using Xamarin.Bundler;
using Xamarin.Tuner;
namespace Mono.Tuner {
public class CoreRemoveSecurity : RemoveSecurity {
protected DerivedLinkContext LinkContext {
get {
return (DerivedLinkContext) base.context;
}
}
public override bool IsActiveFor (AssemblyDefinition assembly)
{
#if MMP
// CoreRemoveSecurity can modify non-linked assemblies
// but the conditions for this cannot happen if only the platform assembly is linked
if (LinkContext.App.LinkMode == LinkMode.Platform)
return false;
#endif
// if we run the linker then we can't ignore any assemblies since the security
// declarations can refers to types that would not be marked (and preserved)
// leading to invalid binaries (that even Cecil won't be able to read back)

Просмотреть файл

@ -7,16 +7,9 @@ using Xamarin.Linker;
using Xamarin.Bundler;
namespace MonoTouch.Tuner {
public class OptimizeGeneratedCodeSubStep : CoreOptimizeGeneratedCode {
public OptimizeGeneratedCodeSubStep (LinkerOptions options)
: base (options)
{
}
public bool Device {
get { return Options.Device; }
get { return LinkContext.App.IsDeviceBuild; }
}
// https://app.asana.com/0/77259014252/77812690163

Просмотреть файл

@ -11,18 +11,12 @@ namespace MonoTouch.Tuner {
bool product;
public RemoveCode (LinkerOptions options)
{
Device = options.Device;
Debug = options.DebugBuild;
}
protected override string Name { get; } = "Code Remover";
protected override int ErrorCode { get; } = 2050;
public bool Device { get; set; }
public bool Device { get { return LinkContext.App.IsDeviceBuild; } }
public bool Debug { get; set; }
public bool Debug { get { return LinkContext.App.EnableDebug; } }
public override SubStepTargets Targets {
get { return SubStepTargets.Assembly | SubStepTargets.Type; }
@ -30,6 +24,9 @@ namespace MonoTouch.Tuner {
public override bool IsActiveFor (AssemblyDefinition assembly)
{
if (!LinkContext.Target.LinkerOptions.LinkAway)
return false;
switch (assembly.Name.Name) {
case "mscorlib":
product = false;

Просмотреть файл

@ -12,11 +12,6 @@ namespace Xamarin.Linker {
#if MTOUCH
const string Content = "__monotouch_content_";
const string Page = "__monotouch_page_";
public RemoveUserResourcesSubStep (MonoTouch.Tuner.LinkerOptions options)
{
Device = options.Device;
}
#else
const string Content = "__xammac_content_";
const string Page = "__xammac_page_";
@ -25,7 +20,7 @@ namespace Xamarin.Linker {
get { return SubStepTargets.Assembly; }
}
public bool Device { get; private set; }
public bool Device { get { return LinkContext.App.IsDeviceBuild; } }
protected override string Name { get; } = "Removing User Resources";
protected override int ErrorCode { get; } = 2030;

Просмотреть файл

@ -133,7 +133,7 @@ namespace MonoMac.Tuner {
if (options.LinkMode != LinkMode.None) {
pipeline.Append (new CoreTypeMapStep ());
pipeline.Append (GetSubSteps (options));
pipeline.Append (GetSubSteps ());
pipeline.Append (new CorePreserveCode (options.I18nAssemblies));
pipeline.Append (new PreserveCrypto ());
@ -165,23 +165,19 @@ namespace MonoMac.Tuner {
return pipeline;
}
static SubStepDispatcher GetSubSteps (LinkerOptions options)
static SubStepDispatcher GetSubSteps ()
{
SubStepDispatcher sub = new SubStepDispatcher ();
sub.Add (new ApplyPreserveAttribute ());
sub.Add (new OptimizeGeneratedCodeSubStep (options));
sub.Add (new OptimizeGeneratedCodeSubStep ());
sub.Add (new RemoveUserResourcesSubStep ());
// OptimizeGeneratedCodeSubStep and RemoveUserResourcesSubStep needs [GeneratedCode] so it must occurs before RemoveAttributes
if (options.Application.Optimizations.CustomAttributesRemoval == true)
sub.Add (new CoreRemoveAttributes ());
sub.Add (new CoreRemoveAttributes ());
sub.Add (new CoreHttpMessageHandler (options));
sub.Add (new CoreHttpMessageHandler ());
sub.Add (new MarkNSObjects ());
// CoreRemoveSecurity can modify non-linked assemblies
// but the conditions for this cannot happen if only the platform assembly is linked
if (options.LinkMode != LinkMode.Platform)
sub.Add (new CoreRemoveSecurity ());
sub.Add (new CoreRemoveSecurity ());
return sub;
}

Просмотреть файл

@ -7,12 +7,6 @@ using Mono.Tuner;
using Xamarin.Linker;
namespace MonoMac.Tuner {
public class OptimizeGeneratedCodeSubStep : CoreOptimizeGeneratedCode {
public OptimizeGeneratedCodeSubStep (LinkerOptions options)
: base (options)
{
}
}
}

Просмотреть файл

@ -100,21 +100,19 @@ namespace MonoTouch.Tuner {
return context;
}
static SubStepDispatcher GetSubSteps (LinkerOptions options)
static SubStepDispatcher GetSubSteps ()
{
SubStepDispatcher sub = new SubStepDispatcher ();
sub.Add (new ApplyPreserveAttribute ());
sub.Add (new CoreRemoveSecurity ());
sub.Add (new OptimizeGeneratedCodeSubStep (options));
sub.Add (new RemoveUserResourcesSubStep (options));
if (options.Application.Optimizations.CustomAttributesRemoval == true)
sub.Add (new RemoveAttributes ());
sub.Add (new OptimizeGeneratedCodeSubStep ());
sub.Add (new RemoveUserResourcesSubStep ());
sub.Add (new RemoveAttributes ());
// http://bugzilla.xamarin.com/show_bug.cgi?id=1408
if (options.LinkAway)
sub.Add (new RemoveCode (options));
sub.Add (new RemoveCode ());
sub.Add (new MarkNSObjects ());
sub.Add (new PreserveSoapHttpClients ());
sub.Add (new CoreHttpMessageHandler (options));
sub.Add (new CoreHttpMessageHandler ());
sub.Add (new InlinerSubStep ());
sub.Add (new PreserveSmartEnumConversionsSubStep ());
return sub;
@ -166,7 +164,7 @@ namespace MonoTouch.Tuner {
if (options.LinkMode != LinkMode.None) {
pipeline.Append (new CoreTypeMapStep ());
pipeline.Append (GetSubSteps (options));
pipeline.Append (GetSubSteps ());
pipeline.Append (new PreserveCode (options));
@ -188,7 +186,7 @@ namespace MonoTouch.Tuner {
pipeline.Append (new FixModuleFlags ());
} else {
SubStepDispatcher sub = new SubStepDispatcher () {
new RemoveUserResourcesSubStep (options),
new RemoveUserResourcesSubStep (),
};
if (options.Application.Optimizations.ForceRejectedTypesRemoval == true)
sub.Add (new RemoveRejectedTypesStep ());