Example #1
0
 public static bool Exists(EETypePairList *pList, EEType *pEEType1, EEType *pEEType2)
 {
     while (pList != null)
     {
         if (pList->_eetype1 == pEEType1 && pList->_eetype2 == pEEType2)
         {
             return(true);
         }
         if (pList->_eetype1 == pEEType2 && pList->_eetype2 == pEEType1)
         {
             return(true);
         }
         pList = pList->_next;
     }
     return(false);
 }
Example #2
0
            private static unsafe bool CacheMiss(ref Key key, EETypePairList *pVisited)
            {
                //
                // First, check if we previously visited the input types pair, to avoid infinite recursions
                //
                if (EETypePairList.Exists(pVisited, key.SourceType, key.TargetType))
                {
                    return(false);
                }

                bool result = false;

                // bool previouslyCached = false;

                //
                // Try to find the entry in the previous version of the cache that is kept alive by weak reference
                //
                if (s_previousCache.IsAllocated)
                {
                    // Unchecked cast to avoid recursive dependency on array casting
                    Entry[] previousCache = Unsafe.As <Entry[]>(s_previousCache.Target);
                    if (previousCache != null)
                    {
                        Entry previousEntry = LookupInCache(previousCache, ref key);
                        if (previousEntry != null)
                        {
                            result = previousEntry.Result;
                            // previouslyCached = true;
                        }
                    }
                }

                //
                // Call into the type cast code to calculate the result
                //
                Debugger.Break();

                /*
                 * if (!previouslyCached)
                 * {
                 *  EETypePairList newList = new EETypePairList(key.SourceType, key.TargetType, pVisited);
                 *  result = TypeCast.AreTypesAssignableInternal(key.SourceType, key.TargetType, key.Variation, &newList);
                 * }
                 *
                 * //
                 * // Update the cache under the lock
                 * //
                 * InternalCalls.RhpAcquireCastCacheLock();
                 */
                try
                {
                    try
                    {
                        // Avoid duplicate entries
                        Entry existingEntry = LookupInCache(s_cache, ref key);
                        if (existingEntry != null)
                        {
                            return(existingEntry.Result);
                        }

                        // Resize cache as necessary
                        Entry[] cache = ResizeCacheForNewEntryAsNecessary();

                        int entryIndex = key.CalculateHashCode() & (cache.Length - 1);

                        Entry newEntry = new Entry()
                        {
                            Key = key, Result = result, Next = cache[entryIndex]
                        };

                        // BEWARE: Array store check can lead to infinite recursion. We avoid this by making certain
                        // that the cache trivially answers the case of equivalent types without triggering the cache
                        // miss path. (See CastCache.AreTypesAssignableInternal)
                        cache[entryIndex] = newEntry;
                        return(newEntry.Result);
                    }
                    catch (OutOfMemoryException)
                    {
                        // Entry allocation failed -- but we can still return the correct cast result.
                        return(result);
                    }
                }
                finally
                {
                    InternalCalls.RhpReleaseCastCacheLock();
                }
            }
Example #3
0
            public static unsafe bool AreTypesAssignableInternal_SourceNotTarget_BoxedSource(EEType *pSourceType, EEType *pTargetType, EETypePairList *pVisited)
            {
                Debug.Assert(pSourceType != pTargetType, "target is source");
                Key   key   = new Key(pSourceType, pTargetType, AssignmentVariation.BoxedSource);
                Entry entry = LookupInCache(s_cache, ref key);

                if (entry == null)
                {
                    return(CacheMiss(ref key, pVisited));
                }

                return(entry.Result);
            }
Example #4
0
            public static unsafe bool AreTypesAssignableInternal(EEType *pSourceType, EEType *pTargetType, AssignmentVariation variation, EETypePairList *pVisited)
            {
                // Important special case -- it breaks infinite recursion in CastCache itself!
                if (pSourceType == pTargetType)
                {
                    return(true);
                }

                Key   key   = new Key(pSourceType, pTargetType, variation);
                Entry entry = LookupInCache(s_cache, ref key);

                if (entry == null)
                {
                    return(CacheMiss(ref key, pVisited));
                }

                return(entry.Result);
            }
Example #5
0
 public EETypePairList(EEType *pEEType1, EEType *pEEType2, EETypePairList *pNext)
 {
     _eetype1 = pEEType1;
     _eetype2 = pEEType2;
     _next    = pNext;
 }