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