Esempio n. 1
0
        /// <summary>
        /// Retrieves an existing instance of a callsite associated with a UID
        /// It creates a new callsite if non was found
        /// </summary>
        /// <param name="core"></param>
        /// <param name="uid"></param>
        /// <returns></returns>
        public CallSite GetCallSite(GraphNode graphNode,
                                    int classScope,
                                    string methodName,
                                    Executable executable,
                                    int runningBlock,
                                    Options options,
                                    RuntimeStatus runtimeStatus
             )
        {
            Validity.Assert(null != executable.FunctionTable);
            CallSite csInstance = null;

            // TODO Jun: Currently generates a new callsite for imperative and 
            // internally generated functions.
            // Fix the issues that cause the cache to go out of sync when 
            // attempting to cache internal functions. This may require a 
            // secondary callsite cache for internal functions so they dont 
            // clash with the graphNode UID key
            var language = executable.instrStreamList[runningBlock].language;
            bool isImperative = language == Language.kImperative;
            bool isInternalFunction = CoreUtils.IsInternalFunction(methodName);

            if (isInternalFunction || isImperative)
            {
                csInstance = new CallSite(classScope,
                                          methodName,
                                          executable.FunctionTable,
                                          options.ExecutionMode);
            }
            else if (!CallsiteCache.TryGetValue(graphNode.CallsiteIdentifier, out csInstance))
            {
                // Attempt to retrieve a preloaded callsite data (optional).
                var traceData = GetAndRemoveTraceDataForNode(graphNode.guid);

                csInstance = new CallSite(classScope,
                                          methodName,
                                          executable.FunctionTable,
                                          options.ExecutionMode,
                                          traceData);

                CallsiteCache[graphNode.CallsiteIdentifier] = csInstance;
                CallSiteToNodeMap[csInstance.CallSiteID] = graphNode.guid;
                ASTToCallSiteMap[graphNode.AstID] = csInstance;

            }

            if (graphNode != null && !CoreUtils.IsDisposeMethod(methodName))
            {
                csInstance.UpdateCallSite(classScope, methodName);
                if (options.IsDeltaExecution)
                {
                    runtimeStatus.ClearWarningForExpression(graphNode.exprUID);
                }
            }

            return csInstance;
        }
Esempio n. 2
0
            public void SerialisationDataLoadSave()
            {
                //Test to ensure that the first time the code is executed the wasTraced attribute is marked as false
                //and the secodn time it is marked as true


                string setupCode =
                    @"import(""FFITarget.dll""); 
x = 0; 
mtcA = IncrementerTracedClass.IncrementerTracedClass(x); 
mtcAID = mtcA.ID;
mtcAWasTraced = mtcA.WasCreatedWithTrace(); ";



                // Create 2 CBNs

                List <Subtree> added = new List <Subtree>();


                // Simulate a new new CBN
                Guid guid1 = System.Guid.NewGuid();

                added.Add(ProtoTestFx.TD.TestFrameWork.CreateSubTreeFromCode(guid1, setupCode));

                var syncData = new GraphSyncData(null, added, null);

                astLiveRunner.UpdateGraph(syncData);

                //Get the callsite for the ctor
                var core          = astLiveRunner.RuntimeCore;
                var ctorCallsites = core.RuntimeData.CallsiteCache.Values.Where(c => c.MethodName == "IncrementerTracedClass");

                Assert.IsTrue(ctorCallsites.Count() == 1);
                ProtoCore.CallSite cs = ctorCallsites.First();

                //Request serialisation
                string serialisationData = cs.GetTraceDataToSave();

                //It shouldn't be empty
                Assert.IsTrue(!String.IsNullOrEmpty(serialisationData));


                //Wipe the trace data
                cs.TraceData.Clear();

                //Re-inject the data into the trace cache
                cs.LoadSerializedDataIntoTraceCache(serialisationData);

                ExecuteMoreCode("x = 1;");


                // Verify that a is re-executed
                TestFrameWork.AssertValue("mtcAID", 0, astLiveRunner);
                TestFrameWork.AssertValue("mtcAWasTraced", true, astLiveRunner);
            }
Esempio n. 3
0
            public void EnsureSerialisationDataNonNull()
            {
                //Test to ensure that the first time the code is executed the wasTraced attribute is marked as false
                //and the secodn time it is marked as true


                string setupCode =
                    @"import(""FFITarget.dll""); 
x = 0; 
mtcA = IncrementerTracedClass.IncrementerTracedClass(x); 
mtcAID = mtcA.ID;
mtcAWasTraced = mtcA.WasCreatedWithTrace(); ";



                // Create 2 CBNs

                List <Subtree> added = new List <Subtree>();


                // Simulate a new new CBN
                Guid guid1 = System.Guid.NewGuid();

                added.Add(CreateSubTreeFromCode(guid1, setupCode));

                var syncData = new GraphSyncData(null, added, null);

                astLiveRunner.UpdateGraph(syncData);

                //Get the callsite for the ctor
                var core          = astLiveRunner.Core;
                var ctorCallsites = core.DSExecutable.RuntimeData.CallsiteCache.Values.Where(c => c.MethodName == "IncrementerTracedClass");

                Assert.IsTrue(ctorCallsites.Count() == 1);
                ProtoCore.CallSite cs = ctorCallsites.First();

                //Request serialisation
                string serialisationData = cs.GetTraceDataToSave();

                //It shouldn't be empty
                Assert.IsTrue(!String.IsNullOrEmpty(serialisationData));
            }
Esempio n. 4
0
        /// <summary>
        /// Retrieves an existing instance of a callsite associated with a UID
        /// It creates a new callsite if non was found
        /// </summary>
        /// <param name="core"></param>
        /// <param name="uid"></param>
        /// <returns></returns>
        public CallSite GetCallSite(int classScope, string methodName, Executable executable, RuntimeCore runtimeCore)
        {
            Validity.Assert(null != executable.FunctionTable);
            CallSite csInstance = null;
            var graphNode = executable.ExecutingGraphnode;
            var topGraphNode = graphNode;

            // If it is a nested function call, append all callsite ids
            List<string> callsiteIdentifiers = new List<string>();
            foreach (var prop in runtimeCore.InterpreterProps)
            {
                if (prop != null && prop.executingGraphNode != null && graphNode != prop.executingGraphNode)
                {
                    topGraphNode = prop.executingGraphNode;
                    if (!string.IsNullOrEmpty(topGraphNode.CallsiteIdentifier))
                    {
                        callsiteIdentifiers.Add(topGraphNode.CallsiteIdentifier);
                    }
                }
            }
            if (graphNode != null)
            {
                callsiteIdentifiers.Add(graphNode.CallsiteIdentifier);
            }
            var callsiteID = string.Join(";", callsiteIdentifiers.ToArray());

            // TODO Jun: Currently generates a new callsite for imperative and 
            // internally generated functions.
            // Fix the issues that cause the cache to go out of sync when 
            // attempting to cache internal functions. This may require a 
            // secondary callsite cache for internal functions so they dont 
            // clash with the graphNode UID key
            var language = executable.instrStreamList[runtimeCore.RunningBlock].language;
            bool isImperative = language == Language.Imperative;
            bool isInternalFunction = CoreUtils.IsInternalFunction(methodName);

            if (isInternalFunction || isImperative)
            {
                csInstance = new CallSite(classScope,
                                          methodName,
                                          executable.FunctionTable,
                                          runtimeCore.Options.ExecutionMode);
            }
            else if (!CallsiteCache.TryGetValue(callsiteID, out csInstance))
            {
                // Attempt to retrieve a preloaded callsite data (optional).
                var traceData = GetAndRemoveTraceDataForNode(topGraphNode.guid, callsiteID);

                csInstance = new CallSite(classScope,
                                          methodName,
                                          executable.FunctionTable,
                                          runtimeCore.Options.ExecutionMode,
                                          traceData);

                CallsiteCache[callsiteID] = csInstance;
                CallSiteToNodeMap[csInstance.CallSiteID] = topGraphNode.guid;
            }

            if (graphNode != null && !CoreUtils.IsDisposeMethod(methodName))
            {
                csInstance.UpdateCallSite(classScope, methodName);
                if (runtimeCore.Options.IsDeltaExecution)
                {
                    runtimeCore.RuntimeStatus.ClearWarningForExpression(graphNode.exprUID);
                }
            }

            return csInstance;
        }
Esempio n. 5
0
        public void SetUpCallrForDebug(RuntimeCore runtimeCore, DSASM.Executive exec, ProcedureNode fNode, int pc, bool isBaseCall = false,
            CallSite callsite = null, List<StackValue> arguments = null, List<List<ReplicationGuide>> replicationGuides = null, StackFrame stackFrame = null,
            List<StackValue> dotCallDimensions = null, bool hasDebugInfo = false, bool isMember = false, StackValue? thisPtr = null)
        {
            //ProtoCore.DSASM.Executive exec = core.CurrentExecutive.CurrentDSASMExec;

            DebugFrame debugFrame = new DebugFrame();
            debugFrame.IsBaseCall = isBaseCall;
            debugFrame.Arguments = arguments;
            debugFrame.IsMemberFunction = isMember;
            debugFrame.ThisPtr = thisPtr;
            debugFrame.HasDebugInfo = hasDebugInfo;

            if (CoreUtils.IsDisposeMethod(fNode.name))
            {
                debugFrame.IsDisposeCall = true;
                ReturnPCFromDispose = DebugEntryPC;
            }

            if (RunMode == Runmode.StepNext)
            {
                debugFrame.FunctionStepOver = true;
            }

            bool isReplicating = false;
            bool isExternalFunction = false;
            
            // callsite is set to null for a base class constructor call in CALL
            if (callsite == null)
            {
                isReplicating = false;
                isExternalFunction = false;
                
                SetUpCallr(ref debugFrame, isReplicating, isExternalFunction, exec);
                DebugStackFrame.Push(debugFrame);

                return;
            }

            // Comment Jun: A dot call does not replicate and  must be handled immediately
            if (fNode.name == Constants.kDotMethodName)
            {
                isReplicating = false;
                isExternalFunction = false;
                debugFrame.IsDotCall = true;
                debugFrame.DotCallDimensions = dotCallDimensions;
                
                SetUpCallr(ref debugFrame, isReplicating, isExternalFunction, exec);
                DebugStackFrame.Push(debugFrame);

                return;
            }

            List<List<ReplicationInstruction>> replicationTrials;
            bool willReplicate = callsite.WillCallReplicate(new Context(), arguments, replicationGuides, stackFrame, runtimeCore, out replicationTrials);
            
            // the inline conditional built-in is handled separately as 'WillCallReplicate' is always true in this case
            if(fNode.name.Equals(Constants.kInlineConditionalMethodName))
            {
                // The inline conditional built-in is created only for associative blocks and needs to be handled separately as below
                InstructionStream istream = runtimeCore.DSExecutable.instrStreamList[CurrentBlockId];
                Validity.Assert(istream.language == Language.kAssociative);
                {
                    runtimeCore.DebugProps.InlineConditionOptions.isInlineConditional = true;
                    runtimeCore.DebugProps.InlineConditionOptions.startPc = pc;

                    runtimeCore.DebugProps.InlineConditionOptions.endPc = FindEndPCForAssocGraphNode(pc, istream, fNode, exec.Properties.executingGraphNode, runtimeCore.Options.ExecuteSSA);


                    runtimeCore.DebugProps.InlineConditionOptions.instructionStream = runtimeCore.RunningBlock;
                    debugFrame.IsInlineConditional = true;
                }
                
                // no replication case
                if (willReplicate && replicationTrials.Count == 1)
                {
                    runtimeCore.DebugProps.InlineConditionOptions.ActiveBreakPoints.AddRange(runtimeCore.Breakpoints);

                    /*if (core.DebugProps.RunMode == Runmode.StepNext)
                    {
                        core.Breakpoints.Clear();
                    }*/

                    isReplicating = false;
                    isExternalFunction = false;
                }
                else // an inline conditional call that replicates
                {
#if !__DEBUG_REPLICATE
                    // Clear all breakpoints for outermost replicated call
                    if(!DebugStackFrameContains(StackFrameFlagOptions.IsReplicating))
                    {
                        ActiveBreakPoints.AddRange(runtimeCore.Breakpoints);
                        runtimeCore.Breakpoints.Clear();
                    }
#endif
                    isExternalFunction = false;
                    isReplicating = true;
                }
                SetUpCallr(ref debugFrame, isReplicating, isExternalFunction, exec, 0);
                
                DebugStackFrame.Push(debugFrame);

                return;
            }            
            // Prevent breaking inside a function that is external except for dot calls
            // by clearing all breakpoints from outermost external function call
            // This check takes precedence over the replication check
            else if (fNode.isExternal && fNode.name != Constants.kDotMethodName)
            {
                // Clear all breakpoints 
                if (!DebugStackFrameContains(StackFrameFlagOptions.IsExternalFunction) && fNode.name != Constants.kFunctionRangeExpression)
                {
                    ActiveBreakPoints.AddRange(runtimeCore.Breakpoints);
                    runtimeCore.Breakpoints.Clear();
                }

                isExternalFunction = true;
                isReplicating = false;
            }
            // Find if function call will replicate or not and if so
            // prevent stepping in by removing all breakpoints from outermost replicated call
            else if (willReplicate)
            {
#if !__DEBUG_REPLICATE
                // Clear all breakpoints for outermost replicated call
                if(!DebugStackFrameContains(StackFrameFlagOptions.IsReplicating))
                {
                    ActiveBreakPoints.AddRange(runtimeCore.Breakpoints);
                    runtimeCore.Breakpoints.Clear();
                }
#endif

                isReplicating = true;
                isExternalFunction = false;
            }
            // For all other function calls
            else
            {
                isReplicating = false;
                isExternalFunction = false;
            }

            SetUpCallr(ref debugFrame, isReplicating, isExternalFunction, exec);
            DebugStackFrame.Push(debugFrame);
        }
Esempio n. 6
0
            public void LoadSave_R2R_2()
            {
                string setupCode =
                    @"import(""FFITarget.dll""); 
x = 0..2; 
mtcA = IncrementerTracedClass.IncrementerTracedClass(x); 
mtcAID = mtcA.ID;
mtcAWasTraced = mtcA.WasCreatedWithTrace(); ";


                // Create 2 CBNs

                List <Subtree> added = new List <Subtree>();


                // Simulate a new new CBN
                Guid guid1 = System.Guid.NewGuid();

                added.Add(CreateSubTreeFromCode(guid1, setupCode));

                var syncData = new GraphSyncData(null, added, null);

                astLiveRunner.UpdateGraph(syncData);

                TestFrameWork.AssertValue("mtcAID", new List <int>()
                {
                    0,
                    1,
                    2
                }, astLiveRunner);

                TestFrameWork.AssertValue("mtcAWasTraced", new List <bool>()
                {
                    false,
                    false,
                    false
                }, astLiveRunner);

                //Get the callsite for the ctor
                var core          = astLiveRunner.Core;
                var ctorCallsites = core.DSExecutable.RuntimeData.CallsiteCache.Values.Where(c => c.MethodName == "IncrementerTracedClass");

                Assert.IsTrue(ctorCallsites.Count() == 1);
                ProtoCore.CallSite cs = ctorCallsites.First();

                //Request serialisation
                string serialisationData = cs.GetTraceDataToSave();

                //It shouldn't be empty
                Assert.IsTrue(!String.IsNullOrEmpty(serialisationData));


                //Wipe the trace data
                cs.TraceData.Clear();

                //Re-inject the data into the trace cache
                cs.LoadSerializedDataIntoTraceCache(serialisationData);


                // Simulate a new new CBN
                Guid guid2 = System.Guid.NewGuid();

                added = new List <Subtree>();
                added.Add(CreateSubTreeFromCode(guid2, "x = 1..2;"));


                syncData = new GraphSyncData(null, added, null);
                astLiveRunner.UpdateGraph(syncData);

                // Verify that a is re-executed
                TestFrameWork.AssertValue("mtcAID", new List <int>()
                {
                    0,
                    1
                }, astLiveRunner);
                TestFrameWork.AssertValue("mtcAWasTraced", new List <bool>()
                {
                    true,
                    true
                }, astLiveRunner);
            }