/// <summary> /// This method is called from a ReadyToRun helper to get base address of thread /// static storage for the given type. /// </summary> internal static unsafe object GetThreadStaticBaseForType(TypeManagerSlot* pModuleData, Int32 typeTlsIndex) { // Get the array that holds thread static memory blocks for each type in the given module Int32 moduleIndex = pModuleData->ModuleIndex; object[] storage = (object[])RuntimeImports.RhGetThreadStaticStorageForModule(moduleIndex); // Check whether thread static storage has already been allocated for this module and type. if ((storage != null) && (typeTlsIndex < storage.Length) && (storage[typeTlsIndex] != null)) { return storage[typeTlsIndex]; } // This the first access to the thread statics of the type corresponding to typeTlsIndex. // Make sure there is enough storage allocated to hold it. storage = EnsureThreadStaticStorage(moduleIndex, storage, requiredSize: typeTlsIndex + 1); // Allocate an object that will represent a memory block for all thread static fields of the type object threadStaticBase = AllocateThreadStaticStorageForType(pModuleData->TypeManager, typeTlsIndex); storage[typeTlsIndex] = threadStaticBase; return threadStaticBase; }
private unsafe static object CheckStaticClassConstructionReturnThreadStaticBase(TypeManagerSlot* pModuleData, Int32 typeTlsIndex, StaticClassConstructionContext* context) { object threadStaticBase = ThreadStatics.GetThreadStaticBaseForType(pModuleData, typeTlsIndex); EnsureClassConstructorRun(context); return threadStaticBase; }