[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:
Родитель
7b1f3bbd99
Коммит
a9f8d7b379
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче