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)
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)
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.__code__.co_firstlineno if hasattr(graph, 'source'): data += '\n%s' % graph.source.split('\n', 1)[0] else: continue self.links.setdefault(name, data)
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)
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)
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)
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)
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)
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
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