Merge pull request #2983 from akoeplinger/fix-bug40462
authorAleksey Kliger (λgeek) <akliger@gmail.com>
Tue, 10 May 2016 21:06:54 +0000 (17:06 -0400)
committerAleksey Kliger (λgeek) <akliger@gmail.com>
Tue, 10 May 2016 21:06:54 +0000 (17:06 -0400)
[corlib] Ignore DirectoryNotFoundException in FileStreamTest.OpenCharDeviceRepeatedly test

26 files changed:
mcs/class/System/Mono.Net.Security/SystemCertificateValidator.cs
mcs/class/System/System.Security.Cryptography.X509Certificates/X509ChainPolicy.cs
mcs/class/corlib/System.Threading/Monitor.cs
mcs/class/corlib/Test/System.Threading/MonitorTest.cs
mcs/class/corlib/corlib.dll.sources
mcs/class/referencesource/mscorlib/system/threading/monitor.cs
mcs/errors/cs0121-24.cs [deleted file]
mcs/mcs/ecore.cs
mcs/tests/gtest-optional-38.cs [new file with mode: 0644]
mcs/tests/gtest-optional-39.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_x.xml
mono/metadata/icall-def.h
mono/metadata/marshal.c
mono/metadata/monitor.c
mono/metadata/monitor.h
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/decompose.c
mono/mini/method-to-ir.c
mono/mini/mini-generic-sharing.c
mono/mini/mini-llvm.c
mono/mini/mini.h
mono/utils/mono-threads-coop.c
mono/utils/mono-threads-state-machine.c
mono/utils/mono-threads.h
tools/offsets-tool/Makefile

index 55969818a8b5d4299725c0e5f81129020d1f9366..14f7d1a586d2c3520881ab576cda88b3cb97e37b 100644 (file)
@@ -65,16 +65,12 @@ namespace Mono.Net.Security
                public static X509Chain CreateX509Chain (XX509CertificateCollection certs)
                {
                        var chain = new X509Chain ();
-                       chain.ChainPolicy = new X509ChainPolicy ();
+                       chain.ChainPolicy = new X509ChainPolicy ((X509CertificateCollection)(object)certs);
 
 #if !MOBILE
                        chain.ChainPolicy.RevocationMode = revocation_mode;
 #endif
 
-                       for (int i = 1; i < certs.Count; i++) {
-                               chain.ChainPolicy.ExtraStore.Add (certs [i]);
-                       }
-
                        return chain;
                }
 
index 86d4aee925e6a09ee74f5a4313a7e0e8d277a5c8..1dc234575b86a3cb6806c7b471f8d0ba8ec9f694 100644 (file)
@@ -35,7 +35,8 @@ namespace System.Security.Cryptography.X509Certificates {
 
                private OidCollection apps;
                private OidCollection cert;
-               private X509Certificate2Collection store;
+               private X509CertificateCollection store;
+               private X509Certificate2Collection store2;
                private X509RevocationFlag rflag;
                private X509RevocationMode mode;
                private TimeSpan timeout;
@@ -49,6 +50,24 @@ namespace System.Security.Cryptography.X509Certificates {
                        Reset ();
                }
 
+               /*
+                * Lazy-init ExtraStore from X509CertificateCollection.
+                * This is called from Mono.Net.Security.SystemCertificateValidator.CreateX509Chain.
+                *
+                * AppleTLS supports a lazily-initialized X509Certificate, but not X509Certificate2 so
+                * we need to fall-back to using Mono.Security.X509 whenever we need an X509Certificate2.
+                * To avoid unnecessary fallbacks, the private Mono.Net.Security APIs use X509Certificate
+                * instead of X509Certificate2.
+                *
+                * Since 'ExtraStore' returns X509Certificate2Collection, we need to convert these to
+                * X509Certificate2.
+                */
+               internal X509ChainPolicy (X509CertificateCollection store)
+               {
+                       this.store = store;
+                       Reset ();
+               }
+
                // properties
 
                public OidCollection ApplicationPolicy {
@@ -60,7 +79,18 @@ namespace System.Security.Cryptography.X509Certificates {
                }
 
                public X509Certificate2Collection ExtraStore {
-                       get { return store; }
+                       get {
+                               if (store2 != null)
+                                       return store2;
+
+                               store2 = new X509Certificate2Collection ();
+                               if (store != null) {
+                                       foreach (var cert in store) {
+                                               store2.Add (new X509Certificate2 (cert));
+                                       }
+                               }
+                               return store2;
+                       }
                }
 
                public X509RevocationFlag RevocationFlag {
@@ -106,7 +136,7 @@ namespace System.Security.Cryptography.X509Certificates {
                {
                        apps = new OidCollection ();
                        cert = new OidCollection ();
-                       store = new X509Certificate2Collection ();
+                       store2 = null;
                        rflag = X509RevocationFlag.ExcludeRoot;
                        mode = X509RevocationMode.Online;
                        timeout = TimeSpan.Zero;
index b76c35d2d88324116507e97faef0a68db4969c08..9ec94ff97f9985ce8764e276fc3cae5cfe8dd964 100644 (file)
@@ -37,151 +37,51 @@ using System.Runtime.InteropServices;
 
 namespace System.Threading
 {
-       [ComVisible (true)]
-       public static class Monitor
+       public static partial class Monitor
        {
-               // Grabs the mutex on object 'obj', with a maximum
-               // wait time 'ms' but doesn't block - if it can't get
-               // the lock it returns false, true if it can
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static bool Monitor_try_enter(object obj, int ms);
+               extern static bool Monitor_test_synchronised(object obj);
 
-               // Enter/Exit are implemented directly as icalls for performance reasons
-
-               // Acquires the mutex on object 'obj'
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern static void Enter(object obj);
-
-               // Releases the mutex on object 'obj'
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public extern static void Exit(object obj);
-
-               // Signals one of potentially many objects waiting on
-               // object 'obj'
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static void Monitor_pulse(object obj);
+               extern static void Monitor_pulse(object obj);
 
-               // Checks whether object 'obj' is currently synchronised
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static bool Monitor_test_synchronised(object obj);
-
-               public static void Pulse(object obj) {
-                       if(obj==null) {
-                               throw new ArgumentNullException("obj");
-                       }
-                       if(Monitor_test_synchronised(obj)==false) {
+               static void ObjPulse(Object obj)
+               {
+                       if (!Monitor_test_synchronised (obj))
                                throw new SynchronizationLockException("Object is not synchronized");
-                       }
 
-                       Monitor_pulse(obj);
+                       Monitor_pulse (obj);
                }
 
-               // Signals all of potentially many objects waiting on
-               // object 'obj'
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static void Monitor_pulse_all(object obj);
-
-               public static void PulseAll(object obj) {
-                       if(obj==null) {
-                               throw new ArgumentNullException("obj");
-                       }
-                       if(Monitor_test_synchronised(obj)==false) {
-                               throw new SynchronizationLockException("Object is not synchronized");
-                       }
-
-                       Monitor_pulse_all(obj);
-               }
+               extern static void Monitor_pulse_all(object obj);
 
-               public static bool TryEnter (object obj)
+               static void ObjPulseAll(Object obj)
                {
-                       return TryEnter (obj, 0);
-               }
-
-               public static bool TryEnter (object obj, int millisecondsTimeout)
-               {
-                       if (obj == null)
-                               throw new ArgumentNullException ("obj");
-
-                       if (millisecondsTimeout == Timeout.Infinite) {
-                               Enter (obj);
-                               return true;
-                       }
-
-                       if (millisecondsTimeout < 0)
-                               throw new ArgumentException ("negative value for millisecondsTimeout", "millisecondsTimeout");
-                       
-                       return Monitor_try_enter (obj, millisecondsTimeout);
-               }
+                       if (!Monitor_test_synchronised (obj))
+                               throw new SynchronizationLockException("Object is not synchronized");
 
-               public static bool TryEnter (object obj, TimeSpan timeout)
-               {
-                       long ms = (long) timeout.TotalMilliseconds;
-                       if (ms < Timeout.Infinite || ms > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("timeout", "timeout out of range");
-                       
-                       return TryEnter (obj, (int) ms);
+                       Monitor_pulse_all (obj);
                }
 
-               // Waits for a signal on object 'obj' with maximum
-               // wait time 'ms'. Returns true if the object was
-               // signalled, false if it timed out
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static bool Monitor_wait(object obj, int ms);
-
-               public static bool Wait (object obj)
-               {
-                       return Wait (obj, Timeout.Infinite);
-               }
+               extern static bool Monitor_wait(object obj, int ms);
 
-               public static bool Wait (object obj, int millisecondsTimeout)
+               static bool ObjWait(bool exitContext, int millisecondsTimeout, Object obj)
                {
-                       if (obj == null)
-                               throw new ArgumentNullException ("obj");
-
-                       if (millisecondsTimeout < Timeout.Infinite)
-                               throw new ArgumentOutOfRangeException ("millisecondsTimeout", "timeout out of range");
-
+                       if (millisecondsTimeout < 0 && millisecondsTimeout != (int) Timeout.Infinite)
+                               throw new ArgumentOutOfRangeException ("millisecondsTimeout");
                        if (!Monitor_test_synchronised (obj))
                                throw new SynchronizationLockException ("Object is not synchronized");
 
-                       return Monitor_wait (obj, millisecondsTimeout);
-               }
-
-               public static bool Wait (object obj, TimeSpan timeout)
-               {
-                       long ms = (long) timeout.TotalMilliseconds;
-                       if (ms < Timeout.Infinite || ms > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("timeout", "timeout out of range");
-
-                       return Wait (obj, (int) ms);
-               }
-
-               public static bool Wait(object obj, int millisecondsTimeout, bool exitContext) {
                        try {
 #if !DISABLE_REMOTING
                                if (exitContext)
                                        SynchronizationAttribute.ExitContext ();
 #endif
-                               return Wait (obj, millisecondsTimeout);
-                       }
-                       finally {
-#if !DISABLE_REMOTING
-                               if (exitContext)
-                                       SynchronizationAttribute.EnterContext ();
-#endif
-                       }
-               }
 
-               public static bool Wait(object obj, TimeSpan timeout, bool exitContext) {
-                       try {
-#if !DISABLE_REMOTING
-                               if (exitContext)
-                                       SynchronizationAttribute.ExitContext ();
-#endif
-                               return Wait (obj, timeout);
-                       }
-                       finally {
+                               return Monitor_wait (obj, millisecondsTimeout);
+                       } finally {
 #if !DISABLE_REMOTING
                                if (exitContext)
                                        SynchronizationAttribute.EnterContext ();
@@ -192,50 +92,27 @@ namespace System.Threading
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                extern static void try_enter_with_atomic_var (object obj, int millisecondsTimeout, ref bool lockTaken);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               extern static void enter_with_atomic_var (object obj, ref bool lockTaken);
-
-               // Can't make this an icall since it has the same name as the other Enter method
-               [MethodImpl(MethodImplOptions.AggressiveInlining)]
-               public static void Enter (object obj, ref bool lockTaken)
+               static void ReliableEnterTimeout(Object obj, int timeout, ref bool lockTaken)
                {
-                       enter_with_atomic_var (obj, ref lockTaken);
-               }
+                       if (obj == null)
+                               throw new ArgumentNullException ("obj");
+                       if (timeout < 0 && timeout != (int) Timeout.Infinite)
+                               throw new ArgumentOutOfRangeException ("millisecondsTimeout");
 
-               public static void TryEnter (object obj, ref bool lockTaken)
-               {
-                       TryEnter (obj, 0, ref lockTaken);
+                       try_enter_with_atomic_var (obj, timeout, ref lockTaken);
                }
 
-               public static void TryEnter (object obj, TimeSpan timeout, ref bool lockTaken)
+               static void ReliableEnter(Object obj, ref bool lockTaken)
                {
-                       long ms = (long) timeout.TotalMilliseconds;
-                       if (ms < Timeout.Infinite || ms > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("timeout", "timeout out of range");
-                       TryEnter (obj, (int)ms, ref lockTaken);
+                       ReliableEnterTimeout (obj, (int) Timeout.Infinite, ref lockTaken);
                }
 
-               public static void TryEnter (object obj, int millisecondsTimeout, ref bool lockTaken)
-               {
-                       if (obj == null)
-                               throw new ArgumentNullException ("obj");
-                       if (lockTaken)
-                               throw new ArgumentException ("lockTaken");
-
-                       if (millisecondsTimeout < 0 && millisecondsTimeout != Timeout.Infinite)
-                               throw new ArgumentException ("negative value for millisecondsTimeout", "millisecondsTimeout");
-
-                       try_enter_with_atomic_var (obj, millisecondsTimeout, ref lockTaken);
-               }               
-
-
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                extern static bool Monitor_test_owner (object obj);
 
-               public
-               static bool IsEntered (object obj)
+               static bool IsEnteredNative(Object obj)
                {
-                       return Monitor_test_owner(obj);
+                       return Monitor_test_owner (obj);
                }
        }
 }
index 1c4ae9408a0e936dcb9053181c91ca59f4ac5a29..158a9afc9424f0cb0b67358b8d588c4269273a0b 100644 (file)
@@ -144,7 +144,7 @@ namespace MonoTests.System.Threading {
                }
 
                [Test]
-               [ExpectedException (typeof (ArgumentException))]
+               [ExpectedException (typeof (ArgumentOutOfRangeException))]
                public void TryEnter_Int_Negative ()
                {
                        object o = new object ();
index d1202a94e80eccaa411fd34a533e27d8925a0ae1..76f25a22e35de24c0879a6f022c921f3828eda03 100644 (file)
@@ -1556,6 +1556,7 @@ ReferenceSources/SecurityContext.cs
 ../referencesource/mscorlib/system/threading/lockrecursionexception.cs
 ../referencesource/mscorlib/system/threading/manualresetevent.cs
 ../referencesource/mscorlib/system/threading/ManualResetEventSlim.cs
+../referencesource/mscorlib/system/threading/monitor.cs
 ../referencesource/mscorlib/system/threading/parameterizedthreadstart.cs
 ../referencesource/mscorlib/system/threading/semaphorefullexception.cs
 ../referencesource/mscorlib/system/threading/SemaphoreSlim.cs
index 9232230801d229d6917bcf3c9a72c48b9c5ed8a0..2bb82ed520e13f8c22650469c3ad1c723be7cfe2 100644 (file)
@@ -31,7 +31,7 @@ namespace System.Threading {
 
     [HostProtection(Synchronization=true, ExternalThreading=true)]
     [System.Runtime.InteropServices.ComVisible(true)]
-    public static class Monitor 
+    public static partial class Monitor
     {
         /*=========================================================================
         ** Obtain the monitor lock of obj. Will block if another thread holds the lock
@@ -66,11 +66,12 @@ namespace System.Threading {
             throw new ArgumentException(Environment.GetResourceString("Argument_MustBeFalse"), "lockTaken");
         }
 
+#if !MONO
         [System.Security.SecuritySafeCritical]
         [ResourceExposure(ResourceScope.None)]
         [MethodImplAttribute(MethodImplOptions.InternalCall)]
         private static extern void ReliableEnter(Object obj, ref bool lockTaken);
-
+#endif
 
 
         /*=========================================================================
@@ -160,10 +161,12 @@ namespace System.Threading {
             ReliableEnterTimeout(obj, MillisecondsTimeoutFromTimeSpan(timeout), ref lockTaken);
         }
 
+#if !MONO
         [System.Security.SecuritySafeCritical]
         [ResourceExposure(ResourceScope.None)]
         [MethodImplAttribute(MethodImplOptions.InternalCall)]
         private static extern void ReliableEnterTimeout(Object obj, int timeout, ref bool lockTaken);
+#endif
 
         [System.Security.SecuritySafeCritical]
         public static bool IsEntered(object obj)
@@ -174,10 +177,12 @@ namespace System.Threading {
             return IsEnteredNative(obj);
         }
 
+#if !MONO
         [System.Security.SecurityCritical]
         [ResourceExposure(ResourceScope.None)]
         [MethodImplAttribute(MethodImplOptions.InternalCall)]
         private static extern bool IsEnteredNative(Object obj);
+#endif
 
         /*========================================================================
     ** Waits for notification from the object (via a Pulse/PulseAll). 
@@ -190,10 +195,12 @@ namespace System.Threading {
     **
         ** Exceptions: ArgumentNullException if object is null.
     ========================================================================*/
+#if !MONO
         [System.Security.SecurityCritical]  // auto-generated
         [ResourceExposure(ResourceScope.None)]
         [MethodImplAttribute(MethodImplOptions.InternalCall)]
         private static extern bool ObjWait(bool exitContext, int millisecondsTimeout, Object obj);
+#endif
 
         [System.Security.SecuritySafeCritical]  // auto-generated
         public static bool Wait(Object obj, int millisecondsTimeout, bool exitContext)
@@ -228,10 +235,12 @@ namespace System.Threading {
         * Exceptions: SynchronizationLockException if this method is not called inside
         * a synchronized block of code.
         ========================================================================*/
+#if !MONO
         [System.Security.SecurityCritical]  // auto-generated
         [ResourceExposure(ResourceScope.None)]
         [MethodImplAttribute(MethodImplOptions.InternalCall)]
         private static extern void ObjPulse(Object obj);
+#endif
 
         [System.Security.SecuritySafeCritical]  // auto-generated
         public static void Pulse(Object obj)
@@ -247,10 +256,12 @@ namespace System.Threading {
         /*========================================================================
         ** Sends a notification to all waiting objects. 
         ========================================================================*/
+#if !MONO
         [System.Security.SecurityCritical]  // auto-generated
         [ResourceExposure(ResourceScope.None)]
         [MethodImplAttribute(MethodImplOptions.InternalCall)]
         private static extern void ObjPulseAll(Object obj);
+#endif
 
         [System.Security.SecuritySafeCritical]  // auto-generated
         public static void PulseAll(Object obj)
diff --git a/mcs/errors/cs0121-24.cs b/mcs/errors/cs0121-24.cs
deleted file mode 100644 (file)
index 6617508..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// CS0121: The call is ambiguous between the following methods or properties: `A.GetValues(string[], string)' and `A.GetValues(string, params string[])'
-// Line: 23
-// CSC BUG: Correct according the spec, no identity conversion to do tie-breaking
-
-class A
-{
-       public int GetValues (string[] s, string value = null)
-       {
-               return 1;
-       }
-
-       public int GetValues (string s, params string [] args)
-       {
-               return 2;
-       }
-}
-
-
-class B
-{
-       public static void Main ()
-       {
-               var a = new A ();
-               a.GetValues (null);
-       }
-}
\ No newline at end of file
index fc99defc44e19359646b879d59bb7feb63bba902..63d6367309d7150bc430e8da642c61072b66a955 100644 (file)
@@ -4658,7 +4658,9 @@ namespace Mono.CSharp {
                        AParametersCollection candidate_pd = ((IParametersMember) candidate).Parameters;
                        AParametersCollection best_pd = ((IParametersMember) best).Parameters;
 
-                       bool better_at_least_one = false;
+                       int candidate_better_count = 0;
+                       int best_better_count = 0;
+
                        bool are_equivalent = true;
                        int args_count = args == null ? 0 : args.Count;
                        int j = 0;
@@ -4713,30 +4715,31 @@ namespace Mono.CSharp {
                                        //
                                        // No optional parameters tie breaking rules for delegates overload resolution
                                        //
-                                       if ((this.restrictions & Restrictions.CovariantDelegate) != 0)
+                                       if ((restrictions & Restrictions.CovariantDelegate) != 0)
                                                return false;
 
-                                       better_at_least_one = false;
-
-                                       ++j;
-                                       while (j < args_count && !args [j++].IsDefaultArgument) ;
-
-                                       break;
+                                       ++best_better_count;
+                                       continue;
                                }
 
                                // for at least one argument, the conversion to 'ct' should be better than 
                                // the conversion to 'bt'.
                                if (result != 0)
-                                       better_at_least_one = true;
+                                       ++candidate_better_count;
                        }
 
-                       if (better_at_least_one)
+                       if (candidate_better_count != 0 && best_better_count == 0)
                                return true;
 
+                       if (best_better_count > 0 && candidate_better_count == 0)
+                               return false;
+
                        //
                        // LAMESPEC: Tie-breaking rules for not equivalent parameter types
                        //
                        if (!are_equivalent) {
+                               while (j < args_count && !args [j++].IsDefaultArgument) ;
+
                                //
                                // A candidate with no default parameters is still better when there
                                // is no better expression conversion
diff --git a/mcs/tests/gtest-optional-38.cs b/mcs/tests/gtest-optional-38.cs
new file mode 100644 (file)
index 0000000..1f44b03
--- /dev/null
@@ -0,0 +1,36 @@
+class C
+{
+}
+
+class Foo 
+{
+               public int SetValue (string name, string value, string defaultValue = null, bool preserveExistingCase = false)
+               {
+                       return 1;
+               }
+
+               public int SetValue (string name, C value, C defaultValue = default(C), bool relativeToProject = true, C relativeToPath = default(C), bool mergeToMainGroup = false, string condition = null)
+               {
+                       return 2;
+               }
+
+               public int SetValue (string name, object value, C defaultValue = null)
+               {
+                       return 3;
+               }
+}
+
+class Test 
+{
+       static int Main() 
+       {
+               var f = new Foo ();
+               C b = null;
+               C c = null;
+
+               if (f.SetValue ("a", b, c) != 2)
+                       return 1;
+
+               return 0;
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/gtest-optional-39.cs b/mcs/tests/gtest-optional-39.cs
new file mode 100644 (file)
index 0000000..26aee13
--- /dev/null
@@ -0,0 +1,25 @@
+class A
+{
+       public int GetValues (string[] s, string value = null)
+       {
+               return 1;
+       }
+
+       public int GetValues (string s, params string [] args)
+       {
+               return 2;
+       }
+}
+
+
+class B
+{
+       public static int Main ()
+       {
+               var a = new A ();
+               if (a.GetValues (null) != 1)
+                       return 1;
+
+               return 0;
+       }
+}
\ No newline at end of file
index 027fd9871ef422bf008dc6f7e66ff4196ed13027..7ba3329b35d0b6ec07745f7a19c895346b2b589b 100644 (file)
       </method>
     </type>
   </test>
+  <test name="gtest-optional-38.cs">
+    <type name="C">
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Foo">
+      <method name="Int32 SetValue(System.String, System.String, System.String, Boolean)" attrs="134">
+        <size>10</size>
+      </method>
+      <method name="Int32 SetValue(System.String, C, C, Boolean, C, Boolean, System.String)" attrs="134">
+        <size>10</size>
+      </method>
+      <method name="Int32 SetValue(System.String, System.Object, C)" attrs="134">
+        <size>10</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="Test">
+      <method name="Int32 Main()" attrs="145">
+        <size>50</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
+  <test name="gtest-optional-39.cs">
+    <type name="A">
+      <method name="Int32 GetValues(System.String[], System.String)" attrs="134">
+        <size>10</size>
+      </method>
+      <method name="Int32 GetValues(System.String, System.String[])" attrs="134">
+        <size>10</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="B">
+      <method name="Int32 Main()" attrs="150">
+        <size>37</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="gtest-partial-01.cs">
     <type name="B`1[U]">
       <method name="Void .ctor()" attrs="6278">
index b74631fd9420a19a216568a45eb1d0c00380a785..c659b843ce27cddc9d068c12de977128c45fef2d 100644 (file)
@@ -873,9 +873,7 @@ ICALL(MONIT_2, "Monitor_pulse", ves_icall_System_Threading_Monitor_Monitor_pulse
 ICALL(MONIT_3, "Monitor_pulse_all", ves_icall_System_Threading_Monitor_Monitor_pulse_all)
 ICALL(MONIT_4, "Monitor_test_owner", ves_icall_System_Threading_Monitor_Monitor_test_owner)
 ICALL(MONIT_5, "Monitor_test_synchronised", ves_icall_System_Threading_Monitor_Monitor_test_synchronised)
-ICALL(MONIT_6, "Monitor_try_enter", ves_icall_System_Threading_Monitor_Monitor_try_enter)
 ICALL(MONIT_7, "Monitor_wait", ves_icall_System_Threading_Monitor_Monitor_wait)
-ICALL(MONIT_10, "enter_with_atomic_var", mono_monitor_enter_v4)
 ICALL(MONIT_9, "try_enter_with_atomic_var", ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var)
 
 ICALL_TYPE(MUTEX, "System.Threading.Mutex", MUTEX_1)
index 4a3a5e78a50c362ba662db929b44813a818ed57c..dfe806d97ec86f6875d742d66168887f19fd127a 100644 (file)
@@ -9265,7 +9265,7 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method)
        if (!enter_method) {
                MonoMethodDesc *desc;
 
-               desc = mono_method_desc_new ("Monitor:enter_with_atomic_var(object,bool&)", FALSE);
+               desc = mono_method_desc_new ("Monitor:Enter(object,bool&)", FALSE);
                enter_method = mono_method_desc_search_in_class (desc, mono_defaults.monitor_class);
                g_assert (enter_method);
                mono_method_desc_free (desc);
index 510d1c18bcd31b3fcd86556f7ee0cea21b4fe0ef..0fe4b593d58e782171e329439a29745266bdd87f 100644 (file)
@@ -1071,25 +1071,6 @@ mono_monitor_threads_sync_members_offset (int *status_offset, int *nest_offset)
        *nest_offset = ENCODE_OFF_SIZE (MONO_STRUCT_OFFSET (MonoThreadsSync, nest), sizeof (ts.nest));
 }
 
-gboolean 
-ves_icall_System_Threading_Monitor_Monitor_try_enter (MonoObject *obj, guint32 ms)
-{
-       gint32 res;
-
-       do {
-               res = mono_monitor_try_enter_internal (obj, ms, TRUE);
-               if (res == -1) {
-                       MonoException *exc = mono_thread_interruption_checkpoint ();
-                       if (exc) {
-                               mono_set_pending_exception (exc);
-                               return FALSE;
-                       }
-               }
-       } while (res == -1);
-       
-       return res == 1;
-}
-
 void
 ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var (MonoObject *obj, guint32 ms, char *lockTaken)
 {
@@ -1132,6 +1113,8 @@ mono_monitor_enter_v4_fast (MonoObject *obj, char *lock_taken)
 {
        if (*lock_taken == 1)
                return FALSE;
+       if (G_UNLIKELY (!obj))
+               return FALSE;
        gint32 res = mono_monitor_try_enter_internal (obj, 0, TRUE);
        *lock_taken = res == 1;
        return res == 1;
index f8e89936ba93067e658532d75e2e05e042321e0b..f43e08caece432d1aba4a7bedd81d8e063138ff1 100644 (file)
@@ -115,7 +115,6 @@ void mono_monitor_threads_sync_members_offset (int *status_offset, int *nest_off
 #define MONO_THREADS_SYNC_MEMBER_OFFSET(o)     ((o)>>8)
 #define MONO_THREADS_SYNC_MEMBER_SIZE(o)       ((o)&0xff)
 
-extern gboolean ves_icall_System_Threading_Monitor_Monitor_try_enter(MonoObject *obj, guint32 ms);
 extern gboolean ves_icall_System_Threading_Monitor_Monitor_test_owner(MonoObject *obj);
 extern gboolean ves_icall_System_Threading_Monitor_Monitor_test_synchronised(MonoObject *obj);
 extern void ves_icall_System_Threading_Monitor_Monitor_pulse(MonoObject *obj);
index 167c06d95469ccdd8b3813425af33ecc9b9ea9c5..a8c0946eeed8948f957c193793eaf1185463e70e 100644 (file)
@@ -8104,6 +8104,14 @@ mono_aot_get_method_name (MonoCompile *cfg)
 gboolean
 mono_aot_is_linkonce_method (MonoMethod *method)
 {
+       // FIXME:
+       // This doesn't work yet, because
+       // it can make us call methods which belong
+       // to aot modules which haven't been loaded yet,
+       // so the init method will read uninitialized got
+       // entries.
+       return FALSE;
+#if 0
        WrapperInfo *info;
 
        // FIXME: Add more cases
@@ -8113,6 +8121,7 @@ mono_aot_is_linkonce_method (MonoMethod *method)
        if ((info && (info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_IN_SIG || info->subtype == WRAPPER_SUBTYPE_GSHAREDVT_OUT_SIG)))
                return TRUE;
        return FALSE;
+#endif
 }
 
 static gboolean
index 5cf86261d209f157fec8532671096931307e719f..ef9a9c035c90e1ce1de80e3e06898e274711d46f 100644 (file)
@@ -4265,9 +4265,10 @@ mono_aot_init_llvm_method (gpointer aot_module, guint32 method_index)
        gboolean res;
        MonoError error;
 
-       // FIXME: Handle errors
        res = init_method (amodule, method_index, NULL, NULL, NULL, &error);
-       g_assert (res);
+       // FIXME: Pass the exception up to the caller ?
+       /* Its okay to raise in llvmonly mode */
+       mono_error_raise_exception (&error);
 }
 
 void
@@ -4293,7 +4294,7 @@ mono_aot_init_gshared_method_this (gpointer aot_module, guint32 method_index, Mo
        g_assert (context);
 
        res = init_method (amodule, method_index, NULL, klass, context, &error);
-       g_assert (res);
+       mono_error_raise_exception (&error);
 }
 
 void
@@ -4312,7 +4313,7 @@ mono_aot_init_gshared_method_mrgctx (gpointer aot_module, guint32 method_index,
        context.method_inst = rgctx->method_inst;
 
        res = init_method (amodule, method_index, NULL, rgctx->class_vtable->klass, &context, &error);
-       g_assert (res);
+       mono_error_raise_exception (&error);
 }
 
 void
@@ -4336,7 +4337,7 @@ mono_aot_init_gshared_method_vtable (gpointer aot_module, guint32 method_index,
        g_assert (context);
 
        res = init_method (amodule, method_index, NULL, klass, context, &error);
-       g_assert (res);
+       mono_error_raise_exception (&error);
 }
 
 /*
index 45849a824337eb2fd5dd7bb8d9eae312640afd27..3c1a17befe59f4a3408d59315e951dd0bb9ac500 100644 (file)
@@ -1922,9 +1922,9 @@ mono_local_emulate_ops (MonoCompile *cfg)
 
                                /* We emit the call on a separate dummy basic block */
                                cfg->cbb = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoBasicBlock));
-                               first_bb = cfg->cbb;
+                               first_bb = cfg->cbb;
 
-                               call = mono_emit_jit_icall_by_info (cfg, info, args);
+                               call = mono_emit_jit_icall_by_info (cfg, bb->real_offset, info, args);
                                call->dreg = ins->dreg;
 
                                /* Replace ins with the emitted code and do the necessary bb linking */
index b677b3ad6adee8e3fa01ce0af5e0cc0e64fb7254..18121c85b69607ce34967263a895c31b53ee3cb4 100644 (file)
@@ -3068,7 +3068,7 @@ direct_icalls_enabled (MonoCompile *cfg)
 {
        /* LLVM on amd64 can't handle calls to non-32 bit addresses */
 #ifdef TARGET_AMD64
-       if (cfg->compile_llvm)
+       if (cfg->compile_llvm && !cfg->llvm_only)
                return FALSE;
 #endif
        if (cfg->gen_sdb_seq_points || cfg->disable_direct_icalls)
@@ -3077,7 +3077,7 @@ direct_icalls_enabled (MonoCompile *cfg)
 }
 
 MonoInst*
-mono_emit_jit_icall_by_info (MonoCompile *cfg, MonoJitICallInfo *info, MonoInst **args)
+mono_emit_jit_icall_by_info (MonoCompile *cfg, int il_offset, MonoJitICallInfo *info, MonoInst **args)
 {
        /*
         * Call the jit icall without a wrapper if possible.
@@ -3104,7 +3104,7 @@ mono_emit_jit_icall_by_info (MonoCompile *cfg, MonoJitICallInfo *info, MonoInst
                 * an exception check.
                 */
                costs = inline_method (cfg, info->wrapper_method, NULL,
-                                                          args, NULL, cfg->real_offset, TRUE);
+                                                          args, NULL, il_offset, TRUE);
                g_assert (costs > 0);
                g_assert (!MONO_TYPE_IS_VOID (info->sig->ret));
 
@@ -6110,12 +6110,7 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
                        return NULL;
        } else if (cmethod->klass == mono_defaults.monitor_class) {
                gboolean is_enter = FALSE;
-               gboolean is_v4 = FALSE;
 
-               if (!strcmp (cmethod->name, "enter_with_atomic_var") && mono_method_signature (cmethod)->param_count == 2) {
-                       is_enter = TRUE;
-                       is_v4 = TRUE;
-               }
                if (!strcmp (cmethod->name, "Enter") && mono_method_signature (cmethod)->param_count == 1)
                        is_enter = TRUE;
 
@@ -6128,10 +6123,10 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
 
                        NEW_BBLOCK (cfg, end_bb);
 
-                       ins = mono_emit_jit_icall (cfg, is_v4 ? (gpointer)mono_monitor_enter_v4_fast : (gpointer)mono_monitor_enter_fast, args);
+                       ins = mono_emit_jit_icall (cfg, (gpointer)mono_monitor_enter_fast, args);
                        MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ICOMPARE_IMM, -1, ins->dreg, 0);
                        MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBNE_UN, end_bb);
-                       ins = mono_emit_jit_icall (cfg, is_v4 ? (gpointer)mono_monitor_enter_v4 : (gpointer)mono_monitor_enter, args);
+                       ins = mono_emit_jit_icall (cfg, (gpointer)mono_monitor_enter, args);
                        MONO_START_BB (cfg, end_bb);
                        return ins;
                }
@@ -13640,6 +13635,12 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        if (cfg->verbose_level > 2)
                                printf ("REGION BB%d IL_%04x ID_%08X\n", bb->block_num, bb->real_offset, bb->region);
                }
+       } else {
+               MonoBasicBlock *bb;
+               /* get_most_deep_clause () in mini-llvm.c depends on this for inlined bblocks */
+               for (bb = start_bblock; bb != end_bblock; bb  = bb->next_bb) {
+                       bb->real_offset = inline_offset;
+               }
        }
 
        if (inline_costs < 0) {
index 1c37f38d726df2839d8fe82a9172edf7c47f2962..ec606a934b7955538e0c0576f26c2d1c27333ce6 100644 (file)
@@ -1085,7 +1085,11 @@ get_wrapper_shared_type (MonoType *t)
        case MONO_TYPE_SZARRAY:
        case MONO_TYPE_ARRAY:
        case MONO_TYPE_PTR:
-               return &mono_defaults.int_class->byval_arg;
+               // FIXME: refs and intptr cannot be shared because
+               // they are treated differently when a method has a vret arg,
+               // see get_call_info ().
+               return &mono_defaults.object_class->byval_arg;
+               //return &mono_defaults.int_class->byval_arg;
        case MONO_TYPE_GENERICINST: {
                MonoError error;
                MonoClass *klass;
index 5256f7b7bdb1b02dc2604b1c91ffe0d48b1305fd..7955a0e2be07ed9347cbd17be4add38c8eb9d57e 100644 (file)
@@ -1744,26 +1744,14 @@ get_most_deep_clause (MonoCompile *cfg, EmitContext *ctx, MonoBasicBlock *bb)
 {
        // Since they're sorted by nesting we just need
        // the first one that the bb is a member of
-       MonoExceptionClause *last = NULL;
-
        for (int i = 0; i < cfg->header->num_clauses; i++) {
                MonoExceptionClause *curr = &cfg->header->clauses [i];
 
                if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset))
                        return curr;
-               /*
-               if (MONO_OFFSET_IN_CLAUSE (curr, bb->real_offset)) {
-                       if (last && CLAUSE_END(last) > CLAUSE_END(curr))
-                               last = curr;
-                       else
-                               last = curr;
-               } else if(last) {
-                       break;
-               }
-               */
        }
 
-       return last;
+       return NULL;
 }
        
 static void
index 8cec0404bead1caf3efaf3a1aaad5bc006bfcb89..99e082907a63cbe0e89798f4d4f3920c99638426 100644 (file)
@@ -2418,7 +2418,7 @@ MonoInst *mono_get_got_var (MonoCompile *cfg);
 void      mono_add_seq_point (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, int native_offset);
 void      mono_add_var_location (MonoCompile *cfg, MonoInst *var, gboolean is_reg, int reg, int offset, int from, int to);
 MonoInst* mono_emit_jit_icall (MonoCompile *cfg, gconstpointer func, MonoInst **args);
-MonoInst* mono_emit_jit_icall_by_info (MonoCompile *cfg, MonoJitICallInfo *info, MonoInst **args);
+MonoInst* mono_emit_jit_icall_by_info (MonoCompile *cfg, int il_offset, MonoJitICallInfo *info, MonoInst **args);
 MonoInst* mono_emit_method_call (MonoCompile *cfg, MonoMethod *method, MonoInst **args, MonoInst *this_ins);
 void      mono_create_helper_signatures (void);
 
index d5d4c56da3a796c0995bd537163aaf36c0c6524a..9eb62c0c2812b28673f0a544ea681f57f50cc9cd 100644 (file)
@@ -267,8 +267,8 @@ mono_threads_reset_blocking_start (void* stackdata)
        case AbortBlockingOk:
                info->thread_saved_state [SELF_SUSPEND_STATE_INDEX].valid = FALSE;
                break;
-       case AbortBlockingOkAndPool:
-               mono_threads_state_poll ();
+       case AbortBlockingWait:
+               mono_thread_info_wait_for_resume (info);
                break;
        default:
                g_error ("Unknown thread state");
index 4b0ad1147122b2e1fd4232684996cd335daf5062..4b11800c818411a1a6f8b469c0c05e651ea89768 100644 (file)
@@ -559,7 +559,7 @@ It returns one of:
 -Ignore: Thread was not in blocking, nothing to do;
 -IgnoreAndPool: Thread was not blocking and there's a pending suspend that needs to be processed;
 -Ok: Blocking state successfully aborted;
--OkAndPool: Blocking state successfully aborted, there's a pending suspend to be processed though
+-Wait: Blocking state successfully aborted, there's a pending suspend to be processed though
 */
 MonoAbortBlockingResult
 mono_threads_transition_abort_blocking (THREAD_INFO_TYPE* info)
@@ -584,10 +584,12 @@ retry_state_change:
                        trace_state_change ("ABORT_BLOCKING", info, raw_state, STATE_RUNNING, 0);
                        return AbortBlockingOk;
                } else {
-                       if (InterlockedCompareExchange (&info->thread_state, build_thread_state (STATE_SELF_SUSPEND_REQUESTED, suspend_count), raw_state) != raw_state)
+                       if (!(suspend_count > 0))
+                               mono_fatal_with_history ("suspend_count = %d, but should be > 0", suspend_count);
+                       if (InterlockedCompareExchange (&info->thread_state, build_thread_state (STATE_BLOCKING_AND_SUSPENDED, suspend_count), raw_state) != raw_state)
                                goto retry_state_change;
-                       trace_state_change ("ABORT_BLOCKING", info, raw_state, STATE_SELF_SUSPEND_REQUESTED, 0);
-                       return AbortBlockingOkAndPool;
+                       trace_state_change ("ABORT_BLOCKING", info, raw_state, STATE_BLOCKING_AND_SUSPENDED, 0);
+                       return AbortBlockingWait;
                }
 /*
 STATE_ASYNC_SUSPENDED:
index a12f5e77cb061767aaa29776b709e226e292faae..0bf4bdfb168e46662784f7e2104b1516f125cebe 100644 (file)
@@ -589,9 +589,9 @@ typedef enum {
 
 typedef enum {
        AbortBlockingIgnore, //Ignore
-       AbortBlockingIgnoreAndPoll, //Ignore and pool
+       AbortBlockingIgnoreAndPoll, //Ignore and poll
        AbortBlockingOk, //Abort worked
-       AbortBlockingOkAndPool, //Abort worked, but pool before
+       AbortBlockingWait, //Abort worked, but should wait for resume
 } MonoAbortBlockingResult;
 
 
index 64863625da2110e86aec1c37874467bde5810715..d4e07fd8965d5796ac61c0cf557c18c12a2e1d11 100644 (file)
@@ -11,8 +11,7 @@ MONO_OPTIONS_SRC = $(SRC_ROOT)/mcs/class/Mono.Options/Mono.Options/Options.cs
 
 .stamp-clone:
        @if [ ! -d $(CPPSHARP_DIR) ]; then \
-               git clone git@github.com:xamarin/CppSharpBinaries.git $(CPPSHARP_DIR); \
-               touch $@; \
+               git clone git@github.com:xamarin/CppSharpBinaries.git $(CPPSHARP_DIR) && touch $@; \
        fi
 
 MonoAotOffsetsDumper.exe: .stamp-clone MonoAotOffsetsDumper.cs $(MONO_OPTIONS_SRC)