Author: Carl Friedrich Bolz <[email protected]>
Branch: faster-set-of-iterator
Changeset: r65397:052963cf1e59
Date: 2013-07-10 22:07 +0200
http://bitbucket.org/pypy/pypy/changeset/052963cf1e59/

Log:    reinstante jit driver support, some cleanups

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -20,9 +20,6 @@
 
 UINT_MAX_32_BITS = r_uint(4294967295)
 
-unpackiterable_driver = jit.JitDriver(name='unpackiterable',
-                                      greens=['tp'],
-                                      reds=['items', 'w_iterator'])
 
 
 class W_Root(object):
@@ -32,6 +29,9 @@
     _settled_ = True
     user_overridden_class = False
 
+    # unpacking support
+    from pypy.interpreter.unpack import generic_unpack_into as unpack_into
+
     def getdict(self, space):
         return None
 
@@ -233,17 +233,6 @@
     def __spacebind__(self, space):
         return self
 
-    def unpack_into(self, space, unpack_target):
-        w_iterator = space.iter(self)
-        while True:
-            # YYY jit driver
-            try:
-                w_item = space.next(w_iterator)
-            except OperationError, e:
-                if not e.match(space, space.w_StopIteration):
-                    raise
-                break  # done
-            unpack_target.append(w_item)
 
     def unwrap(self, space):
         """NOT_RPYTHON"""
@@ -763,41 +752,25 @@
 
         Raise an OperationError(w_ValueError) if the length is wrong."""
         from pypy.interpreter import unpack
-        w_iterator = self.iter(w_iterable)
         if expected_length == -1:
             unpack_target = unpack.InterpListUnpackTarget(self, w_iterable)
             self.unpack_into(w_iterable, unpack_target)
             return unpack_target.items_w
         else:
-            lst_w = self._unpackiterable_known_length(w_iterator,
+            lst_w = self._unpackiterable_known_length(w_iterable,
                                                       expected_length)
             return lst_w[:]     # make the resulting list resizable
 
-    def unpack_into(self, w_iterable, unpack_target):
-        w_iterable.unpack_into(self, unpack_target)
+    def unpack_into(self, w_iterable, unpack_target, unroll=False):
+        w_iterable.unpack_into(self, unpack_target, unroll)
 
     def iteriterable(self, w_iterable):
         return W_InterpIterable(self, w_iterable)
 
-    def _unpackiterable_unknown_length(self, w_iterator, w_iterable):
-        """Unpack an iterable of unknown length into an interp-level
-        list.
-        """
-
-    @jit.dont_look_inside
-    def _unpackiterable_known_length(self, w_iterator, expected_length):
-        # Unpack a known length list, without letting the JIT look inside.
-        # Implemented by just calling the @jit.unroll_safe version, but
-        # the JIT stopped looking inside already.
-        return self._unpackiterable_known_length_jitlook(w_iterator,
-                                                         expected_length)
-
-    @jit.unroll_safe
-    def _unpackiterable_known_length_jitlook(self, w_iterator,
-                                             expected_length):
+    def _unpackiterable_known_length(self, w_iterable, expected_length, 
unroll=False):
         from pypy.interpreter import unpack
         unpack_target = unpack.FixedSizeUnpackTarget(self, w_iterable)
-        self.unpack_into(unpack_target)
+        self.unpack_into(w_iterable, unpack_target, unroll=unroll)
         if unpack_target.index < expected_length:
             if idx == 1:
                 plural = ""
@@ -812,11 +785,9 @@
         # Like unpackiterable(), but for the cases where we have
         # an expected_length and want to unroll when JITted.
         # Returns a fixed-size list.
-        w_iterator = self.iter(w_iterable)
         assert expected_length != -1
-        # YYY correct unrolling
-        return self._unpackiterable_known_length_jitlook(w_iterator,
-                                                         expected_length)
+        return self._unpackiterable_known_length(
+            w_iterable, expected_length, unroll=True)
 
     def length_hint(self, w_obj, default):
         """Return the length of an object, consulting its __length_hint__
diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -3,6 +3,9 @@
 from pypy.interpreter.pyopcode import LoopBlock
 from rpython.rlib import jit
 
+unpack_into_jitdriver = jit.JitDriver(greens=['pycode'],
+                                      reds=['self', 'frame', 'unpack_target'],
+                                      name='unpack_into')
 
 class GeneratorIterator(W_Root):
     "An iterator created by a generator."
@@ -169,45 +172,35 @@
                     break
                 block = block.previous
 
-    # Results can be either an RPython list of W_Root, or it can be an
-    # app-level W_ListObject, which also has an append() method, that's why we
-    # generate 2 versions of the function and 2 jit drivers.
-    def _create_unpack_into():
-        jitdriver = jit.JitDriver(greens=['pycode'],
-                                  reds=['self', 'frame', 'results'],
-                                  name='unpack_into')
-
-        def unpack_into(self, space, results):
-            """This is a hack for performance: runs the generator and collects
-            all produced items in a list."""
-            # XXX copied and simplified version of send_ex()
-            space = self.space
-            if self.running:
-                raise OperationError(space.w_ValueError,
-                                     space.wrap('generator already executing'))
-            frame = self.frame
-            if frame is None:    # already finished
-                return
-            self.running = True
-            try:
-                pycode = self.pycode
-                while True:
-                    jitdriver.jit_merge_point(self=self, frame=frame,
-                                              results=results, pycode=pycode)
-                    try:
-                        w_result = frame.execute_frame(space.w_None)
-                    except OperationError, e:
-                        if not e.match(space, space.w_StopIteration):
-                            raise
-                        break
-                    # if the frame is now marked as finished, it was RETURNed 
from
-                    if frame.frame_finished_execution:
-                        break
-                    results.append(w_result)     # YIELDed
-            finally:
-                frame.f_backref = jit.vref_None
-                self.running = False
-                self.frame = None
-        return unpack_into
-    unpack_into = _create_unpack_into()
-    unpack_into_w = _create_unpack_into()
+    def unpack_into(self, space, unpack_target, unroll=False):
+        """This is a hack for performance: runs the generator and collects
+        all produced items in a list."""
+        # YYY stop ignoring unroll
+        # XXX copied and simplified version of send_ex()
+        space = self.space
+        if self.running:
+            raise OperationError(space.w_ValueError,
+                                 space.wrap('generator already executing'))
+        frame = self.frame
+        if frame is None:    # already finished
+            return
+        self.running = True
+        try:
+            pycode = self.pycode
+            while True:
+                unpack_into_jitdriver.jit_merge_point(self=self, frame=frame,
+                                                      
unpack_target=unpack_target, pycode=pycode)
+                try:
+                    w_result = frame.execute_frame(space.w_None)
+                except OperationError, e:
+                    if not e.match(space, space.w_StopIteration):
+                        raise
+                    break
+                # if the frame is now marked as finished, it was RETURNed from
+                if frame.frame_finished_execution:
+                    break
+                unpack_target.append(w_result)     # YIELDed
+        finally:
+            frame.f_backref = jit.vref_None
+            self.running = False
+            self.frame = None
diff --git a/pypy/interpreter/unpack.py b/pypy/interpreter/unpack.py
--- a/pypy/interpreter/unpack.py
+++ b/pypy/interpreter/unpack.py
@@ -1,4 +1,7 @@
 from rpython.rlib.objectmodel import newlist_hint
+from rpython.rlib import jit
+
+from pypy.interpreter.error import OperationError
 
 class UnpackTarget(object):
     def __init__(self, space):
@@ -30,5 +33,31 @@
         if self.index == len(self.items_w):
             raise OperationError(self.w_ValueError,
                                 self.wrap("too many values to unpack"))
-        items[self.index] = w_item
+        self.items_w[self.index] = w_item
         self.index += 1
+
+
+
+unpack_into_driver = jit.JitDriver(name='unpack_into',
+                                   greens=['unroll', 'w_type'],
+                                   reds=['unpack_target', 'w_iterator'])
+
+def generic_unpack_into(w_iterable, space, unpack_target, unroll=False):
+    w_iterator = space.iter(w_iterable)
+    w_type = space.type(w_iterator)
+    while True:
+        if not unroll:
+            unpack_into_driver.can_enter_jit(w_type=w_type, unroll=unroll,
+                                             w_iterator=w_iterator,
+                                             unpack_target=unpack_target)
+        unpack_into_driver.jit_merge_point(w_type=w_type, unroll=unroll,
+                                           w_iterator=w_iterator,
+                                           unpack_target=unpack_target)
+        try:
+            w_item = space.next(w_iterator)
+        except OperationError, e:
+            if not e.match(space, space.w_StopIteration):
+                raise
+            break  # done
+        unpack_target.append(w_item)
+
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to