Esempio n. 1
0
 public static bool HasCctor(RuntimeTypeHandle typeHandle)
 {
     return(RuntimeImports.RhHasCctor(CreateEETypePtr(typeHandle)));
 }
Esempio n. 2
0
 public static IntPtr RuntimeHandleAllocRefCounted(object value)
 {
     return(RuntimeImports.RhHandleAlloc(value, (GCHandleType)RefCountedHandleType));
 }
Esempio n. 3
0
 public static void RuntimeHandleFree(IntPtr handle)
 {
     RuntimeImports.RhHandleFree(handle);
 }
Esempio n. 4
0
 public static bool RuntimeRegisterGcCalloutForGCEnd(IntPtr pCalloutMethod)
 {
     return(RuntimeImports.RhRegisterGcCallout(RuntimeImports.GcRestrictedCalloutKind.EndCollection, pCalloutMethod));
 }
Esempio n. 5
0
 public static bool RuntimeRegisterRefCountedHandleCallback(IntPtr pCalloutMethod, RuntimeTypeHandle pTypeFilter)
 {
     return(RuntimeImports.RhRegisterRefCountedHandleCallback(pCalloutMethod, pTypeFilter.ToEETypePtr()));
 }
Esempio n. 6
0
 // Block until the next finalization pass is complete.
 public static void WaitForPendingFinalizers()
 {
     RuntimeImports.RhWaitForPendingFinalizers(Thread.ReentrantWaitsEnabled);
 }
Esempio n. 7
0
 public static long GetAllocatedBytesForCurrentThread()
 {
     return(RuntimeImports.RhGetAllocatedBytesForCurrentThread());
 }
Esempio n. 8
0
        public static RuntimeTypeHandle GetNullableType(RuntimeTypeHandle nullableType)
        {
            EETypePtr theT = RuntimeImports.RhGetNullableType(nullableType.ToEETypePtr());

            return(new RuntimeTypeHandle(theT));
        }
Esempio n. 9
0
 // if functionPointer points at an import or unboxing stub, find the target of the stub
 public static IntPtr GetCodeTarget(IntPtr functionPointer)
 {
     return(RuntimeImports.RhGetCodeTarget(functionPointer));
 }
Esempio n. 10
0
        public static bool IsAssignable(Object srcObject, RuntimeTypeHandle dstType)
        {
            EETypePtr srcEEType = srcObject.EETypePtr;

            return(RuntimeImports.AreTypesAssignable(srcEEType, dstType.ToEETypePtr()));
        }
Esempio n. 11
0
 //==============================================================================================
 // Nullable<> support
 //==============================================================================================
 public static bool IsNullable(RuntimeTypeHandle declaringTypeHandle)
 {
     return(RuntimeImports.RhIsNullable(declaringTypeHandle.ToEETypePtr()));
 }
Esempio n. 12
0
 public static bool IsGenericTypeDefinition(RuntimeTypeHandle typeHandle)
 {
     return(RuntimeImports.RhGetEETypeClassification(CreateEETypePtr(typeHandle)) == RuntimeImports.RhEETypeClassification.GenericTypeDefinition);
 }
Esempio n. 13
0
 public static bool IsUnmanagedPointerType(RuntimeTypeHandle typeHandle)
 {
     return(RuntimeImports.RhGetEETypeClassification(CreateEETypePtr(typeHandle)) == RuntimeImports.RhEETypeClassification.UnmanagedPointer);
 }
Esempio n. 14
0
 public static IntPtr ResolveDispatch(object instance, RuntimeTypeHandle interfaceType, int slot)
 {
     return(RuntimeImports.RhResolveDispatch(instance, CreateEETypePtr(interfaceType), checked ((ushort)slot)));
 }
Esempio n. 15
0
 /// <summary>
 /// Returns the status of a registered notification about whether a blocking garbage collection
 /// is imminent. May wait indefinitely for a full collection.
 /// </summary>
 /// <returns>The status of a registered full GC notification</returns>
 public static GCNotificationStatus WaitForFullGCApproach()
 {
     return((GCNotificationStatus)RuntimeImports.RhWaitForFullGCApproach(-1));
 }
Esempio n. 16
0
 public static int GetCorElementType(RuntimeTypeHandle type)
 {
     return((int)RuntimeImports.RhGetCorElementType(type.ToEETypePtr()));
 }
Esempio n. 17
0
 /// <summary>
 /// Returns the status of a registered notification about whether a blocking garbage collection
 /// has completed. May wait indefinitely for a full collection.
 /// </summary>
 /// <returns>The status of a registered full GC notification</returns>
 public static GCNotificationStatus WaitForFullGCComplete()
 {
     return((GCNotificationStatus)RuntimeImports.RhWaitForFullGCComplete(-1));
 }
Esempio n. 18
0
 // Move memory which may be on the heap which may have object references in it.
 // In general, a memcpy on the heap is unsafe, but this is able to perform the
 // correct write barrier such that the GC is not incorrectly impacted.
 public unsafe static void BulkMoveWithWriteBarrier(IntPtr dmem, IntPtr smem, int size)
 {
     RuntimeImports.RhBulkMoveWithWriteBarrier((byte *)dmem.ToPointer(), (byte *)smem.ToPointer(), size);
 }
Esempio n. 19
0
        /// <summary>
        /// New AddMemoryPressure implementation (used by RCW and the CLRServicesImpl class)
        /// 1. Less sensitive than the original implementation (start budget 3 MB)
        /// 2. Focuses more on newly added memory pressure
        /// 3. Budget adjusted by effectiveness of last 3 triggered GC (add / remove ratio, max 10x)
        /// 4. Budget maxed with 30% of current managed GC size
        /// 5. If Gen2 GC is happening naturally, ignore past pressure
        ///
        /// Here's a brief description of the ideal algorithm for Add/Remove memory pressure:
        /// Do a GC when (HeapStart is less than X * MemPressureGrowth) where
        /// - HeapStart is GC Heap size after doing the last GC
        /// - MemPressureGrowth is the net of Add and Remove since the last GC
        /// - X is proportional to our guess of the ummanaged memory death rate per GC interval,
        /// and would be calculated based on historic data using standard exponential approximation:
        /// Xnew = UMDeath/UMTotal * 0.5 + Xprev
        /// </summary>
        /// <param name="bytesAllocated"></param>
        public static void AddMemoryPressure(long bytesAllocated)
        {
            if (bytesAllocated <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(bytesAllocated),
                                                      SR.ArgumentOutOfRange_NeedPosNum);
            }

#if !BIT64
            if (bytesAllocated > int.MaxValue)
            {
                throw new ArgumentOutOfRangeException(nameof(bytesAllocated),
                                                      SR.ArgumentOutOfRange_MustBeNonNegInt32);
            }
#endif

            CheckCollectionCount();
            uint p           = s_iteration % PressureCount;
            long newMemValue = InterlockedAddMemoryPressure(ref s_addPressure[p], bytesAllocated);

            Debug.Assert(PressureCount == 4, "GC.AddMemoryPressure contains unrolled loops which depend on the PressureCount");

            if (newMemValue >= MinGCMemoryPressureBudget)
            {
                long add = s_addPressure[0] + s_addPressure[1] + s_addPressure[2] + s_addPressure[3] - s_addPressure[p];
                long rem = s_removePressure[0] + s_removePressure[1] + s_removePressure[2] + s_removePressure[3] - s_removePressure[p];

                long budget = MinGCMemoryPressureBudget;

                if (s_iteration >= PressureCount)  // wait until we have enough data points
                {
                    // Adjust according to effectiveness of GC
                    // Scale budget according to past m_addPressure / m_remPressure ratio
                    if (add >= rem * MaxGCMemoryPressureRatio)
                    {
                        budget = MinGCMemoryPressureBudget * MaxGCMemoryPressureRatio;
                    }
                    else if (add > rem)
                    {
                        Debug.Assert(rem != 0);

                        // Avoid overflow by calculating addPressure / remPressure as fixed point (1 = 1024)
                        budget = (add * 1024 / rem) * budget / 1024;
                    }
                }

                // If still over budget, check current managed heap size
                if (newMemValue >= budget)
                {
                    long heapOver3 = RuntimeImports.RhGetCurrentObjSize() / 3;

                    if (budget < heapOver3)  //Max
                    {
                        budget = heapOver3;
                    }

                    if (newMemValue >= budget)
                    {
                        // last check - if we would exceed 20% of GC "duty cycle", do not trigger GC at this time
                        if ((RuntimeImports.RhGetGCNow() - RuntimeImports.RhGetLastGCStartTime(2)) > (RuntimeImports.RhGetLastGCDuration(2) * 5))
                        {
                            RuntimeImports.RhCollect(2, InternalGCCollectionMode.NonBlocking);
                            CheckCollectionCount();
                        }
                    }
                }
            }
        }
Esempio n. 20
0
 public static IntPtr GetUniversalTransitionThunk()
 {
     return(RuntimeImports.RhGetUniversalTransitionThunk());
 }
Esempio n. 21
0
 public static bool AreTypesAssignable(RuntimeTypeHandle sourceType, RuntimeTypeHandle targetType)
 {
     return(RuntimeImports.AreTypesAssignable(sourceType.ToEETypePtr(), targetType.ToEETypePtr()));
 }
Esempio n. 22
0
 public static void CallDescrWorker(IntPtr callDescr)
 {
     RuntimeImports.RhCallDescrWorker(callDescr);
 }
Esempio n. 23
0
 public static bool RuntimeRegisterGcCalloutForAfterMarkPhase(IntPtr pCalloutMethod)
 {
     return(RuntimeImports.RhRegisterGcCallout(RuntimeImports.GcRestrictedCalloutKind.AfterMarkPhase, pCalloutMethod));
 }
 internal static IntPtr IDynamicCastableGetInterfaceImplementation(object instance, MethodTable *interfaceType, ushort slot)
 {
     RuntimeImports.RhpFallbackFailFast();
     return(default);
Esempio n. 25
0
 public static void RuntimeUnregisterRefCountedHandleCallback(IntPtr pCalloutMethod, RuntimeTypeHandle pTypeFilter)
 {
     RuntimeImports.RhUnregisterRefCountedHandleCallback(pCalloutMethod, pTypeFilter.ToEETypePtr());
 }
Esempio n. 26
0
        private static void SerializeExceptionsForDump(Exception currentException, IntPtr exceptionCCWPtr, LowLevelList <byte[]> serializedExceptions)
        {
            const uint NoInnerExceptionValue = 0xFFFFFFFF;

            // Approximate upper size limit for the serialized exceptions (but we'll always serialize currentException)
            // If we hit the limit, because we serialize in arbitrary order, there may be missing InnerExceptions or nested exceptions.
            const int MaxBufferSize = 20000;

            int nExceptions;

            RuntimeImports.RhGetExceptionsForCurrentThread(null, out nExceptions);
            Exception[] curThreadExceptions = new Exception[nExceptions];
            RuntimeImports.RhGetExceptionsForCurrentThread(curThreadExceptions, out nExceptions);
            LowLevelList <Exception> exceptions = new LowLevelList <Exception>(curThreadExceptions);
            LowLevelList <Exception> nonThrownInnerExceptions = new LowLevelList <Exception>();

            uint currentThreadId = (uint)Environment.CurrentNativeThreadId;

            // Reset nesting levels for exceptions on this thread that might not be currently in flight
            foreach (KeyValuePair <Exception, ExceptionData> item in s_exceptionDataTable)
            {
                ExceptionData exceptionData = item.Value;
                if (exceptionData.ExceptionMetadata.ThreadId == currentThreadId)
                {
                    exceptionData.ExceptionMetadata.NestingLevel = -1;
                }
            }

            // Find all inner exceptions, even if they're not currently being handled
            for (int i = 0; i < exceptions.Count; i++)
            {
                if (exceptions[i].InnerException != null && !exceptions.Contains(exceptions[i].InnerException))
                {
                    exceptions.Add(exceptions[i].InnerException);
                    nonThrownInnerExceptions.Add(exceptions[i].InnerException);
                }
            }

            int currentNestingLevel = curThreadExceptions.Length - 1;

            // Make sure we serialize currentException
            if (!exceptions.Contains(currentException))
            {
                // When this happens, currentException is probably passed to this function through System.Environment.FailFast(), we
                // would want to treat as if this exception is last thrown in the current thread.
                exceptions.Insert(0, currentException);
                currentNestingLevel++;
            }

            // Populate exception data for all exceptions interesting to this thread.
            // Whether or not there was previously data for that object, it might have changed.
            for (int i = 0; i < exceptions.Count; i++)
            {
                ExceptionData exceptionData = s_exceptionDataTable.GetOrCreateValue(exceptions[i]);

                exceptionData.ExceptionMetadata.ExceptionId = (uint)System.Threading.Interlocked.Increment(ref s_currentExceptionId);
                if (exceptionData.ExceptionMetadata.ExceptionId == NoInnerExceptionValue)
                {
                    exceptionData.ExceptionMetadata.ExceptionId = (uint)System.Threading.Interlocked.Increment(ref s_currentExceptionId);
                }

                exceptionData.ExceptionMetadata.ThreadId = currentThreadId;

                // Only include nesting information for exceptions that were thrown on this thread
                if (!nonThrownInnerExceptions.Contains(exceptions[i]))
                {
                    exceptionData.ExceptionMetadata.NestingLevel = currentNestingLevel;
                    currentNestingLevel--;
                }
                else
                {
                    exceptionData.ExceptionMetadata.NestingLevel = -1;
                }

                // Only match the CCW pointer up to the current exception
                if (object.ReferenceEquals(exceptions[i], currentException))
                {
                    exceptionData.ExceptionMetadata.ExceptionCCWPtr = exceptionCCWPtr;
                }

                byte[] serializedEx = exceptions[i].SerializeForDump();
                exceptionData.SerializedExceptionData = serializedEx;
            }

            // Populate inner exception ids now that we have all of them in the table
            for (int i = 0; i < exceptions.Count; i++)
            {
                ExceptionData exceptionData;
                if (!s_exceptionDataTable.TryGetValue(exceptions[i], out exceptionData))
                {
                    // This shouldn't happen, but we can't meaningfully throw here
                    continue;
                }

                if (exceptions[i].InnerException != null)
                {
                    ExceptionData innerExceptionData;
                    if (s_exceptionDataTable.TryGetValue(exceptions[i].InnerException, out innerExceptionData))
                    {
                        exceptionData.ExceptionMetadata.InnerExceptionId = innerExceptionData.ExceptionMetadata.ExceptionId;
                    }
                }
                else
                {
                    exceptionData.ExceptionMetadata.InnerExceptionId = NoInnerExceptionValue;
                }
            }

            int totalSerializedExceptionSize = 0;
            // Make sure we include the current exception, regardless of buffer size
            ExceptionData currentExceptionData = null;

            if (s_exceptionDataTable.TryGetValue(currentException, out currentExceptionData))
            {
                byte[] serializedExceptionData = currentExceptionData.Serialize();
                serializedExceptions.Add(serializedExceptionData);
                totalSerializedExceptionSize = serializedExceptionData.Length;
            }

            checked
            {
                foreach (KeyValuePair <Exception, ExceptionData> item in s_exceptionDataTable)
                {
                    ExceptionData exceptionData = item.Value;

                    // Already serialized currentException
                    if (currentExceptionData != null && exceptionData.ExceptionMetadata.ExceptionId == currentExceptionData.ExceptionMetadata.ExceptionId)
                    {
                        continue;
                    }

                    byte[] serializedExceptionData = exceptionData.Serialize();
                    if (totalSerializedExceptionSize + serializedExceptionData.Length >= MaxBufferSize)
                    {
                        break;
                    }

                    serializedExceptions.Add(serializedExceptionData);
                    totalSerializedExceptionSize += serializedExceptionData.Length;
                }
            }
        }
Esempio n. 27
0
 public static void RuntimeHandleSet(IntPtr handle, object value)
 {
     RuntimeImports.RhHandleSet(handle, value);
 }
Esempio n. 28
0
 // Garbage collect all generations.
 public static void Collect()
 {
     //-1 says to GC all generations.
     RuntimeImports.RhCollect(-1, InternalGCCollectionMode.Blocking);
 }
Esempio n. 29
0
 public static IntPtr RuntimeHandleAllocDependent(object primary, object secondary)
 {
     return(RuntimeImports.RhHandleAllocDependent(primary, secondary));
 }
Esempio n. 30
0
 public static bool IsDynamicType(RuntimeTypeHandle typeHandle)
 {
     return(RuntimeImports.RhIsDynamicType(CreateEETypePtr(typeHandle)));
 }