/// <summary> /// Caching GenericTypeInstanceRefernece objects based on interned key, avoiding GenericTypeInstance.InitializeIfNecessary expense /// </summary> public IGenericTypeInstanceReference GetOrMakeGenericTypeInstanceReference(INamedTypeReference genericTypeReference, IEnumerable <ITypeReference> genericArguments) { InternFactory factory = m_factory as InternFactory; if (factory != null && !factory.InternKeysAreReliablyUnique) { return(new Microsoft.Cci.Immutable.GenericTypeInstanceReference(genericTypeReference, genericArguments, this, true)); } uint key = m_factory.GetGenericTypeInstanceReferenceInternedKey(genericTypeReference, genericArguments); IGenericTypeInstanceReference type = null; object value; if (m_objects.TryGetValue(key, out value)) { type = value as IGenericTypeInstanceReference; if (type != null && !SequenceEquals(genericArguments, type.GenericArguments)) { // We can currently get problematic cache hits here for different objects representing the same type. // e.g. SignatureGenericTypeParameter from ref signature can substitute for GenericTypeParameter // from def signature. This breaks assumptions that were there prior to the sharing of generic // type instances that was introduced by the caching intern factory. In that particular case, it breaks // the subsequent specialization of the type parameter. // // We should investigate how to share more in these cases, but in the meantime, we conservatively // only use an existing instantiation if the genericArguments are identical object references and // otherwise force a cache miss here. type = null; } } if (type == null) { type = new Microsoft.Cci.Immutable.GenericTypeInstanceReference(genericTypeReference, genericArguments, this, true); m_objects[key] = type; } return(type); }
/// <summary> /// Caching GenericTypeInstanceRefernece objects based on interned key, avoiding GenericTypeInstance.InitializeIfNecessary expense /// </summary> public IGenericTypeInstanceReference GetOrMakeGenericTypeInstanceReference(INamedTypeReference genericTypeReference, IEnumerable<ITypeReference> genericArguments) { InternFactory factory = m_factory as InternFactory; if (factory != null && !factory.InternKeysAreReliablyUnique) { return new Microsoft.Cci.Immutable.GenericTypeInstanceReference(genericTypeReference, genericArguments, this, true); } uint key = m_factory.GetGenericTypeInstanceReferenceInternedKey(genericTypeReference, genericArguments); IGenericTypeInstanceReference type = null; object value; if (m_objects.TryGetValue(key, out value)) { type = value as IGenericTypeInstanceReference; if (type != null && !SequenceEquals(genericArguments, type.GenericArguments)) { // We can currently get problematic cache hits here for different objects representing the same type. // e.g. SignatureGenericTypeParameter from ref signature can substitute for GenericTypeParameter // from def signature. This breaks assumptions that were there prior to the sharing of generic // type instances that was introduced by the caching intern factory. In that particular case, it breaks // the subsequent specialization of the type parameter. // // We should investigate how to share more in these cases, but in the meantime, we conservatively // only use an existing instantiation if the genericArguments are identical object references and // otherwise force a cache miss here. type = null; } } if (type == null) { type = new Microsoft.Cci.Immutable.GenericTypeInstanceReference(genericTypeReference, genericArguments, this, true); m_objects[key] = type; } return type; }