Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/tools/trace/model.py
4561 views
1
#!/usr/bin/env python3
2
##########################################################################
3
#
4
# Copyright 2008 VMware, Inc.
5
# All Rights Reserved.
6
#
7
# Permission is hereby granted, free of charge, to any person obtaining a
8
# copy of this software and associated documentation files (the
9
# "Software"), to deal in the Software without restriction, including
10
# without limitation the rights to use, copy, modify, merge, publish,
11
# distribute, sub license, and/or sell copies of the Software, and to
12
# permit persons to whom the Software is furnished to do so, subject to
13
# the following conditions:
14
#
15
# The above copyright notice and this permission notice (including the
16
# next paragraph) shall be included in all copies or substantial portions
17
# of the Software.
18
#
19
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22
# IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
23
# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
#
27
##########################################################################
28
29
30
'''Trace data model.'''
31
32
33
import sys
34
import string
35
import binascii
36
from io import StringIO
37
import format
38
39
40
class Node:
41
42
def visit(self, visitor):
43
raise NotImplementedError
44
45
def __str__(self):
46
stream = StringIO()
47
formatter = format.Formatter(stream)
48
pretty_printer = PrettyPrinter(formatter, {})
49
self.visit(pretty_printer)
50
return stream.getvalue()
51
52
53
class Literal(Node):
54
55
def __init__(self, value):
56
self.value = value
57
58
def visit(self, visitor):
59
visitor.visit_literal(self)
60
61
62
class Blob(Node):
63
64
def __init__(self, value):
65
self._rawValue = None
66
self._hexValue = value
67
68
def getValue(self):
69
if self._rawValue is None:
70
self._rawValue = binascii.a2b_hex(self._hexValue)
71
self._hexValue = None
72
return self._rawValue
73
74
def visit(self, visitor):
75
visitor.visit_blob(self)
76
77
78
class NamedConstant(Node):
79
80
def __init__(self, name):
81
self.name = name
82
83
def visit(self, visitor):
84
visitor.visit_named_constant(self)
85
86
87
class Array(Node):
88
89
def __init__(self, elements):
90
self.elements = elements
91
92
def visit(self, visitor):
93
visitor.visit_array(self)
94
95
96
class Struct(Node):
97
98
def __init__(self, name, members):
99
self.name = name
100
self.members = members
101
102
def visit(self, visitor):
103
visitor.visit_struct(self)
104
105
106
class Pointer(Node):
107
108
ptr_list = {}
109
ptr_type_list = {}
110
ptr_types_list = {}
111
ptr_ignore_list = ["ret", "elem"]
112
113
def __init__(self, address, pname):
114
self.address = address
115
116
# Check if address exists in list and if it is a return value address
117
t1 = address in self.ptr_list
118
if t1:
119
rname = self.ptr_type_list[address]
120
t2 = rname in self.ptr_ignore_list and pname not in self.ptr_ignore_list
121
else:
122
rname = pname
123
t2 = False
124
125
# If address does NOT exist (add it), OR IS a ret value (update with new type)
126
if not t1 or t2:
127
# If previously set to ret value, remove one from count
128
if t1 and t2:
129
self.adjust_ptr_type_count(rname, -1)
130
131
# Add / update
132
self.adjust_ptr_type_count(pname, 1)
133
tmp = "{}_{}".format(pname, self.ptr_types_list[pname])
134
self.ptr_list[address] = tmp
135
self.ptr_type_list[address] = pname
136
137
def adjust_ptr_type_count(self, pname, delta):
138
if pname not in self.ptr_types_list:
139
self.ptr_types_list[pname] = 0
140
141
self.ptr_types_list[pname] += delta
142
143
def visit(self, visitor):
144
visitor.visit_pointer(self)
145
146
147
class Call:
148
149
def __init__(self, no, klass, method, args, ret, time):
150
self.no = no
151
self.klass = klass
152
self.method = method
153
self.args = args
154
self.ret = ret
155
self.time = time
156
157
def visit(self, visitor):
158
visitor.visit_call(self)
159
160
161
class Trace:
162
163
def __init__(self, calls):
164
self.calls = calls
165
166
def visit(self, visitor):
167
visitor.visit_trace(self)
168
169
170
class Visitor:
171
172
def visit_literal(self, node):
173
raise NotImplementedError
174
175
def visit_blob(self, node):
176
raise NotImplementedError
177
178
def visit_named_constant(self, node):
179
raise NotImplementedError
180
181
def visit_array(self, node):
182
raise NotImplementedError
183
184
def visit_struct(self, node):
185
raise NotImplementedError
186
187
def visit_pointer(self, node):
188
raise NotImplementedError
189
190
def visit_call(self, node):
191
raise NotImplementedError
192
193
def visit_trace(self, node):
194
raise NotImplementedError
195
196
197
class PrettyPrinter:
198
199
def __init__(self, formatter, options):
200
self.formatter = formatter
201
self.options = options
202
203
def visit_literal(self, node):
204
if node.value is None:
205
self.formatter.literal('NULL')
206
return
207
208
if isinstance(node.value, str):
209
self.formatter.literal('"' + node.value + '"')
210
return
211
212
self.formatter.literal(repr(node.value))
213
214
def visit_blob(self, node):
215
self.formatter.address('blob()')
216
217
def visit_named_constant(self, node):
218
self.formatter.literal(node.name)
219
220
def visit_array(self, node):
221
self.formatter.text('{')
222
sep = ''
223
for value in node.elements:
224
self.formatter.text(sep)
225
value.visit(self)
226
sep = ', '
227
self.formatter.text('}')
228
229
def visit_struct(self, node):
230
self.formatter.text('{')
231
sep = ''
232
for name, value in node.members:
233
self.formatter.text(sep)
234
self.formatter.variable(name)
235
self.formatter.text(' = ')
236
value.visit(self)
237
sep = ', '
238
self.formatter.text('}')
239
240
def visit_pointer(self, node):
241
if "named_ptrs" in self.options and self.options.named_ptrs:
242
self.formatter.address(node.ptr_list[node.address])
243
else:
244
self.formatter.address(node.address)
245
246
def visit_call(self, node):
247
if not self.options.suppress_variants:
248
self.formatter.text('%s ' % node.no)
249
250
if node.klass is not None:
251
self.formatter.function(node.klass + '::' + node.method)
252
else:
253
self.formatter.function(node.method)
254
255
if not self.options.method_only:
256
self.formatter.text('(')
257
sep = ''
258
for name, value in node.args:
259
self.formatter.text(sep)
260
self.formatter.variable(name)
261
self.formatter.text(' = ')
262
value.visit(self)
263
sep = ', '
264
self.formatter.text(')')
265
if node.ret is not None:
266
self.formatter.text(' = ')
267
node.ret.visit(self)
268
269
if not self.options.suppress_variants and node.time is not None:
270
self.formatter.text(' // time ')
271
node.time.visit(self)
272
273
def visit_trace(self, node):
274
for call in node.calls:
275
call.visit(self)
276
self.formatter.newline()
277
278
279