private void addToTrace(ErrorTraceInstr inst, InstrLocation loc, ref ErrorTraceBlock curr, ErrorTrace trace)
        {
            if (curr == null)
            {
                curr = new ErrorTraceBlock(loc.blockName);
                Debug.Assert(loc.num == 0);
                curr.addInstr(inst);
                return;
            }

            // curr != null. We need to see if inst should be put inside curr or start a new block?

            if (loc.num == curr.Cmds.Count && loc.blockName == curr.blockName)
            {
                curr.addInstr(inst);
            }
            else
            {
                // start a new block
                Debug.Assert(loc.num == 0);
                trace.addBlock(curr);
                curr = new ErrorTraceBlock(loc.blockName);
                curr.addInstr(inst);
            }
        }
        // map back through an identity transformation (basically just recurse
        // on the callee traces)
        public static ErrorTraceBlock mapBackTraceIdentity(ErrorTraceBlock tblock, ModifyTrans tinfo)
        {
            var ret = new ErrorTraceBlock(tblock.blockName);

            ret.info = tblock.info;

            for (int i = 0; i < tblock.Cmds.Count; i++)
            {
                var tp = new InstrType();
                if (tblock.Cmds[i] is CallInstr)
                {
                    var ci = tblock.Cmds[i] as CallInstr;
                    if (ci.asyncCall)
                    {
                        tp = new InstrType(InstrTypeEnum.ASYNC, ci.callee);
                    }
                    else
                    {
                        tp = new InstrType(InstrTypeEnum.CALL, ci.callee);
                    }
                }

                var it = new InstrTrans(tp);
                ret.addInstr(it.mapBackTrace(tblock.Cmds, i, tinfo));
            }

            return(ret);
        }
示例#3
0
        public ErrorTrace mapBackTrace(ErrorTrace trace)
        {
            Debug.Assert(tinfo.ContainsKey(trace.procName));

            var ret  = new ErrorTrace(trace.procName);
            var info = tinfo[trace.procName];

            foreach (var blk in trace.Blocks)
            {
                var peices = info[blk.blockName];
                Debug.Assert(peices.Count != 0);

                // This is an index into blk.Cmds
                var cnt     = 0;
                var done    = false;
                var lastInf = blk.info;

                for (int i = 0; !done && i < peices.Count; i++)
                {
                    // Do we have enough in blk.Cmds for peices[i]?
                    if (cnt + peices[i].snd - 1 >= blk.Cmds.Count)
                    {
                        done = true;
                    }

                    var eblk = new ErrorTraceBlock(peices[i].fst);
                    eblk.info = lastInf;

                    int j = 0;
                    while (j < peices[i].snd && cnt < blk.Cmds.Count)
                    {
                        var inst = blk.Cmds[cnt];
                        lastInf = inst.info;
                        if (inst is CallInstr)
                        {
                            var cinst = inst as CallInstr;
                            if (cinst.hasCalledTrace)
                            {
                                inst = new CallInstr(cinst.callee, mapBackTrace(cinst.calleeTrace), cinst.asyncCall, cinst.info);
                                if (!(inst as CallInstr).calleeTrace.returns)
                                {
                                    done = true;
                                }
                            }
                        }

                        eblk.addInstr(inst);
                        cnt++;
                        j++;
                    }
                    ret.addBlock(eblk);
                }
            }
            if (trace.returns)
            {
                ret.addReturn();
            }
            return(ret);
        }
示例#4
0
        public ErrorTrace mapBackTraceRecord(ErrorTrace trace)
        {
            var ret = new ErrorTrace(trace.procName);

            foreach (var block in trace.Blocks)
            {
                var nb = new ErrorTraceBlock(block.blockName);
                foreach (var cmd in block.Cmds)
                {
                    if (cmd is CallInstr)
                    {
                        var ccmd = cmd as CallInstr;
                        if (ccmd.callee == recordProcNameInt || ccmd.callee == recordProcNameBool || ccmd.callee.StartsWith(recordProcNameCtor))
                        {
                            Debug.Assert(nb.Cmds.Count != 0);
                            nb.Cmds.Last().info = ccmd.info;
                            continue;
                        }

                        if (ccmd.hasCalledTrace)
                        {
                            var c = new CallInstr(mapBackTraceRecord(ccmd.calleeTrace), ccmd.asyncCall, ccmd.info);
                            nb.addInstr(c);
                        }
                        else
                        {
                            nb.addInstr(ccmd);
                        }
                    }
                    else
                    {
                        nb.addInstr(cmd.Copy());
                    }
                }
                ret.addBlock(nb);
            }

            if (trace.returns)
            {
                ret.addReturn(trace.raisesException);
            }

            return(ret);
        }
示例#5
0
        // map back "trace" through this transformation. tinfo is the parent
        // transformation info for the whole program -- it is used for recursively
        // calling the mapBack procedure on callee traces
        public ErrorTraceBlock mapBackTrace(ErrorTraceBlock tblock, ModifyTrans tinfo)
        {
            var ret = new ErrorTraceBlock(tblock.blockName);

            ret.info = tblock.info;

            // This is the number of instructions in tblock that we've processed
            int count = 0;
            // This is an index into trans
            int trans_index = 0;

            while (trans_index < trans.Count)
            {
                var it = trans[trans_index];

                // Does tblock have enough instructions for this transformation to apply?
                //if (count + it.Size <= tblock.Cmds.Count ||
                //    (it.correspondingInstr >= 0 && count + it.correspondingInstr <= tblock.Cmds.Count )
                //    break;

                var inst = it.mapBackTrace(tblock.Cmds, count, tinfo);
                if (inst == null)
                {
                    break;
                }

                ret.addInstr(inst);

                // Are we done?
                if (inst is CallInstr && (inst as CallInstr).calleeTrace != null && (
                        !(inst as CallInstr).calleeTrace.returns || (
                            (inst as CallInstr).calleeTrace.raisesException && !(inst as CallInstr).asyncCall
                            )
                        ))
                {
                    break;
                }

                count += it.Size;
                trans_index++;
            }

            return(ret);
        }