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