[pypy-svn] r48053 - pypy/dist/pypy/lang/smalltalk

cfbolz at codespeak.net cfbolz at codespeak.net
Fri Oct 26 14:27:09 CEST 2007


Author: cfbolz
Date: Fri Oct 26 14:27:09 2007
New Revision: 48053

Modified:
   pypy/dist/pypy/lang/smalltalk/interpreter.py
   pypy/dist/pypy/lang/smalltalk/squeakimage.py
Log:
turn the bytecode loop into a C switch (instead of a list lookup and an
indirect call). should help perfomance a bit.


Modified: pypy/dist/pypy/lang/smalltalk/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/interpreter.py	(original)
+++ pypy/dist/pypy/lang/smalltalk/interpreter.py	Fri Oct 26 14:27:09 2007
@@ -3,6 +3,7 @@
 from pypy.lang.smalltalk import objtable
 from pypy.lang.smalltalk.model import W_ContextPart
 from pypy.lang.smalltalk.conftest import option
+from pypy.rlib import objectmodel, unroll
 
 
 class MissingBytecode(NotImplementedError):
@@ -24,7 +25,6 @@
     def __init__(self):
         self.w_active_context = None
 
-   
     def interpret(self):
         try:
             while True:
@@ -34,13 +34,20 @@
 
     def step(self):
         next = self.w_active_context.getNextBytecode()
-        bytecodeimpl = BYTECODE_TABLE[next]
-        if option.bc_trace:
-            print "About to execute bytecode at %d (%d:%s):" % (
-                self.w_active_context.pc,
-                next, bytecodeimpl.__name__,)
-            print "  Stack=%s" % (repr(self.w_active_context.stack),)
-        bytecodeimpl(self.w_active_context, self)
+        if not objectmodel.we_are_translated():
+            bytecodeimpl = BYTECODE_TABLE[next]
+            if option.bc_trace:
+                print "About to execute bytecode at %d (%d:%s):" % (
+                    self.w_active_context.pc,
+                    next, bytecodeimpl.__name__,)
+                print "  Stack=%s" % (repr(self.w_active_context.stack),)
+            bytecodeimpl(self.w_active_context, self)
+        else:
+            for code, bytecodeimpl in unrolling_bytecode_table:
+                if code == next:
+                    bytecodeimpl(self.w_active_context, self)
+                    break
+
         
 class ReturnFromTopLevel(Exception):
     def __init__(self, object):
@@ -482,6 +489,7 @@
             (208, 255, W_ContextPart.sendLiteralSelectorBytecode),
             ]
 
+
 def initialize_bytecode_table():
     result = [None] * 256
     for entry in BYTECODE_RANGES:
@@ -495,3 +503,4 @@
     return result
 
 BYTECODE_TABLE = initialize_bytecode_table()
+unrolling_bytecode_table = unroll.unrolling_iterable(enumerate(BYTECODE_TABLE))

Modified: pypy/dist/pypy/lang/smalltalk/squeakimage.py
==============================================================================
--- pypy/dist/pypy/lang/smalltalk/squeakimage.py	(original)
+++ pypy/dist/pypy/lang/smalltalk/squeakimage.py	Fri Oct 26 14:27:09 2007
@@ -18,18 +18,22 @@
         first = first - 0x100
     return first << 24 | ord(b[2]) << 16 | ord(b[1]) << 8 | ord(b[0])            
 
-def splitbits(integer, lengths):
-    #XXX we can later let the tool chain mask and unroll this
-    result = []
-    sum = 0
-    for length in lengths:
-        sum += length
-        n = integer & ((1<<length) - 1)
-        assert n >= 0
-        result.append(n)
-        integer = integer >> length
-    assert sum <= 32
-    return result
+def make_bit_splitter(lengths):
+    from pypy.rlib import unroll
+    iterator = unroll.unrolling_iterable(lengths)
+    def splitbits(integer):
+        result = []
+        sum = 0
+        for length in iterator:
+            sum += length
+            n = integer & ((1<<length) - 1)
+            assert n >= 0
+            result.append(n)
+            integer = integer >> length
+        assert sum <= 32
+        return result
+    splitbits.func_name = "split_bits_" + "_".join([str(i) for str in lengths])
+    return splitbits
 
 # ____________________________________________________________
 #
@@ -180,19 +184,21 @@
                      for _ in range(size - 1)] #size-1, excluding header   
         return chunk, pos     
         
+    split_header = make_bit_splitter([2,6,4,5,12])
     def read_1wordobjectheader(self):
         kind, size, format, classid, idhash = (
-            splitbits(self.stream.next(), [2,6,4,5,12]))
+            self.split_header(self.stream.next()))
         assert kind == 3
         return ImageChunk(size, format, classid, idhash), self.stream.count - 4
 
     def read_2wordobjectheader(self):
         assert self.stream.peek() & 3 == 1 #kind
         classid = self.stream.next() - 01 # remove headertype to get pointer
-        kind, size, format, _, idhash = splitbits(self.stream.next(), [2,6,4,5,12])
+        kind, size, format, _, idhash = self.split_header(f.stream.next(), [2,6,4,5,12])
         assert kind == 1
         return ImageChunk(size, format, classid, idhash), self.stream.count - 4
 
+    split_2_30 = make_bit_splitter([2, 30])
     def read_3wordobjectheader(self):
         kind, size = splitbits(self.stream.next(), [2,30]) 
         assert kind == 0



More information about the Pypy-commit mailing list