[System.Private.CoreLib] Cleanup intrinsic tracking (mono/mono#17884)
authorMarek Safar <marek.safar@gmail.com>
Tue, 7 Jan 2020 10:17:06 +0000 (11:17 +0100)
committerGitHub <noreply@github.com>
Tue, 7 Jan 2020 10:17:06 +0000 (11:17 +0100)
* [System.Private.CoreLib] Cleanup intrinsic tracking

1. Removed icalls where intrinsic version for the method exists

2. Add [Intrinsic] attribute to methods which have runtime intrinsic
   to make them easier to track and to tell linker not to analyze them

3. Use recursive syntax for any intrinsic which can be called via
   reflection to correctly apply the intrinsic when invoked.

```c#
public static bool IsSupported { get => IsSupported; }
```

When one calls X86.IsSupported, the call gets replaced by an
intrinsics. When one calls it with an Invoke, the body of IsSupported
gets replaced by intrinsics. It's just a hack to get Invoke support for free.

* [interp] implement System.Type::op_Equality

* Undo changes which are not yet supported by interpreter

* [interp] Implement System.Runtime.CompilerServices.RuntimeHelpers::OffsetToStringData

Co-authored-by: Bernhard Urban-Forster <bernhard.urban@xamarin.com>
Commit migrated from https://github.com/mono/mono/commit/adcd62248d8956ab4d512c5b970c867b7432887f

14 files changed:
src/mono/mono/metadata/icall-def-netcore.h
src/mono/mono/metadata/icall.c
src/mono/mono/metadata/monitor.c
src/mono/mono/mini/interp/transform.c
src/mono/netcore/System.Private.CoreLib/src/System/Array.Mono.cs
src/mono/netcore/System.Private.CoreLib/src/System/Diagnostics/Debugger.cs
src/mono/netcore/System.Private.CoreLib/src/System/Object.Mono.cs
src/mono/netcore/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeFeature.Mono.cs
src/mono/netcore/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.Mono.cs
src/mono/netcore/System.Private.CoreLib/src/System/String.Mono.cs
src/mono/netcore/System.Private.CoreLib/src/System/Threading/Interlocked.cs
src/mono/netcore/System.Private.CoreLib/src/System/Threading/Monitor.cs
src/mono/netcore/System.Private.CoreLib/src/System/Threading/Thread.Mono.cs
src/mono/netcore/System.Private.CoreLib/src/System/Type.Mono.cs

index 735d1ee..41b130e 100644 (file)
@@ -42,9 +42,7 @@ HANDLES(ARRAY_4, "FastCopy",         ves_icall_System_Array_FastCopy, MonoBoolea
 HANDLES(ARRAY_4a, "GetCorElementTypeOfElementType", ves_icall_System_Array_GetCorElementTypeOfElementType, gint32, 1, (MonoArray))
 NOHANDLES(ICALL(ARRAY_5, "GetGenericValue_icall", ves_icall_System_Array_GetGenericValue_icall))
 HANDLES(ARRAY_6, "GetLength",        ves_icall_System_Array_GetLength, gint32, 2, (MonoArray, gint32))
-HANDLES(ARRAY_15, "GetLongLength",   ves_icall_System_Array_GetLongLength, gint64, 2, (MonoArray, gint32))
 HANDLES(ARRAY_7, "GetLowerBound",    ves_icall_System_Array_GetLowerBound, gint32, 2, (MonoArray, gint32))
-HANDLES(ARRAY_8, "GetRank",          ves_icall_System_Array_GetRank, gint32, 1, (MonoObject))
 HANDLES(ARRAY_9, "GetValue",         ves_icall_System_Array_GetValue, MonoObject, 2, (MonoArray, MonoArray))
 HANDLES(ARRAY_10, "GetValueImpl",    ves_icall_System_Array_GetValueImpl, MonoObject, 2, (MonoArray, guint32))
 NOHANDLES(ICALL(ARRAY_10a, "InternalCreate", ves_icall_System_Array_InternalCreate))
@@ -172,8 +170,7 @@ NOHANDLES(ICALL(MATHF_19, "Sqrt", ves_icall_System_MathF_Sqrt))
 NOHANDLES(ICALL(MATHF_20, "Tan", ves_icall_System_MathF_Tan))
 NOHANDLES(ICALL(MATHF_21, "Tanh", ves_icall_System_MathF_Tanh))
 
-ICALL_TYPE(OBJ, "System.Object", OBJ_1)
-HANDLES(OBJ_1, "GetType", ves_icall_System_Object_GetType, MonoReflectionType, 1, (MonoObject))
+ICALL_TYPE(OBJ, "System.Object", OBJ_3)
 HANDLES(OBJ_3, "MemberwiseClone", ves_icall_System_Object_MemberwiseClone, MonoObject, 1, (MonoObject))
 
 ICALL_TYPE(ASSEM, "System.Reflection.Assembly", ASSEM_2)
@@ -329,7 +326,6 @@ HANDLES(RUNH_3a, "PrepareMethod", ves_icall_System_Runtime_CompilerServices_Runt
 HANDLES(RUNH_4, "RunClassConstructor", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunClassConstructor, void, 1, (MonoType_ptr))
 HANDLES(RUNH_5, "RunModuleConstructor", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_RunModuleConstructor, void, 1, (MonoImage_ptr))
 NOHANDLES(ICALL(RUNH_5h, "SufficientExecutionStack", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_SufficientExecutionStack))
-NOHANDLES(ICALL(RUNH_6, "get_OffsetToStringData", ves_icall_System_Runtime_CompilerServices_RuntimeHelpers_GetOffsetToStringData))
 
 ICALL_TYPE(GCH, "System.Runtime.InteropServices.GCHandle", GCH_1)
 HANDLES(GCH_1, "InternalAlloc", ves_icall_System_GCHandle_InternalAlloc, gpointer, 2, (MonoObject, gint32))
@@ -505,7 +501,6 @@ HANDLES(THREAD_8, "SetName_icall", ves_icall_System_Threading_Thread_SetName_ica
 HANDLES(THREAD_9, "SetPriority", ves_icall_System_Threading_Thread_SetPriority, void, 2, (MonoThreadObject, int))
 HANDLES(THREAD_10, "SetState", ves_icall_System_Threading_Thread_SetState, void, 2, (MonoInternalThread, guint32))
 HANDLES(THREAD_11, "SleepInternal", ves_icall_System_Threading_Thread_Sleep_internal, void, 2, (gint32, MonoBoolean))
-HANDLES(THREAD_12, "SpinWait_nop", ves_icall_System_Threading_Thread_SpinWait_nop, void, 0, ())
 HANDLES(THREAD_13, "StartInternal", ves_icall_System_Threading_Thread_StartInternal, void, 1, (MonoThreadObject))
 NOHANDLES(ICALL(THREAD_14, "YieldInternal", ves_icall_System_Threading_Thread_YieldInternal))
 
index 26b5d34..775e958 100644 (file)
@@ -944,7 +944,6 @@ ves_icall_System_Array_CreateInstanceImpl (MonoReflectionTypeHandle type, MonoAr
 
        return mono_array_new_full_handle (MONO_HANDLE_DOMAIN (type), aklass, sizes, lower_bounds, error);
 }
-#endif
 
 gint32
 ves_icall_System_Array_GetRank (MonoObjectHandle arr, MonoError *error)
@@ -955,6 +954,7 @@ ves_icall_System_Array_GetRank (MonoObjectHandle arr, MonoError *error)
 
        return result;
 }
+#endif
 
 #ifdef ENABLE_NETCORE
 gint32
@@ -996,6 +996,7 @@ ves_icall_System_Array_GetLength (MonoArrayHandle arr, gint32 dimension, MonoErr
        return (gint32)length;
 }
 
+#ifndef ENABLE_NETCORE
 gint64
 ves_icall_System_Array_GetLongLength (MonoArrayHandle arr, gint32 dimension, MonoError *error)
 {
@@ -1003,6 +1004,7 @@ ves_icall_System_Array_GetLongLength (MonoArrayHandle arr, gint32 dimension, Mon
 
        return (gint64)mono_array_get_length (arr, dimension, error);
 }
+#endif
 
 gint32
 ves_icall_System_Array_GetLowerBound (MonoArrayHandle arr, gint32 dimension, MonoError *error)
@@ -1640,6 +1642,7 @@ ves_icall_System_ValueType_Equals (MonoObjectHandle this_obj, MonoObjectHandle t
        }
 }
 
+#ifndef ENABLE_NETCORE
 MonoReflectionTypeHandle
 ves_icall_System_Object_GetType (MonoObjectHandle obj, MonoError *error)
 {
@@ -1661,6 +1664,7 @@ ves_icall_System_Object_GetType (MonoObjectHandle obj, MonoError *error)
 #endif
                return mono_type_get_object_handle (domain, m_class_get_byval_arg (klass), error);
 }
+#endif
 
 static gboolean
 get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
index 6b726cd..14d9dcc 100644 (file)
@@ -1499,7 +1499,6 @@ ves_icall_System_Threading_Monitor_Monitor_wait (MonoObjectHandle obj_handle, gu
        return mono_monitor_wait (obj_handle, ms, TRUE, error);
 }
 #endif
-
 void
 ves_icall_System_Threading_Monitor_Monitor_Enter (MonoObjectHandle obj, MonoError* error)
 {
index 0da8b1c..226c2a6 100644 (file)
@@ -1698,7 +1698,15 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas
 #endif
        } else if (in_corlib && !strcmp (klass_name_space, "System.Runtime.CompilerServices") && !strcmp (klass_name, "RuntimeHelpers")) {
 #ifdef ENABLE_NETCORE
-               if (!strcmp (tm, "IsBitwiseEquatable")) {
+               if (!strcmp (tm, "get_OffsetToStringData")) {
+                       g_assert (csignature->param_count == 0);
+                       int offset = MONO_STRUCT_OFFSET (MonoString, chars);
+                       interp_add_ins (td, MINT_LDC_I4);
+                       WRITE32_INS (td->last_ins, 0, &offset);
+                       PUSH_SIMPLE_TYPE (td, STACK_TYPE_I4);
+                       td->ip += 5;
+                       return TRUE;
+               } else if (!strcmp (tm, "IsBitwiseEquatable")) {
                        g_assert (csignature->param_count == 0);
                        MonoGenericContext *ctx = mono_method_get_context (target_method);
                        g_assert (ctx);
@@ -1737,6 +1745,8 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas
        } else if (in_corlib && !strcmp (klass_name_space, "System") && !strcmp (klass_name, "RuntimeMethodHandle") && !strcmp (tm, "GetFunctionPointer") && csignature->param_count == 1) {
                // We must intrinsify this method on interp so we don't return a pointer to native code entering interpreter
                *op = MINT_LDFTN_DYNAMIC;
+       } else if (in_corlib && target_method->klass == mono_defaults.systemtype_class && !strcmp (target_method->name, "op_Equality")) {
+               *op = MINT_CEQ_P;
        } else if (in_corlib && target_method->klass == mono_defaults.object_class) {
                if (!strcmp (tm, "InternalGetHashCode"))
                        *op = MINT_INTRINS_GET_HASHCODE;
index 1010479..e65df0c 100644 (file)
@@ -28,14 +28,8 @@ namespace System
                }
 
                public int Length {
-                       get {
-                               int length = GetLength (0);
-
-                               for (int i = 1; i < Rank; i++) {
-                                       length *= GetLength (i);
-                               }
-                               return length;
-                       }
+                       [Intrinsic]
+                       get => Length;
                }
 
                public long LongLength {
@@ -50,9 +44,8 @@ namespace System
                }
 
                public int Rank {
-                       get {
-                               return GetRank ();
-                       }
+                       [Intrinsic]
+                       get => Rank;
                }
 
                public static unsafe void Clear (Array array, int index, int length)
@@ -455,6 +448,7 @@ namespace System
                [MethodImpl (MethodImplOptions.AggressiveInlining)]
                internal ref byte GetRawSzArrayData ()
                {
+                       // TODO: Missing intrinsic in interpreter
                        return ref Unsafe.As<RawData>(this).Data;
                }
 
@@ -462,27 +456,20 @@ namespace System
                [MethodImpl (MethodImplOptions.AggressiveInlining)]
                internal ref byte GetRawArrayData ()
                {
+                       // TODO: Missing intrinsic in interpreter
                        return ref Unsafe.As<RawData>(this).Data;
                }
 
                [Intrinsic]
-               internal int GetElementSize ()
-               {
-                       ThrowHelper.ThrowNotSupportedException ();
-                       return 0;
-               }
+               internal int GetElementSize () => GetElementSize ();
 
                [Intrinsic]
-               public bool IsPrimitive ()
-               {
-                       ThrowHelper.ThrowNotSupportedException ();
-                       return false;
-               }
+               public bool IsPrimitive () => IsPrimitive ();
 
-               [MethodImpl(MethodImplOptions.InternalCall)]
+               [MethodImpl (MethodImplOptions.InternalCall)]
                internal extern CorElementType GetCorElementTypeOfElementType();
 
-               [MethodImpl(MethodImplOptions.InternalCall)]
+               [MethodImpl (MethodImplOptions.InternalCall)]
                extern bool IsValueOfElementType(object value);
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
@@ -491,9 +478,7 @@ namespace System
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                internal extern static bool FastCopy (Array source, int source_idx, Array dest, int dest_idx, int length);
 
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               extern int GetRank ();
-
+               [Intrinsic] // when dimension is `0` constant
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern int GetLength (int dimension);
 
@@ -519,14 +504,14 @@ namespace System
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                extern static void SetGenericValue_icall<T> (ref Array self, int pos, ref T value);
 
-               // This is a special case in the runtime.
+               [Intrinsic]
                void GetGenericValueImpl<T> (int pos, out T value)
                {
                        var self = this;
                        GetGenericValue_icall (ref self, pos, out value);
                }
 
-               // This is a special case in the runtime.
+               [Intrinsic]
                void SetGenericValueImpl<T> (int pos, ref T value)
                {
                        var self = this;
index 884c5f7..1692021 100644 (file)
@@ -15,6 +15,7 @@ namespace System.Diagnostics
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                extern static bool IsAttached_internal ();
 
+               [Intrinsic]
                public static void Break ()
                {
                        // The JIT inserts a breakpoint on the caller.
index 8321b0a..a34de19 100644 (file)
@@ -8,14 +8,14 @@ namespace System
 {
        partial class Object
        {
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public extern Type GetType ();
+               [Intrinsic]
+               public Type GetType () => GetType ();
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                protected extern object MemberwiseClone ();
 
                [Intrinsic]
-               internal ref byte GetRawData () => throw new NotImplementedException ();
+               internal ref byte GetRawData () => ref GetRawData ();
 
                internal object CloneInternal () => MemberwiseClone ();
        }
index 97551e2..00b5c98 100644 (file)
@@ -6,16 +6,14 @@ namespace System.Runtime.CompilerServices
 {
        partial class RuntimeFeature
        {
-               public static bool IsDynamicCodeSupported
-               {
+               public static bool IsDynamicCodeSupported {
                        [Intrinsic]  // the JIT/AOT compiler will change this flag to false for FullAOT scenarios, otherwise true
-                       get { throw new NotImplementedException (); }
+                       get => IsDynamicCodeSupported;
                }
 
-               public static bool IsDynamicCodeCompiled
-               {
+               public static bool IsDynamicCodeCompiled {
                        [Intrinsic]  // the JIT/AOT compiler will change this flag to false for FullAOT scenarios, otherwise true
-                       get { throw new NotImplementedException (); }
+                       get => IsDynamicCodeCompiled;
                }
        }
 }
index 23d16af..43efbaa 100644 (file)
@@ -14,9 +14,9 @@ namespace System.Runtime.CompilerServices
                        InitializeArray (array, fldHandle.Value);
                }
 
-               public static extern int OffsetToStringData {
-                       [MethodImpl (MethodImplOptions.InternalCall)]
-                       get;
+               public static int OffsetToStringData {
+                       [Intrinsic]
+                       get => OffsetToStringData;
                }
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
@@ -100,26 +100,18 @@ namespace System.Runtime.CompilerServices
                }
 
                [Intrinsic]
-               public static bool IsReferenceOrContainsReferences<T> ()
-               {
-                       return !typeof (T).IsValueType || RuntimeTypeHandle.HasReferences ((typeof (T) as RuntimeType));
-               }
+               public static bool IsReferenceOrContainsReferences<T> () => IsReferenceOrContainsReferences<T> ();
 
                [Intrinsic]
-               internal static bool IsBitwiseEquatable<T> ()
-               {
-                       throw new NotImplementedException ();
-               }
+               internal static bool IsBitwiseEquatable<T> () => IsBitwiseEquatable<T> ();
 
                [Intrinsic]
-               internal static bool ObjectHasComponentSize (object obj)
-               {
-                       throw new NotImplementedException ();
-               }
+               internal static bool ObjectHasComponentSize (object obj) => ObjectHasComponentSize (obj);
 
                [Intrinsic]
                internal static bool ObjectHasReferences (object obj)
                {
+                       // TODO: Missing intrinsic in interpreter
                        return RuntimeTypeHandle.HasReferences (obj.GetType () as RuntimeType);
                }
 
index e21879c..a4b8526 100644 (file)
@@ -12,17 +12,15 @@ namespace System
                [Intrinsic]
                public static readonly String Empty;
 
-               public int Length => _stringLength;
+               public int Length {
+                       [Intrinsic]
+                       get => _stringLength;
+               }
 
                [IndexerName ("Chars")]
                public char this [int index] {
                        [Intrinsic]
-                       get {
-                               if ((uint)index >= _stringLength)
-                                       ThrowHelper.ThrowIndexOutOfRangeException ();
-
-                               return Unsafe.Add (ref _firstChar, index);
-                       }
+                       get => this [index];
                }
 
                public static String Intern (String str)
index 0f99892..cbc041c 100644 (file)
@@ -10,12 +10,15 @@ namespace System.Threading
 {
        public static class Interlocked
        {
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               [Intrinsic]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern static int CompareExchange (ref int location1, int value, int comparand);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               [Intrinsic]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
                extern static void CompareExchange (ref object location1, ref object value, ref object comparand, ref object result);
 
+               [Intrinsic]
                public static object CompareExchange (ref object location1, object value, object comparand)
                {
                        // This avoids coop handles, esp. on the output which would be particularly inefficient.
@@ -38,18 +41,23 @@ namespace System.Threading
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static float CompareExchange (ref float location1, float value, float comparand);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               [Intrinsic]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern static int Decrement (ref int location);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               [Intrinsic]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern static long Decrement (ref long location);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               [Intrinsic]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern static int Increment (ref int location);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               [Intrinsic]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern static long Increment (ref long location);
 
+               [Intrinsic]
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static int Exchange (ref int location1, int value);
 
@@ -64,7 +72,8 @@ namespace System.Threading
                        return result;
                }
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               [Intrinsic]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern static float Exchange (ref float location1, float value);
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
@@ -101,13 +110,16 @@ namespace System.Threading
                        return result;
                }
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               [Intrinsic]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern static long Exchange (ref long location1, long value);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               [Intrinsic]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern static IntPtr Exchange (ref IntPtr location1, IntPtr value);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               [Intrinsic]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern static double Exchange (ref double location1, double value);
 
                [return: NotNullIfNotNull("location1")]
@@ -130,16 +142,22 @@ namespace System.Threading
                        return result;
                }
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               [Intrinsic]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern static long Read (ref long location);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               [Intrinsic]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern static int Add (ref int location1, int value);
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               [Intrinsic]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern static long Add (ref long location1, long value);
 
-               public static void MemoryBarrier () => Thread.MemoryBarrier ();
+               [Intrinsic]
+               public static void MemoryBarrier ()
+               {
+               }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public extern static void MemoryBarrierProcessWide ();
index ca2cbdb..5c94a16 100644 (file)
@@ -8,15 +8,18 @@ namespace System.Threading
 {
        public static class Monitor
        {
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               public static extern void Enter (object obj);
+               [Intrinsic]
+               [MethodImplAttribute (MethodImplOptions.InternalCall)] // Interpreter is missing this intrinsic
+               public static void Enter (object obj) => Enter (obj);
 
+               [Intrinsic]
                public static void Enter (object obj, ref bool lockTaken)
                {
+                       // TODO: Interpreter is missing this intrinsic
                        if (lockTaken)
                                throw new ArgumentException (SR.Argument_MustBeFalse, nameof (lockTaken));
 
-                       ReliableEnter (obj, ref lockTaken);
+                       ReliableEnterTimeout (obj, (int) Timeout.Infinite, ref lockTaken);
                }
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
@@ -159,11 +162,6 @@ namespace System.Threading
                        try_enter_with_atomic_var (obj, timeout, true, ref lockTaken);
                }
 
-               static void ReliableEnter (object obj, ref bool lockTaken)
-               {
-                       ReliableEnterTimeout (obj, (int) Timeout.Infinite, ref lockTaken);
-               }
-
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                extern static bool Monitor_test_owner (object obj);
 
@@ -172,8 +170,7 @@ namespace System.Threading
                        return Monitor_test_owner (obj);
                }
                
-               public extern static long LockContentionCount
-               {
+               public extern static long LockContentionCount {
                        [MethodImplAttribute (MethodImplOptions.InternalCall)]
                        get;
                }
index 6b4bb79..102e79a 100644 (file)
@@ -320,8 +320,10 @@ namespace System.Threading
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                extern static void SleepInternal (int millisecondsTimeout, bool allowInterruption);
 
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               extern static void SpinWait_nop ();
+               [Intrinsic]
+               static void SpinWait_nop ()
+               {
+               }
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                extern static Thread CreateInternal ();
index 2c22261..a5f4fa1 100644 (file)
@@ -124,14 +124,12 @@ namespace System
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                static extern Type internal_from_handle (IntPtr handle);
 
-               public static bool operator == (Type? left, Type? right)
-               {
-                       return object.ReferenceEquals (left, right);
-               }
+               [Intrinsic]
+               public static bool operator == (Type? left, Type? right) => left == right;
 
                public static bool operator != (Type? left, Type? right)
                {
-                       return !object.ReferenceEquals (left, right);
+                       return !(left == right);
                }
        }
 }