Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

Commit ad1b0d8

Browse files
[XamlC] cache ImportReference and ImportMethodReference as they're slow (#2025)
* [XamlC] cache ImportReference and ImportMethodReference as they're slow on ns1.4 * more ns14 fixes
1 parent 6100b00 commit ad1b0d8

21 files changed

+452
-257
lines changed

Xamarin.Forms.Build.Tasks/CompiledConverters/BindingTypeConverter.cs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
using System.Collections.Generic;
2-
using System.Linq;
3-
4-
using Mono.Cecil;
52
using Mono.Cecil.Cil;
63

74
using Xamarin.Forms.Xaml;
@@ -20,14 +17,19 @@ public IEnumerable<Instruction> ConvertFromString(string value, ILContext contex
2017
if (IsNullOrEmpty(value))
2118
throw new XamlParseException($"Cannot convert \"{value}\" into {typeof(Binding)}", node);
2219

23-
var bindingCtorRef = module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Binding"), paramCount: 6);
2420
yield return Instruction.Create(OpCodes.Ldstr, value);
2521
yield return Instruction.Create(OpCodes.Ldc_I4, (int)BindingMode.Default);
2622
yield return Instruction.Create(OpCodes.Ldnull);
2723
yield return Instruction.Create(OpCodes.Ldnull);
2824
yield return Instruction.Create(OpCodes.Ldnull);
2925
yield return Instruction.Create(OpCodes.Ldnull);
30-
yield return Instruction.Create(OpCodes.Newobj, bindingCtorRef);
26+
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Binding"), parameterTypes: new[] {
27+
("mscorlib", "System", "String"),
28+
("Xamarin.Forms.Core", "Xamarin.Forms", "BindingMode"),
29+
("Xamarin.Forms.Core", "Xamarin.Forms", "IValueConverter"),
30+
("mscorlib", "System", "Object"),
31+
("mscorlib", "System", "String"),
32+
("mscorlib", "System", "Object")}));
3133
}
3234
}
3335
}

Xamarin.Forms.Build.Tasks/CompiledConverters/BoundsTypeConverter.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,11 @@ IEnumerable<Instruction> GenerateIL(double x, double y, double w, double h, Modu
6767
yield return Instruction.Create(OpCodes.Ldc_R8, y);
6868
yield return Instruction.Create(OpCodes.Ldc_R8, w);
6969
yield return Instruction.Create(OpCodes.Ldc_R8, h);
70-
71-
var rectangleCtorRef = module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Rectangle"), paramCount: 4);
72-
yield return Instruction.Create(OpCodes.Newobj, rectangleCtorRef);
70+
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Rectangle"), parameterTypes: new[] {
71+
("mscorlib", "System", "Double"),
72+
("mscorlib", "System", "Double"),
73+
("mscorlib", "System", "Double"),
74+
("mscorlib", "System", "Double")}));
7375
}
7476
}
7577
}

Xamarin.Forms.Build.Tasks/CompiledConverters/ColorTypeConverter.cs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ public IEnumerable<Instruction> ConvertFromString(string value, ILContext contex
2929
yield return Instruction.Create(OpCodes.Ldc_R8, color.B);
3030
yield return Instruction.Create(OpCodes.Ldc_R8, color.A);
3131

32-
var colorCtorRef = module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Color"),
33-
paramCount: 4,
34-
predicate: md => md.Parameters.All(p => p.ParameterType.FullName == "System.Double"));
35-
yield return Instruction.Create(OpCodes.Newobj, colorCtorRef);
32+
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Color"), parameterTypes: new[] {
33+
("mscorlib", "System", "Double"),
34+
("mscorlib", "System", "Double"),
35+
("mscorlib", "System", "Double"),
36+
("mscorlib", "System", "Double")}));
3637
yield break;
3738
}
3839
var parts = value.Split('.');
@@ -41,14 +42,12 @@ public IEnumerable<Instruction> ConvertFromString(string value, ILContext contex
4142

4243
var fieldReference = module.ImportFieldReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Color"),
4344
color,
44-
fd => fd.IsStatic);
45+
isStatic: true);
4546
if (fieldReference != null) {
4647
yield return Instruction.Create(OpCodes.Ldsfld, fieldReference);
4748
yield break;
4849
}
49-
var propertyGetterReference = module.ImportPropertyGetterReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Color"),
50-
color,
51-
pd => pd.GetMethod.IsStatic);
50+
var propertyGetterReference = module.ImportPropertyGetterReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Color"), color, isStatic: true);
5251
if (propertyGetterReference != null) {
5352
yield return Instruction.Create(OpCodes.Call, propertyGetterReference);
5453
yield break;
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
using System.Collections.Generic;
22
using System.Globalization;
3-
using System.Linq;
43

5-
using Mono.Cecil;
64
using Mono.Cecil.Cil;
75

86
using Xamarin.Forms.Xaml;
97
using Xamarin.Forms.Build.Tasks;
108

9+
using static Mono.Cecil.Cil.Instruction;
10+
using static Mono.Cecil.Cil.OpCodes;
11+
1112
namespace Xamarin.Forms.Core.XamlC
1213
{
1314
class ConstraintTypeConverter : ICompiledTypeConverter
@@ -21,12 +22,11 @@ public IEnumerable<Instruction> ConvertFromString(string value, ILContext contex
2122
if (string.IsNullOrEmpty(value) || !double.TryParse(value, NumberStyles.Number, CultureInfo.InvariantCulture, out size))
2223
throw new XamlParseException($"Cannot convert \"{value}\" into {typeof(Constraint)}", node);
2324

24-
yield return Instruction.Create(OpCodes.Ldc_R8, size);
25-
var constantReference = module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Constraint"),
26-
methodName: "Constant",
27-
paramCount: 1,
28-
predicate: md => md.IsStatic);
29-
yield return Instruction.Create(OpCodes.Call, constantReference);
25+
yield return Create(Ldc_R8, size);
26+
yield return Create(Call, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Constraint"),
27+
methodName: "Constant",
28+
parameterTypes: new[] { ("mscorlib", "System", "Double") },
29+
isStatic: true));
3030
}
3131
}
3232
}

Xamarin.Forms.Build.Tasks/CompiledConverters/LayoutOptionsConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public IEnumerable<Instruction> ConvertFromString(string value, ILContext contex
2828

2929
var fieldReference = module.ImportFieldReference(("Xamarin.Forms.Core", "Xamarin.Forms", "LayoutOptions"),
3030
fieldName: options,
31-
predicate: fd => fd.IsStatic);
31+
isStatic: true);
3232
if (fieldReference != null) {
3333
yield return Instruction.Create(OpCodes.Ldsfld, fieldReference);
3434
yield break;

Xamarin.Forms.Build.Tasks/CompiledConverters/ListStringTypeConverter.cs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
using System.Collections.Generic;
33
using System.Linq;
44

5-
using Mono.Cecil;
65
using Mono.Cecil.Cil;
76

87
using Xamarin.Forms.Xaml;
98
using Xamarin.Forms.Build.Tasks;
109

10+
using static Mono.Cecil.Cil.Instruction;
11+
using static Mono.Cecil.Cil.OpCodes;
12+
1113
namespace Xamarin.Forms.Core.XamlC
1214
{
1315
class ListStringTypeConverter : ICompiledTypeConverter
@@ -17,25 +19,22 @@ public IEnumerable<Instruction> ConvertFromString(string value, ILContext contex
1719
var module = context.Body.Method.Module;
1820

1921
if (value == null) {
20-
yield return Instruction.Create(OpCodes.Ldnull);
22+
yield return Create(Ldnull);
2123
yield break;
2224
}
2325
var parts = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToList();
2426

25-
var add = module.ImportMethodReference(("mscorlib", "System.Collections.Generic", "ICollection`1"),
26-
methodName: "Add",
27-
paramCount: 1,
28-
classArguments: new[] { ("mscorlib", "System", "String") });
29-
30-
yield return Instruction.Create(OpCodes.Ldc_I4, parts.Count);
31-
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("System.Collections", "System.Collections.Generic", "List`1"),
32-
paramCount: 1,
33-
predicate: md => md.Parameters[0].ParameterType.FullName == "System.Int32",
34-
classArguments: new[] { ("mscorlib", "System", "String") }));
27+
yield return Create(Ldc_I4, parts.Count);
28+
yield return Create(Newobj, module.ImportCtorReference(("System.Collections", "System.Collections.Generic", "List`1"),
29+
parameterTypes: new[] { ("mscorlib", "System", "Int32") },
30+
classArguments: new[] { ("mscorlib", "System", "String") }));
3531
foreach (var part in parts) {
36-
yield return Instruction.Create(OpCodes.Dup);
37-
yield return Instruction.Create(OpCodes.Ldstr, part);
38-
yield return Instruction.Create(OpCodes.Callvirt, add);
32+
yield return Create(Dup);
33+
yield return Create(Ldstr, part);
34+
yield return Create(Callvirt, module.ImportMethodReference(("mscorlib", "System.Collections.Generic", "ICollection`1"),
35+
methodName: "Add",
36+
paramCount: 1,
37+
classArguments: new[] { ("mscorlib", "System", "String") }));
3938
}
4039
}
4140
}

Xamarin.Forms.Build.Tasks/CompiledConverters/RDSourceTypeConverter.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,15 @@ public IEnumerable<Instruction> ConvertFromString(string value, ILContext contex
4949
yield return Create(Stloc, uriVarDef);
5050
yield return Create(Ldstr, resourcePath); //resourcePath
5151
yield return Create(Ldtoken, module.ImportReference(((ILRootNode)rootNode).TypeReference));
52-
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", paramCount: 1, predicate: md => md.IsStatic));
53-
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System.Reflection", "IntrospectionExtensions"), methodName: "GetTypeInfo", paramCount: 1, predicate: md => md.IsStatic));
52+
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") }, isStatic: true));
53+
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System.Reflection", "IntrospectionExtensions"), methodName: "GetTypeInfo", parameterTypes: new[] { ("mscorlib", "System", "Type") }, isStatic: true));
5454
yield return Create(Callvirt, module.ImportPropertyGetterReference(("mscorlib", "System.Reflection", "TypeInfo"), propertyName: "Assembly", flatten: true));
5555

5656
foreach (var instruction in node.PushXmlLineInfo(context))
5757
yield return instruction; //lineinfo
58-
yield return Create(Callvirt, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms", "ResourceDictionary"), methodName: "SetAndLoadSource", paramCount: 4));
58+
yield return Create(Callvirt, module.ImportMethodReference(("Xamarin.Forms.Core", "Xamarin.Forms", "ResourceDictionary"),
59+
methodName: "SetAndLoadSource",
60+
parameterTypes: new[] { ("System", "System", "Uri"), ("mscorlib", "System", "String"), ("mscorlib", "System.Reflection", "Assembly"), ("System.Xml.ReaderWriter", "System.Xml", "IXmlLineInfo") }));
5961
//ldloc the stored uri as return value
6062
yield return Create(Ldloc, uriVarDef);
6163
}

Xamarin.Forms.Build.Tasks/CompiledConverters/RectangleTypeConverter.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,11 @@ IEnumerable<Instruction> GenerateIL(double x, double y, double w, double h, Modu
4242
yield return Instruction.Create(OpCodes.Ldc_R8, y);
4343
yield return Instruction.Create(OpCodes.Ldc_R8, w);
4444
yield return Instruction.Create(OpCodes.Ldc_R8, h);
45-
46-
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Rectangle"), paramCount: 4));
45+
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Rectangle"), parameterTypes: new[] {
46+
("mscorlib", "System", "Double"),
47+
("mscorlib", "System", "Double"),
48+
("mscorlib", "System", "Double"),
49+
("mscorlib", "System", "Double")}));
4750
}
4851
}
4952
}

Xamarin.Forms.Build.Tasks/CompiledConverters/ThicknessTypeConverter.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ IEnumerable<Instruction> GenerateIL(ModuleDefinition module, params double[] arg
4545
{
4646
foreach (var d in args)
4747
yield return Instruction.Create(OpCodes.Ldc_R8, d);
48-
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Thickness"),
49-
paramCount: args.Length));
48+
yield return Instruction.Create(OpCodes.Newobj, module.ImportCtorReference(("Xamarin.Forms.Core", "Xamarin.Forms", "Thickness"), parameterTypes: args.Select(a => ("mscorlib", "System", "Double")).ToArray()));
5049
}
5150
}
5251

Xamarin.Forms.Build.Tasks/CompiledConverters/TypeTypeConverter.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
using System.Collections.Generic;
33
using System.Xml;
44

5-
using Mono.Cecil;
65
using Mono.Cecil.Cil;
76

87
using Xamarin.Forms.Build.Tasks;
98
using Xamarin.Forms.Xaml;
109

10+
using static Mono.Cecil.Cil.Instruction;
11+
using static Mono.Cecil.Cil.OpCodes;
12+
1113
namespace Xamarin.Forms.Core.XamlC
1214
{
1315
class TypeTypeConverter : ICompiledTypeConverter
@@ -33,8 +35,11 @@ public IEnumerable<Instruction> ConvertFromString(string value, ILContext contex
3335
if (typeRef == null)
3436
goto error;
3537

36-
yield return Instruction.Create(OpCodes.Ldtoken, module.ImportReference(typeRef));
37-
yield return Instruction.Create(OpCodes.Call, module.ImportMethodReference(("mscorlib", "System", "Type"), methodName: "GetTypeFromHandle", paramCount: 1, predicate: md => md.IsStatic));
38+
yield return Create(Ldtoken, module.ImportReference(typeRef));
39+
yield return Create(Call, module.ImportMethodReference(("mscorlib", "System", "Type"),
40+
methodName: "GetTypeFromHandle",
41+
parameterTypes: new[] { ("mscorlib", "System", "RuntimeTypeHandle") },
42+
isStatic: true));
3843

3944
yield break;
4045

0 commit comments

Comments
 (0)