[mtouch][mmp] Add control over the the linker new `BeforeFieldInit` optimization (#5820)

Add an mtouch/mmp optimization flag to control this new optimization since
3rd party code (in particular binaries) might depend on this side effect.
This commit is contained in:
Sebastien Pouliot 2019-04-01 21:21:56 -05:00 коммит произвёл GitHub
Родитель 7b1f3bbd99
Коммит a9f8d7b379
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 37 добавлений и 3 удалений

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

@ -717,3 +717,23 @@ unless the interpreter is used.
The default behavior can be overridden by passing
`--optimize=[+|-]seal-and-devirtualize` to `mtouch`.
## Static constructors for BeforeFieldInit removal
This optimization requires the linker to be enabled and is applied globally
on all code inside the application.
This optimization allows the linker not to mark every `.cctor` when a type
is preserved, e.g. whenever the class/static constructor `.cctor` is only
used for field initialization and those fields are not marked themselves
then it is possible to remove the `.cctor`.
This optimization is enabled, by default, on both Xamarin.iOS and
Xamarin.Mac. However it represent a change from older versions of the linker.
It is possible that some existing code depend on this side effect (i.e.
those `.cctor` not being removed). In such case the optimization can be
disabled until the correct linker annotations (e.g.
`[Preserve (Conditional=true)]`) are added.
The default behavior can be overridden by passing
`--optimize=[+|-]cctor-beforefieldinit` to `mtouch` or `mmp`.

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

@ -646,7 +646,7 @@ namespace Xamarin.MMP.Tests
"<LinkMode>Full</LinkMode>",
};
var rv = TI.TestUnifiedExecutable (test, shouldFail: false);
rv.Messages.AssertWarning (132, $"Unknown optimization: '{opt}'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock, register-protocols, inline-dynamic-registration-supported, static-block-to-delegate-lookup, trim-architectures, inline-is-arm64-calling-convention.");
rv.Messages.AssertWarning (132, $"Unknown optimization: '{opt}'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, blockliteral-setupblock, register-protocols, inline-dynamic-registration-supported, static-block-to-delegate-lookup, trim-architectures, inline-is-arm64-calling-convention, cctor-beforefieldinit.");
rv.Messages.AssertErrorCount (0);
});
}

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

@ -1752,7 +1752,7 @@ public class TestApp {
mtouch.Linker = MTouchLinker.LinkSdk;
mtouch.Optimize = new string [] { "foo" };
mtouch.AssertExecute (MTouchAction.BuildSim, "build");
mtouch.AssertWarning (132, "Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, inline-runtime-arch, blockliteral-setupblock, register-protocols, inline-dynamic-registration-supported, static-block-to-delegate-lookup, remove-dynamic-registrar, remove-unsupported-il-for-bitcode, inline-is-arm64-calling-convention, seal-and-devirtualize.");
mtouch.AssertWarning (132, "Unknown optimization: 'foo'. Valid optimizations are: remove-uithread-checks, dead-code-elimination, inline-isdirectbinding, inline-intptr-size, inline-runtime-arch, blockliteral-setupblock, register-protocols, inline-dynamic-registration-supported, static-block-to-delegate-lookup, remove-dynamic-registrar, remove-unsupported-il-for-bitcode, inline-is-arm64-calling-convention, seal-and-devirtualize, cctor-beforefieldinit.");
}
}
@ -3564,7 +3564,8 @@ public partial class NotificationService : UNNotificationServiceExtension
mtouch.AssertWarning (2003, "Option '--optimize=static-block-to-delegate-lookup' will be ignored since the static registrar is not enabled");
mtouch.AssertWarning (2003, "Option '--optimize=inline-is-arm64-calling-convention' will be ignored since linking is disabled");
mtouch.AssertWarning (2003, "Option '--optimize=seal-and-devirtualize' will be ignored since linking is disabled");
mtouch.AssertWarningCount (12);
mtouch.AssertWarning (2003, "Option '--optimize=cctor-beforefieldinit' will be ignored since linking is disabled");
mtouch.AssertWarningCount (13);
}
using (var mtouch = new MTouchTool ()) {

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

@ -40,6 +40,7 @@ namespace Xamarin.Bundler
#else
"", // dummy value to make indices match up between XM and XI
#endif
"cctor-beforefieldinit",
};
enum Opt
@ -58,6 +59,7 @@ namespace Xamarin.Bundler
RemoveUnsupportedILForBitcode,
InlineIsARM64CallingConvention,
SealAndDevirtualize,
StaticConstructorBeforeFieldInit,
}
bool? all;
@ -131,6 +133,11 @@ namespace Xamarin.Bundler
}
#endif
public bool? StaticConstructorBeforeFieldInit {
get { return values [(int) Opt.StaticConstructorBeforeFieldInit]; }
set { values [(int) Opt.StaticConstructorBeforeFieldInit] = value; }
}
public Optimizations ()
{
values = new bool? [opt_names.Length];
@ -283,6 +290,10 @@ namespace Xamarin.Bundler
if (!InlineIsARM64CallingConvention.HasValue)
InlineIsARM64CallingConvention = true;
// by default we try to eliminate any .cctor we can
if (!StaticConstructorBeforeFieldInit.HasValue)
StaticConstructorBeforeFieldInit = true;
if (Driver.Verbosity > 3)
Driver.Log (4, "Enabled optimizations: {0}", string.Join (", ", values.Select ((v, idx) => v == true ? opt_names [idx] : string.Empty).Where ((v) => !string.IsNullOrEmpty (v))));
}

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

@ -136,6 +136,8 @@ namespace MonoTouch.Tuner {
context.Target = options.Target;
context.ExcludedFeatures = new [] { "remoting", "com", "sre" };
context.SymbolWriterProvider = new CustomSymbolWriterProvider ();
if (options.Application.Optimizations.StaticConstructorBeforeFieldInit == false)
context.DisabledOptimizations |= CodeOptimizations.BeforeFieldInit;
options.LinkContext = context;
return context;