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();
            }
        }