public static unsafe IntPtr GetDictionary(this RuntimeTypeHandle rtth) { return(EETypeCreator.GetDictionary(rtth.ToEETypePtr())); }
public unsafe IntPtr UpdateFloatingDictionary(IntPtr context, IntPtr dictionaryPtr) { IntPtr newFloatingDictionary; bool isNewlyAllocatedDictionary; bool isTypeContext = context != dictionaryPtr; if (isTypeContext) { EEType* pEEType = (EEType*)context.ToPointer(); IntPtr curDictPtr = EETypeCreator.GetDictionary(pEEType); // 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. while (curDictPtr != dictionaryPtr) { pEEType = pEEType->BaseType; Debug.Assert(pEEType != null); curDictPtr = EETypeCreator.GetDictionary(pEEType); Debug.Assert(curDictPtr != IntPtr.Zero); } context = (IntPtr)pEEType; } 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; }