Author: Carl Friedrich Bolz-Tereick <[email protected]>
Branch: pypy-jitdriver-greenkeys
Changeset: r98689:28f7848bd9ca
Date: 2020-02-09 13:20 +0100
http://bitbucket.org/pypy/pypy/changeset/28f7848bd9ca/

Log:    - introduce space.iterator_greenkey which returns "something" that
        can be used as the green key for an iterator to get the right
        specialization. by default it's just the type of the iterator, but
        generators override it to use the underlying pycode. That way,
        space.unpackiterable of two different generators produce two
        different loops.

        - make a pass over all jitdrivers to use this new api

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -22,12 +22,12 @@
 
 __all__ = ['ObjSpace', 'OperationError', 'W_Root']
 
-def get_printable_location(tp):
-    return "unpackiterable: %s" % (tp, )
+def get_printable_location(greenkey):
+    return "unpackiterable [%s]" % (greenkey.iterator_greenkey_printable(), )
 
 unpackiterable_driver = jit.JitDriver(name='unpackiterable',
-                                      greens=['tp'],
-                                      reds=['items', 'w_iterator'],
+                                      greens=['greenkey'],
+                                      reds='auto',
                                       
get_printable_location=get_printable_location)
 
 
@@ -373,6 +373,15 @@
             return lst[:]
         return None
 
+    def iterator_greenkey(self, space):
+        """ Return something that can be used as a green key in jit drivers
+        that iterate over self. by default, it's just the type of self, but
+        custom iterators should override it. """
+        return space.type(self)
+
+    def iterator_greenkey_printable(self):
+        return "?"
+
 
 class InterpIterable(object):
     def __init__(self, space, w_iterable):
@@ -986,11 +995,9 @@
         except MemoryError:
             items = [] # it might have lied
 
-        tp = self.type(w_iterator)
+        greenkey = self.iterator_greenkey(w_iterator)
         while True:
-            unpackiterable_driver.jit_merge_point(tp=tp,
-                                                  w_iterator=w_iterator,
-                                                  items=items)
+            unpackiterable_driver.jit_merge_point(greenkey=greenkey)
             try:
                 w_item = self.next(w_iterator)
             except OperationError as e:
@@ -2045,6 +2052,12 @@
         finally:
             self.sys.track_resources = flag
 
+    def iterator_greenkey(self, w_iterable):
+        """ Return something that can be used as a green key in jit drivers
+        that iterate over self. by default, it's just the type of self, but
+        custom iterators should override it. """
+        return w_iterable.iterator_greenkey(self)
+
 
 class AppExecCache(SpaceCache):
     @not_rpython
diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -231,6 +231,9 @@
         self.frame = None
         rgc.may_ignore_finalizer(self)
 
+    def iterator_greenkey(self):
+        return self.pycode
+
 
 def get_printable_location_genentry(bytecode):
     return '%s <generator>' % (bytecode.get_repr(),)
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -425,6 +425,9 @@
         return "<code object %s, file '%s', line %d>" % (
             self.co_name, self.co_filename, self.co_firstlineno)
 
+    def iterator_greenkey_printable(self):
+        return self.get_repr()
+
     def __repr__(self):
         return self.get_repr()
 
diff --git a/pypy/module/__builtin__/functional.py 
b/pypy/module/__builtin__/functional.py
--- a/pypy/module/__builtin__/functional.py
+++ b/pypy/module/__builtin__/functional.py
@@ -131,10 +131,21 @@
         v = v.add(step)
     return space.newlist(res_w)
 
+def get_printable_location(has_key, has_item, greenkey):
+    return "min [has_key=%s, has_item=%s, %s]" % (
+            has_key, has_item, greenkey.iterator_greenkey_printable())
+
 min_jitdriver = jit.JitDriver(name='min',
-        greens=['has_key', 'has_item', 'w_type'], reds='auto')
+        greens=['has_key', 'has_item', 'greenkey'], reds='auto',
+        get_printable_location=get_printable_location)
+
+def get_printable_location(has_key, has_item, greenkey):
+    return "min [has_key=%s, has_item=%s, %s]" % (
+            has_key, has_item, greenkey.iterator_greenkey_printable())
+
 max_jitdriver = jit.JitDriver(name='max',
-        greens=['has_key', 'has_item', 'w_type'], reds='auto')
+        greens=['has_key', 'has_item', 'greenkey'], reds='auto',
+        get_printable_location=get_printable_location)
 
 @specialize.arg(3)
 def min_max_sequence(space, w_sequence, w_key, implementation_of):
@@ -145,14 +156,14 @@
         compare = space.lt
         jitdriver = min_jitdriver
     w_iter = space.iter(w_sequence)
-    w_type = space.type(w_iter)
+    greenkey = space.iterator_greenkey(w_iter)
     has_key = w_key is not None
     has_item = False
     w_max_item = None
     w_max_val = None
     while True:
         jitdriver.jit_merge_point(has_key=has_key, has_item=has_item,
-                                  w_type=w_type)
+                                  greenkey=greenkey)
         try:
             w_item = space.next(w_iter)
         except OperationError as e:
diff --git a/pypy/module/itertools/interp_itertools.py 
b/pypy/module/itertools/interp_itertools.py
--- a/pypy/module/itertools/interp_itertools.py
+++ b/pypy/module/itertools/interp_itertools.py
@@ -322,10 +322,12 @@
     """)
 
 
+def get_printable_location(greenkey):
+    return "islice_ignore_items [%s]" % 
(greenkey.iterator_greenkey_printable(), )
 islice_ignore_items_driver = jit.JitDriver(name='islice_ignore_items',
-                                           greens=['tp'],
-                                           reds=['num', 'w_islice',
-                                                 'w_iterator'])
+                                           greens=['greenkey'],
+                                           reds='auto',
+                                           
get_printable_location=get_printable_location)
 
 class W_ISlice(W_Root):
     def __init__(self, space, w_iterable, w_startstop, args_w):
@@ -418,12 +420,9 @@
         if w_iterator is None:
             raise OperationError(self.space.w_StopIteration, self.space.w_None)
 
-        tp = self.space.type(w_iterator)
+        greenkey = self.space.iterator_greenkey(w_iterator)
         while True:
-            islice_ignore_items_driver.jit_merge_point(tp=tp,
-                                                       num=num,
-                                                       w_islice=self,
-                                                       w_iterator=w_iterator)
+            islice_ignore_items_driver.jit_merge_point(greenkey=greenkey)
             try:
                 self.space.next(w_iterator)
             except OperationError as e:
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -125,7 +125,7 @@
         pass
 
 contains_jitdriver = jit.JitDriver(name='contains',
-        greens=['w_type'], reds='auto')
+        greens=['itergreenkey', 'w_itemtype'], reds='auto')
 
 class DescrOperation(object):
     # This is meant to be a *mixin*.
@@ -406,9 +406,10 @@
 
     def _contains(space, w_container, w_item):
         w_iter = space.iter(w_container)
-        w_type = space.type(w_iter)
+        itergreenkey = space.iterator_greenkey(w_iter)
+        w_itemtype = space.type(w_item)
         while 1:
-            contains_jitdriver.jit_merge_point(w_type=w_type)
+            contains_jitdriver.jit_merge_point(itergreenkey=itergreenkey, 
w_itemtype=w_itemtype)
             try:
                 w_next = space.next(w_iter)
             except OperationError as e:
diff --git a/pypy/objspace/std/bytearrayobject.py 
b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -561,14 +561,14 @@
         return list(buf.as_str())
     return _from_byte_sequence(space, w_source)
 
-def _get_printable_location(w_type):
-    return ('bytearray_from_byte_sequence [w_type=%s]' %
-            w_type.getname(w_type.space))
+def _get_printable_location(greenkey):
+    return ('bytearray_from_byte_sequence [%s]' %
+            greenkey.iterator_greenkey_printable())
 
 _byteseq_jitdriver = jit.JitDriver(
     name='bytearray_from_byte_sequence',
-    greens=['w_type'],
-    reds=['w_iter', 'data'],
+    greens=['greenkey'],
+    reds='auto'
     get_printable_location=_get_printable_location)
 
 def _from_byte_sequence(space, w_source):
@@ -586,11 +586,9 @@
     return data
 
 def _from_byte_sequence_loop(space, w_iter, data):
-    w_type = space.type(w_iter)
+    greenkey = space.iterator_greenkey(w_iter)
     while True:
-        _byteseq_jitdriver.jit_merge_point(w_type=w_type,
-                                           w_iter=w_iter,
-                                           data=data)
+        _byteseq_jitdriver.jit_merge_point(greenkey=greenkey)
         try:
             w_item = space.next(w_iter)
         except OperationError as e:
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -131,26 +131,26 @@
     return space.fromcache(ObjectListStrategy)
 
 
-def _get_printable_location(w_type):
-    return ('list__do_extend_from_iterable [w_type=%s]' %
-            w_type.getname(w_type.space))
+def _get_printable_location(greenkey):
+    return 'list__do_extend_from_iterable [%s, %s]' % (
+        strategy,
+        greenkey.iterator_greenkey_printable())
 
 
 _do_extend_jitdriver = jit.JitDriver(
     name='list__do_extend_from_iterable',
-    greens=['w_type'],
-    reds=['i', 'w_iterator', 'w_list'],
+    greens=['strategy', 'greenkey'],
+    reds='auto',
     get_printable_location=_get_printable_location)
 
 def _do_extend_from_iterable(space, w_list, w_iterable):
     w_iterator = space.iter(w_iterable)
-    w_type = space.type(w_iterator)
+    w_type = space.iterator_greenkey_printable(w_iterator)
     i = 0
     while True:
-        _do_extend_jitdriver.jit_merge_point(w_type=w_type,
-                                             i=i,
-                                             w_iterator=w_iterator,
-                                             w_list=w_list)
+        _do_extend_jitdriver.jit_merge_point(
+                w_type=w_type,
+                strategy = w_list.strategy)
         try:
             w_list.append(space.next(w_iterator))
         except OperationError as e:
@@ -749,7 +749,9 @@
         if mucked:
             raise oefmt(space.w_ValueError, "list modified during sort")
 
-find_jmp = jit.JitDriver(greens = ['tp'], reds = 'auto', name = 'list.find')
+def get_printable_location(strategy, tp):
+    return "list.find [%s, %s]" % (strategy, tp.getname(tp.space), )
+find_jmp = jit.JitDriver(greens = ['strategy', 'tp'], reds = 'auto', name = 
'list.find', get_printable_location=get_printable_location)
 
 class ListStrategy(object):
 
@@ -777,7 +779,7 @@
         # needs to be safe against eq_w mutating stuff
         tp = space.type(w_item)
         while i < stop and i < w_list.length():
-            find_jmp.jit_merge_point(tp=tp)
+            find_jmp.jit_merge_point(tp=tp, strategy=self)
             if space.eq_w(w_item, w_list.getitem(i)):
                 return i
             i += 1
diff --git a/pypy/objspace/std/setobject.py b/pypy/objspace/std/setobject.py
--- a/pypy/objspace/std/setobject.py
+++ b/pypy/objspace/std/setobject.py
@@ -1681,7 +1681,7 @@
 
 
 def get_printable_location(tp, strategy):
-    return "create_set: %s %s" % (tp, strategy)
+    return "create_set: %s %s" % (tp.iterator_greenkey_printable(), strategy)
 
 create_set_driver = jit.JitDriver(name='create_set',
                                   greens=['tp', 'strategy'],
@@ -1692,7 +1692,7 @@
     w_set.strategy = strategy = space.fromcache(EmptySetStrategy)
     w_set.sstorage = strategy.get_empty_storage()
 
-    tp = space.type(w_iterable)
+    tp = space.iterator_greenkey(w_iterable)
 
     w_iter = space.iter(w_iterable)
     while True:
diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py
--- a/pypy/objspace/std/tupleobject.py
+++ b/pypy/objspace/std/tupleobject.py
@@ -27,13 +27,22 @@
             jit.loop_unrolling_heuristic(other, other.length(), UNROLL_CUTOFF))
 
 
+def get_printable_location(tp):
+    return "tuple.contains [%s]" % (tp.getname(tp.space), )
+
 contains_jmp = jit.JitDriver(greens = ['tp'], reds = 'auto',
-                             name = 'tuple.contains')
+                             name = 'tuple.contains',
+                             get_printable_location=get_printable_location)
+
+def get_printable_location(w_type):
+    return "tuple.hash [%s]" % (w_type.getname(w_type.space), )
 
 hash_driver = jit.JitDriver(
     name='tuple.hash',
     greens=['w_type'],
-    reds='auto')
+    reds='auto',
+    get_printable_location=get_printable_location
+    )
 
 class W_AbstractTupleObject(W_Root):
     __slots__ = ()
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to