Hi PyPys! 

Here's a patch that counts the number of times the different bytecodes are 
used. I haven't tried doing translation yet as I can't use the work 
machine cycles, but it can't be far off. I've put the counts on the object 
space as this is accessable from most places.

I've also implemented something that should resort the opcodes in the 
switch statement of the bytecode dispatcher according to the statistics I 
found. This may have a slight speed improvement.



Cheers,
Ben
Index: interpreter/opcodeorder.py
===================================================================
--- interpreter/opcodeorder.py  (revision 0)
+++ interpreter/opcodeorder.py  (revision 0)
@@ -0,0 +1 @@
+opcodeorder = [124, 125, 100, 105, 1, 131, 116, 111, 106, 83, 23, 93, 113, 25, 
95, 64, 112, 66, 102, 110, 60, 92, 62, 120, 68, 87, 32, 136, 4, 103, 24, 63, 
18, 65, 15, 55, 121, 3, 101, 22, 12, 80, 86, 135, 126, 90, 140, 104, 2, 33, 20, 
108, 107, 31, 134, 132, 88, 30, 133, 130, 137, 141, 61, 122, 11, 40, 74, 73, 
51, 96, 21, 42, 56, 85, 82, 89, 142, 77, 78, 79, 91, 76, 97, 57, 19, 43, 84, 
50, 41, 99, 53, 26]
\ No newline at end of file

Property changes on: interpreter/opcodeorder.py
___________________________________________________________________
Name: svn:executable
   + *

Index: interpreter/baseobjspace.py
===================================================================
--- interpreter/baseobjspace.py (revision 31092)
+++ interpreter/baseobjspace.py (working copy)
@@ -145,6 +145,10 @@
         self.config = config
         self.interned_strings = {}
         self.setoptions(**kw)
+
+        if self.config.logbytecodes:            
+            self.bytecodecounts = {}
+
         self.initialize()
 
     def setoptions(self):
@@ -428,7 +432,7 @@
         """
          If w_obj is a wrapped internal interpreter class instance unwrap to 
it,
          otherwise return None.  (Can be overridden in specific spaces; you
-        should generally use the helper space.interp_w() instead.)
+     should generally use the helper space.interp_w() instead.)
         """
         if isinstance(w_obj, Wrappable):
             return w_obj
@@ -436,19 +440,19 @@
 
     def interp_w(self, RequiredClass, w_obj, can_be_None=False):
         """
-        Unwrap w_obj, checking that it is an instance of the required internal
-        interpreter class (a subclass of Wrappable).
-       """
-       if can_be_None and self.is_w(w_obj, self.w_None):
-           return None
-       obj = self.interpclass_w(w_obj)
-       if not isinstance(obj, RequiredClass):   # or obj is None
-           msg = "'%s' object expected, got '%s' instead" % (
-               RequiredClass.typedef.name,
-               w_obj.getclass(self).getname(self, '?'))
-           raise OperationError(self.w_TypeError, self.wrap(msg))
-       return obj
-    interp_w._annspecialcase_ = 'specialize:arg(1)'
+        Unwrap w_obj, checking that it is an instance of the required internal
+        interpreter class (a subclass of Wrappable).
+        """
+        if can_be_None and self.is_w(w_obj, self.w_None):
+            return None
+        obj = self.interpclass_w(w_obj)
+        if not isinstance(obj, RequiredClass):   # or obj is None
+            msg = "'%s' object expected, got '%s' instead" % (
+                RequiredClass.typedef.name,
+            w_obj.getclass(self).getname(self, '?'))
+            raise OperationError(self.w_TypeError, self.wrap(msg))
+        return obj
+        interp_w._annspecialcase_ = 'specialize:arg(1)'
 
     def unpackiterable(self, w_iterable, expected_length=-1):
         """Unpack an iterable object into a real (interpreter-level) list.
Index: interpreter/pyopcode.py
===================================================================
--- interpreter/pyopcode.py     (revision 31092)
+++ interpreter/pyopcode.py     (working copy)
@@ -11,6 +11,7 @@
 from pypy.interpreter.miscutils import InitializedClass
 from pypy.interpreter.argument import Arguments, ArgumentsFromValuestack
 from pypy.interpreter.pycode import PyCode
+from pypy.interpreter.opcodeorder import opcodeorder
 from pypy.tool.sourcetools import func_with_new_name
 from pypy.rpython.objectmodel import we_are_translated
 from pypy.rpython.rarithmetic import intmask
@@ -57,6 +58,8 @@
             ec.bytecode_trace(self)
             self.next_instr = self.last_instr
             opcode = self.nextop()
+            if self.space.config.logbytecodes:
+                self.space.bytecodecounts[opcode] = 
self.space.bytecodecounts.get(opcode, 0) + 1
             if opcode >= pythonopcode.HAVE_ARGUMENT:
                 oparg = self.nextarg()
                 while True:
@@ -813,6 +816,8 @@
         ec.bytecode_trace(self)
         self.next_instr = self.last_instr
         opcode = ord(code[self.next_instr])
+        if self.space.config.logbytecodes:
+            self.space.bytecodecounts[opcode] = 
self.space.bytecodecounts.get(opcode, 0) + 1
         self.next_instr += 1
         if opcode >= %s:
             oparg = ord(code[self.next_instr]) | ord(code[self.next_instr + 
1]) << 8
@@ -828,8 +833,16 @@
 ''' % (pythonopcode.HAVE_ARGUMENT,
         pythonopcode.EXTENDED_ARG,
         pythonopcode.HAVE_ARGUMENT)
+
+        def sortkey(opcode, opcodeorder=opcodeorder, ValueError=ValueError):
+            try:
+                index = opcodeorder.index(opcode)
+            except ValueError:
+                index = 1000000
+            return index, opcode
         opcases = [(i, opname) for opname, i in pythonopcode.opmap.iteritems()]
-        opcases.sort()    # for predictable results
+        opcases.sort(key = sortkey)    # for predictable results
+
         for i, opname in opcases:
             if i == pythonopcode.EXTENDED_ARG or i < 
pythonopcode.HAVE_ARGUMENT:
                 continue
Index: config/pypyoption.py
===================================================================
--- config/pypyoption.py        (revision 31092)
+++ config/pypyoption.py        (working copy)
@@ -73,6 +73,10 @@
 
     ]),
 
+    BoolOption("logbytecodes",
+               "keep track of bytecode usage",
+               default=False),
+
     BoolOption("translating", "indicates whether we are translating currently",
                default=False),
 ])
Index: bin/py.py
===================================================================
--- bin/py.py   (revision 31092)
+++ bin/py.py   (working copy)
@@ -57,6 +57,7 @@
     mod = __import__('pypy.objspace.%s' % conf.objspace.name,
                      None, None, ['Space'])
     Space = mod.Space
+    #conf.logbytecodes = True
     space = Space(conf) 
     return space 
             
@@ -127,6 +128,13 @@
             space.finish()
         main.run_toplevel(space, doit, verbose=Options.verbose)
 
+        if space.config.logbytecodes:
+            import dis
+            counts = space.bytecodecounts.items()
+            counts.sort(key = (lambda x: (-x[1], x[0])))
+            print [(dis.opname[opcode], count) for opcode, count in counts]
+            print [opcode for opcode, count in counts]
+
     return exit_status
 
 ##def main_(argv=None):
_______________________________________________
[email protected]
http://codespeak.net/mailman/listinfo/pypy-dev

Reply via email to