Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Safar <marek.safar@gmail.com>2016-03-10 19:53:21 +0300
committerMarek Safar <marek.safar@gmail.com>2016-03-10 20:08:53 +0300
commitf8474c43504a049923e864eb71cbe98c69e9cdee (patch)
treea1c5cc344f7738df6953187c3b32f5ce205980a0
parentd29212628eaa3ff98d0d80c2e9426e43b7144f10 (diff)
[mcs] Codegen update for specialized struct initialization with awaited element initializer. Fixes #39459mono-4.4.0.40
-rw-r--r--mcs/mcs/expression.cs16
-rw-r--r--mcs/tests/test-async-84.cs35
-rw-r--r--mcs/tests/ver-il-net_4_x.xml32
3 files changed, 81 insertions, 2 deletions
diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs
index c5139d57f67..bfba44fbb8c 100644
--- a/mcs/mcs/expression.cs
+++ b/mcs/mcs/expression.cs
@@ -6465,7 +6465,7 @@ namespace Mono.CSharp
}
New n_source = source as New;
- if (n_source != null) {
+ if (n_source != null && n_source.CanEmitOptimizedLocalTarget (ec)) {
if (!n_source.Emit (ec, this)) {
if (leave_copy) {
EmitLoad (ec);
@@ -7605,6 +7605,11 @@ namespace Mono.CSharp
ec.Emit (OpCodes.Pop);
}
+ public virtual bool CanEmitOptimizedLocalTarget (EmitContext ec)
+ {
+ return true;
+ }
+
public override void FlowAnalysis (FlowAnalysisContext fc)
{
if (arguments != null)
@@ -12137,7 +12142,7 @@ namespace Mono.CSharp
public override void Emit (EmitContext ec)
{
- if (method == null && TypeSpec.IsValueType (type) && initializers.Initializers.Count > 1 && ec.HasSet (BuilderContext.Options.AsyncBody) && initializers.ContainsEmitWithAwait ()) {
+ if (!CanEmitOptimizedLocalTarget (ec)) {
var fe = ec.GetTemporaryField (type);
if (!Emit (ec, fe))
@@ -12225,6 +12230,13 @@ namespace Mono.CSharp
return true;
}
+ public override bool CanEmitOptimizedLocalTarget (EmitContext ec)
+ {
+ return !(method == null && TypeSpec.IsValueType (type) &&
+ initializers.Initializers.Count > 1 && ec.HasSet (BuilderContext.Options.AsyncBody) &&
+ initializers.ContainsEmitWithAwait ());
+ }
+
protected override IMemoryLocation EmitAddressOf (EmitContext ec, AddressOp Mode)
{
instance = base.EmitAddressOf (ec, Mode);
diff --git a/mcs/tests/test-async-84.cs b/mcs/tests/test-async-84.cs
new file mode 100644
index 00000000000..03825613f1f
--- /dev/null
+++ b/mcs/tests/test-async-84.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Threading.Tasks;
+
+struct S
+{
+ public int value;
+ public string str;
+}
+
+public class Program
+{
+ async Task<S> Foo ()
+ {
+ return new S {
+ value = 1,
+ str = await DoAsync ()
+ };
+
+ }
+
+ static async Task<string> DoAsync ()
+ {
+ await Task.Yield ();
+ return "asdafs";
+ }
+
+ static int Main ()
+ {
+ var res = new Program ().Foo ().Result;
+ if (res.value != 1)
+ return 1;
+
+ return 0;
+ }
+} \ No newline at end of file
diff --git a/mcs/tests/ver-il-net_4_x.xml b/mcs/tests/ver-il-net_4_x.xml
index eca75aea8eb..55a55a8ce00 100644
--- a/mcs/tests/ver-il-net_4_x.xml
+++ b/mcs/tests/ver-il-net_4_x.xml
@@ -65617,6 +65617,38 @@
</method>
</type>
</test>
+ <test name="test-async-84.cs">
+ <type name="Program">
+ <method name="System.Threading.Tasks.Task`1[S] Foo()" attrs="129">
+ <size>33</size>
+ </method>
+ <method name="System.Threading.Tasks.Task`1[System.String] DoAsync()" attrs="145">
+ <size>33</size>
+ </method>
+ <method name="Int32 Main()" attrs="145">
+ <size>46</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="Program+&lt;Foo&gt;c__async0">
+ <method name="Void MoveNext()" attrs="486">
+ <size>204</size>
+ </method>
+ <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+ <size>13</size>
+ </method>
+ </type>
+ <type name="Program+&lt;DoAsync&gt;c__async1">
+ <method name="Void MoveNext()" attrs="486">
+ <size>171</size>
+ </method>
+ <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+ <size>13</size>
+ </method>
+ </type>
+ </test>
<test name="test-cls-00.cs">
<type name="CLSCLass_6">
<method name="Void add_Disposed(Delegate)" attrs="2182">