Exemplo n.º 1
0
        public override ReachabilitySummary SummarizeMethod(IMethodDefinition methodDefinition, WholeProgram wholeProgram)
        {
            // Console.WriteLine("Running ReachabilityBasedLocalFlowMethodSummarizer on {0}", methodDefinition);

            ReachabilityStateAbstraction stateAbstraction = new ReachabilityStateAbstraction();
            ReachabilityStateInterpreter stateInterpreter = new ReachabilityStateInterpreter(stateAbstraction);


            var algorithm = new WorkListAlgorithm <ReachabilityStateInterpreter, ReachabilityStateAbstraction, bool>(stateInterpreter);

            algorithm.RunOnMethod(methodDefinition, wholeProgram.Host());

            SimpleBytecodeMethodSummarizer.BytecodeVisitor visitor = new SimpleBytecodeMethodSummarizer.BytecodeVisitor();


            foreach (BasicBlock <Instruction> block in algorithm.ControlFlowGraph.AllBlocks)
            {
                bool blockIsReachable = algorithm.GetBlockPostState(block);

                if (blockIsReachable)
                {
                    foreach (Instruction instruction in block.Instructions)
                    {
                        visitor.Visit(instruction.Operation);
                    }
                }
            }
            return(visitor.GetSummary());
        }
Exemplo n.º 2
0
        public override ReachabilitySummary SummarizeMethod(IMethodDefinition methodDefinition, WholeProgram wholeProgram)
        {
            //Console.WriteLine("Running AlwaysTopLocalFlowMethodSummarizer on {0}", methodDefinition);



            // hack to analyze on Foo<T> rather than Foo
            // since we need this for data flow

            // Unfortunately, this makes the CFG barf. Need to revisit later.

            /*
             * ITypeReference fullyInstantiatedSpecializedTypeReference;
             *
             * if (TypeHelper.TryGetFullyInstantiatedSpecializedTypeReference(methodDefinition.ContainingTypeDefinition, out fullyInstantiatedSpecializedTypeReference)) {
             * foreach (IMethodDefinition instantiatedMethod in fullyInstantiatedSpecializedTypeReference.ResolvedType.Methods) {
             *  if (GarbageCollectHelper.UnspecializeAndResolveMethodReference(instantiatedMethod).InternedKey == methodDefinition.InternedKey) {
             *    methodDefinition = instantiatedMethod;
             *    break;
             *  }
             * }
             * }
             */

            var valueAbstraction = new TypesValueAbstraction(wholeProgram.Host());


            var stateInterpreter = new VirtualCallRecordingStateInterpreter <TypesValueAbstraction, ITypeDefinition>(valueAbstraction);



            var algorithm = new WorkListAlgorithm <VirtualCallRecordingStateInterpreter <TypesValueAbstraction, ITypeDefinition>,
                                                   LocalsAndOperandsStateAbstraction <TypesValueAbstraction, ITypeDefinition>,
                                                   LocalsAndOperands <ITypeDefinition> >(stateInterpreter);

            try {
                algorithm.RunOnMethod(methodDefinition, wholeProgram.Host());
            }
            catch (Exception e) {
                if (e.GetType().FullName.Contains("ContractException"))
                {
                    // Very hokey, but it is what it is.
                    // Sometimes we fail because building the CFG fails, and occasionally
                    // we fail because of something in the analysis. In either event,
                    // we pick ourselves up and fall back on the regular summarization

                    // Need to record statistics on how often this happens.

                    Console.WriteLine("Got contract exception running local flow for " + methodDefinition);

                    return(new SimpleBytecodeMethodSummarizer().SummarizeMethod(methodDefinition, wholeProgram));
                }
                else
                {
                    throw;
                }
            }



            LocalFlowEnhancedBytecodeVisitor bytecodeVisitor = new LocalFlowEnhancedBytecodeVisitor();

            foreach (BasicBlock <Instruction> block in algorithm.ControlFlowGraph.AllBlocks)
            {
                foreach (Instruction instruction in block.Instructions)
                {
                    if (instruction.Operation.OperationCode == OperationCode.Callvirt)
                    {
                        ITypeDefinition valueAtReceiver = algorithm.StateInterpreter.ReceiverValueForVirtualCallInstruction(instruction.Operation);

                        Contract.Assert(valueAtReceiver != null);

                        //t-devinc: handle not resolving method gracefully.
                        IMethodDefinition compileTimeTargetMethod = (instruction.Operation.Value as IMethodReference).ResolvedMethod;

                        // The only way we allow the analysis to return a type that is a supertype of the type being dispatched upon is
                        // if we've gone to top (System.Object).
                        //
                        // This is really just a sanity check.
                        ITypeDefinition compileTimeType = compileTimeTargetMethod.ContainingTypeDefinition;

                        Contract.Assert(valueAtReceiver == wholeProgram.Host().PlatformType.SystemObject.ResolvedType ||
                                        TypeHelper.Type1DerivesFromOrIsTheSameAsType2(valueAtReceiver, compileTimeType) ||
                                        (compileTimeType.IsInterface && TypeHelper.Type1ImplementsType2(valueAtReceiver, compileTimeType)) ||
                                        (valueAtReceiver.IsInterface && compileTimeType == wholeProgram.Host().PlatformType.SystemObject.ResolvedType)
                                        );


                        bytecodeVisitor.NoteReceiverTypeForCallVirtual(valueAtReceiver, instruction.Operation);
                    }
                }
            }



            foreach (IOperation operation in methodDefinition.Body.Operations)
            {
                bytecodeVisitor.Visit(operation);
            }

            return(bytecodeVisitor.GetSummary());
        }