Esempio n. 1
0
            internal static SingleRunTraceData DeserialseFromData(SerializationInfo info, StreamingContext context, int objectID, string marker)
            {
                SingleRunTraceData srtd = new SingleRunTraceData();

                bool hasData = info.GetBoolean(marker + objectID + "_HasData");

                if (hasData)
                {
                    Byte[] data = Convert.FromBase64String(info.GetString(marker + objectID + "_Data"));


                    IFormatter formatter = new SoapFormatter();
                    MemoryStream s = new MemoryStream(data);

                    srtd.Data = (ISerializable) formatter.Deserialize(s);
                }

                bool hasNestedData = info.GetBoolean(marker + objectID + "_HasNestedData");

                if (hasNestedData)
                {
                    
                    int nestedDataCount = info.GetInt32(marker + objectID + "_NestedDataCount");

                    if (nestedDataCount > 0)
                        srtd.NestedData = new List<SingleRunTraceData>();

                    for (int i = 0; i < nestedDataCount; i++)
                    {
                        srtd.NestedData.Add(
                            DeserialseFromData(info, context, i, marker + objectID + "-")
                            );
                    }

                }

                return srtd;
            }
Esempio n. 2
0
        //Single function call
        /// <summary>
        /// Dispatch without replication
        /// </summary>
        private StackValue ExecWithZeroRI(List<FunctionEndPoint> functionEndPoint, Context c,
                                          List<StackValue> formalParameters, StackFrame stackFrame, RuntimeCore runtimeCore,
                                          FunctionGroup funcGroup, SingleRunTraceData previousTraceData, SingleRunTraceData newTraceData)
        {
            if (runtimeCore.CancellationPending)
            {
                throw new ExecutionCancelledException();               
            }

            //@PERF: Todo add a fast path here for the case where we have a homogenious array so we can directly dispatch
            FunctionEndPoint finalFep = SelectFinalFep(c, functionEndPoint, formalParameters, stackFrame, runtimeCore);

            if (functionEndPoint == null)
            {
                runtimeCore.RuntimeStatus.LogWarning(WarningID.kMethodResolutionFailure, 
                    string.Format(Resources.FunctionDispatchFailed, "{2EB39E1B-557C-4819-94D8-CF7C9F933E8A}"));
                return StackValue.Null;
            }

            if (runtimeCore.Options.IDEDebugMode && runtimeCore.Options.RunMode != InterpreterMode.kExpressionInterpreter)
            {
                DebugFrame debugFrame = runtimeCore.DebugProps.DebugStackFrame.Peek();
                debugFrame.FinalFepChosen = finalFep;
            }

            List<StackValue> coercedParameters = finalFep.CoerceParameters(formalParameters, runtimeCore);

            // Correct block id where the function is defined. 
            stackFrame.FunctionBlock = finalFep.BlockScope;

            //TraceCache -> TLS
            //Extract left most high-D pack
            ISerializable traceD = previousTraceData.GetLeftMostData();

            if (traceD != null)
            {
                //There was data associated with the previous execution, push this into the TLS

                Dictionary<string, ISerializable> dataDict = new Dictionary<string, ISerializable>();
                dataDict.Add(TRACE_KEY, traceD);

                TraceUtils.SetObjectToTLS(dataDict);
            }
            else
            {
                //There was no trace data for this run
                TraceUtils.ClearAllKnownTLSKeys();
            }

            //EXECUTE
            StackValue ret = finalFep.Execute(c, coercedParameters, stackFrame, runtimeCore);

            if (ret.IsNull)
            {
                //wipe the trace cache
                TraceUtils.ClearTLSKey(TRACE_KEY);
            }

            //TLS -> TraceCache
            Dictionary<string, ISerializable> traceRet = TraceUtils.GetObjectFromTLS();

            if (traceRet.ContainsKey(TRACE_KEY))
            {
                var val = traceRet[TRACE_KEY];
                newTraceData.Data = val;
            }

            // An explicit call requires return coercion at the return instruction
            if (!ret.IsExplicitCall)
            {
                ret = PerformReturnTypeCoerce(finalFep, runtimeCore, ret);
            }
            return ret;
        }
Esempio n. 3
0
        /// <summary>
        /// Excecute an arbitrary depth replication using the full slow path algorithm
        /// </summary>
        /// <param name="functionEndPoint"> </param>
        /// <param name="c"></param>
        /// <param name="formalParameters"></param>
        /// <param name="replicationInstructions"></param>
        /// <param name="stackFrame"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        private StackValue ExecWithRISlowPath(
            List<FunctionEndPoint> functionEndPoint, 
            Context c, 
            List<StackValue> formalParameters, 
            List<ReplicationInstruction> replicationInstructions, 
            StackFrame stackFrame, 
            RuntimeCore runtimeCore, 
            FunctionGroup funcGroup, 
            SingleRunTraceData previousTraceData, 
            SingleRunTraceData newTraceData)
        {
            if (runtimeCore.Options.ExecutionMode == ExecutionMode.Parallel)
                throw new NotImplementedException("Parallel mode disabled: {BF417AD5-9EA9-4292-ABBC-3526FC5A149E}");

            //Recursion base case
            if (replicationInstructions.Count == 0)
            {
                return ExecWithZeroRI(functionEndPoint, c, formalParameters, stackFrame, runtimeCore, funcGroup, previousTraceData, newTraceData);
            }

            //Get the replication instruction that this call will deal with
            ReplicationInstruction ri = replicationInstructions[0];

            if (ri.Zipped)
            {
                ZipAlgorithm algorithm = ri.ZipAlgorithm;

                //For each item in this plane, an array of the length of the minimum will be constructed

                //The size of the array will be the minimum size of the passed arrays
                List<int> repIndecies = ri.ZipIndecies;

                //this will hold the heap elements for all the arrays that are going to be replicated over
                List<StackValue[]> parameters = new List<StackValue[]>();

                int retSize;
                switch (algorithm)
                {
                    case ZipAlgorithm.Shortest:
                        retSize = Int32.MaxValue; //Search to find the smallest
                        break;

                    case ZipAlgorithm.Longest:
                        retSize = Int32.MinValue; //Search to find the largest
                        break;

                    default:
                        throw new ReplicationCaseNotCurrentlySupported(Resources.AlgorithmNotSupported);
                }


                bool hasEmptyArg = false;
                foreach (int repIndex in repIndecies)
                {

                    StackValue[] subParameters = null;
                    if (formalParameters[repIndex].IsArray)
                    {
                        subParameters = runtimeCore.Heap.ToHeapObject<DSArray>(formalParameters[repIndex]).Values.ToArray();
                    }
                    else
                    {
                        subParameters = new StackValue[] { formalParameters[repIndex] };
                    }
                    parameters.Add(subParameters);

                    if (subParameters.Length == 0)
                        hasEmptyArg = true;

                    switch (algorithm)
                    {
                        case ZipAlgorithm.Shortest:
                            retSize = Math.Min(retSize, subParameters.Length); //We need the smallest array
                            break;
                        case ZipAlgorithm.Longest:
                            retSize = Math.Max(retSize, subParameters.Length); //We need the longest array
                            break;
                    }

                }

                // If we're being asked to replicate across an empty list
                // then it's always going to be zero, as there will never be any
                // data to pass to that parameter.
                if (hasEmptyArg)
                    retSize = 0;

                StackValue[] retSVs = new StackValue[retSize];
                SingleRunTraceData retTrace = newTraceData;
                retTrace.NestedData = new List<SingleRunTraceData>(); //this will shadow the SVs as they are created

                //Populate out the size of the list with default values
                //@TODO:Luke perf optimisation here
                for (int i = 0; i < retSize; i++)
                    retTrace.NestedData.Add(new SingleRunTraceData());

                for (int i = 0; i < retSize; i++)
                {
                    SingleRunTraceData lastExecTrace = new SingleRunTraceData();

                    if (previousTraceData.HasNestedData && i < previousTraceData.NestedData.Count)
                    {
                        //There was previous data that needs loading into the cache
                        lastExecTrace = previousTraceData.NestedData[i];
                    }
                    else
                    {
                        //We're off the edge of the previous trace window
                        //So just pass in an empty block
                        lastExecTrace = new SingleRunTraceData();
                    }

                    //Build the call
                    List<StackValue> newFormalParams = new List<StackValue>();
                    newFormalParams.AddRange(formalParameters);

                    for (int repIi = 0; repIi < repIndecies.Count; repIi++)
                    {
                        switch (algorithm)
                        {
                            case ZipAlgorithm.Shortest:
                                //If the shortest algorithm is selected this would
                                newFormalParams[repIndecies[repIi]] = parameters[repIi][i];
                                break;
                            
                            case ZipAlgorithm.Longest:

                                int length = parameters[repIi].Length;
                                if (i < length)
                                {
                                    newFormalParams[repIndecies[repIi]] = parameters[repIi][i];
                                }
                                else
                                {
                                    newFormalParams[repIndecies[repIi]] = parameters[repIi].Last();
                                }
                                break;
                        }
                    }

                    List<ReplicationInstruction> newRIs = new List<ReplicationInstruction>();
                    newRIs.AddRange(replicationInstructions);
                    newRIs.RemoveAt(0);


                    SingleRunTraceData cleanRetTrace = new SingleRunTraceData();

                    retSVs[i] = ExecWithRISlowPath(functionEndPoint, c, newFormalParams, newRIs, stackFrame, runtimeCore,
                                                    funcGroup, lastExecTrace, cleanRetTrace);

                    runtimeCore.AddCallSiteGCRoot(CallSiteID, retSVs[i]);

                    retTrace.NestedData[i] = cleanRetTrace;
                }

                StackValue ret = runtimeCore.RuntimeMemory.Heap.AllocateArray(retSVs);
                return ret;
            }
            else
            {
                //With a cartesian product over an array, we are going to create an array of n
                //where the n is the product of the next item

                //We will call the subsequent reductions n times
                int cartIndex = ri.CartesianIndex;

                //this will hold the heap elements for all the arrays that are going to be replicated over
                bool supressArray = false;
                int retSize;
                StackValue[] parameters = null; 
                
                if (formalParameters[cartIndex].IsArray)
                {
                    DSArray array = runtimeCore.Heap.ToHeapObject<DSArray>(formalParameters[cartIndex]);
                    parameters = array.Values.ToArray();
                    retSize = parameters.Length;
                }
                else
                {
                    retSize = 1;
                    supressArray = true;
                }

                StackValue[] retSVs = new StackValue[retSize];

                SingleRunTraceData retTrace = newTraceData;
                retTrace.NestedData = new List<SingleRunTraceData>(); //this will shadow the SVs as they are created

                //Populate out the size of the list with default values
                //@TODO:Luke perf optimisation here
                for (int i = 0; i < retSize; i++)
                {
                    retTrace.NestedData.Add(new SingleRunTraceData());
                }

                if (supressArray)
                {
                    List<ReplicationInstruction> newRIs = new List<ReplicationInstruction>();
                    newRIs.AddRange(replicationInstructions);
                    newRIs.RemoveAt(0);

                    List<StackValue> newFormalParams = new List<StackValue>();
                    newFormalParams.AddRange(formalParameters);

                    return ExecWithRISlowPath(functionEndPoint, c, newFormalParams, newRIs, stackFrame, runtimeCore,
                                                funcGroup, previousTraceData, newTraceData);
                }

                //Now iterate over each of these options
                for (int i = 0; i < retSize; i++)
                {
                    //Build the call
                    List<StackValue> newFormalParams = new List<StackValue>();
                    newFormalParams.AddRange(formalParameters);

                    if (parameters != null)
                    {
                        //It was an array pack the arg with the current value
                        newFormalParams[cartIndex] = parameters[i];
                    }

                    List<ReplicationInstruction> newRIs = new List<ReplicationInstruction>();
                    newRIs.AddRange(replicationInstructions);
                    newRIs.RemoveAt(0);


                    SingleRunTraceData lastExecTrace;

                    if (previousTraceData.HasNestedData && i < previousTraceData.NestedData.Count)
                    {
                        //There was previous data that needs loading into the cache
                        lastExecTrace = previousTraceData.NestedData[i];
                    }
                    else if (previousTraceData.HasData && i == 0)
                    {
                        //We've moved up one dimension, and there was a previous run
                        lastExecTrace = new SingleRunTraceData();
                        lastExecTrace.Data = previousTraceData.GetLeftMostData();

                    }
                    else
                    {
                        //We're off the edge of the previous trace window
                        //So just pass in an empty block
                        lastExecTrace = new SingleRunTraceData();
                    }

                    //previousTraceData = lastExecTrace;
                    SingleRunTraceData cleanRetTrace = new SingleRunTraceData();

                    retSVs[i] = ExecWithRISlowPath(functionEndPoint, c, newFormalParams, newRIs, stackFrame, runtimeCore,
                                                    funcGroup, lastExecTrace, cleanRetTrace);

                    runtimeCore.AddCallSiteGCRoot(CallSiteID, retSVs[i]);

                    retTrace.NestedData[i] = cleanRetTrace;
                }


                StackValue ret = runtimeCore.RuntimeMemory.Heap.AllocateArray(retSVs);
                return ret;
            }
        }
Esempio n. 4
0
        private StackValue Execute(
            List<FunctionEndPoint> functionEndPoint, 
            Context c, 
            List<StackValue> formalParameters, 
            List<ReplicationInstruction> replicationInstructions, 
            StackFrame stackFrame, 
            RuntimeCore runtimeCore, 
            FunctionGroup funcGroup)
        {
            SingleRunTraceData singleRunTraceData = (invokeCount < traceData.Count) ? traceData[invokeCount] : new SingleRunTraceData();
            SingleRunTraceData newTraceData = new SingleRunTraceData();
            StackValue ret;

            if (replicationInstructions.Count == 0)
            {
                c.IsReplicating = false;
                ret = ExecWithZeroRI(functionEndPoint, c, formalParameters, stackFrame, runtimeCore, funcGroup,
                    singleRunTraceData, newTraceData);
            }
            else //replicated call
            {
                c.IsReplicating = true;
                ret = ExecWithRISlowPath(functionEndPoint, c, formalParameters, replicationInstructions, stackFrame,
                                         runtimeCore, funcGroup, singleRunTraceData, newTraceData);
            }

            //Do a trace save here
            if (invokeCount < traceData.Count)
            {
                traceData[invokeCount] = newTraceData;
            }
            else
            {
                traceData.Add(newTraceData);
            }

            invokeCount++; //We've completed this invocation
            return ret;
        }
Esempio n. 5
0
        //Repication

        /// <summary>
        /// Excecute an arbitrary depth replication using the full slow path algorithm
        /// </summary>
        /// <param name="functionEndPoint"> </param>
        /// <param name="c"></param>
        /// <param name="formalParameters"></param>
        /// <param name="replicationInstructions"></param>
        /// <param name="stackFrame"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        private StackValue ExecWithRISlowPath(List<FunctionEndPoint> functionEndPoint, ProtoCore.Runtime.Context c,
                                              List<StackValue> formalParameters,
                                              List<ReplicationInstruction> replicationInstructions,
                                              StackFrame stackFrame, Core core, FunctionGroup funcGroup, 
            SingleRunTraceData previousTraceData, SingleRunTraceData newTraceData)
        {
            if (core.Options.ExecutionMode == ExecutionMode.Parallel)
                throw new NotImplementedException("Parallel mode disabled: {BF417AD5-9EA9-4292-ABBC-3526FC5A149E}");


            //Recursion base case
            if (replicationInstructions.Count == 0)
                return ExecWithZeroRI(functionEndPoint, c, formalParameters, stackFrame, core, funcGroup, previousTraceData, newTraceData);

            //Get the replication instruction that this call will deal with
            ReplicationInstruction ri = replicationInstructions[0];

            if (ri.Zipped)
            {
                ZipAlgorithm algorithm = ri.ZipAlgorithm;

                //For each item in this plane, an array of the length of the minimum will be constructed

                //The size of the array will be the minimum size of the passed arrays
                List<int> repIndecies = ri.ZipIndecies;

                //this will hold the heap elements for all the arrays that are going to be replicated over
                List<StackValue[]> parameters = new List<StackValue[]>();

                int retSize;
                switch (algorithm)
                {
                    case ZipAlgorithm.Shortest:
                        retSize = Int32.MaxValue; //Search to find the smallest
                        break;

                    case ZipAlgorithm.Longest:
                        retSize = Int32.MinValue; //Search to find the largest
                        break;

                    default:
                        throw new ReplicationCaseNotCurrentlySupported("Selected algorithm not supported");
                }

                foreach (int repIndex in repIndecies)
                {

                    StackValue[] subParameters = null;
                    if (formalParameters[repIndex].IsArray)
                    {
                        subParameters = ArrayUtils.GetValues(formalParameters[repIndex], core);
                    }
                    else
                    {
                        subParameters = new StackValue[] { formalParameters[repIndex] };
                    }
                    parameters.Add(subParameters);

                    switch (algorithm)
                    {
                        case ZipAlgorithm.Shortest:
                            retSize = Math.Min(retSize, subParameters.Length); //We need the smallest array
                            break;
                        case ZipAlgorithm.Longest:
                            retSize = Math.Max(retSize, subParameters.Length); //We need the longest array
                            break;
                    }

                }

                StackValue[] retSVs = new StackValue[retSize];
                SingleRunTraceData retTrace = newTraceData;
                retTrace.NestedData = new List<SingleRunTraceData>(); //this will shadow the SVs as they are created

                //Populate out the size of the list with default values
                //@TODO:Luke perf optimisation here
                for (int i = 0; i < retSize; i++)
                    retTrace.NestedData.Add(new SingleRunTraceData());


                for (int i = 0; i < retSize; i++)
                {
                    SingleRunTraceData lastExecTrace = new SingleRunTraceData();

                    if (previousTraceData.HasNestedData && i < previousTraceData.NestedData.Count)
                    {
                        //There was previous data that needs loading into the cache
                        lastExecTrace = previousTraceData.NestedData[i];
                    }
                    else
                    {
                        //We're off the edge of the previous trace window
                        //So just pass in an empty block
                        lastExecTrace = new SingleRunTraceData();
                    }


                    //Build the call
                    List<StackValue> newFormalParams = new List<StackValue>();
                    newFormalParams.AddRange(formalParameters);

                    for (int repIi = 0; repIi < repIndecies.Count; repIi++)
                    {
                        switch (algorithm)
                        {
                            case ZipAlgorithm.Shortest:
                                //If the shortest algorithm is selected this would
                                newFormalParams[repIndecies[repIi]] = parameters[repIi][i];
                                break;
                            
                            case ZipAlgorithm.Longest:

                                int length = parameters[repIi].Length;
                                if (i < length)
                                {
                                    newFormalParams[repIndecies[repIi]] = parameters[repIi][i];
                                }
                                else
                                {
                                    newFormalParams[repIndecies[repIi]] = parameters[repIi].Last();
                                }

                                break;
                        }


                        
                    }

                    List<ReplicationInstruction> newRIs = new List<ReplicationInstruction>();
                    newRIs.AddRange(replicationInstructions);
                    newRIs.RemoveAt(0);


                    SingleRunTraceData cleanRetTrace = new SingleRunTraceData();

                    retSVs[i] = ExecWithRISlowPath(functionEndPoint, c, newFormalParams, newRIs, stackFrame, core,
                                                    funcGroup, lastExecTrace, cleanRetTrace);



                    retTrace.NestedData[i] = cleanRetTrace;

                }

                StackValue ret = HeapUtils.StoreArray(retSVs, null, core);
                GCUtils.GCRetain(ret, core);
                return ret;
            }
            else
            {
                //With a cartesian product over an array, we are going to create an array of n
                //where the n is the product of the next item

                //We will call the subsequent reductions n times

                int cartIndex = ri.CartesianIndex;

                //this will hold the heap elements for all the arrays that are going to be replicated over


                bool supressArray = false;
                int retSize;
                StackValue[] parameters = null; 
                
                if (formalParameters[cartIndex].IsArray)
                {
                    parameters = ArrayUtils.GetValues(formalParameters[cartIndex], core);
                    retSize = parameters.Length;
                }
                else
                {
                    retSize = 1;
                    supressArray = true;
                }


                StackValue[] retSVs = new StackValue[retSize];

                SingleRunTraceData retTrace = newTraceData;
                retTrace.NestedData = new List<SingleRunTraceData>(); //this will shadow the SVs as they are created

                //Populate out the size of the list with default values
                //@TODO:Luke perf optimisation here
                for (int i = 0; i < retSize; i++)
                {
                    retTrace.NestedData.Add(new SingleRunTraceData());
                }

 
                if (supressArray)
                {

                    List<ReplicationInstruction> newRIs = new List<ReplicationInstruction>();
                    newRIs.AddRange(replicationInstructions);
                    newRIs.RemoveAt(0);

                    List<StackValue> newFormalParams = new List<StackValue>();
                    newFormalParams.AddRange(formalParameters);

                    return ExecWithRISlowPath(functionEndPoint, c, newFormalParams, newRIs, stackFrame, core,
                                                funcGroup, previousTraceData, newTraceData);
                }


                    

                //Now iterate over each of these options
                for (int i = 0; i < retSize; i++)
                {
#if __PROTOTYPE_ARRAYUPDATE_FUNCTIONCALL

                    // Comment Jun: If the array pointer passed in was of type DS Null, 
                    // then it means this is the first time the results are being computed.
                    bool executeAll = c.ArrayPointer.IsNull;

                    if (executeAll || ProtoCore.AssociativeEngine.ArrayUpdate.IsIndexInElementUpdateList(i, c.IndicesIntoArgMap))
                    {
                        List<List<int>> prevIndexIntoList = new List<List<int>>();

                        foreach (List<int> dimList in c.IndicesIntoArgMap)
                        {
                            prevIndexIntoList.Add(new List<int>(dimList));
                        }


                        StackValue svPrevPtr = c.ArrayPointer;
                        if (!executeAll)
                        {
                            c.IndicesIntoArgMap = ProtoCore.AssociativeEngine.ArrayUpdate.UpdateIndexIntoList(i, c.IndicesIntoArgMap);
                            c.ArrayPointer = ProtoCore.Utils.ArrayUtils.GetArrayElementAt(c.ArrayPointer, i, core);
                        }

                        //Build the call
                        List<StackValue> newFormalParams = new List<StackValue>();
                        newFormalParams.AddRange(formalParameters);

                        if (he != null)
                        {
                            //It was an array pack the arg with the current value
                            newFormalParams[cartIndex] = he.Stack[i];
                        }

                        List<ReplicationInstruction> newRIs = new List<ReplicationInstruction>();
                        newRIs.AddRange(replicationInstructions);
                        newRIs.RemoveAt(0);

                        retSVs[i] = ExecWithRISlowPath(functionEndPoint, c, newFormalParams, newRIs, stackFrame, core, funcGroup);

                        // Restore the context properties for arrays
                        c.IndicesIntoArgMap = new List<List<int>>(prevIndexIntoList);
                        c.ArrayPointer = svPrevPtr;
                    }
                    else
                    {
                        retSVs[i] = ProtoCore.Utils.ArrayUtils.GetArrayElementAt(c.ArrayPointer, i, core);
                    }
#else
                    //Build the call
                    List<StackValue> newFormalParams = new List<StackValue>();
                    newFormalParams.AddRange(formalParameters);

                    if (parameters != null)
                    {
                        //It was an array pack the arg with the current value
                        newFormalParams[cartIndex] = parameters[i];
                    }

                    List<ReplicationInstruction> newRIs = new List<ReplicationInstruction>();
                    newRIs.AddRange(replicationInstructions);
                    newRIs.RemoveAt(0);


                    SingleRunTraceData lastExecTrace;

                    if (previousTraceData.HasNestedData && i < previousTraceData.NestedData.Count)
                    {
                        //There was previous data that needs loading into the cache
                        lastExecTrace = previousTraceData.NestedData[i];
                    }
                    else if (previousTraceData.HasData && i == 0)
                    {
                        //We've moved up one dimension, and there was a previous run
                        lastExecTrace = new SingleRunTraceData();
                        lastExecTrace.Data = previousTraceData.GetLeftMostData();

                    }

                    else
                    {
                        //We're off the edge of the previous trace window
                        //So just pass in an empty block
                        lastExecTrace = new SingleRunTraceData();
                    }


                    //previousTraceData = lastExecTrace;
                    SingleRunTraceData cleanRetTrace = new SingleRunTraceData();

                    retSVs[i] = ExecWithRISlowPath(functionEndPoint, c, newFormalParams, newRIs, stackFrame, core,
                                                    funcGroup, lastExecTrace, cleanRetTrace);



                    retTrace.NestedData[i] = cleanRetTrace;

//                        retSVs[i] = ExecWithRISlowPath(functionEndPoint, c, newFormalParams, newRIs, stackFrame, core,
//                                                        funcGroup, previousTraceData, newTraceData);
#endif
                }

                StackValue ret = HeapUtils.StoreArray(retSVs, null, core);
                GCUtils.GCRetain(ret, core);
                return ret;

            }
        }
Esempio n. 6
0
        private StackValue Execute(List<FunctionEndPoint> functionEndPoint, ProtoCore.Runtime.Context c,
                                   List<StackValue> formalParameters,
                                   List<ReplicationInstruction> replicationInstructions, DSASM.StackFrame stackFrame,
                                   Core core, FunctionGroup funcGroup)
        {
            for (int i = 0; i < formalParameters.Count; ++i)
            {
                GCUtils.GCRetain(formalParameters[i], core);
            }

            StackValue ret;

            if (replicationInstructions.Count == 0)
            {
                c.IsReplicating = false;


                SingleRunTraceData singleRunTraceData;
                //READ TRACE FOR NON-REPLICATED CALL
                //Lookup the trace data in the cache
                if (invokeCount < traceData.Count)
                {
                    singleRunTraceData = (SingleRunTraceData) traceData[invokeCount];
                }
                else
                {
                    //We don't have any previous stored data for the previous invoke calls, so 
                    //gen an empty packet and push it through
                    singleRunTraceData = new SingleRunTraceData();
                }

                SingleRunTraceData newTraceData = new SingleRunTraceData();

                ret = ExecWithZeroRI(functionEndPoint, c, formalParameters, stackFrame, core, funcGroup,
                    singleRunTraceData, newTraceData);


                //newTraceData is update with the trace cache assocaite with the single shot executions
                
                if (invokeCount < traceData.Count)
                    traceData[invokeCount] = newTraceData;
                else
                {
                    traceData.Add(newTraceData);
                }
                
            }
            else //replicated call
            {
                //Extract the correct run data from the trace cache here

                //This is the thing that will get unpacked from the datastore

                SingleRunTraceData singleRunTraceData;
                SingleRunTraceData newTraceData = new SingleRunTraceData();

                //Lookup the trace data in the cache
                if (invokeCount < traceData.Count)
                {
                    singleRunTraceData = (SingleRunTraceData)traceData[invokeCount];
                }
                else
                {
                    //We don't have any previous stored data for the previous invoke calls, so 
                    //gen an empty packet and push it through
                    singleRunTraceData = new SingleRunTraceData();
                }


                c.IsReplicating = true;
                ret = ExecWithRISlowPath(functionEndPoint, c, formalParameters, replicationInstructions, stackFrame,
                                         core, funcGroup, singleRunTraceData, newTraceData);

                //Do a trace save here
                if (invokeCount < traceData.Count)
                    traceData[invokeCount] = newTraceData;
                else
                {
                    traceData.Add(newTraceData);
                }
            }

            // Explicit calls require the GC of arguments in the function return instruction
            if (!ret.IsExplicitCall)
            {
                for (int i = 0; i < formalParameters.Count; ++i)
                {
                    GCUtils.GCRelease(formalParameters[i], core);
                }
            }


            invokeCount++; //We've completed this invocation

            if (ret.IsNull)
                return ret; //It didn't return a value

            return ret;
        }
Esempio n. 7
0
        //Single function call
        /// <summary>
        /// Dispatch without replication
        /// </summary>
        private StackValue ExecWithZeroRI(List<FunctionEndPoint> functionEndPoint, ProtoCore.Runtime.Context c,
                                          List<StackValue> formalParameters, StackFrame stackFrame, Core core,
                                          FunctionGroup funcGroup, SingleRunTraceData previousTraceData, SingleRunTraceData newTraceData)
        {
            //@PERF: Todo add a fast path here for the case where we have a homogenious array so we can directly dispatch

            FunctionEndPoint finalFep = SelectFinalFep(c, functionEndPoint, formalParameters, stackFrame, core);

            if (functionEndPoint == null)
            {
                core.RuntimeStatus.LogWarning(ProtoCore.RuntimeData.WarningID.kMethodResolutionFailure,
                                              "Function dispatch could not be completed {2EB39E1B-557C-4819-94D8-CF7C9F933E8A}");
                return StackValue.Null;
            }

            if (core.Options.IDEDebugMode && core.ExecMode != ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
            {
                DebugFrame debugFrame = core.DebugProps.DebugStackFrame.Peek();
                debugFrame.FinalFepChosen = finalFep;
            }

            List<StackValue> coercedParameters = finalFep.CoerceParameters(formalParameters, core);

            // Correct block id where the function is defined.
            StackValue funcBlock = stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kFunctionBlock);
            funcBlock.opdata = finalFep.BlockScope;
            stackFrame.SetAt(DSASM.StackFrame.AbsoluteIndex.kFunctionBlock, funcBlock);

            //TraceCache -> TLS
            //Extract left most high-D pack
            Object traceD = previousTraceData.GetLeftMostData();

            if (traceD != null)
            {
                //There was data associated with the previous execution, push this into the TLS

                Dictionary<string, object> dataDict = new Dictionary<string, object>();
                dataDict.Add(TRACE_KEY, traceD);

                TraceUtils.SetObjectToTLS(dataDict);
            }
            else
            {
                //There was no trace data for this run
                TraceUtils.ClearAllKnownTLSKeys();
            }

            //EXECUTE
            StackValue ret = finalFep.Execute(c, coercedParameters, stackFrame, core);

            if (StackUtils.IsNull(ret))
            {

                //wipe the trace cache
                TraceUtils.ClearTLSKey(TRACE_KEY);
            }

            //TLS -> TraceCache
            Dictionary<String, Object> traceRet = TraceUtils.GetObjectFromTLS();

            if (traceRet.ContainsKey(TRACE_KEY))
            {
                Object val = traceRet[TRACE_KEY];
                newTraceData.Data = val;
            }

            // An explicit call requires return coercion at the return instruction
            if (ret.optype != AddressType.ExplicitCall)
            {
                ret = PerformReturnTypeCoerce(finalFep, core, ret);
            }
            return ret;
        }