private async Task ProcessCalleesAsync(IEnumerable <CallInfo> calleesInfo, PropagationKind propKind)
        {
            var tasks = new List <Task>();

            foreach (var calleeInfo in calleesInfo)
            {
                //TODO: Need to Refactor to get rid of this ifs!
                if (calleeInfo is MethodCallInfo)
                {
                    // TODO: This should work in any order because the technique is flow insensitive
                    // But actually for some reason the ordering is affecting the result
                    // I think the problem is the conservative treatment when types(receiver).Count = 0
                    // (FIXED??)

                    var task = this.DispatchCallMessageForMethodCallAsync(calleeInfo as MethodCallInfo, propKind);
                    //await task;
                    tasks.Add(task);
                }
                else if (calleeInfo is DelegateCallInfo)
                {
                    var task = this.DispatchCallMessageForDelegateCallAsync(calleeInfo as DelegateCallInfo, propKind);
                    //await task;
                    tasks.Add(task);
                }
            }

            await Task.WhenAll(tasks);
        }
        public async Task <PropagationEffects> PropagateAsync(PropagationKind propKind)
        {
            await StatsHelper.RegisterMsg("MethodEntityGrain::Propagate", this.GrainFactory);

            //if (status.Equals(EntityGrainStatus.Busy))
            //{
            //	await Task.Delay(WAIT_TIME);
            //	if (status.Equals(EntityGrainStatus.Busy))
            //	{
            //		return new PropagationEffects();
            //	}
            //}

            Logger.LogVerbose(this.GetLogger(), "MethodEntityGrain", "Propagate", "Propagation for {0} ", this.methodEntity.MethodDescriptor);

            var sw = new Stopwatch();

            sw.Start();
            var propagationEffects = await this.methodEntityPropagator.PropagateAsync(propKind);

            sw.Stop();
            propagationEffects.SiloAddress = StatsHelper.GetMyIPAddr();

            Logger.LogInfo(this.GetLogger(), "MethodEntityGrain", "Propagate", "End Propagation for {0}. Time elapsed {1} Effects size: {2}", this.methodEntity.MethodDescriptor, sw.Elapsed, propagationEffects.CalleesInfo.Count);
            await StatsHelper.RegisterPropagationUpdates(propagationEffects.NumberOfUpdates, propagationEffects.WorkListInitialSize, this.GrainFactory);

            return(propagationEffects);
        }
示例#3
0
 public ReturnMessageInfo(MethodDescriptor caller, MethodDescriptor callee, ISet <TypeDescriptor> resultPossibleTypes,
                          AnalysisCallNode callNode, VariableNode lhs, PropagationKind propKind)
 {
     this.Caller = caller;
     this.Callee = callee;
     this.LHS    = lhs;
     this.ResultPossibleTypes = resultPossibleTypes;
     this.PropagationKind     = propKind;
     this.CallNode            = callNode;
 }
示例#4
0
        private Task CreateAndSendReturnMessageAsync(ReturnInfo returnInfo, PropagationKind propKind)
        {
            var returnMessageInfo = new ReturnMessageInfo(returnInfo.CallerContext.Caller, returnInfo.Callee, returnInfo.ResultPossibleTypes,
                                                          returnInfo.CallerContext.CallNode, returnInfo.CallerContext.LHS, propKind);

            var source        = new MethodEntityDescriptor(returnInfo.Callee);
            var calleeMessage = new CalleeMessage(source, returnMessageInfo);

            return(this.AnalyzeReturnAsync(returnMessageInfo.Caller, calleeMessage, propKind));
        }
        public async Task PropagateAndProcessAsync(PropagationKind propKind, IEnumerable <PropGraphNodeDescriptor> reWorkSet)
        {
            await StatsHelper.RegisterMsg("MethodEntityGrain::PropagateAndProcess", this.GrainFactory);

            var effects = await this.methodEntityPropagator.PropagateAsync(propKind, reWorkSet);             // await this.PropagateAsync(propKind, reWorkSet);

            await StatsHelper.RegisterPropagationUpdates(effects.NumberOfUpdates, effects.WorkListInitialSize, this.GrainFactory);

            await ProcessEffectsAsync(effects);
        }
示例#6
0
        private async Task <PropagationEffects> InternalPropagateAsync(PropagationKind propKind)
        {
            //Logger.LogS("MethodEntityProp", "PropagateAsync", "Propagation for {0} ", this.methodEntity.MethodDescriptor);
            //Logger.Log("Propagating {0} to {1}", this.methodEntity.MethodDescriptor, propKind);

            // var codeProvider = await ProjectGrainWrapper.CreateProjectGrainWrapperAsync(this.methodEntity.MethodDescriptor);
            PropagationEffects propagationEffects = null;

            switch (propKind)
            {
            case PropagationKind.ADD_TYPES:
                propagationEffects = await this.methodEntity.PropGraph.PropagateAsync(codeProvider);

                break;

            case PropagationKind.REMOVE_TYPES:
                propagationEffects = await this.methodEntity.PropGraph.PropagateDeletionAsync(codeProvider);

                break;

            default:
                throw new Exception("Unsupported propagation kind");
            }

            await this.PopulatePropagationEffectsInfo(propagationEffects, propKind);

            Logger.LogS("MethodEntityGrain", "PropagateAsync", "End Propagation for {0} ", this.methodEntity.MethodDescriptor);
            //this.methodEntity.Save(@"C:\Temp\"+this.methodEntity.MethodDescriptor.MethodName + @".dot");

            //if (propagationEffects.CalleesInfo.Count > 100)
            //{
            //	int index = 0;
            //	var count = propagationEffects.CalleesInfo.Count;
            //	var callessInfo = propagationEffects.CalleesInfo.ToList();
            //	propagationEffects.CalleesInfo = new HashSet<CallInfo>(callessInfo.GetRange(index, count > 100 ? 100 : count));
            //	propagationEffects.MoreEffectsToFetch = true;
            //
            //	while (count > 100)
            //	{
            //		count -= 100;
            //		index += 100;
            //
            //		var propEffect = new PropagationEffects(new HashSet<CallInfo>(callessInfo.GetRange(index, count > 100 ? 100 : count)), false);
            //
            //		if (count > 100)
            //		{
            //			propEffect.MoreEffectsToFetch = true;
            //		}
            //
            //		this.propagationEffectsToSend.Enqueue(propEffect);
            //	}
            //}
            //this.UpdateHistory.Add(this.methodEntity.PropGraph.UpdateCount);
            return(propagationEffects);
        }
 internal async Task<bool> DiffPropAsync(IEnumerable<TypeDescriptor> src, PropGraphNodeDescriptor n, PropagationKind propKind)
 {
     if (propKind == PropagationKind.REMOVE_TYPES || propKind == PropagationKind.REMOVE_ASSIGNMENT)
     {
         return DiffDelProp(src, n);
     }
     else
     {
         return await DiffPropAsync(src, n);
     }
 }
示例#8
0
 public CallMessageInfo(MethodDescriptor caller, MethodDescriptor callee, TypeDescriptor receiverType,
                        IList <ISet <TypeDescriptor> > argumentsPossibleTypes, AnalysisCallNode callNode, VariableNode lhs,
                        PropagationKind propKind)
 {
     this.Caller = caller;
     this.Callee = callee;
     this.ArgumentsPossibleTypes = argumentsPossibleTypes;
     this.ReceiverType           = receiverType;
     this.LHS             = lhs;
     this.PropagationKind = propKind;
     this.CallNode        = callNode;
 }
示例#9
0
        private async Task ProcessCalleesAsync(IEnumerable <CallInfo> calleesInfo, PropagationKind propKind)
        {
            var tasks = new List <Task>();

            foreach (var calleeInfo in calleesInfo)
            {
                var task = this.DispatchCallMessageAsync(calleeInfo, propKind);
                //await task;
                tasks.Add(task);
            }

            await Task.WhenAll(tasks);
        }
示例#10
0
        private async Task DispatchCallMessageAsync(CallInfo callInfo, PropagationKind propKind)
        {
            var tasks = new List <Task>();

            foreach (var callee in callInfo.PossibleCallees)
            {
                var task = this.CreateAndSendCallMessageAsync(callInfo, callee, propKind);
                //await task;
                tasks.Add(task);
            }

            await Task.WhenAll(tasks);
        }
示例#11
0
        private ISet <TypeDescriptor> GetTypes(PropGraphNodeDescriptor node, PropagationKind prop)
        {
            switch (prop)
            {
            case PropagationKind.ADD_TYPES:
                return(GetTypes(node));

            case PropagationKind.REMOVE_TYPES:
                return(GetDeletedTypes(node));

            default:
                return(GetTypes(node));
            }
        }
        public Task <PropagationEffects> PropagateAsync(PropagationKind propKind, IEnumerable <PropGraphNodeDescriptor> reWorkSet)
        {
            StatsHelper.RegisterMsg("MethodEntityGrain::PropagateWithRework", this.GrainFactory);

            //if (status.Equals(EntityGrainStatus.Busy))
            //{
            //	await Task.Delay(WAIT_TIME);
            //	if (status.Equals(EntityGrainStatus.Busy))
            //	{
            //		return new PropagationEffects();
            //	}
            //}

            return(this.methodEntityPropagator.PropagateAsync(propKind, reWorkSet));
        }
        private async Task ProcessEffectsAsync(PropagationEffects effects, PropagationKind propKind = PropagationKind.ADD_TYPES)
        {
            effects.Kind = propKind;

            var maxCallSitesCount = Math.Min(effects.CalleesInfo.Count, 8);
            var maxCallersCount   = Math.Min(effects.CallersInfo.Count, 8);

            // This is an optimization, it is not really needed
            if (maxCallSitesCount == 0 && maxCallersCount == 0)
            {
                return;
            }

            await this.SplitAndEnqueueEffectsAsync(effects, maxCallSitesCount, maxCallersCount, int.MaxValue);
        }
        private Task CreateAndSendReturnMessageAsync(ReturnInfo returnInfo, PropagationKind propKind)
        {
            var returnMessageInfo = new ReturnMessageInfo(returnInfo.CallerContext.Caller, returnInfo.Callee, returnInfo.ResultPossibleTypes,
                                                          returnInfo.CallerContext.CallNode, returnInfo.CallerContext.LHS, propKind);

            var source        = new MethodEntityDescriptor(returnInfo.Callee);
            var calleeMessage = new CalleeMessage(source, returnMessageInfo);

            //await WaitQueue(QUEUE_THRESHOLD);
            this.messageWorkList.Enqueue(calleeMessage);
            //this.messageWorkList.Add(calleeMessage);

            return(Task.CompletedTask);
            //return AnalyzeReturnAsync(returnMessageInfo.Caller, calleeMessage, propKind);
        }
示例#15
0
        private async Task CreateAndSendReturnMessageAsync(ReturnInfo returnInfo, PropagationKind propKind)
        {
            var returnMessageInfo = new ReturnMessageInfo(returnInfo.CallerContext.Caller, returnInfo.Callee, returnInfo.ResultPossibleTypes,
                                                          returnInfo.CallerContext.CallNode, returnInfo.CallerContext.LHS, propKind);

            var source        = new MethodEntityDescriptor(returnInfo.Callee);
            var calleeMessage = new CalleeMessage(source, returnMessageInfo);

            await this.solutionManager.UpdateCounter(1);

            //await WaitQueue(QUEUE_THRESHOLD);
            this.messageWorkList.Enqueue(calleeMessage);
            //this.messageWorkList.Add(calleeMessage);

            //return TaskDone.Done;
        }
示例#16
0
        private async Task ProcessReturnAsync(IEnumerable <ReturnInfo> callersInfo, PropagationKind propKind)
        {
            var tasks = new List <Task>();

            foreach (var callerInfo in callersInfo)
            {
                if (callerInfo.ResultPossibleTypes.Count > 0)
                {
                    var task = this.DispachReturnMessageAsync(callerInfo, propKind);
                    //await task;
                    tasks.Add(task);
                }
            }

            await Task.WhenAll(tasks);
        }
示例#17
0
        public Task <PropagationEffects> PropagateAsync(PropagationKind propKind, IEnumerable <PropGraphNodeDescriptor> reWorkSet)
        {
            Contract.Requires(reWorkSet != null);

            switch (propKind)
            {
            case PropagationKind.ADD_TYPES:
                methodEntity.PropGraph.AddToWorkList(reWorkSet);
                break;

            case PropagationKind.REMOVE_TYPES:
                methodEntity.PropGraph.AddToDeletionWorkList(reWorkSet);
                break;

            default:
                throw new Exception("Unsupported propagation kind");
            }

            return(PropagateAsync(propKind));
        }
示例#18
0
        private async Task ProcessCalleesAsync(IEnumerable <CallInfo> calleesInfo, PropagationKind propKind)
        {
            var tasks = new List <Task>();

            foreach (var calleeInfo in calleesInfo)
            {
                //TODO: Need to Refactor to get rid of this ifs!
                if (calleeInfo is MethodCallInfo)
                {
                    var task = this.DispatchCallMessageForMethodCallAsync(calleeInfo as MethodCallInfo, propKind);
                    //await task;
                    tasks.Add(task);
                }
                else if (calleeInfo is DelegateCallInfo)
                {
                    var task = this.DispatchCallMessageForDelegateCallAsync(calleeInfo as DelegateCallInfo, propKind);
                    tasks.Add(task);
                }
            }
            await Task.WhenAll(tasks);
        }
		public async Task EndOfPropagationEventAsync(PropagationKind propKind, bool retValueChange)
		{
			if (this.Verbose)
			{
				Logger.Instance.Log("MethodEntityProcessor", "EndOfPropagationEventAsync", this.MethodEntity.MethodDescriptor);
			}

			// Should do something more clever
			if (retValueChange)
			{
				await ProcessReturnNodeAsync(propKind);
			}
		}
 /// <summary>
 /// When the method returns I should inform the computed return value to all its caller
 /// It may also propagate other info from out parameters and escaping objects (not implemented)
 /// </summary>
 private void ProcessReturnNode(PropagationKind propKind)
 {
     if (this.MethodEntity.ReturnVariable != null)
     {
         // Should do the same with out and escaping info
         foreach (var callerContex in this.MethodEntity.Callers)
         {
             DispachReturnMessage(callerContex, this.MethodEntity.ReturnVariable, propKind);
         }
     }
 }
        private async Task PropagateFromCallersAsync(IEnumerable <ReturnInfo> callersInfo, PropagationKind propKind = PropagationKind.ADD_TYPES)
        {
            var tasks = new List <Task>();

            foreach (var callerInfo in callersInfo)
            {
                var reworkSet   = new HashSet <PropGraphNodeDescriptor>();
                var callContext = callerInfo.CallerContext;
                reworkSet.Add(callContext.CallNode);
                var task = this.AnalyzeAsync(callContext.Caller, reworkSet, propKind);
                //await task;
                tasks.Add(task);
            }

            await Task.WhenAll(tasks);
        }
示例#22
0
        private async Task AnalyzeCalleeAsync(MethodDescriptor callee, CallerMessage callerMessage, PropagationKind propKind)
        {
            Logger.LogS("EffectsDispatcherManager", "AnalyzeCallee", "Analyzing: {0}", callee);

            //var methodEntityProc = await this.solutionManager.GetMethodEntityAsync(callee);
            var methodEntityProc = await this.GetMethodEntityGrainAndActivateInProject(callee);

            await methodEntityProc.PropagateAndProcessAsync(callerMessage.CallMessageInfo);

            Logger.LogS("EffectsDispatcherManager", "AnalyzeCallee", "End Analyzing call to {0} ", callee);
        }
 internal ISet<TypeDescriptor> GetTypes(PropGraphNodeDescriptor node, PropagationKind prop)
 {
     switch (prop)
     {
         case PropagationKind.ADD_TYPES:
             return GetTypes(node);
         case PropagationKind.REMOVE_TYPES:
             return GetDeletedTypes(node);
         default:
             return GetTypes(node);
     }
 }
        /// <summary>
        /// Given an invocations this method dispatch a message to every potential callee to propagate the info in the arguments
        /// </summary>
        /// <param name="callInfo"></param>
        /// <param name="propKind"></param>
        private void DispatchCallMessage(CallInfo callInfo, PropagationKind propKind)
        {
            if (!callInfo.IsStatic && callInfo.Receiver != null)
            {
                // I need to computes all the calless
                // In case of a deletion we can discar the deleted callee
                //var types = GetTypes(callNode.Receiver, propKind);
                var types = GetTypes(callInfo.Receiver);

                /// If types=={} it means that some info ins missing => we should be conservative and use the instantiated types (RTA)
                if (types.Count() == 0 && propKind != PropagationKind.REMOVE_TYPES)
                {
                    var instantiatedTypes = new HashSet<TypeDescriptor>();
                    /// We get the instantiated type that are compatible with the receiver type
                    instantiatedTypes.UnionWith(
                        this.MethodEntity.InstantiatedTypes
                            .Where(type => codeProvider.IsSubtype(type,callInfo.Receiver.Type)));
                        // .Where(type => type.IsSubtype(callInfo.Receiver.Type)));
                    foreach (var type in instantiatedTypes)
                    {
                        types.Add(type);
                    }
                    // TO-DO: SHould I fix the node in the receiver to show that is not loaded? Ideally I should use the declared type.
                    // Here I will use the already instantiated types
                    this.MethodEntity.PropGraph.Add(callInfo.Receiver, types);
                    //var declaredType = callInfo.Receiver.AType;
                    //this.PropGraph.Add(callInfo.Receiver, declaredType);
                }
                // Now we compute the potential callees we are going to send the messsages
                // I need to propagate the change to all potential callees, in particular the change in arguments
                if (types.Count() > 0)
                {
                    foreach (var receiverType in types)
                    {
                        // Given a method m and T find the most accurate implementation wrt to T
                        // it can be T.m or the first super class implementing m
                        //var realCallee = callInfo.Callee.FindMethodImplementation(receiverType);
                        var realCallee = codeProvider.FindMethodImplementation(callInfo.Callee,receiverType);
                        CreateAndSendCallMessage(
                            callInfo, realCallee, receiverType, propKind);
                    }
                }
                // This is not good: One reason is that loads like b = this.f are not working
                // in a meth m a after  call r.m() because only the value of r is passed and not all its structure
                else
                {
                    CreateAndSendCallMessage(callInfo, callInfo.Callee, callInfo.Callee.ContainerType, propKind);
                }
            }
            else
            {
                CreateAndSendCallMessage(callInfo,
                    callInfo.Callee,
                    callInfo.Callee.ContainerType, propKind);
            }
        }
 private void DispatchCallMessageForDelegate(DelegateCallInfo delegateCallInfo, PropagationKind propKind)
 {
     foreach (var callee in GetDelegateCallees(delegateCallInfo.CalleeDelegate))
     {
         CreateAndSendCallMessage(delegateCallInfo, callee, callee.ContainerType, propKind);
     }
 }
		private async Task ProcessCalleesAffectedByPropagationAsync(IEnumerable<AnalysisInvocationExpession> callInvocationInfoForCalls, PropagationKind propKind)
		{
			/// Diego: I did this for the demo because I query directly the entities instead of querying the callgraph 
            //if (callInvocationInfoForCalls.Count() > 0)
            //{
            //    this.InvalidateCaches();
            //}
			// I made a new list to avoid a concurrent modification exception we received in some tests
			var invocationsToProcess = new List<AnalysisInvocationExpession>(callInvocationInfoForCalls);
			var continuations = new List<Task>();

			foreach (var invocationInfo in invocationsToProcess)
			{
				//  Add instanciated types! 
				/// Diego: Ben. This may not work well in parallel... 
				/// We need a different way to update this info
				invocationInfo.InstatiatedTypes = this.MethodEntity.InstantiatedTypes;
				// I hate to do this. Need to Refactor!
				if (invocationInfo is CallInfo)
				{
					var t = DispatchCallMessageAsync(invocationInfo as CallInfo, propKind);
					await t;
					//continuations.Add(t);
				}
				if (invocationInfo is DelegateCallInfo)
				{
					var t = DispatchCallMessageForDelegateAsync(invocationInfo as DelegateCallInfo, propKind);
					await t;
					//continuations.Add(t);
				}
			}
			Contract.Assert(invocationsToProcess.Count == invocationsToProcess.Count);
			await Task.WhenAll(continuations);
		}
 public Task PropagateAndProcessAsync(PropagationKind propKind)
 {
     this.SetRequestContext();
     return(methodEntityGrain.PropagateAndProcessAsync(propKind));
 }
 public Task <PropagationEffects> PropagateAsync(PropagationKind propKind)
 {
     this.SetRequestContext();
     return(methodEntityGrain.PropagateAsync(propKind));
 }
 /// <summary>
 /// This method is executed when a method finishes its analysis
 /// If some output info was generated it will generate return messahe
 /// </summary>
 /// <param name="propKind"></param>
 private void EndOfPropagationEvent(PropagationKind propKind, bool retValueChange)
 {
     // Should do something more clever
     ProcessReturnNode(propKind);
 }
 private void ProcessCalleesAffectedByPropagation(IEnumerable<AnalysisInvocationExpession> callInvocationInfoForCalls, PropagationKind propKind)
 {
     /// This to to remove any information about calls that we cached
     /// This is for the incremental reasoning
     /// Diego: I did this for the demo because I query directly the entities instead of querying the callgraph
     if (callInvocationInfoForCalls.Count() > 0)
     {
         this.InvalidateCaches();
     }
     /// I made a new list to avoid a concurrent modification exception we received in some tests
     var invocationsToProcess = new List<AnalysisInvocationExpession>(callInvocationInfoForCalls);
     /// Every invocation that was "touched" by a propagation is signaled to propagate the new data
     foreach (var invocationInfo in invocationsToProcess)
     {
         ///  Add instanciated types
         invocationInfo.InstatiatedTypes = this.MethodEntity.InstantiatedTypes;
         // I hate to do this. Need to Refactor!
         if (invocationInfo is CallInfo)
         {
             DispatchCallMessage(invocationInfo as CallInfo, propKind);
         }
         if (invocationInfo is DelegateCallInfo)
         {
             DispatchCallMessageForDelegate(invocationInfo as DelegateCallInfo, propKind);
         }
     }
 }
        //public bool DiffProp(IEnumerable<T> src, N n)
        //{
        //    var ts = GetTypes(n);
        //    int c = ts.Count;
        //    ts.UnionWith(src.Where(t => !ts.Contains(t)));
        //    if (ts.Count > c)
        //    {
        //        this.workList.Add(n);
        //        return true;
        //    }
        //    return false;
        //}

        internal bool DiffProp(IEnumerable <TypeDescriptor> src, PropGraphNodeDescriptor n, PropagationKind propKind)
        {
            if (propKind == PropagationKind.REMOVE_TYPES || propKind == PropagationKind.REMOVE_ASSIGNMENT)
            {
                return(DiffDelProp(src, n));
            }
            else
            {
                return(DiffProp(src, n));
            }
        }
示例#32
0
 public Task <PropagationEffects> PropagateAsync(PropagationKind propKind)
 {
     this.methodEntity.PropGraph.ResetUpdateCount();
     return(InternalPropagateAsync(propKind));
 }
示例#33
0
        internal async Task <bool> DiffPropAsync(IEnumerable <TypeDescriptor> src, PropGraphNodeDescriptor n, PropagationKind propKind)
        {
            Logger.LogS("PropagationGraph", "DiffPropAsync", "Diff({0},{1})", src, n);

            if (propKind == PropagationKind.REMOVE_TYPES || propKind == PropagationKind.REMOVE_ASSIGNMENT)
            {
                return(DiffDelProp(src, n));
            }
            else
            {
                return(await DiffPropAsync(src, n));
            }
        }
        /// <summary>
        /// This method "replaces" the send + dispatch + processReturnMessage for calless that used the methodProcessor and dispatcher
        /// The idea is trying to avoid reentrant calls to grains
        /// We wil need to improve the code / design but this is a first approach to solve that problem
        /// </summary>
        /// <param name="caller"></param>
        /// <param name="calleeMessage"></param>
        /// <param name="propKind"></param>
        /// <returns></returns>
        private async Task AnalyzeReturnAsync(MethodDescriptor caller, CalleeMessage calleeMessage, PropagationKind propKind)
        {
            Logger.LogS("AnalysisOrchestator", "AnalyzeReturnAsync", "Analyzing return to {0} ", caller);

            //var methodEntityProc = await this.solutionManager.GetMethodEntityAsync(caller);
            var methodEntityProc = await GetMethodEntityGrainAndActivateInProject(caller);

            //PropagationEffects propagationEffects = null;
            //var ready = true;
            //
            //do
            //{
            //	propagationEffects = await methodEntityProc.PropagateAsync(calleeMessage.ReturnMessageInfo);
            //	ready = await WaitForReady(propagationEffects, caller);
            //}
            //while (!ready);
            //
            //await this.PropagateEffectsAsync(propagationEffects, propKind, methodEntityProc);

            var exit = false;

            for (int i = 0; i < 3 && !exit; i++)
            {
                try
                {
                    exit = true;
                    var propagationEffects = await methodEntityProc.PropagateAsync(calleeMessage.ReturnMessageInfo);

                    await this.PropagateEffectsAsync(propagationEffects, propKind, methodEntityProc);
                }
                catch                 //(Exception e)
                {
                    exit = false;
                }
            }

            //var propagationEffects = await methodEntityProc.PropagateAsync(calleeMessage.ReturnMessageInfo);
            //await this.PropagateEffectsAsync(propagationEffects, propKind, methodEntityProc);

            Logger.LogS("AnalysisOrchestator", "AnalyzeReturnAsync", "End Analyzing return to {0} ", caller);
        }
示例#35
0
 private Task DispachReturnMessageAsync(ReturnInfo returnInfo, PropagationKind propKind)
 {
     return(this.CreateAndSendReturnMessageAsync(returnInfo, propKind));
 }
		private async Task CreateAndSendCallMessageAsync(AnalysisInvocationExpession callInfo, 
                            MethodDescriptor realCallee, TypeDescriptor receiverType, PropagationKind propKind)
		{
			var callMessage = await CreateCallMessageAsync(callInfo, realCallee, receiverType, propKind);
			var callerMessage = new CallerMessage(this.EntityDescriptor, callMessage);
			var destination = EntityFactory.Create(realCallee, this.dispatcher);

			await this.SendMessageAsync(destination, callerMessage);
		}
        private void CreateAndSendCallMessage(AnalysisInvocationExpession callInfo, MethodDescriptor realCallee, 
            TypeDescriptor receiverType, PropagationKind propKind)
        {
            /// Here I have all the necessary info to update the callgraph
            ///
            var callMessage = CreateCallMessage(callInfo, realCallee, receiverType, propKind);
            var callerMessage = new CallerMessage(this.EntityDescriptor, callMessage);
            var destination = EntityFactory.Create(realCallee, this.dispatcher);

            this.SendMessage(destination, callerMessage);
        }
		private async Task DispatchCallMessageForDelegateAsync(DelegateCallInfo delegateCallInfo, PropagationKind propKind)
		{
			var continuations = new List<Task>();
			foreach (var callee in await GetDelegateCalleesAsync(delegateCallInfo.CalleeDelegate))
			{
				var continuation = CreateAndSendCallMessageAsync(delegateCallInfo, 
					callee, callee.ContainerType, propKind);
                await continuation;
                //continuations.Add(continuation);
			}
			await Task.WhenAll(continuations);
		}
示例#39
0
        private Task CreateAndSendCallMessageAsync(CallInfo callInfo, ResolvedCallee callee, PropagationKind propKind)
        {
            var callMessageInfo = new CallMessageInfo(callInfo.Caller, callee.Method, callee.ReceiverType,
                                                      callInfo.ArgumentsPossibleTypes, callInfo.CallNode, callInfo.LHS, propKind);

            var source        = new MethodEntityDescriptor(callInfo.Caller);
            var callerMessage = new CallerMessage(source, callMessageInfo);

            return(this.AnalyzeCalleeAsync(callMessageInfo.Callee, callerMessage, propKind));
        }
		/// <summary>
		/// When the method returns I should inform the computed return value to all its caller
		/// It may also propagate other info from out parameters and escaping objects (not implemented)
		/// </summary>
		private async Task ProcessReturnNodeAsync(PropagationKind propKind)
		{
            if(this.Verbose)
            {
                Logger.Instance.Log("MethodEntityProcessor", "ProcessReturnNodeAsync", this.MethodEntity.MethodDescriptor);
            }
			if (this.MethodEntity.ReturnVariable != null)
			{
				// A test to try to force only one simultaneous entity 
				// We should use a Queue instead
				//while (this.MethodEntity.CurrentContext == null)
				//{
				//    Logger.Instance.Log(string.Format("Waiting: {0} to start before return...", this.Method));
				//    Thread.Sleep(10);
				//}
				//CallConext<M, E> callContext=null;
				//lock(this.MethodEntity)
				//{
				//    callContext = this.MethodEntity.CurrentContext;
				//    this.MethodEntity.CurrentContext = null;
				//}
				//var ret = this.MethodEntity.ReturnVariable;
				//if (callContext.Invocation != null)
				//{
				//    var task = DispachReturnMessageAsync(callContext, ret, propKind);
				//    if (task != null) task.RunSynchronously();
				//}

				var continuations = new List<Task>();
				foreach (var callerContex in this.MethodEntity.Callers)
				{
					var ret = this.MethodEntity.ReturnVariable;
					var t = DispachReturnMessageAsync(callerContex, ret, propKind);
                    await t;
                    //continuations.Add(t);
				}

				await Task.WhenAll(continuations);

			}
		}
示例#41
0
        private async Task PopulatePropagationEffectsInfo(PropagationEffects propagationEffects, PropagationKind propKind)
        {
            await this.PopulateCalleesInfo(propagationEffects.CalleesInfo);

            if (this.methodEntity.ReturnVariable != null || propKind == PropagationKind.REMOVE_TYPES)
            {
                this.PopulateCallersInfo(propagationEffects.CallersInfo);
            }
        }
        /// <summary>
        /// Async versions of DispachReturnMessage
        /// </summary>
        /// <param name="context"></param>
        /// <param name="returnVariable"></param>
        /// <param name="propKind"></param>
        /// <returns></returns>
        internal async Task DispachReturnMessageAsync(CallContext context, VariableNode returnVariable, PropagationKind propKind)
		{
			var caller = context.Caller;
			var lhs = context.CallLHS;
			var types = returnVariable != null ?
				GetTypes(returnVariable, propKind) : 
				new HashSet<TypeDescriptor>();

			// Diego TO-DO, different treatment for adding and removal
			if (propKind == PropagationKind.ADD_TYPES && types.Count() == 0 && returnVariable != null)
			{
				var instTypes = new HashSet<TypeDescriptor>();

				foreach (var iType in this.MethodEntity.InstantiatedTypes)
				{
					var isSubtype = await codeProvider.IsSubtypeAsync(iType,returnVariable.Type);
					
					if (isSubtype)
					{
						instTypes.Add(iType);
					}
				}

				//instTypes.UnionWith(
				//	this.MethodEntity.InstantiatedTypes
				//		.Where(iType => codeProvider.IsSubtypeAsync(iType,returnVariable.Type).Result));
                ////    .Where(iType => iType.IsSubtype(returnVariable.Type)));
				foreach (var t in instTypes)
				{
					types.Add(t);
				}
			}

			// Jump to caller
			var destination = EntityFactory.Create(caller,this.dispatcher);
			var retMessageInfo = new ReturnMessageInfo(
				lhs,
				types,
				propKind, this.MethodEntity.InstantiatedTypes,
				context.Invocation);
			var returnMessage = new ReturnMessage(this.MethodEntity.EntityDescriptor, retMessageInfo);
			//if (lhs != null)
			{
				await this.SendMessageAsync(destination, returnMessage);
			}
			//else
			//{
			//    return new Task(() => { });
			//}
		}
		/// <summary>
		/// Async veprsion
		/// </summary>
		/// <param name="callInfo"></param>
		/// <param name="propKind"></param>
		/// <returns></returns>
		private async Task DispatchCallMessageAsync(CallInfo callInfo, PropagationKind propKind)
		{
			if (!callInfo.IsStatic && callInfo.Receiver != null)
			{
				// I need to computes all the calless
				// In case of a deletion we can discar the deleted callee
				//var types = GetTypes(callNode.Receiver, propKind); 
				var types = GetTypes(callInfo.Receiver);

				// If types=={} it means that some info ins missing => we should be conservative and use the instantiated types (RTA) 
				if (types.Count() == 0 && propKind != PropagationKind.REMOVE_TYPES)	//  && propKind==PropagationKind.ADD_TYPES) 
				{
					var instTypes = new HashSet<TypeDescriptor>();
                    foreach (var candidateTypeDescriptor in this.MethodEntity.InstantiatedTypes)
                    {
                        var isSubType = await codeProvider.IsSubtypeAsync(candidateTypeDescriptor, callInfo.Receiver.Type);

                        if (isSubType)
                        {
                            instTypes.Add(candidateTypeDescriptor);
                        }
                    }
                    //instTypes.UnionWith(this.MethodEntity.InstantiatedTypes
                    //    .Where(candidateTypeDescriptor => codeProvider.IsSubtype(candidateTypeDescriptor,callInfo.Receiver.Type)));
					foreach (var t in instTypes)
					{
						types.Add(t);
					}
					// TO-DO: SHould I fix the node in the receiver to show that is not loaded. Ideally I should use the declared type. 
					// Here I will use the already instantiated types
					this.MethodEntity.PropGraph.Add(callInfo.Receiver, types);
					//var declaredType = callInfo.Receiver.AType;
					//this.PropGraph.Add(callInfo.Receiver, declaredType);
				}
				if (types.Count() > 0)
				{
					var continuations = new List<Task>();
				    // Hack
					// Parallel.ForEach(types, async (receiverType) =>
					foreach(var receiverType in types)
					{
						// Given a method m and T find the most accurate implementation wrt to T
						// it can be T.m or the first super class implementing m
						//var realCallee = callInfo.Callee.FindMethodImplementation(receiverType);
						var realCallee = await codeProvider.FindMethodImplementationAsync(callInfo.Callee, receiverType);
						var task = CreateAndSendCallMessageAsync(callInfo, realCallee, receiverType, propKind);
                        await task;
						//continuations.Add(task);
						//CreateAndSendCallMessage(callInfo, realCallee, receiverType, propKind);
					};//);
					await Task.WhenAll(continuations);
				}
				// This is not good: One reason is that loads like b = this.f are not working
				// in a meth m a after  call r.m() because only the value of r is passed and not all its structure
				else
				{
					await CreateAndSendCallMessageAsync(callInfo, 
						callInfo.Callee, callInfo.Callee.ContainerType, propKind);
				}
			}
			else
			{
				await CreateAndSendCallMessageAsync(callInfo, callInfo.Callee, callInfo.Callee.ContainerType, propKind);
			}
		}
        private Task CreateAndSendCallMessageAsync(CallInfo callInfo, ResolvedCallee callee, PropagationKind propKind)
        {
            var callMessageInfo = new CallMessageInfo(callInfo.Caller, callee.Method, callee.ReceiverType,
                                                      callInfo.ArgumentsPossibleTypes, callInfo.CallNode, callInfo.LHS, propKind);

            var source        = new MethodEntityDescriptor(callInfo.Caller);
            var callerMessage = new CallerMessage(source, callMessageInfo);

            //Logger.LogWarning(GrainClient.Logger, "Orchestrator", "CreateAndSendCallMsg", "Enqueuing: {0}", callee);

            //await WaitQueue(QUEUE_THRESHOLD);
            this.messageWorkList.Enqueue(callerMessage);
            //this.messageWorkList.Add(callerMessage);

            return(Task.CompletedTask);
            //return AnalyzeCalleeAsync(callMessageInfo.Callee, callerMessage, propKind);
        }
 public Task PropagateAndProcessAsync(PropagationKind propKind, IEnumerable <PropGraphNodeDescriptor> reWorkSet)
 {
     this.SetRequestContext();
     return(methodEntityGrain.PropagateAndProcessAsync(propKind, reWorkSet));
 }
        private async Task<CallMessageInfo> CreateCallMessageAsync(AnalysisInvocationExpession callInfo,
                                                            MethodDescriptor actuallCallee,
                                                            TypeDescriptor computedReceiverType,
                                                            PropagationKind propKind)
        {
            // var calleType = (TypeDescriptor)actuallCallee.ContainerType;
            var calleType = computedReceiverType;
            ISet<TypeDescriptor> potentialReceivers = new HashSet<TypeDescriptor>();

            if (callInfo.Receiver != null)
            {
                // BUG!!!! I should use simply computedReceiverType
                // Instead of copying all types with use the type we use to compute the callee
                foreach (var type in GetTypes(callInfo.Receiver, propKind))
                {
                    var isSubType = await codeProvider.IsSubtypeAsync(type, calleType);

                    if(isSubType)
                    {
                        potentialReceivers.Add(type);
                    }
                }
                //potentialReceivers.UnionWith(
                //        GetTypes(callInfo.Receiver, propKind)
                //        .Where(t => codeProvider.IsSubtype(t, calleType)));
                //.Where(t => t.IsSubtype(calleType)));

                // potentialReceivers.Add((AnalysisType)calleType);
            }

            var argumentValues = callInfo.Arguments
                .Select(a => a != null ?
                GetTypes(a, propKind) :
                new HashSet<TypeDescriptor>());

            Contract.Assert(argumentValues.Count() == callInfo.Arguments.Count());

            return new CallMessageInfo(callInfo.Caller, actuallCallee, callInfo.CallNode,
                                                potentialReceivers, new List<ISet<TypeDescriptor>>(argumentValues),
                                                callInfo.LHS, callInfo.InstatiatedTypes, propKind);
        }