Exemplo n.º 1
0
        public unsafe IntPtr UpdateFloatingDictionary(IntPtr context, IntPtr dictionaryPtr)
        {
            IntPtr newFloatingDictionary;
            bool isNewlyAllocatedDictionary;
            bool isTypeContext = context != dictionaryPtr;

            if (isTypeContext)
            {
                // Look for the exact base type that owns the dictionary. We may be having
                // a virtual method run on a derived type and the generic lookup are performed
                // on the base type's dictionary.
                MethodTable* pEEType = (MethodTable*)context.ToPointer();
                context = (IntPtr)EETypeCreator.GetBaseEETypeForDictionaryPtr(pEEType, dictionaryPtr);
            }

            using (LockHolder.Hold(_typeLoaderLock))
            {
                // Check if some other thread already allocated a floating dictionary and updated the fixed portion
                if (*(IntPtr*)dictionaryPtr != IntPtr.Zero)
                    return *(IntPtr*)dictionaryPtr;

                try
                {
                    if (t_isReentrant)
                        Environment.FailFast("Reentrant update to floating dictionary");
                    t_isReentrant = true;

                    newFloatingDictionary = TypeBuilder.TryBuildFloatingDictionary(context, isTypeContext, dictionaryPtr, out isNewlyAllocatedDictionary);

                    t_isReentrant = false;
                }
                catch
                {
                    // Catch and rethrow any exceptions instead of using finally block. Otherwise, filters that are run during
                    // the first pass of exception unwind may hit the re-entrancy fail fast above.

                    // TODO: Convert this to filter for better diagnostics once we switch to Roslyn

                    t_isReentrant = false;
                    throw;
                }
            }

            if (newFloatingDictionary == IntPtr.Zero)
            {
                Environment.FailFast("Unable to update floating dictionary");
                return IntPtr.Zero;
            }

            // The pointer to the floating dictionary is the first slot of the fixed dictionary.
            if (Interlocked.CompareExchange(ref *(IntPtr*)dictionaryPtr, newFloatingDictionary, IntPtr.Zero) != IntPtr.Zero)
            {
                // Some other thread beat us and updated the pointer to the floating dictionary.
                // Free the one allocated by the current thread
                if (isNewlyAllocatedDictionary)
                    MemoryHelpers.FreeMemory(newFloatingDictionary);
            }

            return *(IntPtr*)dictionaryPtr;
        }
Exemplo n.º 2
0
 public static unsafe IntPtr GetDictionary(this RuntimeTypeHandle rtth)
 {
     return(EETypeCreator.GetDictionary(rtth.ToEETypePtr()));
 }