1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 ////////////////////////////////////////////////////////////////////////////////
6 ////////////////////////////////////////////////////////////////////////////////
9 // This class defines a set of static methods that provide support for compilers.
13 namespace System.Runtime.CompilerServices
16 using System.Security;
18 using System.Runtime.CompilerServices;
19 using System.Runtime.InteropServices;
20 using System.Runtime.ConstrainedExecution;
21 using System.Runtime.Serialization;
22 using System.Threading;
23 using System.Runtime.Versioning;
25 public static class RuntimeHelpers
27 // Exposed here as a more appropriate place than on FormatterServices itself,
28 // which is a high level reflection heavy type.
29 public static Object GetUninitializedObject(Type type)
31 return FormatterServices.GetUninitializedObject(type);
34 [MethodImplAttribute(MethodImplOptions.InternalCall)]
35 public static extern void InitializeArray(Array array, RuntimeFieldHandle fldHandle);
37 // GetObjectValue is intended to allow value classes to be manipulated as 'Object'
38 // but have aliasing behavior of a value class. The intent is that you would use
39 // this function just before an assignment to a variable of type 'Object'. If the
40 // value being assigned is a mutable value class, then a shallow copy is returned
41 // (because value classes have copy semantics), but otherwise the object itself
44 // Note: VB calls this method when they're about to assign to an Object
45 // or pass it as a parameter. The goal is to make sure that boxed
46 // value types work identical to unboxed value types - ie, they get
47 // cloned when you pass them around, and are always passed by value.
48 // Of course, reference types are not cloned.
50 [MethodImplAttribute(MethodImplOptions.InternalCall)]
51 public static extern Object GetObjectValue(Object obj);
53 // RunClassConstructor causes the class constructor for the given type to be triggered
54 // in the current domain. After this call returns, the class constructor is guaranteed to
55 // have at least been started by some thread. In the absence of class constructor
56 // deadlock conditions, the call is further guaranteed to have completed.
58 // This call will generate an exception if the specified class constructor threw an
59 // exception when it ran.
61 [MethodImplAttribute(MethodImplOptions.InternalCall)]
62 private static extern void _RunClassConstructor(RuntimeType type);
64 public static void RunClassConstructor(RuntimeTypeHandle type)
66 _RunClassConstructor(type.GetRuntimeType());
69 // RunModuleConstructor causes the module constructor for the given type to be triggered
70 // in the current domain. After this call returns, the module constructor is guaranteed to
71 // have at least been started by some thread. In the absence of module constructor
72 // deadlock conditions, the call is further guaranteed to have completed.
74 // This call will generate an exception if the specified module constructor threw an
75 // exception when it ran.
77 [MethodImplAttribute(MethodImplOptions.InternalCall)]
78 private static extern void _RunModuleConstructor(System.Reflection.RuntimeModule module);
80 public static void RunModuleConstructor(ModuleHandle module)
82 _RunModuleConstructor(module.GetRuntimeModule());
86 [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
87 internal static extern void _CompileMethod(IRuntimeMethodInfo method);
89 [MethodImplAttribute(MethodImplOptions.InternalCall)]
90 private static unsafe extern void _PrepareMethod(IRuntimeMethodInfo method, IntPtr* pInstantiation, int cInstantiation);
92 public static void PrepareMethod(RuntimeMethodHandle method)
96 _PrepareMethod(method.GetMethodInfo(), null, 0);
100 public static void PrepareMethod(RuntimeMethodHandle method, RuntimeTypeHandle[] instantiation)
105 IntPtr[] instantiationHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(instantiation, out length);
106 fixed (IntPtr* pInstantiation = instantiationHandles)
108 _PrepareMethod(method.GetMethodInfo(), pInstantiation, length);
109 GC.KeepAlive(instantiation);
114 public static void PrepareContractedDelegate(Delegate d) { }
116 [MethodImplAttribute(MethodImplOptions.InternalCall)]
117 public static extern void PrepareDelegate(Delegate d);
119 [MethodImplAttribute(MethodImplOptions.InternalCall)]
120 public static extern int GetHashCode(Object o);
122 [MethodImplAttribute(MethodImplOptions.InternalCall)]
123 public new static extern bool Equals(Object o1, Object o2);
125 public static int OffsetToStringData
127 // This offset is baked in by string indexer intrinsic, so there is no harm
128 // in getting it baked in here as well.
129 [System.Runtime.Versioning.NonVersionable]
132 // Number of bytes from the address pointed to by a reference to
133 // a String to the first 16-bit character in the String. Skip
134 // over the MethodTable pointer, & String
135 // length. Of course, the String reference points to the memory
136 // after the sync block, so don't count that.
137 // This property allows C#'s fixed statement to work on Strings.
138 // On 64 bit platforms, this should be 12 (8+4) and on 32 bit 8 (4+4).
147 // This method ensures that there is sufficient stack to execute the average Framework function.
148 // If there is not enough stack, then it throws System.InsufficientExecutionStackException.
149 // Note: this method is not part of the CER support, and is not to be confused with ProbeForSufficientStack
151 [MethodImplAttribute(MethodImplOptions.InternalCall)]
152 public static extern void EnsureSufficientExecutionStack();
154 // This method ensures that there is sufficient stack to execute the average Framework function.
155 // If there is not enough stack, then it return false.
156 // Note: this method is not part of the CER support, and is not to be confused with ProbeForSufficientStack
158 [MethodImplAttribute(MethodImplOptions.InternalCall)]
159 public static extern bool TryEnsureSufficientExecutionStack();
161 public static void ProbeForSufficientStack()
165 // This method is a marker placed immediately before a try clause to mark the corresponding catch and finally blocks as
166 // constrained. There's no code here other than the probe because most of the work is done at JIT time when we spot a call to this routine.
167 public static void PrepareConstrainedRegions()
169 ProbeForSufficientStack();
172 // When we detect a CER with no calls, we can point the JIT to this non-probing version instead
173 // as we don't need to probe.
174 public static void PrepareConstrainedRegionsNoOP()
178 public delegate void TryCode(Object userData);
180 public delegate void CleanupCode(Object userData, bool exceptionThrown);
182 [MethodImplAttribute(MethodImplOptions.InternalCall)]
183 public static extern void ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData);
185 internal static void ExecuteBackoutCodeHelper(Object backoutCode, Object userData, bool exceptionThrown)
187 ((CleanupCode)backoutCode)(userData, exceptionThrown);
190 /// <returns>true if given type is reference type or value type that contains references</returns>
191 static public bool IsReferenceOrContainsReferences<T>()
193 // The body of this function will be replaced by the EE with unsafe code!!!
194 // See getILIntrinsicImplementation for how this happens.
195 throw new InvalidOperationException();