Imported Upstream version 5.14.0.156

Former-commit-id: ce0a73a36728a56d19f47892a92fda2d0d642f64
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-06-30 08:22:57 +00:00
parent 01c08d50e8
commit e747ac1590
45 changed files with 271 additions and 59 deletions

View File

@@ -253,6 +253,10 @@ namespace Mono.Linker.Steps {
Tracer.Push (provider);
try {
foreach (CustomAttribute ca in provider.CustomAttributes) {
if (IsUserDependencyMarker (ca.AttributeType)) {
MarkUserDependency (provider as MethodReference, ca);
continue;
}
if (_context.KeepUsedAttributeTypesOnly) {
_lateMarkedAttributes.Enqueue (new AttributeProviderPair (ca, provider));
@@ -268,6 +272,151 @@ namespace Mono.Linker.Steps {
}
}
protected virtual bool IsUserDependencyMarker (TypeReference type)
{
return type.Name == "PreserveDependencyAttribute" &&
type.Namespace == "System.Runtime.CompilerServices";
}
protected virtual void MarkUserDependency (MethodReference context, CustomAttribute ca)
{
var args = ca.ConstructorArguments;
if (args.Count == 2 && args[1].Value is string condition) {
switch (condition) {
case "":
case null:
break;
case "DEBUG":
if (!_context.KeepMembersForDebugger)
return;
break;
default:
// Don't have yet a way to match the general condition so everything is excluded
return;
}
}
if (args.Count >= 1 && args[0].Value is string dependency) {
string member = null;
string type = null;
string[] signature = null;
TypeDefinition td = null;
var sign_start = dependency.IndexOf ('(');
var sign_end = dependency.LastIndexOf (')');
if (sign_start > 0 && sign_end > sign_start) {
var parameters = dependency.Substring (sign_start + 1, sign_end - sign_start - 1).Replace (" ", "");
signature = string.IsNullOrEmpty (parameters) ? Array.Empty<string> () : parameters.Split (',');
var idx = dependency.LastIndexOf ('.', sign_start);
if (idx > 0) {
member = dependency.Substring (idx + 1, sign_start - idx - 1).TrimEnd ();
type = dependency.Substring (0, idx);
} else {
member = dependency.Substring (0, sign_start - 1);
td = context.DeclaringType.Resolve ();
}
} else if (sign_start < 0) {
var idx = dependency.LastIndexOf ('.');
if (idx > 0) {
member = dependency.Substring (idx + 1);
type = dependency.Substring (0, idx);
} else {
member = dependency;
td = context.DeclaringType.Resolve ();
}
}
if (td == null) {
if (type == null) {
_context.Logger.LogMessage (MessageImportance.Low, $"Could not resolve '{dependency}' dependency");
return;
}
td = FindType (context.Module.Assembly, type);
if (td == null) {
_context.Logger.LogMessage (MessageImportance.Low, $"Could not find '{dependency}' dependency");
return;
}
}
if (MarkDependencyMethod (td, member, signature))
return;
if (MarkDependencyField (td, member))
return;
_context.Logger.LogMessage (MessageImportance.High, $"Could not resolve dependency member '{member}' declared in type '{dependency}'");
}
}
static TypeDefinition FindType (AssemblyDefinition assembly, string fullName)
{
fullName = fullName.ToCecilName ();
var type = assembly.MainModule.GetType (fullName);
return type?.Resolve ();
}
bool MarkDependencyMethod (TypeDefinition type, string name, string[] signature)
{
bool marked = false;
int arity;
int arity_marker = name.IndexOf ('`');
if (arity_marker < 1 || !int.TryParse (name.Substring (arity_marker + 1), out arity)) {
arity = 0;
} else {
name = name.Substring (0, arity_marker);
}
foreach (var m in type.Methods) {
if (m.Name != name)
continue;
if (m.GenericParameters.Count != arity)
continue;
if (signature == null) {
MarkMethod (m);
marked = true;
continue;
}
var mp = m.Parameters;
if (mp.Count != signature.Length)
continue;
int i = 0;
for (; i < signature.Length; ++i) {
if (mp [i].ParameterType.FullName != signature [i].Trim ().ToCecilName ()) {
i = -1;
break;
}
}
if (i < 0)
continue;
MarkMethod (m);
marked = true;
}
return marked;
}
bool MarkDependencyField (TypeDefinition type, string name)
{
foreach (var f in type.Fields) {
if (f.Name == name) {
MarkField (f);
return true;
}
}
return false;
}
void LazyMarkCustomAttributes (ICustomAttributeProvider provider, AssemblyDefinition assembly)
{
if (!provider.HasCustomAttributes)
@@ -303,15 +452,17 @@ namespace Mono.Linker.Steps {
protected virtual bool ShouldMarkCustomAttribute (CustomAttribute ca, ICustomAttributeProvider provider)
{
var attr_type = ca.AttributeType;
if (_context.KeepUsedAttributeTypesOnly) {
switch (ca.AttributeType.FullName) {
switch (attr_type.FullName) {
// [ThreadStatic] and [ContextStatic] are required by the runtime
case "System.ThreadStaticAttribute":
case "System.ContextStaticAttribute":
return true;
}
if (!Annotations.IsMarked (ca.AttributeType.Resolve ()))
if (!Annotations.IsMarked (attr_type.Resolve ()))
return false;
}
@@ -872,7 +1023,7 @@ namespace Mono.Linker.Steps {
void MarkTypeWithDebuggerDisplayAttribute (TypeDefinition type, CustomAttribute attribute)
{
if (_context.KeepMembersForDebuggerAttributes) {
if (_context.KeepMembersForDebugger) {
string displayString = (string) attribute.ConstructorArguments[0].Value;
@@ -926,7 +1077,7 @@ namespace Mono.Linker.Steps {
void MarkTypeWithDebuggerTypeProxyAttribute (TypeDefinition type, CustomAttribute attribute)
{
if (_context.KeepMembersForDebuggerAttributes) {
if (_context.KeepMembersForDebugger) {
object constructorArgument = attribute.ConstructorArguments[0].Value;
TypeReference proxyTypeReference = constructorArgument as TypeReference;
if (proxyTypeReference == null) {

View File

@@ -154,6 +154,11 @@ namespace Mono.Linker.Steps {
{
while (iterator.MoveNext ()) {
XPathNavigator nav = iterator.Current;
var feature = GetAttribute (nav, "feature");
if (Context.IsFeatureExcluded (feature))
continue;
string fullname = GetFullName (nav);
if (IsTypePattern (fullname)) {

View File

@@ -178,8 +178,9 @@ namespace Mono.Linker.Steps {
if (!AreSameReference (r.Name, target.Name))
continue;
ReferenceRemoved (assembly, references [i]);
references.RemoveAt (i);
ReferenceRemoved (assembly, reference);
// removal from `references` requires an adjustment to `i`
references.RemoveAt (i--);
// Removing the reference does not mean it will be saved back to disk!
// That depends on the AssemblyAction set for the `assembly`
switch (Annotations.GetAction (assembly)) {
@@ -208,7 +209,6 @@ namespace Mono.Linker.Steps {
}
break;
}
return;
}
}

View File

@@ -89,6 +89,7 @@ namespace Mono.Linker {
I18nAssemblies assemblies = I18nAssemblies.All;
var custom_steps = new List<string> ();
var excluded_features = new HashSet<string> ();
bool dumpDependencies = false;
bool resolver = false;
@@ -136,7 +137,7 @@ namespace Mono.Linker {
context.KeepUsedAttributeTypesOnly = bool.Parse (GetParam ());
continue;
}
if (token == "--strip-security") {
if (bool.Parse (GetParam ()))
p.AddStepBefore (typeof (MarkStep), new RemoveSecurityStep ());
@@ -148,6 +149,13 @@ namespace Mono.Linker {
continue;
}
if (token == "--exclude-feature") {
var name = GetParam ();
if (!excluded_features.Contains (name))
excluded_features.Add (name);
continue;
}
switch (token [2]) {
case 'v':
Version ();
@@ -162,11 +170,10 @@ namespace Mono.Linker {
}
switch (token [1]) {
case 'd': {
case 'd':
DirectoryInfo info = new DirectoryInfo (GetParam ());
context.Resolver.AddSearchDirectory (info.FullName);
break;
}
break;
case 'o':
context.OutputDirectory = GetParam ();
break;
@@ -219,11 +226,11 @@ namespace Mono.Linker {
p.RemoveStep (typeof (RegenerateGuidStep));
break;
case 'z':
if (!bool.Parse (GetParam ()))
p.RemoveStep (typeof (BlacklistStep));
break;
if (!bool.Parse (GetParam ()))
p.RemoveStep (typeof (BlacklistStep));
break;
case 'v':
context.KeepMembersForDebuggerAttributes = bool.Parse (GetParam ());
context.KeepMembersForDebugger = bool.Parse (GetParam ());
break;
default:
Usage ("Unknown option: `" + token [1] + "'");
@@ -246,6 +253,12 @@ namespace Mono.Linker {
p.AddStepAfter (typeof (SweepStep), new AddBypassNGenStep ());
}
if (excluded_features.Count > 0) {
var excluded = new string [excluded_features.Count];
excluded_features.CopyTo (excluded);
context.ExcludedFeatures = excluded;
}
try {
p.Process (context);
}
@@ -375,6 +388,7 @@ namespace Mono.Linker {
Console.WriteLine (" --used-attrs-only Attributes on types, methods, etc will be removed if the attribute type is not used");
Console.WriteLine (" --strip-security In linked assemblies, attributes on assemblies, types, and methods related to security will be removed");
Console.WriteLine (" --strip-resources Remove link xml resources that were processed (true or false), default to true");
Console.WriteLine (" --exclude-feature Any code which has feature-name dependency will be removed");
Console.WriteLine (" -out Specify the output directory, default to `output'");
Console.WriteLine (" -c Action on the core assemblies, skip, copy, copyused, addbypassngen, addbypassngenused or link, default to skip");
Console.WriteLine (" -u Action on the user assemblies, skip, copy, copyused, addbypassngen, addbypassngenused or link, default to link");
@@ -384,7 +398,7 @@ namespace Mono.Linker {
Console.WriteLine (" -d Add a directory where the linker will look for assemblies");
Console.WriteLine (" -b Generate debug symbols for each linked module (true or false)");
Console.WriteLine (" -g Generate a new unique guid for each linked module (true or false)");
Console.WriteLine (" -v Keep memebers needed by debugger attributes (true or false)");
Console.WriteLine (" -v Keep members needed by debugger (true or false)");
Console.WriteLine (" -l List of i18n assemblies to copy to the output directory");
Console.WriteLine (" separated with a comma: none,all,cjk,mideast,other,rare,west");
Console.WriteLine (" default is all");

View File

@@ -50,7 +50,7 @@ namespace Mono.Linker {
readonly Dictionary<string, string> _parameters;
bool _linkSymbols;
bool _keepTypeForwarderOnlyAssemblies;
bool _keepMembersForDebuggerAttributes;
bool _keepMembersForDebugger;
bool _ignoreUnresolved;
AssemblyResolver _resolver;
@@ -95,10 +95,10 @@ namespace Mono.Linker {
set { _keepTypeForwarderOnlyAssemblies = value; }
}
public bool KeepMembersForDebuggerAttributes
public bool KeepMembersForDebugger
{
get { return _keepMembersForDebuggerAttributes; }
set { _keepMembersForDebuggerAttributes = value; }
get { return _keepMembersForDebugger; }
set { _keepMembersForDebugger = value; }
}
public bool IgnoreUnresolved
@@ -135,7 +135,7 @@ namespace Mono.Linker {
set { _symbolWriterProvider = value; }
}
public bool LogMessages { get; set; } = false;
public bool LogMessages { get; set; }
public ILogger Logger { get; set; } = new ConsoleLogger ();
@@ -143,6 +143,8 @@ namespace Mono.Linker {
public Tracer Tracer { get; private set; }
public string[] ExcludedFeatures { get; set; }
public LinkContext (Pipeline pipeline)
: this (pipeline, new AssemblyResolver ())
{
@@ -179,7 +181,7 @@ namespace Mono.Linker {
public TypeDefinition GetType (string fullName)
{
int pos = fullName.IndexOf (",");
fullName = fullName.Replace ("+", "/");
fullName = TypeReferenceExtensions.ToCecilName (fullName);
if (pos == -1) {
foreach (AssemblyDefinition asm in GetAssemblies ()) {
var type = asm.MainModule.GetType (fullName);
@@ -353,6 +355,11 @@ namespace Mono.Linker {
_resolver.Dispose ();
}
public bool IsFeatureExcluded (string featureName)
{
return ExcludedFeatures != null && Array.IndexOf (ExcludedFeatures, featureName) >= 0;
}
public void LogMessage (string message, params object[] values)
{
LogMessage (MessageImportance.Normal, message, values);

View File

@@ -195,5 +195,10 @@ namespace Mono.Linker
return method;
}
public static string ToCecilName (this string fullTypeName)
{
return fullTypeName.Replace ('+', '/');
}
}
}