xref: /aosp_15_r20/external/mesa3d/src/gallium/tools/trace/model.py (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*61046927SAndroid Build Coastguard Worker##########################################################################
3*61046927SAndroid Build Coastguard Worker#
4*61046927SAndroid Build Coastguard Worker# Copyright 2008 VMware, Inc.
5*61046927SAndroid Build Coastguard Worker# All Rights Reserved.
6*61046927SAndroid Build Coastguard Worker#
7*61046927SAndroid Build Coastguard Worker# Permission is hereby granted, free of charge, to any person obtaining a
8*61046927SAndroid Build Coastguard Worker# copy of this software and associated documentation files (the
9*61046927SAndroid Build Coastguard Worker# "Software"), to deal in the Software without restriction, including
10*61046927SAndroid Build Coastguard Worker# without limitation the rights to use, copy, modify, merge, publish,
11*61046927SAndroid Build Coastguard Worker# distribute, sub license, and/or sell copies of the Software, and to
12*61046927SAndroid Build Coastguard Worker# permit persons to whom the Software is furnished to do so, subject to
13*61046927SAndroid Build Coastguard Worker# the following conditions:
14*61046927SAndroid Build Coastguard Worker#
15*61046927SAndroid Build Coastguard Worker# The above copyright notice and this permission notice (including the
16*61046927SAndroid Build Coastguard Worker# next paragraph) shall be included in all copies or substantial portions
17*61046927SAndroid Build Coastguard Worker# of the Software.
18*61046927SAndroid Build Coastguard Worker#
19*61046927SAndroid Build Coastguard Worker# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20*61046927SAndroid Build Coastguard Worker# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21*61046927SAndroid Build Coastguard Worker# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22*61046927SAndroid Build Coastguard Worker# IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
23*61046927SAndroid Build Coastguard Worker# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24*61046927SAndroid Build Coastguard Worker# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25*61046927SAndroid Build Coastguard Worker# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26*61046927SAndroid Build Coastguard Worker#
27*61046927SAndroid Build Coastguard Worker##########################################################################
28*61046927SAndroid Build Coastguard Worker
29*61046927SAndroid Build Coastguard Worker
30*61046927SAndroid Build Coastguard Worker'''Trace data model.'''
31*61046927SAndroid Build Coastguard Worker
32*61046927SAndroid Build Coastguard Worker
33*61046927SAndroid Build Coastguard Workerimport sys
34*61046927SAndroid Build Coastguard Workerimport string
35*61046927SAndroid Build Coastguard Workerimport binascii
36*61046927SAndroid Build Coastguard Workerfrom io import StringIO
37*61046927SAndroid Build Coastguard Workerimport format
38*61046927SAndroid Build Coastguard Worker
39*61046927SAndroid Build Coastguard Worker
40*61046927SAndroid Build Coastguard Workerclass ModelOptions:
41*61046927SAndroid Build Coastguard Worker
42*61046927SAndroid Build Coastguard Worker    def __init__(self, args=None):
43*61046927SAndroid Build Coastguard Worker        # Initialize the options we need to exist,
44*61046927SAndroid Build Coastguard Worker        # with some reasonable defaults
45*61046927SAndroid Build Coastguard Worker        self.plain = False
46*61046927SAndroid Build Coastguard Worker        self.suppress_variants = False
47*61046927SAndroid Build Coastguard Worker        self.named_ptrs = False
48*61046927SAndroid Build Coastguard Worker        self.method_only = False
49*61046927SAndroid Build Coastguard Worker
50*61046927SAndroid Build Coastguard Worker        # If args is specified, we assume it is the result object
51*61046927SAndroid Build Coastguard Worker        # from ArgumentParser.parse_args(). Copy the attribute values
52*61046927SAndroid Build Coastguard Worker        # we have from it, if they exist.
53*61046927SAndroid Build Coastguard Worker        if args is not None:
54*61046927SAndroid Build Coastguard Worker            for var in self.__dict__:
55*61046927SAndroid Build Coastguard Worker                if var in args.__dict__:
56*61046927SAndroid Build Coastguard Worker                    self.__dict__[var] = args.__dict__[var]
57*61046927SAndroid Build Coastguard Worker
58*61046927SAndroid Build Coastguard Worker
59*61046927SAndroid Build Coastguard Workerclass TraceStateData:
60*61046927SAndroid Build Coastguard Worker
61*61046927SAndroid Build Coastguard Worker    def __init__(self):
62*61046927SAndroid Build Coastguard Worker        self.ptr_list = {}
63*61046927SAndroid Build Coastguard Worker        self.ptr_type_list = {}
64*61046927SAndroid Build Coastguard Worker        self.ptr_types_list = {}
65*61046927SAndroid Build Coastguard Worker
66*61046927SAndroid Build Coastguard Worker
67*61046927SAndroid Build Coastguard Workerclass Node:
68*61046927SAndroid Build Coastguard Worker
69*61046927SAndroid Build Coastguard Worker    def visit(self, visitor):
70*61046927SAndroid Build Coastguard Worker        raise NotImplementedError
71*61046927SAndroid Build Coastguard Worker
72*61046927SAndroid Build Coastguard Worker    def __str__(self):
73*61046927SAndroid Build Coastguard Worker        stream = StringIO()
74*61046927SAndroid Build Coastguard Worker        formatter = format.Formatter(stream)
75*61046927SAndroid Build Coastguard Worker        pretty_printer = PrettyPrinter(formatter, {})
76*61046927SAndroid Build Coastguard Worker        self.visit(pretty_printer)
77*61046927SAndroid Build Coastguard Worker        return stream.getvalue()
78*61046927SAndroid Build Coastguard Worker
79*61046927SAndroid Build Coastguard Worker    def __hash__(self):
80*61046927SAndroid Build Coastguard Worker        raise NotImplementedError
81*61046927SAndroid Build Coastguard Worker
82*61046927SAndroid Build Coastguard Worker
83*61046927SAndroid Build Coastguard Workerclass Literal(Node):
84*61046927SAndroid Build Coastguard Worker
85*61046927SAndroid Build Coastguard Worker    def __init__(self, value):
86*61046927SAndroid Build Coastguard Worker        self.value = value
87*61046927SAndroid Build Coastguard Worker
88*61046927SAndroid Build Coastguard Worker    def visit(self, visitor):
89*61046927SAndroid Build Coastguard Worker        visitor.visit_literal(self)
90*61046927SAndroid Build Coastguard Worker
91*61046927SAndroid Build Coastguard Worker    def __hash__(self):
92*61046927SAndroid Build Coastguard Worker        return hash(self.value)
93*61046927SAndroid Build Coastguard Worker
94*61046927SAndroid Build Coastguard Worker
95*61046927SAndroid Build Coastguard Workerclass Blob(Node):
96*61046927SAndroid Build Coastguard Worker
97*61046927SAndroid Build Coastguard Worker    def __init__(self, value):
98*61046927SAndroid Build Coastguard Worker        self.value = binascii.a2b_hex(value)
99*61046927SAndroid Build Coastguard Worker
100*61046927SAndroid Build Coastguard Worker    def getValue(self):
101*61046927SAndroid Build Coastguard Worker        return self.value
102*61046927SAndroid Build Coastguard Worker
103*61046927SAndroid Build Coastguard Worker    def visit(self, visitor):
104*61046927SAndroid Build Coastguard Worker        visitor.visit_blob(self)
105*61046927SAndroid Build Coastguard Worker
106*61046927SAndroid Build Coastguard Worker    def __hash__(self):
107*61046927SAndroid Build Coastguard Worker        return hash(self.value)
108*61046927SAndroid Build Coastguard Worker
109*61046927SAndroid Build Coastguard Worker
110*61046927SAndroid Build Coastguard Workerclass NamedConstant(Node):
111*61046927SAndroid Build Coastguard Worker
112*61046927SAndroid Build Coastguard Worker    def __init__(self, name):
113*61046927SAndroid Build Coastguard Worker        self.name = name
114*61046927SAndroid Build Coastguard Worker
115*61046927SAndroid Build Coastguard Worker    def visit(self, visitor):
116*61046927SAndroid Build Coastguard Worker        visitor.visit_named_constant(self)
117*61046927SAndroid Build Coastguard Worker
118*61046927SAndroid Build Coastguard Worker    def __hash__(self):
119*61046927SAndroid Build Coastguard Worker        return hash(self.name)
120*61046927SAndroid Build Coastguard Worker
121*61046927SAndroid Build Coastguard Worker
122*61046927SAndroid Build Coastguard Workerclass Array(Node):
123*61046927SAndroid Build Coastguard Worker
124*61046927SAndroid Build Coastguard Worker    def __init__(self, elements):
125*61046927SAndroid Build Coastguard Worker        self.elements = elements
126*61046927SAndroid Build Coastguard Worker
127*61046927SAndroid Build Coastguard Worker    def visit(self, visitor):
128*61046927SAndroid Build Coastguard Worker        visitor.visit_array(self)
129*61046927SAndroid Build Coastguard Worker
130*61046927SAndroid Build Coastguard Worker    def __hash__(self):
131*61046927SAndroid Build Coastguard Worker        tmp = 0
132*61046927SAndroid Build Coastguard Worker        for mobj in self.elements:
133*61046927SAndroid Build Coastguard Worker            tmp = tmp ^ hash(mobj)
134*61046927SAndroid Build Coastguard Worker        return tmp
135*61046927SAndroid Build Coastguard Worker
136*61046927SAndroid Build Coastguard Worker
137*61046927SAndroid Build Coastguard Workerclass Struct(Node):
138*61046927SAndroid Build Coastguard Worker
139*61046927SAndroid Build Coastguard Worker    def __init__(self, name, members):
140*61046927SAndroid Build Coastguard Worker        self.name = name
141*61046927SAndroid Build Coastguard Worker        self.members = members
142*61046927SAndroid Build Coastguard Worker
143*61046927SAndroid Build Coastguard Worker    def visit(self, visitor):
144*61046927SAndroid Build Coastguard Worker        visitor.visit_struct(self)
145*61046927SAndroid Build Coastguard Worker
146*61046927SAndroid Build Coastguard Worker    def __hash__(self):
147*61046927SAndroid Build Coastguard Worker        tmp = hash(self.name)
148*61046927SAndroid Build Coastguard Worker        for mname, mobj in self.members:
149*61046927SAndroid Build Coastguard Worker            tmp = tmp ^ hash(mname) ^ hash(mobj)
150*61046927SAndroid Build Coastguard Worker        return tmp
151*61046927SAndroid Build Coastguard Worker
152*61046927SAndroid Build Coastguard Worker
153*61046927SAndroid Build Coastguard Workerclass Pointer(Node):
154*61046927SAndroid Build Coastguard Worker
155*61046927SAndroid Build Coastguard Worker    ptr_ignore_list = ["ret", "elem"]
156*61046927SAndroid Build Coastguard Worker
157*61046927SAndroid Build Coastguard Worker    def __init__(self, state, address, pname):
158*61046927SAndroid Build Coastguard Worker        self.address = address
159*61046927SAndroid Build Coastguard Worker        self.state = state
160*61046927SAndroid Build Coastguard Worker
161*61046927SAndroid Build Coastguard Worker        # Check if address exists in list and if it is a return value address
162*61046927SAndroid Build Coastguard Worker        t1 = address in state.ptr_list
163*61046927SAndroid Build Coastguard Worker        if t1:
164*61046927SAndroid Build Coastguard Worker            rname = state.ptr_type_list[address]
165*61046927SAndroid Build Coastguard Worker            t2 = rname in self.ptr_ignore_list and pname not in self.ptr_ignore_list
166*61046927SAndroid Build Coastguard Worker        else:
167*61046927SAndroid Build Coastguard Worker            rname = pname
168*61046927SAndroid Build Coastguard Worker            t2 = False
169*61046927SAndroid Build Coastguard Worker
170*61046927SAndroid Build Coastguard Worker        # If address does NOT exist (add it), OR IS a ret value (update with new type)
171*61046927SAndroid Build Coastguard Worker        if not t1 or t2:
172*61046927SAndroid Build Coastguard Worker            # If previously set to ret value, remove one from count
173*61046927SAndroid Build Coastguard Worker            if t1 and t2:
174*61046927SAndroid Build Coastguard Worker                self.adjust_ptr_type_count(rname, -1)
175*61046927SAndroid Build Coastguard Worker
176*61046927SAndroid Build Coastguard Worker            # Add / update
177*61046927SAndroid Build Coastguard Worker            self.adjust_ptr_type_count(pname, 1)
178*61046927SAndroid Build Coastguard Worker            tmp = "{}_{}".format(pname, state.ptr_types_list[pname])
179*61046927SAndroid Build Coastguard Worker            state.ptr_list[address] = tmp
180*61046927SAndroid Build Coastguard Worker            state.ptr_type_list[address] = pname
181*61046927SAndroid Build Coastguard Worker
182*61046927SAndroid Build Coastguard Worker    def adjust_ptr_type_count(self, pname, delta):
183*61046927SAndroid Build Coastguard Worker        if pname not in self.state.ptr_types_list:
184*61046927SAndroid Build Coastguard Worker            self.state.ptr_types_list[pname] = 0
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker        self.state.ptr_types_list[pname] += delta
187*61046927SAndroid Build Coastguard Worker
188*61046927SAndroid Build Coastguard Worker    def named_address(self):
189*61046927SAndroid Build Coastguard Worker        return self.state.ptr_list[self.address]
190*61046927SAndroid Build Coastguard Worker
191*61046927SAndroid Build Coastguard Worker    def visit(self, visitor):
192*61046927SAndroid Build Coastguard Worker        visitor.visit_pointer(self)
193*61046927SAndroid Build Coastguard Worker
194*61046927SAndroid Build Coastguard Worker    def __hash__(self):
195*61046927SAndroid Build Coastguard Worker        return hash(self.named_address())
196*61046927SAndroid Build Coastguard Worker
197*61046927SAndroid Build Coastguard Worker
198*61046927SAndroid Build Coastguard Workerclass Call:
199*61046927SAndroid Build Coastguard Worker
200*61046927SAndroid Build Coastguard Worker    def __init__(self, no, klass, method, args, ret, time):
201*61046927SAndroid Build Coastguard Worker        self.no = no
202*61046927SAndroid Build Coastguard Worker        self.klass = klass
203*61046927SAndroid Build Coastguard Worker        self.method = method
204*61046927SAndroid Build Coastguard Worker        self.args = args
205*61046927SAndroid Build Coastguard Worker        self.ret = ret
206*61046927SAndroid Build Coastguard Worker        self.time = time
207*61046927SAndroid Build Coastguard Worker
208*61046927SAndroid Build Coastguard Worker        # Calculate hashvalue "cached" into a variable
209*61046927SAndroid Build Coastguard Worker        self.hashvalue = hash(self.klass) ^ hash(self.method)
210*61046927SAndroid Build Coastguard Worker        for mname, mobj in self.args:
211*61046927SAndroid Build Coastguard Worker            self.hashvalue = self.hashvalue ^ hash(mname) ^ hash(mobj)
212*61046927SAndroid Build Coastguard Worker
213*61046927SAndroid Build Coastguard Worker    def visit(self, visitor):
214*61046927SAndroid Build Coastguard Worker        visitor.visit_call(self)
215*61046927SAndroid Build Coastguard Worker
216*61046927SAndroid Build Coastguard Worker    def __hash__(self):
217*61046927SAndroid Build Coastguard Worker        return self.hashvalue
218*61046927SAndroid Build Coastguard Worker
219*61046927SAndroid Build Coastguard Worker    def __eq__(self, other):
220*61046927SAndroid Build Coastguard Worker        return self.hashvalue == other.hashvalue
221*61046927SAndroid Build Coastguard Worker
222*61046927SAndroid Build Coastguard Worker
223*61046927SAndroid Build Coastguard Workerclass Trace:
224*61046927SAndroid Build Coastguard Worker
225*61046927SAndroid Build Coastguard Worker    def __init__(self, calls):
226*61046927SAndroid Build Coastguard Worker        self.calls = calls
227*61046927SAndroid Build Coastguard Worker
228*61046927SAndroid Build Coastguard Worker    def visit(self, visitor):
229*61046927SAndroid Build Coastguard Worker        visitor.visit_trace(self)
230*61046927SAndroid Build Coastguard Worker
231*61046927SAndroid Build Coastguard Worker
232*61046927SAndroid Build Coastguard Workerclass Visitor:
233*61046927SAndroid Build Coastguard Worker
234*61046927SAndroid Build Coastguard Worker    def visit_literal(self, node):
235*61046927SAndroid Build Coastguard Worker        raise NotImplementedError
236*61046927SAndroid Build Coastguard Worker
237*61046927SAndroid Build Coastguard Worker    def visit_blob(self, node):
238*61046927SAndroid Build Coastguard Worker        raise NotImplementedError
239*61046927SAndroid Build Coastguard Worker
240*61046927SAndroid Build Coastguard Worker    def visit_named_constant(self, node):
241*61046927SAndroid Build Coastguard Worker        raise NotImplementedError
242*61046927SAndroid Build Coastguard Worker
243*61046927SAndroid Build Coastguard Worker    def visit_array(self, node):
244*61046927SAndroid Build Coastguard Worker        raise NotImplementedError
245*61046927SAndroid Build Coastguard Worker
246*61046927SAndroid Build Coastguard Worker    def visit_struct(self, node):
247*61046927SAndroid Build Coastguard Worker        raise NotImplementedError
248*61046927SAndroid Build Coastguard Worker
249*61046927SAndroid Build Coastguard Worker    def visit_pointer(self, node):
250*61046927SAndroid Build Coastguard Worker        raise NotImplementedError
251*61046927SAndroid Build Coastguard Worker
252*61046927SAndroid Build Coastguard Worker    def visit_call(self, node):
253*61046927SAndroid Build Coastguard Worker        raise NotImplementedError
254*61046927SAndroid Build Coastguard Worker
255*61046927SAndroid Build Coastguard Worker    def visit_trace(self, node):
256*61046927SAndroid Build Coastguard Worker        raise NotImplementedError
257*61046927SAndroid Build Coastguard Worker
258*61046927SAndroid Build Coastguard Worker
259*61046927SAndroid Build Coastguard Workerclass PrettyPrinter:
260*61046927SAndroid Build Coastguard Worker
261*61046927SAndroid Build Coastguard Worker    def __init__(self, formatter, options):
262*61046927SAndroid Build Coastguard Worker        self.formatter = formatter
263*61046927SAndroid Build Coastguard Worker        self.options = options
264*61046927SAndroid Build Coastguard Worker
265*61046927SAndroid Build Coastguard Worker    def visit_literal(self, node):
266*61046927SAndroid Build Coastguard Worker        if node.value is None:
267*61046927SAndroid Build Coastguard Worker            self.formatter.literal('NULL')
268*61046927SAndroid Build Coastguard Worker            return
269*61046927SAndroid Build Coastguard Worker
270*61046927SAndroid Build Coastguard Worker        if isinstance(node.value, str):
271*61046927SAndroid Build Coastguard Worker            self.formatter.literal('"' + node.value + '"')
272*61046927SAndroid Build Coastguard Worker            return
273*61046927SAndroid Build Coastguard Worker
274*61046927SAndroid Build Coastguard Worker        self.formatter.literal(repr(node.value))
275*61046927SAndroid Build Coastguard Worker
276*61046927SAndroid Build Coastguard Worker    def visit_blob(self, node):
277*61046927SAndroid Build Coastguard Worker        self.formatter.address('blob()')
278*61046927SAndroid Build Coastguard Worker
279*61046927SAndroid Build Coastguard Worker    def visit_named_constant(self, node):
280*61046927SAndroid Build Coastguard Worker        self.formatter.literal(node.name)
281*61046927SAndroid Build Coastguard Worker
282*61046927SAndroid Build Coastguard Worker    def visit_array(self, node):
283*61046927SAndroid Build Coastguard Worker        self.formatter.text('{')
284*61046927SAndroid Build Coastguard Worker        sep = ''
285*61046927SAndroid Build Coastguard Worker        for value in node.elements:
286*61046927SAndroid Build Coastguard Worker            self.formatter.text(sep)
287*61046927SAndroid Build Coastguard Worker            value.visit(self)
288*61046927SAndroid Build Coastguard Worker            sep = ', '
289*61046927SAndroid Build Coastguard Worker        self.formatter.text('}')
290*61046927SAndroid Build Coastguard Worker
291*61046927SAndroid Build Coastguard Worker    def visit_struct(self, node):
292*61046927SAndroid Build Coastguard Worker        self.formatter.text('{')
293*61046927SAndroid Build Coastguard Worker        sep = ''
294*61046927SAndroid Build Coastguard Worker        for name, value in node.members:
295*61046927SAndroid Build Coastguard Worker            self.formatter.text(sep)
296*61046927SAndroid Build Coastguard Worker            self.formatter.variable(name)
297*61046927SAndroid Build Coastguard Worker            self.formatter.text(' = ')
298*61046927SAndroid Build Coastguard Worker            value.visit(self)
299*61046927SAndroid Build Coastguard Worker            sep = ', '
300*61046927SAndroid Build Coastguard Worker        self.formatter.text('}')
301*61046927SAndroid Build Coastguard Worker
302*61046927SAndroid Build Coastguard Worker    def visit_pointer(self, node):
303*61046927SAndroid Build Coastguard Worker        if self.options.named_ptrs:
304*61046927SAndroid Build Coastguard Worker            self.formatter.address(node.named_address())
305*61046927SAndroid Build Coastguard Worker        else:
306*61046927SAndroid Build Coastguard Worker            self.formatter.address(node.address)
307*61046927SAndroid Build Coastguard Worker
308*61046927SAndroid Build Coastguard Worker    def visit_call(self, node):
309*61046927SAndroid Build Coastguard Worker        if not self.options.suppress_variants:
310*61046927SAndroid Build Coastguard Worker            self.formatter.text(f'{node.no} ')
311*61046927SAndroid Build Coastguard Worker
312*61046927SAndroid Build Coastguard Worker        if node.klass is not None:
313*61046927SAndroid Build Coastguard Worker            self.formatter.function(node.klass + '::' + node.method)
314*61046927SAndroid Build Coastguard Worker        else:
315*61046927SAndroid Build Coastguard Worker            self.formatter.function(node.method)
316*61046927SAndroid Build Coastguard Worker
317*61046927SAndroid Build Coastguard Worker        if not self.options.method_only:
318*61046927SAndroid Build Coastguard Worker            self.formatter.text('(')
319*61046927SAndroid Build Coastguard Worker            sep = ''
320*61046927SAndroid Build Coastguard Worker            for name, value in node.args:
321*61046927SAndroid Build Coastguard Worker                self.formatter.text(sep)
322*61046927SAndroid Build Coastguard Worker                self.formatter.variable(name)
323*61046927SAndroid Build Coastguard Worker                self.formatter.text(' = ')
324*61046927SAndroid Build Coastguard Worker                value.visit(self)
325*61046927SAndroid Build Coastguard Worker                sep = ', '
326*61046927SAndroid Build Coastguard Worker            self.formatter.text(')')
327*61046927SAndroid Build Coastguard Worker            if node.ret is not None:
328*61046927SAndroid Build Coastguard Worker                self.formatter.text(' = ')
329*61046927SAndroid Build Coastguard Worker                node.ret.visit(self)
330*61046927SAndroid Build Coastguard Worker
331*61046927SAndroid Build Coastguard Worker        if not self.options.suppress_variants and node.time is not None:
332*61046927SAndroid Build Coastguard Worker            self.formatter.text(' // time ')
333*61046927SAndroid Build Coastguard Worker            node.time.visit(self)
334*61046927SAndroid Build Coastguard Worker
335*61046927SAndroid Build Coastguard Worker        self.formatter.newline()
336*61046927SAndroid Build Coastguard Worker
337*61046927SAndroid Build Coastguard Worker    def visit_trace(self, node):
338*61046927SAndroid Build Coastguard Worker        for call in node.calls:
339*61046927SAndroid Build Coastguard Worker            call.visit(self)
340*61046927SAndroid Build Coastguard Worker
341