/// <summary>
        /// Each managed module linked into the final binary may have its own global tables for strings,
        /// statics, etc that need initializing. InitializeGlobalTables walks through the modules
        /// and offers each a chance to initialize its global tables.
        /// </summary>
        private static unsafe void InitializeGlobalTablesForModule(TypeManagerHandle typeManager, int moduleIndex)
        {
            // Configure the module indirection cell with the newly created TypeManager. This allows EETypes to find
            // their interface dispatch map tables.
            int length;
            TypeManagerSlot *section = (TypeManagerSlot *)RuntimeImports.RhGetModuleSection(typeManager, ReadyToRunSectionType.TypeManagerIndirection, out length);

            section->TypeManager = typeManager;
            section->ModuleIndex = moduleIndex;

#if CORERT
            // Initialize statics if any are present
            IntPtr staticsSection = RuntimeImports.RhGetModuleSection(typeManager, ReadyToRunSectionType.GCStaticRegion, out length);
            if (staticsSection != IntPtr.Zero)
            {
                Debug.Assert(length % IntPtr.Size == 0);
                InitializeStatics(staticsSection, length);
            }
#endif

            // Initialize frozen object segment with GC present
            IntPtr frozenObjectSection = RuntimeImports.RhGetModuleSection(typeManager, ReadyToRunSectionType.FrozenObjectRegion, out length);
            if (frozenObjectSection != IntPtr.Zero)
            {
                Debug.Assert(length % IntPtr.Size == 0);
                InitializeFrozenObjectSegment(frozenObjectSection, length);
            }
        }
Example #2
0
        /// <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, int typeTlsIndex)
        {
            // Get the array that holds thread static memory blocks for each type in the given module
            object[] storage = RuntimeImports.RhGetThreadStaticStorageForModule(pModuleData->ModuleIndex);

            // Check whether thread static storage has already been allocated for this module and type.
            if ((storage != null) && ((uint)typeTlsIndex < (uint)storage.Length) && (storage[typeTlsIndex] != null))
            {
                return(storage[typeTlsIndex]);
            }

            return(GetThreadStaticBaseForTypeSlow(pModuleData, typeTlsIndex));
        }
Example #3
0
        internal static unsafe object GetThreadStaticBaseForTypeSlow(TypeManagerSlot *pModuleData, int typeTlsIndex)
        {
            // Get the array that holds thread static memory blocks for each type in the given module
            object[] storage = RuntimeImports.RhGetThreadStaticStorageForModule(pModuleData->ModuleIndex);

            // 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(pModuleData->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);
        }
Example #4
0
        /// <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);
        }
Example #5
0
        /// <summary>
        /// Each managed module linked into the final binary may have its own global tables for strings,
        /// statics, etc that need initializing. InitializeGlobalTables walks through the modules
        /// and offers each a chance to initialize its global tables.
        /// </summary>
        private static unsafe void InitializeGlobalTablesForModule(TypeManagerHandle typeManager, int moduleIndex, object[] gcStaticBaseSpines)
        {
            // Configure the module indirection cell with the newly created TypeManager. This allows EETypes to find
            // their interface dispatch map tables.
            int length;
            TypeManagerSlot *section = (TypeManagerSlot *)RuntimeImports.RhGetModuleSection(typeManager, ReadyToRunSectionType.TypeManagerIndirection, out length);

            section->TypeManager = typeManager;
            section->ModuleIndex = moduleIndex;

            // Initialize statics if any are present
            IntPtr staticsSection = RuntimeImports.RhGetModuleSection(typeManager, ReadyToRunSectionType.GCStaticRegion, out length);

            if (staticsSection != IntPtr.Zero)
            {
                Debug.Assert(length % IntPtr.Size == 0);

                object[] spine = InitializeStatics(staticsSection, length);

                // Call write barrier directly. Assigning object reference does a type check.
                Debug.Assert((uint)moduleIndex < (uint)gcStaticBaseSpines.Length);
                ref object rawSpineIndexData = ref Unsafe.As <byte, object>(ref Unsafe.As <RawArrayData>(gcStaticBaseSpines).Data);
                InternalCalls.RhpAssignRef(ref Unsafe.Add(ref rawSpineIndexData, moduleIndex), spine);
            }
Example #6
0
        private static unsafe object CheckStaticClassConstructionReturnThreadStaticBase(TypeManagerSlot *pModuleData, int typeTlsIndex, StaticClassConstructionContext *context)
        {
            object threadStaticBase = ThreadStatics.GetThreadStaticBaseForType(pModuleData, typeTlsIndex);

            EnsureClassConstructorRun(context);
            return(threadStaticBase);
        }