Path: blob/21.2-virgl/src/gallium/tools/trace/model.py
4561 views
#!/usr/bin/env python31##########################################################################2#3# Copyright 2008 VMware, Inc.4# All Rights Reserved.5#6# Permission is hereby granted, free of charge, to any person obtaining a7# copy of this software and associated documentation files (the8# "Software"), to deal in the Software without restriction, including9# without limitation the rights to use, copy, modify, merge, publish,10# distribute, sub license, and/or sell copies of the Software, and to11# permit persons to whom the Software is furnished to do so, subject to12# the following conditions:13#14# The above copyright notice and this permission notice (including the15# next paragraph) shall be included in all copies or substantial portions16# of the Software.17#18# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS19# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF20# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.21# IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR22# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,23# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE24# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.25#26##########################################################################272829'''Trace data model.'''303132import sys33import string34import binascii35from io import StringIO36import format373839class Node:4041def visit(self, visitor):42raise NotImplementedError4344def __str__(self):45stream = StringIO()46formatter = format.Formatter(stream)47pretty_printer = PrettyPrinter(formatter, {})48self.visit(pretty_printer)49return stream.getvalue()505152class Literal(Node):5354def __init__(self, value):55self.value = value5657def visit(self, visitor):58visitor.visit_literal(self)596061class Blob(Node):6263def __init__(self, value):64self._rawValue = None65self._hexValue = value6667def getValue(self):68if self._rawValue is None:69self._rawValue = binascii.a2b_hex(self._hexValue)70self._hexValue = None71return self._rawValue7273def visit(self, visitor):74visitor.visit_blob(self)757677class NamedConstant(Node):7879def __init__(self, name):80self.name = name8182def visit(self, visitor):83visitor.visit_named_constant(self)848586class Array(Node):8788def __init__(self, elements):89self.elements = elements9091def visit(self, visitor):92visitor.visit_array(self)939495class Struct(Node):9697def __init__(self, name, members):98self.name = name99self.members = members100101def visit(self, visitor):102visitor.visit_struct(self)103104105class Pointer(Node):106107ptr_list = {}108ptr_type_list = {}109ptr_types_list = {}110ptr_ignore_list = ["ret", "elem"]111112def __init__(self, address, pname):113self.address = address114115# Check if address exists in list and if it is a return value address116t1 = address in self.ptr_list117if t1:118rname = self.ptr_type_list[address]119t2 = rname in self.ptr_ignore_list and pname not in self.ptr_ignore_list120else:121rname = pname122t2 = False123124# If address does NOT exist (add it), OR IS a ret value (update with new type)125if not t1 or t2:126# If previously set to ret value, remove one from count127if t1 and t2:128self.adjust_ptr_type_count(rname, -1)129130# Add / update131self.adjust_ptr_type_count(pname, 1)132tmp = "{}_{}".format(pname, self.ptr_types_list[pname])133self.ptr_list[address] = tmp134self.ptr_type_list[address] = pname135136def adjust_ptr_type_count(self, pname, delta):137if pname not in self.ptr_types_list:138self.ptr_types_list[pname] = 0139140self.ptr_types_list[pname] += delta141142def visit(self, visitor):143visitor.visit_pointer(self)144145146class Call:147148def __init__(self, no, klass, method, args, ret, time):149self.no = no150self.klass = klass151self.method = method152self.args = args153self.ret = ret154self.time = time155156def visit(self, visitor):157visitor.visit_call(self)158159160class Trace:161162def __init__(self, calls):163self.calls = calls164165def visit(self, visitor):166visitor.visit_trace(self)167168169class Visitor:170171def visit_literal(self, node):172raise NotImplementedError173174def visit_blob(self, node):175raise NotImplementedError176177def visit_named_constant(self, node):178raise NotImplementedError179180def visit_array(self, node):181raise NotImplementedError182183def visit_struct(self, node):184raise NotImplementedError185186def visit_pointer(self, node):187raise NotImplementedError188189def visit_call(self, node):190raise NotImplementedError191192def visit_trace(self, node):193raise NotImplementedError194195196class PrettyPrinter:197198def __init__(self, formatter, options):199self.formatter = formatter200self.options = options201202def visit_literal(self, node):203if node.value is None:204self.formatter.literal('NULL')205return206207if isinstance(node.value, str):208self.formatter.literal('"' + node.value + '"')209return210211self.formatter.literal(repr(node.value))212213def visit_blob(self, node):214self.formatter.address('blob()')215216def visit_named_constant(self, node):217self.formatter.literal(node.name)218219def visit_array(self, node):220self.formatter.text('{')221sep = ''222for value in node.elements:223self.formatter.text(sep)224value.visit(self)225sep = ', '226self.formatter.text('}')227228def visit_struct(self, node):229self.formatter.text('{')230sep = ''231for name, value in node.members:232self.formatter.text(sep)233self.formatter.variable(name)234self.formatter.text(' = ')235value.visit(self)236sep = ', '237self.formatter.text('}')238239def visit_pointer(self, node):240if "named_ptrs" in self.options and self.options.named_ptrs:241self.formatter.address(node.ptr_list[node.address])242else:243self.formatter.address(node.address)244245def visit_call(self, node):246if not self.options.suppress_variants:247self.formatter.text('%s ' % node.no)248249if node.klass is not None:250self.formatter.function(node.klass + '::' + node.method)251else:252self.formatter.function(node.method)253254if not self.options.method_only:255self.formatter.text('(')256sep = ''257for name, value in node.args:258self.formatter.text(sep)259self.formatter.variable(name)260self.formatter.text(' = ')261value.visit(self)262sep = ', '263self.formatter.text(')')264if node.ret is not None:265self.formatter.text(' = ')266node.ret.visit(self)267268if not self.options.suppress_variants and node.time is not None:269self.formatter.text(' // time ')270node.time.visit(self)271272def visit_trace(self, node):273for call in node.calls:274call.visit(self)275self.formatter.newline()276277278279