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:
Коммит
0e03a929e4
|
@ -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 ());
|
||||
|
|
Загрузка…
Ссылка в новой задаче