Beispiel #1
0
        /// <summary>
        /// Get a pointer to a pointer to the nongc static field data of a type. This function works for all generic types
        /// </summary>
        public IntPtr TryGetNonGcStaticFieldData(RuntimeTypeHandle runtimeTypeHandle)
        {
            unsafe
            {
                // Non-generic, non-dynamic static data is found via the FieldAccessMap
                EEType *typeAsEEType = runtimeTypeHandle.ToEETypePtr();
                // Non-generic, non-dynamic types need special handling.
                Debug.Assert(typeAsEEType->IsDynamicType || typeAsEEType->IsGeneric);
            }

            // Search hashtable for static entry
            ExternalReferencesTable staticInfoLookup;
            var parser = GetStaticInfo(runtimeTypeHandle, out staticInfoLookup);

            if (!parser.IsNull)
            {
                var index = parser.GetUnsignedForBagElementKind(BagElementKind.NonGcStaticData);

                return(index.HasValue ? staticInfoLookup.GetIntPtrFromIndex(index.Value) : IntPtr.Zero);
            }

            // Not found in hashtable... must be a dynamically created type
            Debug.Assert(runtimeTypeHandle.IsDynamicType());
            unsafe
            {
                EEType *typeAsEEType = runtimeTypeHandle.ToEETypePtr();
                if ((typeAsEEType->RareFlags & EETypeRareFlags.IsDynamicTypeWithNonGcStatics) != 0)
                {
                    return(typeAsEEType->DynamicNonGcStaticsData);
                }
            }

            // Type has no non-GC statics
            return(IntPtr.Zero);
        }
Beispiel #2
0
        public void RegisterDynamicThreadStaticsInfo(RuntimeTypeHandle runtimeTypeHandle, uint offsetValue, int storageSize)
        {
            bool registered = false;

            Debug.Assert(offsetValue != 0 && storageSize > 0 && runtimeTypeHandle.IsDynamicType());

            _threadStaticsLock.Acquire();
            try
            {
                // Sanity check to make sure we do not register thread statics for the same type more than once
                uint temp;
                Debug.Assert(!_dynamicGenericsThreadStatics.TryGetValue(runtimeTypeHandle, out temp) && storageSize > 0);

                _dynamicGenericsThreadStatics.Add(runtimeTypeHandle, offsetValue);
                _dynamicGenericsThreadStaticSizes.Add(offsetValue, storageSize);
                registered = true;
            }
            finally
            {
                if (!registered)
                {
                    _dynamicGenericsThreadStatics.Remove(runtimeTypeHandle);
                    _dynamicGenericsThreadStaticSizes.Remove(offsetValue);
                }

                _threadStaticsLock.Release();
            }
        }
        public void RegisterDynamicThreadStaticsInfo(RuntimeTypeHandle runtimeTypeHandle, uint offsetValue, IntPtr gcDesc)
        {
            bool registered = false;

            Debug.Assert(offsetValue != 0 && runtimeTypeHandle.IsDynamicType());

            IntPtr typeManager = runtimeTypeHandle.GetTypeManager().GetIntPtrUNSAFE();

            _threadStaticsLock.Acquire();
            try
            {
                if (!_dynamicGenericsThreadStaticDescs.TryGetValue(typeManager, out LowLevelDictionary <uint, IntPtr> gcDescs))
                {
                    _dynamicGenericsThreadStaticDescs.Add(typeManager, gcDescs = new LowLevelDictionary <uint, IntPtr>());
                }
                gcDescs.Add(offsetValue, gcDesc);
                registered = true;
            }
            finally
            {
                if (!registered)
                {
                    if (_dynamicGenericsThreadStaticDescs.TryGetValue(typeManager, out LowLevelDictionary <uint, IntPtr> gcDescs))
                    {
                        gcDescs.Remove(offsetValue);
                    }
                }

                _threadStaticsLock.Release();
            }
        }
Beispiel #4
0
        public unsafe IntPtr TryGetThreadStaticFieldOffsetCookieForTypeAndFieldOffset(RuntimeTypeHandle runtimeTypeHandle, uint fieldOffset)
        {
            var cookieData = new PermanentAllocatedMemoryBlobs.ThreadStaticFieldOffsets();

            if (runtimeTypeHandle.IsDynamicType())
            {
                cookieData.StartingOffsetInTlsBlock = 0;
                cookieData.FieldOffset = fieldOffset;
            }
            else
            {
                IntPtr ptrToTlsOffset = TryGetTlsOffsetDictionaryCellForStaticType(runtimeTypeHandle);
                if (ptrToTlsOffset == IntPtr.Zero)
                {
                    return(IntPtr.Zero);
                }

                IntPtr tlsOffsetAsIntPtr = *(IntPtr *)ptrToTlsOffset.ToPointer();
                uint   tlsOffset         = (uint)tlsOffsetAsIntPtr.ToInt32();
                cookieData.StartingOffsetInTlsBlock = tlsOffset;
                cookieData.FieldOffset = fieldOffset;
            }

            return(PermanentAllocatedMemoryBlobs.GetPointerToThreadStaticFieldOffsets(cookieData));
        }
Beispiel #5
0
        private IntPtr TryGetTlsOffsetDictionaryCellForDynamicType(RuntimeTypeHandle runtimeTypeHandle)
        {
            Debug.Assert(runtimeTypeHandle.IsDynamicType());

            using (LockHolder.Hold(_threadStaticsLock))
            {
                uint offsetValue;
                if (_dynamicGenericsThreadStatics.TryGetValue(runtimeTypeHandle, out offsetValue))
                {
                    return(TryCreateDictionaryCellWithValue(offsetValue));
                }
            }

            return(IntPtr.Zero);
        }
Beispiel #6
0
        public static unsafe bool IsPregeneratedOrTemplateRuntimeTypeHandle(RuntimeTypeHandle rtth)
        {
#if SUPPORTS_NATIVE_METADATA_TYPE_LOADING
            if (!rtth.IsDynamicType())
            {
                return(true);
            }

            if (rtth.ToEETypePtr()->DynamicModule == null)
            {
                return(true);
            }

            return(rtth.ToEETypePtr()->DynamicModule->DynamicTypeSlotDispatchResolve == IntPtr.Zero);
#else
            return(true);
#endif
        }
Beispiel #7
0
        public unsafe bool TryGetThreadStaticStartOffset(RuntimeTypeHandle runtimeTypeHandle, out int threadStaticsStartOffset)
        {
            threadStaticsStartOffset = -1;

            if (runtimeTypeHandle.IsDynamicType())
            {
                // Specific TLS storage is allocated for each dynamic type. There is no starting offset since it's not a
                // TLS storage block shared by multiple types.
                threadStaticsStartOffset = 0;
                return(true);
            }
            else
            {
                IntPtr ptrToTlsOffset = TryGetTlsOffsetDictionaryCellForStaticType(runtimeTypeHandle);
                if (ptrToTlsOffset == IntPtr.Zero)
                {
                    return(false);
                }

                threadStaticsStartOffset = *(int *)ptrToTlsOffset;
                return(true);
            }
        }
Beispiel #8
0
 private IntPtr TryGetTlsIndexDictionaryCellForDynamicType(RuntimeTypeHandle runtimeTypeHandle)
 {
     // Use TLS index of 0 for dynamic types (the index won't really be used)
     Debug.Assert(runtimeTypeHandle.IsDynamicType());
     return(TryCreateDictionaryCellWithValue(0));
 }
        // Various functions in static access need to create permanent pointers for use by thread static lookup.
        #region GC/Non-GC Statics
        /// <summary>
        /// Get a pointer to the nongc static field data of a type. This function works for dynamic
        /// types, reflectable types, and for all generic types
        /// </summary>
        public IntPtr TryGetNonGcStaticFieldData(RuntimeTypeHandle runtimeTypeHandle)
        {
            unsafe
            {
                MethodTable *typeAsEEType = runtimeTypeHandle.ToEETypePtr();
                // Non-generic, non-dynamic types need special handling.
                if (!typeAsEEType->IsDynamicType && !typeAsEEType->IsGeneric)
                {
                    if (typeAsEEType->HasCctor)
                    {
                        // The non-gc area for a type is immediately following its cctor context if it has one
                        IntPtr dataAddress = TryGetStaticClassConstructionContext(runtimeTypeHandle);
                        if (dataAddress != IntPtr.Zero)
                        {
                            return((IntPtr)(((byte *)dataAddress.ToPointer()) + sizeof(System.Runtime.CompilerServices.StaticClassConstructionContext)));
                        }
                    }
                    else
                    {
                        // If the type does not have a Cctor context, search for the field on the type in the field map which has the lowest offset,
                        // yet has the the correct type of storage.
                        IntPtr staticAddress;
                        if (TryGetStaticFieldBaseFromFieldAccessMap(runtimeTypeHandle, FieldAccessStaticDataKind.NonGC, out staticAddress))
                        {
                            return(staticAddress);
                        }
                    }
                }
            }

            IntPtr nonGcStaticsAddress;
            IntPtr gcStaticsAddress;

            if (TryGetStaticsInfoForNamedType(runtimeTypeHandle, out nonGcStaticsAddress, out gcStaticsAddress))
            {
                return(nonGcStaticsAddress);
            }

            unsafe
            {
                // Non-generic, non-dynamic static data is found via the FieldAccessMap
                MethodTable *typeAsEEType = runtimeTypeHandle.ToEETypePtr();
                // Non-generic, non-dynamic types need special handling.
                Debug.Assert(typeAsEEType->IsDynamicType || typeAsEEType->IsGeneric);
            }

            // Search hashtable for static entry
            ExternalReferencesTable staticInfoLookup;
            var parser = GetStaticInfo(runtimeTypeHandle, out staticInfoLookup);

            if (!parser.IsNull)
            {
                var index = parser.GetUnsignedForBagElementKind(BagElementKind.NonGcStaticData);

                return(index.HasValue ? staticInfoLookup.GetIntPtrFromIndex(index.Value) : IntPtr.Zero);
            }

            // Not found in hashtable... must be a dynamically created type
            Debug.Assert(runtimeTypeHandle.IsDynamicType());
            unsafe
            {
                MethodTable *typeAsEEType = runtimeTypeHandle.ToEETypePtr();
                if ((typeAsEEType->RareFlags & EETypeRareFlags.IsDynamicTypeWithNonGcStatics) != 0)
                {
                    return(typeAsEEType->DynamicNonGcStaticsData);
                }
            }

            // Type has no non-GC statics
            return(IntPtr.Zero);
        }
        /// <summary>
        /// Get a pointer to the gc static field data of a type. This function works for dynamic
        /// types, reflectable types, and for all generic types
        /// </summary>
        public IntPtr TryGetGcStaticFieldData(RuntimeTypeHandle runtimeTypeHandle)
        {
            unsafe
            {
                // Non-generic, non-dynamic static data is found via the FieldAccessMap
                MethodTable *typeAsEEType = runtimeTypeHandle.ToEETypePtr();
                // Non-generic, non-dynamic types need special handling.
                if (!typeAsEEType->IsDynamicType && !typeAsEEType->IsGeneric)
                {
                    //search for the field on the type in the field map which has the lowest offset,
                    // yet has the the correct type of storage.
                    IntPtr staticAddress;
                    if (TryGetStaticFieldBaseFromFieldAccessMap(runtimeTypeHandle, FieldAccessStaticDataKind.GC, out staticAddress))
                    {
                        return(staticAddress);
                    }
                    else
                    {
                        return(IntPtr.Zero);
                    }
                }
            }

            IntPtr nonGcStaticsAddress;
            IntPtr gcStaticsAddress;

            if (TryGetStaticsInfoForNamedType(runtimeTypeHandle, out nonGcStaticsAddress, out gcStaticsAddress))
            {
                return(gcStaticsAddress);
            }

            unsafe
            {
                // Non-generic, non-dynamic static data is found via the FieldAccessMap
                MethodTable *typeAsEEType = runtimeTypeHandle.ToEETypePtr();
                // Non-generic, non-dynamic types need special handling.
                Debug.Assert(typeAsEEType->IsDynamicType || typeAsEEType->IsGeneric);
            }

            // Search hashtable for static entry
            ExternalReferencesTable staticInfoLookup;
            var parser = GetStaticInfo(runtimeTypeHandle, out staticInfoLookup);

            if (!parser.IsNull)
            {
                var index = parser.GetUnsignedForBagElementKind(BagElementKind.GcStaticData);

                return(index.HasValue ? staticInfoLookup.GetIntPtrFromIndex(index.Value) : IntPtr.Zero);
            }

            // Not found in hashtable... must be a dynamically created type
            Debug.Assert(runtimeTypeHandle.IsDynamicType());
            unsafe
            {
                MethodTable *typeAsEEType = runtimeTypeHandle.ToEETypePtr();
                if ((typeAsEEType->RareFlags & EETypeRareFlags.IsDynamicTypeWithGcStatics) != 0)
                {
                    return(typeAsEEType->DynamicGcStaticsData);
                }
            }

            // Type has no GC statics
            return(IntPtr.Zero);
        }