public unsafe static 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
        }
        /// <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());
            return RuntimeAugments.GetNonGcStaticFieldData(runtimeTypeHandle);
        }
        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;
        }
 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);
 }
        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;

                uint tlsOffset = *(uint*)ptrToTlsOffset;
                cookieData.StartingOffsetInTlsBlock = tlsOffset;
                cookieData.FieldOffset = fieldOffset;
            }

            return PermanentAllocatedMemoryBlobs.GetPointerToThreadStaticFieldOffsets(cookieData);
        }
        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();
            }
        }