1579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata"""
2579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataObjective-C runtime wrapper for use by LLDB Python formatters
3579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata
4579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granatapart of The LLVM Compiler Infrastructure
5579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataThis file is distributed under the University of Illinois Open Source
6579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico GranataLicense. See LICENSE.TXT for details.
7579a296e7566b7b6d24b51e383bca1fe1e62086fEnrico Granata"""
8b370df27c76fd875f3312be487868528121a4838Enrico Granataimport lldb
96bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granataimport time, datetime
106bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granataimport inspect
116bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata
126bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granataclass TimeMetrics:
136bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata	@staticmethod
146bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata	def generate(label=None):
156bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata		return TimeMetrics(label)
166bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata
176bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata	def __init__(self,lbl=None):
186bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata		self.label = "" if lbl is None else lbl
196bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata		pass
206bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata
216bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata	def __enter__(self):
226bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata		caller = inspect.stack()[1]
236bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata		self.function = str(caller)
246bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata		self.enter_time = time.clock()
256bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata
266bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata	def __exit__(self, a,b,c):
276bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata		self.exit_time = time.clock()
286bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata		print "It took " + str(self.exit_time - self.enter_time) + " time units to run through " + self.function + self.label
296bf058b8054a1152bb227d37d6fe7c6b21a14dd3Enrico Granata		return False
30b370df27c76fd875f3312be487868528121a4838Enrico Granata
31b370df27c76fd875f3312be487868528121a4838Enrico Granataclass Counter:
32b370df27c76fd875f3312be487868528121a4838Enrico Granata	def __init__(self):
33b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.count = 0
34b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.list = []
35b370df27c76fd875f3312be487868528121a4838Enrico Granata	def update(self,name):
36b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.count = self.count + 1
37a58d9e75d6c3a2d02be931f1d549e68c91d10da6Enrico Granata		# avoid getting the full dump of this ValueObject just to save its metrics
38a58d9e75d6c3a2d02be931f1d549e68c91d10da6Enrico Granata		if isinstance(name,lldb.SBValue):
39a58d9e75d6c3a2d02be931f1d549e68c91d10da6Enrico Granata			self.list.append(name.GetName())
40a58d9e75d6c3a2d02be931f1d549e68c91d10da6Enrico Granata		else:
41a58d9e75d6c3a2d02be931f1d549e68c91d10da6Enrico Granata			self.list.append(str(name))
42b370df27c76fd875f3312be487868528121a4838Enrico Granata	def __str__(self):
43b370df27c76fd875f3312be487868528121a4838Enrico Granata		return str(self.count) + " times, for items [" + str(self.list) + "]"
44b370df27c76fd875f3312be487868528121a4838Enrico Granata
45b370df27c76fd875f3312be487868528121a4838Enrico Granataclass MetricsPrinter_Verbose:
46b370df27c76fd875f3312be487868528121a4838Enrico Granata	def __init__(self,metrics):
47b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.metrics = metrics
48b370df27c76fd875f3312be487868528121a4838Enrico Granata	def __str__(self):
49b370df27c76fd875f3312be487868528121a4838Enrico Granata		string = ""
50b370df27c76fd875f3312be487868528121a4838Enrico Granata		for key,value in self.metrics.metrics.items():
51b370df27c76fd875f3312be487868528121a4838Enrico Granata			string = string + "metric " + str(key) + ": " + str(value) + "\n"
52b370df27c76fd875f3312be487868528121a4838Enrico Granata		return string
53b370df27c76fd875f3312be487868528121a4838Enrico Granata
54b370df27c76fd875f3312be487868528121a4838Enrico Granataclass MetricsPrinter_Compact:
55b370df27c76fd875f3312be487868528121a4838Enrico Granata	def __init__(self,metrics):
56b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.metrics = metrics
57b370df27c76fd875f3312be487868528121a4838Enrico Granata	def __str__(self):
58b370df27c76fd875f3312be487868528121a4838Enrico Granata		string = ""
59b370df27c76fd875f3312be487868528121a4838Enrico Granata		for key,value in self.metrics.metrics.items():
60b370df27c76fd875f3312be487868528121a4838Enrico Granata			string = string + "metric " + str(key) + " was hit " + str(value.count) + " times\n"
61b370df27c76fd875f3312be487868528121a4838Enrico Granata		return string
62b370df27c76fd875f3312be487868528121a4838Enrico Granata
63b370df27c76fd875f3312be487868528121a4838Enrico Granataclass Metrics:
64b370df27c76fd875f3312be487868528121a4838Enrico Granata	def __init__(self):
65b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.metrics = {}
66b370df27c76fd875f3312be487868528121a4838Enrico Granata
67b370df27c76fd875f3312be487868528121a4838Enrico Granata	def add_metric(self,name):
68b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.metrics[name] = Counter()
69b370df27c76fd875f3312be487868528121a4838Enrico Granata
70b370df27c76fd875f3312be487868528121a4838Enrico Granata	def metric_hit(self,metric,trigger):
71b370df27c76fd875f3312be487868528121a4838Enrico Granata		self.metrics[metric].update(trigger)
72b370df27c76fd875f3312be487868528121a4838Enrico Granata
73b370df27c76fd875f3312be487868528121a4838Enrico Granata	def __getitem__(self,key):
74b370df27c76fd875f3312be487868528121a4838Enrico Granata		return self.metrics[key]
75b370df27c76fd875f3312be487868528121a4838Enrico Granata
76b370df27c76fd875f3312be487868528121a4838Enrico Granata	def __getattr__(self,name):
77b370df27c76fd875f3312be487868528121a4838Enrico Granata		if name == 'compact':
78b370df27c76fd875f3312be487868528121a4838Enrico Granata			return MetricsPrinter_Compact(self)
79b370df27c76fd875f3312be487868528121a4838Enrico Granata		if name == 'verbose':
80b370df27c76fd875f3312be487868528121a4838Enrico Granata			return MetricsPrinter_Verbose(self)
81b370df27c76fd875f3312be487868528121a4838Enrico Granata		raise AttributeError("%r object has no attribute %r" %
82b370df27c76fd875f3312be487868528121a4838Enrico Granata			                         (type(self).__name__, name))
83b370df27c76fd875f3312be487868528121a4838Enrico Granata
84b370df27c76fd875f3312be487868528121a4838Enrico Granata	def __str__(self):
85b370df27c76fd875f3312be487868528121a4838Enrico Granata		return str(self.verbose)
86b370df27c76fd875f3312be487868528121a4838Enrico Granata
87b370df27c76fd875f3312be487868528121a4838Enrico Granata	def metric_success(self,metric):
88b370df27c76fd875f3312be487868528121a4838Enrico Granata		total_count = 0
89b370df27c76fd875f3312be487868528121a4838Enrico Granata		metric_count = self[metric].count
90b370df27c76fd875f3312be487868528121a4838Enrico Granata		for key,value in self.metrics.items():
91b370df27c76fd875f3312be487868528121a4838Enrico Granata			total_count = total_count + value.count
92b370df27c76fd875f3312be487868528121a4838Enrico Granata		if total_count > 0:
93b370df27c76fd875f3312be487868528121a4838Enrico Granata			return metric_count / float(total_count)
94b370df27c76fd875f3312be487868528121a4838Enrico Granata		return 0
95