示例#1
0
    def compute(self, translator, *args, **kwds):
        self.translator = translator
        self.object_by_name = {}
        self.name_by_object = {}
        dotgen = DotGen(self.graph_name(*args))
        dotgen.emit('mclimit=15.0')

        self.do_compute(dotgen, *args, **kwds)

        self.source = dotgen.generate(target=None)

        # link the function names to the individual flow graphs
        for name, obj in self.object_by_name.items():
            if isinstance(obj, ClassDef):
                data = repr(obj)
            elif isinstance(obj, FunctionGraph):
                graph = obj
                data = graph.name
                if hasattr(graph, 'func'):
                    data += ':%d' % graph.func.func_code.co_firstlineno
                if hasattr(graph, 'source'):
                    data += '\n%s' % graph.source.split('\n', 1)[0]
            else:
                continue
            self.links.setdefault(name, data)
示例#2
0
 def compute(self, graphs, counts):
     dotgen = DotGen('trace')
     self.loops = graphs
     self.links = {}
     self.cache = {}
     for loop in self.loops:
         loop.generate(dotgen, counts)
         loop.getlinks(self.links)
         self.cache["loop" + str(loop.no)] = loop
     self.source = dotgen.generate(target=None)
示例#3
0
    def compute(self, translator, cdef):
        self.translator = translator
        dotgen = DotGen(cdef.shortname, rankdir="LR")

        def writecdef(cdef):
            lines = [cdef.name, '']
            attrs = cdef.attrs.items()
            attrs.sort()

            def writeadefs(prefix, classattrs):
                for name, attrdef in attrs:
                    if bool(attrdef.readonly) == bool(classattrs):
                        s_value = attrdef.s_value
                        linkname = name
                        info = s_value
                        if (classattrs and isinstance(s_value, SomePBC)
                            and s_value.getKind() == MethodDesc):
                            name += '()'
                            info = 'SomePBC(%s)' % ', '.join(
                                ['method %s.%s' % (
                                  desc.originclassdef.shortname,
                                  desc.name) for desc in s_value.descriptions],)
                        lines.append(name)
                        self.links[linkname] = '%s.%s: %s' % (prefix, name, info)

            prefix = cdef.shortname
            writeadefs(prefix + '()', False)
            lines.append('')
            writeadefs(prefix, True)
            dotgen.emit_node(nameof(cdef), color="red", shape="box",
                             label='\n'.join(lines))

        prevcdef = None
        while cdef is not None:
            writecdef(cdef)
            if prevcdef:
                dotgen.emit_edge(nameof(cdef), nameof(prevcdef), color="red")
            prevcdef = cdef
            cdef = cdef.basedef

        self.source = dotgen.generate(target=None)
示例#4
0
    def compute(self, translator, cdef):
        self.translator = translator
        dotgen = DotGen(cdef.shortname, rankdir="LR")

        def writecdef(cdef):
            lines = [cdef.name, '']
            attrs = cdef.attrs.items()
            attrs.sort()

            def writeadefs(prefix, classattrs):
                for name, attrdef in attrs:
                    if bool(attrdef.readonly) == bool(classattrs):
                        s_value = attrdef.s_value
                        linkname = name
                        info = s_value
                        if (classattrs and isinstance(s_value, SomePBC)
                            and s_value.getKind() == MethodDesc):
                            name += '()'
                            info = 'SomePBC(%s)' % ', '.join(
                                ['method %s.%s' % (
                                  desc.originclassdef.shortname,
                                  desc.name) for desc in s_value.descriptions],)
                        lines.append(name)
                        self.links[linkname] = '%s.%s: %s' % (prefix, name, info)

            prefix = cdef.shortname
            writeadefs(prefix + '()', False)
            lines.append('')
            writeadefs(prefix, True)
            dotgen.emit_node(nameof(cdef), color="red", shape="box",
                             label='\n'.join(lines))

        prevcdef = None
        while cdef is not None:
            writecdef(cdef)
            if prevcdef:
                dotgen.emit_edge(nameof(cdef), nameof(prevcdef), color="red")
            prevcdef = cdef
            cdef = cdef.basedef

        self.source = dotgen.generate(target=None)
示例#5
0
 def getsource(self):
     self.find_starters()
     self.pendingedges = []
     self.dotgen = DotGen('resop')
     self.dotgen.emit('clusterrank="local"')
     self.generrmsg()
     for i, graph in enumerate(self.graphs):
         self.gengraph(graph, i)
     # we generate the edges at the end of the file; otherwise, and edge
     # could mention a node before it's declared, and this can cause the
     # node declaration to occur too early -- in the wrong subgraph.
     for frm, to, kwds in self.pendingedges:
         self.dotgen.emit_edge(frm, to, **kwds)
     return self.dotgen.generate(target=None)
示例#6
0
 def compute(self, graph):
     self.links = {}
     dotgen = DotGen(str(graph.no))
     # split over debug_merge_points
     counter = 0
     lines = graph.content.split("\n")
     lines_so_far = []
     for line in lines:
         line = re.sub('.\[.*\]', '', line)
         boxes = re.findall('([pif]\d+)', line)
         for box in boxes:
             self.links[box] = box
         if 'debug_merge_point' in line:
             dotgen.emit_node('node%d' % counter, shape="box",
                              label="\n".join(lines_so_far))
             if counter != 0:
                 dotgen.emit_edge('node%d' % (counter - 1), 'node%d' % counter)
             counter += 1
             lines_so_far = []
         lines_so_far.append(line)
     dotgen.emit_node('node%d' % counter, shape="box",
                      label="\n".join(lines_so_far))
     dotgen.emit_edge('node%d' % (counter - 1), 'node%d' % counter)
     self.source = dotgen.generate(target=None)
示例#7
0
    def compute(self, translator, name, info, caused_by, history, func_names):
        self.linkinfo = {}
        self.translator = translator
        self.func_names = func_names
        dotgen = DotGen('binding')
        label = "Most recent binding of %s\\n\\n%s" % (name, nottoowide(info))
        if info.origin is not None:
            label += "\\n" + self.createlink(info.origin, 'Originated at')
        if caused_by is not None:
            label += '\\n' + self.createlink(caused_by)

        dotgen.emit_node('0', shape="box", color="red", label=label)
        for n, (data, caused_by) in zip(range(len(history)), history):
            label = nottoowide(data)
            if data.origin is not None:
                label += "\\n" + self.createlink(data.origin, 'Originated at')
            if caused_by is not None:
                label += '\\n' + self.createlink(caused_by)
            dotgen.emit_node(str(n + 1), shape="box", label=label)
            dotgen.emit_edge(str(n + 1), str(n))
        self.source = dotgen.generate(target=None)
示例#8
0
    def compute(self, translator, name, info, caused_by, history, func_names):
        self.linkinfo = {}
        self.translator = translator
        self.func_names = func_names
        dotgen = DotGen('binding')
        label = "Most recent binding of %s\\n\\n%s" % (name, nottoowide(info))
        if info.origin is not None:
            label += "\\n" + self.createlink(info.origin, 'Originated at')
        if caused_by is not None:
            label += '\\n' + self.createlink(caused_by)

        dotgen.emit_node('0', shape="box", color="red", label=label)
        for n, (data, caused_by) in zip(range(len(history)), history):
            label = nottoowide(data)
            if data.origin is not None:
                label += "\\n" + self.createlink(data.origin, 'Originated at')
            if caused_by is not None:
                label += '\\n' + self.createlink(caused_by)
            dotgen.emit_node(str(n+1), shape="box", label=label)
            dotgen.emit_edge(str(n+1), str(n))
        self.source = dotgen.generate(target=None)
示例#9
0
class ResOpGen(object):
    CLUSTERING = True
    BOX_COLOR = (128, 0, 96)

    def __init__(self, metainterp_sd=None):
        self.graphs = []
        self.highlight_graphs = {}
        self.block_starters = {}    # {graphindex: {set-of-operation-indices}}
        self.all_operations = {}
        self.errmsg = None
        self.target_tokens = {}
        self.metainterp_sd = metainterp_sd
        self.memo = {}

    def op_name(self, graphindex, opindex):
        return 'g%dop%d' % (graphindex, opindex)

    def mark_starter(self, graphindex, opindex):
        self.block_starters[graphindex][opindex] = True

    def add_graph(self, graph, highlight=False):
        graphindex = len(self.graphs)
        self.graphs.append(graph)
        self.highlight_graphs[graph] = highlight
        for i, op in enumerate(graph.get_operations()):
            self.all_operations[op] = graphindex, i

    def find_starters(self):
        for graphindex in range(len(self.graphs)):
            self.block_starters[graphindex] = {0: True}
        for graphindex, graph in enumerate(self.graphs):
            mergepointblock = None
            for i, op in enumerate(graph.get_operations()):
                if is_interesting_guard(op):
                    self.mark_starter(graphindex, i+1)
                if op.getopnum() == rop.DEBUG_MERGE_POINT:
                    if mergepointblock is None:
                        mergepointblock = i
                elif op.getopnum() == rop.LABEL:
                    self.mark_starter(graphindex, i)
                    self.target_tokens[getdescr(op)] = (graphindex, i)
                    mergepointblock = i
                else:
                    if mergepointblock is not None:
                        self.mark_starter(graphindex, mergepointblock)
                        mergepointblock = None

    def set_errmsg(self, errmsg):
        self.errmsg = errmsg

    def getsource(self):
        self.find_starters()
        self.pendingedges = []
        self.dotgen = DotGen('resop')
        self.dotgen.emit('clusterrank="local"')
        self.generrmsg()
        for i, graph in enumerate(self.graphs):
            self.gengraph(graph, i)
        # we generate the edges at the end of the file; otherwise, and edge
        # could mention a node before it's declared, and this can cause the
        # node declaration to occur too early -- in the wrong subgraph.
        for frm, to, kwds in self.pendingedges:
            self.dotgen.emit_edge(frm, to, **kwds)
        return self.dotgen.generate(target=None)

    def generrmsg(self):
        if self.errmsg:
            self.dotgen.emit_node('errmsg', label=self.errmsg,
                                  shape="box", fillcolor="red")
            if self.graphs and self.block_starters[0]:
                opindex = max(self.block_starters[0])
                blockname = self.op_name(0, opindex)
                self.pendingedges.append((blockname, 'errmsg', {}))

    def getgraphname(self, graphindex):
        return 'graph%d' % graphindex

    def gengraph(self, graph, graphindex):
        graphname = self.getgraphname(graphindex)
        if self.CLUSTERING:
            self.dotgen.emit('subgraph cluster%d {' % graphindex)
        label = graph.get_display_text(self.memo)
        if label is not None:
            colorindex = self.highlight_graphs.get(graph, 0)
            if colorindex == 1:
                fillcolor = '#f084c2'    # highlighted graph
            elif colorindex == 2:
                fillcolor = '#808080'    # invalidated graph
            else:
                fillcolor = '#84f0c2'    # normal color
            self.dotgen.emit_node(graphname, shape="octagon",
                                  label=label, fillcolor=fillcolor)
            self.pendingedges.append((graphname,
                                      self.op_name(graphindex, 0),
                                      {}))
        operations = graph.get_operations()
        for opindex in self.block_starters[graphindex]:
            self.genblock(operations, graphindex, opindex)
        if self.CLUSTERING:
            self.dotgen.emit('}')   # closes the subgraph

    def genedge(self, frm, to, **kwds):
        self.pendingedges.append((self.op_name(*frm),
                                  self.op_name(*to),
                                  kwds))

    def genblock(self, operations, graphindex, opstartindex):
        if opstartindex >= len(operations):
            return
        blockname = self.op_name(graphindex, opstartindex)
        block_starters = self.block_starters[graphindex]
        lines = []
        opindex = opstartindex
        while True:
            op = operations[opindex]
            op_repr = op.repr(self.memo, graytext=True)
            if op.getopnum() == rop.DEBUG_MERGE_POINT:
                jd_sd = self.metainterp_sd.jitdrivers_sd[op.getarg(0).getint()]
                if jd_sd._get_printable_location_ptr:
                    s = jd_sd.warmstate.get_location_str(op.getarglist()[3:])
                    s = s.replace(',', '.') # we use comma for argument splitting
                    op_repr = "debug_merge_point(%d, %d, '%s')" % (op.getarg(1).getint(), op.getarg(2).getint(), s)
            lines.append(op_repr)
            if is_interesting_guard(op):
                tgt = op.getdescr()._debug_suboperations[0]
                tgt_g, tgt_i = self.all_operations[tgt]
                self.genedge((graphindex, opstartindex),
                             (tgt_g, tgt_i),
                             color='red')
            opindex += 1
            if opindex >= len(operations):
                break
            if opindex in block_starters:
                self.genedge((graphindex, opstartindex),
                             (graphindex, opindex))
                break
        if op.getopnum() == rop.JUMP:
            tgt_descr = getdescr(op)
            if tgt_descr is not None and tgt_descr in self.target_tokens:
                self.genedge((graphindex, opstartindex),
                             self.target_tokens[tgt_descr],
                             weight="0")
        lines.append("")
        label = "\\l".join(lines)
        kwds = {}
        #if op in self.highlightops:
        #    kwds['color'] = 'red'
        #    kwds['fillcolor'] = '#ffe8e8'
        self.dotgen.emit_node(blockname, shape="box", label=label, **kwds)

    def getlinks(self):
        boxes = {}
        for op in self.all_operations:
            args = op.getarglist() + [op]
            for box in args:
                s = box.repr_short(self.memo)
                if len(s) > 1 and s[0] in 'irf' and s[1:].isdigit():
                    boxes[box] = s
        links = {}
        for box, s in boxes.items():
            links.setdefault(s, (box.repr(self.memo), self.BOX_COLOR))
        return links
示例#10
0
 def compute(self, graph):
     self.links = {}
     dotgen = DotGen(str(graph.no))
     # split over debug_merge_points
     counter = 0
     lines = graph.content.split("\n")
     lines_so_far = []
     for line in lines:
         line = re.sub('.\[.*\]', '', line)
         boxes = re.findall('([pif]\d+)', line)
         for box in boxes:
             self.links[box] = box
         if 'debug_merge_point' in line:
             dotgen.emit_node('node%d' % counter,
                              shape="box",
                              label="\n".join(lines_so_far))
             if counter != 0:
                 dotgen.emit_edge('node%d' % (counter - 1),
                                  'node%d' % counter)
             counter += 1
             lines_so_far = []
         lines_so_far.append(line)
     dotgen.emit_node('node%d' % counter,
                      shape="box",
                      label="\n".join(lines_so_far))
     dotgen.emit_edge('node%d' % (counter - 1), 'node%d' % counter)
     self.source = dotgen.generate(target=None)
示例#11
0
class ResOpGen(object):
    CLUSTERING = True
    BOX_COLOR = (128, 0, 96)

    def __init__(self, metainterp_sd=None):
        self.graphs = []
        self.highlight_graphs = {}
        self.block_starters = {}  # {graphindex: {set-of-operation-indices}}
        self.all_operations = {}
        self.errmsg = None
        self.target_tokens = {}
        self.metainterp_sd = metainterp_sd

    def op_name(self, graphindex, opindex):
        return 'g%dop%d' % (graphindex, opindex)

    def mark_starter(self, graphindex, opindex):
        self.block_starters[graphindex][opindex] = True

    def add_graph(self, graph, highlight=False):
        graphindex = len(self.graphs)
        self.graphs.append(graph)
        self.highlight_graphs[graph] = highlight
        for i, op in enumerate(graph.get_operations()):
            self.all_operations[op] = graphindex, i

    def find_starters(self):
        for graphindex in range(len(self.graphs)):
            self.block_starters[graphindex] = {0: True}
        for graphindex, graph in enumerate(self.graphs):
            mergepointblock = None
            for i, op in enumerate(graph.get_operations()):
                if is_interesting_guard(op):
                    self.mark_starter(graphindex, i + 1)
                if op.getopnum() == rop.DEBUG_MERGE_POINT:
                    if mergepointblock is None:
                        mergepointblock = i
                elif op.getopnum() == rop.LABEL:
                    self.mark_starter(graphindex, i)
                    self.target_tokens[getdescr(op)] = (graphindex, i)
                    mergepointblock = i
                else:
                    if mergepointblock is not None:
                        self.mark_starter(graphindex, mergepointblock)
                        mergepointblock = None

    def set_errmsg(self, errmsg):
        self.errmsg = errmsg

    def getsource(self):
        self.find_starters()
        self.pendingedges = []
        self.dotgen = DotGen('resop')
        self.dotgen.emit('clusterrank="local"')
        self.generrmsg()
        _prev = Box._extended_display
        try:
            Box._extended_display = False
            for i, graph in enumerate(self.graphs):
                self.gengraph(graph, i)
        finally:
            Box._extended_display = _prev
        # we generate the edges at the end of the file; otherwise, and edge
        # could mention a node before it's declared, and this can cause the
        # node declaration to occur too early -- in the wrong subgraph.
        for frm, to, kwds in self.pendingedges:
            self.dotgen.emit_edge(frm, to, **kwds)
        return self.dotgen.generate(target=None)

    def generrmsg(self):
        if self.errmsg:
            self.dotgen.emit_node('errmsg',
                                  label=self.errmsg,
                                  shape="box",
                                  fillcolor="red")
            if self.graphs and self.block_starters[0]:
                opindex = max(self.block_starters[0])
                blockname = self.op_name(0, opindex)
                self.pendingedges.append((blockname, 'errmsg', {}))

    def getgraphname(self, graphindex):
        return 'graph%d' % graphindex

    def gengraph(self, graph, graphindex):
        graphname = self.getgraphname(graphindex)
        if self.CLUSTERING:
            self.dotgen.emit('subgraph cluster%d {' % graphindex)
        label = graph.get_display_text()
        if label is not None:
            colorindex = self.highlight_graphs.get(graph, 0)
            if colorindex == 1:
                fillcolor = '#f084c2'  # highlighted graph
            elif colorindex == 2:
                fillcolor = '#808080'  # invalidated graph
            else:
                fillcolor = '#84f0c2'  # normal color
            self.dotgen.emit_node(graphname,
                                  shape="octagon",
                                  label=label,
                                  fillcolor=fillcolor)
            self.pendingedges.append((graphname, self.op_name(graphindex,
                                                              0), {}))
        operations = graph.get_operations()
        for opindex in self.block_starters[graphindex]:
            self.genblock(operations, graphindex, opindex)
        if self.CLUSTERING:
            self.dotgen.emit('}')  # closes the subgraph

    def genedge(self, frm, to, **kwds):
        self.pendingedges.append((self.op_name(*frm), self.op_name(*to), kwds))

    def genblock(self, operations, graphindex, opstartindex):
        if opstartindex >= len(operations):
            return
        blockname = self.op_name(graphindex, opstartindex)
        block_starters = self.block_starters[graphindex]
        lines = []
        opindex = opstartindex
        while True:
            op = operations[opindex]
            op_repr = op.repr(graytext=True)
            if op.getopnum() == rop.DEBUG_MERGE_POINT:
                jd_sd = self.metainterp_sd.jitdrivers_sd[op.getarg(0).getint()]
                if jd_sd._get_printable_location_ptr:
                    s = jd_sd.warmstate.get_location_str(op.getarglist()[3:])
                    s = s.replace(',',
                                  '.')  # we use comma for argument splitting
                    op_repr = "debug_merge_point(%d, %d, '%s')" % (
                        op.getarg(1).getint(), op.getarg(2).getint(), s)
            lines.append(op_repr)
            if is_interesting_guard(op):
                tgt = op.getdescr()._debug_suboperations[0]
                tgt_g, tgt_i = self.all_operations[tgt]
                self.genedge((graphindex, opstartindex), (tgt_g, tgt_i),
                             color='red')
            opindex += 1
            if opindex >= len(operations):
                break
            if opindex in block_starters:
                self.genedge((graphindex, opstartindex), (graphindex, opindex))
                break
        if op.getopnum() == rop.JUMP:
            tgt_descr = getdescr(op)
            if tgt_descr is not None and tgt_descr in self.target_tokens:
                self.genedge((graphindex, opstartindex),
                             self.target_tokens[tgt_descr],
                             weight="0")
        lines.append("")
        label = "\\l".join(lines)
        kwds = {}
        #if op in self.highlightops:
        #    kwds['color'] = 'red'
        #    kwds['fillcolor'] = '#ffe8e8'
        self.dotgen.emit_node(blockname, shape="box", label=label, **kwds)

    def getlinks(self):
        boxes = {}
        for op in self.all_operations:
            args = op.getarglist() + [op.result]
            for box in args:
                if getattr(box, 'is_box', False):
                    boxes[box] = True
        links = {}
        for box in boxes:
            links[str(box)] = repr(box), self.BOX_COLOR
        return links