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())); }
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); } } } }