From f83180a1eb9a04393ec278267846171fa6fcddfd Mon Sep 17 00:00:00 2001 From: "vitalyr@chromium.org" Date: Mon, 14 Dec 2009 16:13:52 +0000 Subject: [PATCH] Updated stats-viewer.py to work with chromium. Review URL: http://codereview.chromium.org/473002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3463 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- tools/stats-viewer.py | 81 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 76 insertions(+), 5 deletions(-) diff --git a/tools/stats-viewer.py b/tools/stats-viewer.py index bd6a8fb..220124f 100755 --- a/tools/stats-viewer.py +++ b/tools/stats-viewer.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python +# # Copyright 2008 the V8 project authors. All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are @@ -49,8 +51,9 @@ UPDATE_INTERVAL_MS = 100 COUNTER_LABELS = {"t": "%i ms.", "c": "%i"} -# The magic number used to check if a file is not a counters file +# The magic numbers used to check if a file is not a counters file COUNTERS_FILE_MAGIC_NUMBER = 0xDEADFACE +CHROME_COUNTERS_FILE_MAGIC_NUMBER = 0x13131313 class StatsViewer(object): @@ -99,10 +102,12 @@ class StatsViewer(object): fileno = data_file.fileno() self.shared_mmap = mmap.mmap(fileno, size, access=mmap.ACCESS_READ) data_access = SharedDataAccess(self.shared_mmap) - if data_access.IntAt(0) != COUNTERS_FILE_MAGIC_NUMBER: - print "File %s is not stats data." % self.data_name - sys.exit(1) - return CounterCollection(data_access) + if data_access.IntAt(0) == COUNTERS_FILE_MAGIC_NUMBER: + return CounterCollection(data_access) + elif data_access.IntAt(0) == CHROME_COUNTERS_FILE_MAGIC_NUMBER: + return ChromeCounterCollection(data_access) + print "File %s is not stats data." % self.data_name + sys.exit(1) def CleanUp(self): """Cleans up the memory mapped file if necessary.""" @@ -356,6 +361,72 @@ class CounterCollection(object): return 4 + self.max_name_size +class ChromeCounter(object): + """A pointer to a single counter withing a binary counters file.""" + + def __init__(self, data, name_offset, value_offset): + """Create a new instance. + + Args: + data: the shared data access object containing the counter + name_offset: the byte offset of the start of this counter's name + value_offset: the byte offset of the start of this counter's value + """ + self.data = data + self.name_offset = name_offset + self.value_offset = value_offset + + def Value(self): + """Return the integer value of this counter.""" + return self.data.IntAt(self.value_offset) + + def Name(self): + """Return the ascii name of this counter.""" + result = "" + index = self.name_offset + current = self.data.ByteAt(index) + while current: + result += chr(current) + index += 1 + current = self.data.ByteAt(index) + return result + + +class ChromeCounterCollection(object): + """An overlay over a counters file that provides access to the + individual counters contained in the file.""" + + _HEADER_SIZE = 4 * 4 + _NAME_SIZE = 32 + + def __init__(self, data): + """Create a new instance. + + Args: + data: the shared data access object + """ + self.data = data + self.max_counters = data.IntAt(8) + self.max_threads = data.IntAt(12) + self.counter_names_offset = \ + self._HEADER_SIZE + self.max_threads * (self._NAME_SIZE + 2 * 4) + self.counter_values_offset = \ + self.counter_names_offset + self.max_counters * self._NAME_SIZE + + def CountersInUse(self): + """Return the number of counters in active use.""" + for i in xrange(self.max_counters): + if self.data.ByteAt(self.counter_names_offset + i * self._NAME_SIZE) == 0: + return i + return self.max_counters + + def Counter(self, i): + """Return the i'th counter.""" + return ChromeCounter(self.data, + self.counter_names_offset + i * self._NAME_SIZE, + self.counter_values_offset + i * self.max_threads * 4) + + def Main(data_file): """Run the stats counter. -- 2.7.4