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