Beispiel #1
0
        private void NoteGenericParameterFlow(ITypeDefinition actual, IGenericParameter formal)
        {
            if (createInstanceStrategy == TypeVariableCreateInstanceStrategy.ConstructAllConcreteParameters)
            {
                if (!(actual is IGenericParameter))
                {
                    // actual is concrete

                    ITypeDefinition unspecializedConcreteType = GarbageCollectHelper.UnspecializeAndResolveTypeReference(actual);

                    unspecializedTypesPassedAsTypeVariables.Add(unspecializedConcreteType);

                    if (GarbageCollectHelper.TypeIsConstructable(unspecializedConcreteType))
                    {
                        // t-devinc: We should associate a reason with this construction found
                        ConstructionFound(unspecializedConcreteType);

                        IMethodDefinition defaultConstructor = TypeHelper.GetMethod(unspecializedConcreteType, wholeProgram.Host().NameTable.GetNameFor(".ctor"));

                        if (!(defaultConstructor is Dummy))
                        {
                            // t-devinc: Add reason for this
                            NotePotentialNonVirtualMethodReachedForReason(defaultConstructor, null);
                        }
                    }
                }
            }
        }
Beispiel #2
0
        // Called when the first new T() is detected.
        // This method is where we add worst-case-scenario
        // constructed types for those stategies.

        // t-devinc: Now that we don't do construct reachable types
        // this maybe doesn't make sense.
        private void NoteFirstTypeVariableConstructed()
        {
            IEnumerable <ITypeDefinition> potentialUniverse;

            switch (createInstanceStrategy)
            {
            case TypeVariableCreateInstanceStrategy.ConstructAll:
                potentialUniverse = wholeProgram.AllDefinedTypes();
                break;

            default:
                // do nothing
                potentialUniverse = new HashSet <ITypeDefinition>();
                break;
            }

            foreach (ITypeDefinition t in potentialUniverse)
            {
                if (GarbageCollectHelper.TypeIsConstructable(t))
                {
                    ConstructionFound(t);
                    // t-devinc: We should associate a reason with this!
                }
            }
        }
Beispiel #3
0
        private void ConstructionFound(ITypeDefinition t)
        {
            Contract.Requires(t != null);
            Contract.Requires(!(t is Dummy));
            Contract.Requires(GarbageCollectHelper.TypeDefinitionIsUnspecialized(t));
            Contract.Requires(GarbageCollectHelper.TypeIsConstructable(t));

            Contract.Ensures(this.constructed.Contains(t));

            //Console.WriteLine("Found construction of {0}", t);

            if (this.constructed.Contains(t))
            {
                return;
            }
            this.constructed.Add(t);

            // t-devinc: should change AllSuperTypes, etc. to include t
            foreach (var baseclass in new ITypeDefinition[] { t }.Concat(GarbageCollectHelper.AllSuperTypes(t)))
            {
                ITypeDefinition unspecializedBaseClass = GarbageCollectHelper.UnspecializeAndResolveTypeReference(baseclass);
                foreach (var m in unspecializedBaseClass.Methods)
                {
                    if (m.IsVirtual && VirtualMethodIsInDemand(m))
                    {
                        ICollection <IMethodDefinition> implementationsOfMForT = GarbageCollectHelper.Implements(t, unspecializedBaseClass, m);

                        Contract.Assert(implementationsOfMForT.Count() > 0);

                        foreach (IMethodDefinition mprime in implementationsOfMForT)
                        {
                            NoteDispatch(m, GarbageCollectHelper.UnspecializeAndResolveMethodReference(mprime), t);
                        }
                    }
                }
            }

            // If a type is constructed then its Finalize method may be called

            ICollection <IMethodDefinition> implementationsOfFinalizeForT = GarbageCollectHelper.Implements(t, systemObjectType, systemObjectFinalizeMethod);

            Contract.Assert(implementationsOfFinalizeForT.Count() == 1);

            // t-devinc: Need to to add reason for this

            this.AddToWorklist(GarbageCollectHelper.UnspecializeAndResolveMethodReference(implementationsOfFinalizeForT.First()));
        }
Beispiel #4
0
        private void NoteVirtualDispatch(IMethodDefinition methodDispatchedUpon)
        {
            Contract.Requires(methodDispatchedUpon != null);
            Contract.Requires(!(methodDispatchedUpon is Dummy));
            Contract.Requires(GarbageCollectHelper.MethodDefinitionIsUnspecialized(methodDispatchedUpon));
            Contract.Requires(methodDispatchedUpon.IsVirtual);

            Contract.Ensures(VirtualMethodIsInDemand(methodDispatchedUpon));

            //Console.WriteLine("VirtCallFound on {0} of type {1}", methodDefinition, methodDefinition.GetType());

            bool virtualMethodIsAlreadyKnown = VirtualMethodIsInDemand(methodDispatchedUpon);

            MarkVirtualMethodAsInDemand(methodDispatchedUpon);

            if (virtualMethodIsAlreadyKnown)
            {
                return;
            }

            // The code below this point is called only the first time we learn that
            // someone has dispatched against this method.

            //Console.WriteLine("{0} has {1} derived methods", methodDefinition, this.callgraph.GetAllDerivedMethods(methodDefinition).ToArray().Length);


            ITypeDefinition typeDefiningM = methodDispatchedUpon.ContainingTypeDefinition;

            this.TypeUseFound(typeDefiningM);

            // t-devinc: clean this up
            foreach (ITypeDefinition subType in new ITypeDefinition[] { typeDefiningM }.Concat(wholeProgram.ClassHierarchy().AllSubClassesOfClass(typeDefiningM)))
            {
                if (GarbageCollectHelper.TypeIsConstructable(subType) && ((subType.IsStruct || constructed.Contains(subType))))
                {
                    ICollection <IMethodDefinition> implementationsOfMethodDefinitionForSubType = GarbageCollectHelper.Implements(subType, typeDefiningM, methodDispatchedUpon);

                    Contract.Assert(implementationsOfMethodDefinitionForSubType.Count() > 0);

                    foreach (IMethodDefinition implementationOfM in implementationsOfMethodDefinitionForSubType)
                    {
                        NoteDispatch(methodDispatchedUpon, GarbageCollectHelper.UnspecializeAndResolveMethodReference(implementationOfM), subType);
                    }
                }
            }
        }