示例#1
0
        /// <nodoc/>
        public EvaluationResult EvalWrapper(Node node, Context context, ModuleLiteral env, EvaluationStackFrame args, Func <EvaluationResult> continuation)
        {
            Contract.Requires(node != null);
            Contract.Requires(context != null);
            Contract.Requires(args != null);
            Contract.Requires(continuation != null);

            // We want to profile apply expression nodes only
            var applyExpression = node as ApplyExpression;

            if (applyExpression != null)
            {
                // We record that this functor needs its evaluated value by adding it to the dictionary with a null value if it is not there yet
                m_functorsPendingEvaluation.TryAdd(applyExpression.Functor, null);

                // Register start time and then call the continuation
                var startTime = m_stopwatch.ElapsedMilliseconds;

                var applyResult = continuation();

                var endTime = m_stopwatch.ElapsedMilliseconds;

                // After running the continuation, the functor value should not be pending anymore. So we retrieve its id and location
                Contract.Assert(m_functorsPendingEvaluation.ContainsKey(applyExpression.Functor) && m_functorsPendingEvaluation[applyExpression.Functor] != null);
                GetFunctorIdNameAndLocation(context, m_functorsPendingEvaluation[applyExpression.Functor], out int functorId, out string functorName, out string functorLocation);

                // We cannot really remove the entry here since there might be other parallel evaluations that depend on it
                // TODO: we could try something out if memory turns out to be a problem.
                var entry = new ProfiledFunctionCall(
                    callsiteInvocation: node.ToDisplayString(context),
                    callsiteLocation: node.Location.ToLocationData(env.Path),
                    durationInclusive: endTime - startTime,
                    qualifier: env.Qualifier.QualifierId.ToDisplayString(context),
                    functionId: functorId,
                    functionName: functorName,
                    functionLocation: functorLocation);

                m_profilerEntries.Enqueue(entry);

                return(applyResult);
            }

            // In this case we don't profile the evaluation call, but we check if this happens to be the functor for which we need its value for a parent evaluation
            var result = continuation();

            if (m_functorsPendingEvaluation.TryGetValue(node, out object existingResult) && existingResult == null)
            {
                m_functorsPendingEvaluation[node] = result.Value;
            }

            return(result);
        }
示例#2
0
        private string GetLine(ProfiledFunctionCall entry)
        {
            var result = string.Format(
                CultureInfo.InvariantCulture,
                "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}",
                entry.CallsiteInvocation,
                entry.DurationInclusive,
                entry.CallsiteLocation.ToString(m_pathTable),
                entry.Qualifier,
                entry.FunctionId,
                entry.FunctionName,
                entry.FunctionLocation);

            return(result);
        }