[pypy-commit] pypy remove-tuple-smm: IN-PROGRESS: Remove SMMs on smalltuple, too.

Manuel Jacob noreply at buildbot.pypy.org
Tue May 21 23:14:31 CEST 2013


Author: Manuel Jacob
Branch: remove-tuple-smm
Changeset: r64405:fe9e1fed1393
Date: 2013-05-21 23:12 +0200
http://bitbucket.org/pypy/pypy/changeset/fe9e1fed1393/

Log:	IN-PROGRESS: Remove SMMs on smalltuple, too.

diff --git a/pypy/objspace/std/model.py b/pypy/objspace/std/model.py
--- a/pypy/objspace/std/model.py
+++ b/pypy/objspace/std/model.py
@@ -190,10 +190,6 @@
                 (unicodeobject.W_UnicodeObject,
                                        strbufobject.delegate_buf2unicode)
                 ]
-        if config.objspace.std.withsmalltuple:
-            from pypy.objspace.std import smalltupleobject
-            self.typeorder[smalltupleobject.W_SmallTupleObject] += [
-                (tupleobject.W_TupleObject, smalltupleobject.delegate_SmallTuple2Tuple)]
 
         if config.objspace.std.withspecialisedtuple:
             from pypy.objspace.std import specialisedtupleobject
diff --git a/pypy/objspace/std/smalltupleobject.py b/pypy/objspace/std/smalltupleobject.py
--- a/pypy/objspace/std/smalltupleobject.py
+++ b/pypy/objspace/std/smalltupleobject.py
@@ -6,36 +6,17 @@
 from rpython.rlib.rarithmetic import intmask
 from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
 from pypy.objspace.std import slicetype
+from pypy.objspace.std.util import negate
 from pypy.interpreter import gateway
 from rpython.rlib.debug import make_sure_not_resized
 from rpython.rlib.unroll import unrolling_iterable
 from rpython.tool.sourcetools import func_with_new_name
 from pypy.objspace.std.tupleobject import W_AbstractTupleObject, W_TupleObject
 
+
 class W_SmallTupleObject(W_AbstractTupleObject):
     from pypy.objspace.std.tupletype import tuple_typedef as typedef
 
-    #def tolist(self):   --- inherited from W_AbstractTupleObject
-    #    raise NotImplementedError
-
-    def length(self):
-        raise NotImplementedError
-
-    def getitem(self, index):
-        raise NotImplementedError
-
-    def hash(self, space):
-        raise NotImplementedError
-
-    def eq(self, space, w_other):
-        raise NotImplementedError
-
-    def setitem(self, index, w_item):
-        raise NotImplementedError
-
-    def unwrap(w_tuple, space):
-        items = [space.unwrap(w_item) for w_item in w_tuple.tolist()]
-        return tuple(items)
 
 def make_specialized_class(n):
     iter_n = unrolling_iterable(range(n))
@@ -58,30 +39,40 @@
         def length(self):
             return n
 
-        def getitem(self, index):
+        def descr_len(self):
+            return space.wrap(n)
+
+        def descr_getitem(self, space, w_index):
+            if isinstance(w_index, W_SliceObject):
+                return self._getslice(space, w_index)
+            index = space.getindex_w(w_index, space.w_IndexError,
+                                     "tuple index")
+            if index < 0:
+                index += self.length()
+            return self.getitem(space, index)
+
+        def getitem(self, space, index):
             for i in iter_n:
                 if index == i:
                     return getattr(self,'w_value%s' % i)
-            raise IndexError
+            raise OperationError(space.w_IndexError,
+                                 space.wrap("tuple index out of range"))
 
-        def setitem(self, index, w_item):
-            for i in iter_n:
-                if index == i:
-                    setattr(self, 'w_value%s' % i, w_item)
-                    return
-            raise IndexError
-
-        def eq(self, space, w_other):
+        def descr_eq(self, space, w_other):
+            if not isinstance(w_other, W_AbstractTupleObject):
+                return space.w_NotImplemented
             if n != w_other.length():
                 return space.w_False
             for i in iter_n:
                 item1 = getattr(self,'w_value%s' % i)
-                item2 = w_other.getitem(i)
+                item2 = w_other.getitem(space, i)
                 if not space.eq_w(item1, item2):
                     return space.w_False
             return space.w_True
 
-        def hash(self, space):
+        descr_ne = negate(descr_eq)
+
+        def descr_hash(self, space):
             mult = 1000003
             x = 0x345678
             z = n
@@ -106,56 +97,3 @@
 W_SmallTupleObject8 = make_specialized_class(8)
 
 registerimplementation(W_SmallTupleObject)
-
-def delegate_SmallTuple2Tuple(space, w_small):
-    return W_TupleObject(w_small.tolist())
-
-def len__SmallTuple(space, w_tuple):
-    return space.wrap(w_tuple.length())
-
-def getitem__SmallTuple_ANY(space, w_tuple, w_index):
-    index = space.getindex_w(w_index, space.w_IndexError, "tuple index")
-    if index < 0:
-        index += w_tuple.length()
-    try:
-        return w_tuple.getitem(index)
-    except IndexError:
-        raise OperationError(space.w_IndexError,
-                             space.wrap("tuple index out of range"))
-
-def getitem__SmallTuple_Slice(space, w_tuple, w_slice):
-    length = w_tuple.length()
-    start, stop, step, slicelength = w_slice.indices4(space, length)
-    assert slicelength >= 0
-    subitems = [None] * slicelength
-    for i in range(slicelength):
-        subitems[i] = w_tuple.getitem(start)
-        start += step
-    return space.newtuple(subitems)
-
-def mul_smalltuple_times(space, w_tuple, w_times):
-    try:
-        times = space.getindex_w(w_times, space.w_OverflowError)
-    except OperationError, e:
-        if e.match(space, space.w_TypeError):
-            raise FailedToImplement
-        raise
-    if times == 1 and space.type(w_tuple) == space.w_tuple:
-        return w_tuple
-    items = w_tuple.tolist()
-    return space.newtuple(items * times)
-
-def mul__SmallTuple_ANY(space, w_tuple, w_times):
-    return mul_smalltuple_times(space, w_tuple, w_times)
-
-def mul__ANY_SmallTuple(space, w_times, w_tuple):
-    return mul_smalltuple_times(space, w_tuple, w_times)
-
-def eq__SmallTuple_SmallTuple(space, w_tuple1, w_tuple2):
-    return w_tuple1.eq(space, w_tuple2)
-
-def hash__SmallTuple(space, w_tuple):
-    return w_tuple.hash(space)
-
-from pypy.objspace.std import tupletype
-register_all(vars(), tupletype)
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
@@ -12,51 +12,53 @@
 from rpython.rlib import jit
 from rpython.tool.sourcetools import func_with_new_name
 from pypy.interpreter import gateway
+from pypy.interpreter.gateway import interp2app, interpindirect2app
+
 
 UNROLL_CUTOFF = 10
 
+
+def tuple_unroll_condition(self, space, other):
+    return (jit.loop_unrolling_heuristic(self, self.length(), UNROLL_CUTOFF) or
+            jit.loop_unrolling_heuristic(other, other.length(), UNROLL_CUTOFF))
+
+
 class W_AbstractTupleObject(W_Object):
     __slots__ = ()
 
+    def __repr__(w_self):
+        """representation for debugging purposes"""
+        reprlist = [repr(w_item) for w_item in w_self.tolist()]
+        return "%s(%s)" % (w_self.__class__.__name__, ', '.join(reprlist))
+
+    def unwrap(w_tuple, space):
+        items = [space.unwrap(w_item) for w_item in w_tuple.tolist()]
+        return tuple(items)
+
     def tolist(self):
-        "Returns the items, as a fixed-size list."
+        """Returns the items, as a fixed-size list."""
         raise NotImplementedError
 
     def getitems_copy(self):
-        "Returns a copy of the items, as a resizable list."
+        """Returns a copy of the items, as a resizable list."""
         raise NotImplementedError
 
+    def length(self):
+        raise NotImplementedError
 
-def tuple_unroll_condition(space, self, w_other):
-    return jit.loop_unrolling_heuristic(self, len(self.wrappeditems), UNROLL_CUTOFF) or \
-           jit.loop_unrolling_heuristic(w_other, len(w_other.wrappeditems), UNROLL_CUTOFF)
+    def getitem(self, space, item):
+        raise NotImplementedError
 
+    def descr_len(self, space):
+        result = self.length()
+        return wrapint(space, result)
 
-class W_TupleObject(W_AbstractTupleObject):
-    _immutable_fields_ = ['wrappeditems[*]']
-
-    def __init__(w_self, wrappeditems):
-        make_sure_not_resized(wrappeditems)
-        w_self.wrappeditems = wrappeditems   # a list of wrapped values
-
-    def __repr__(w_self):
-        """ representation for debugging purposes """
-        reprlist = [repr(w_item) for w_item in w_self.wrappeditems]
-        return "%s(%s)" % (w_self.__class__.__name__, ', '.join(reprlist))
-
-    def unwrap(w_tuple, space):
-        items = [space.unwrap(w_item) for w_item in w_tuple.wrappeditems]
-        return tuple(items)
-
-    def tolist(self):
-        return self.wrappeditems
-
-    def getitems_copy(self):
-        return self.wrappeditems[:]   # returns a resizable list
+    def descr_iter(self, space):
+        from pypy.objspace.std import iterobject
+        return iterobject.W_FastTupleIterObject(self, self.tolist())
 
     @staticmethod
     def descr_new(space, w_tupletype, w_sequence=None):
-        from pypy.objspace.std.tupleobject import W_TupleObject
         if w_sequence is None:
             tuple_w = []
         elif (space.is_w(w_tupletype, space.w_tuple) and
@@ -69,24 +71,187 @@
         return w_obj
 
     def descr_repr(self, space):
-        items = self.wrappeditems
+        items = self.tolist()
         # XXX this is quite innefficient, still better than calling
         #     it via applevel
         if len(items) == 1:
             return space.wrap("(" + space.str_w(space.repr(items[0])) + ",)")
-        return space.wrap("(" +
-                     (", ".join([space.str_w(space.repr(item)) for item in items]))
-                          + ")")
+        tmp = ", ".join([space.str_w(space.repr(item)) for item in items])
+        return space.wrap("(" + tmp + ")")
+
+    def descr_hash(self, space):
+        raise NotImplementedError
+
+    def descr_eq(self, space, w_other):
+        raise NotImplementedError
+
+    def descr_ne(self, space, w_other):
+        raise NotImplementedError
+
+    def _make_tuple_comparison(name):
+        import operator
+        op = getattr(operator, name)
+
+        def compare_tuples(self, space, w_other):
+            if not isinstance(w_other, W_AbstractTupleObject):
+                return space.w_NotImplemented
+            return _compare_tuples(self, space, w_other)
+
+        @jit.look_inside_iff(tuple_unroll_condition)
+        def _compare_tuples(self, space, w_other):
+            items1 = self.tolist()
+            items2 = w_other.tolist()
+            ncmp = min(len(items1), len(items2))
+            # Search for the first index where items are different
+            for p in range(ncmp):
+                if not space.eq_w(items1[p], items2[p]):
+                    return getattr(space, name)(items1[p], items2[p])
+            # No more items to compare -- compare sizes
+            return space.newbool(op(len(items1), len(items2)))
+
+        return func_with_new_name(compare_tuples, name + '__Tuple_Tuple')
+
+    descr_lt = _make_tuple_comparison('lt')
+    descr_le = _make_tuple_comparison('le')
+    descr_gt = _make_tuple_comparison('gt')
+    descr_ge = _make_tuple_comparison('ge')
+
+    @jit.look_inside_iff(lambda self, space, w_obj:
+            jit.loop_unrolling_heuristic(self, self.length(), UNROLL_CUTOFF))
+    def descr_contains(self, space, w_obj):
+        for w_item in self.tolist():
+            if space.eq_w(w_item, w_obj):
+                return space.w_True
+        return space.w_False
+
+    def descr_add(self, space, w_other):
+        if not isinstance(w_other, W_AbstractTupleObject):
+            return space.w_NotImplemented
+        items1 = self.tolist()
+        items2 = w_other.tolist()
+        return space.newtuple(items1 + items2)
+
+    def descr_mul(self, space, w_times):
+        try:
+            times = space.getindex_w(w_times, space.w_OverflowError)
+        except OperationError, e:
+            if e.match(space, space.w_TypeError):
+                return space.w_NotImplemented
+            raise
+        if times == 1 and space.type(self) == space.w_tuple:
+            return self
+        items = self.tolist()
+        return space.newtuple(items * times)
+
+    def descr_getitem(self, space, w_other):
+        raise NotImplementedError
+
+    def _getslice(self, space, w_index):
+        items = self.tolist()
+        length = len(items)
+        start, stop, step, slicelength = w_index.indices4(space, length)
+        assert slicelength >= 0
+        subitems = [None] * slicelength
+        for i in range(slicelength):
+            subitems[i] = items[start]
+            start += step
+        return space.newtuple(subitems)
+
+    def descr_getslice(self, space, w_start, w_stop):
+        length = self.length()
+        start, stop = normalize_simple_slice(space, length, w_start, w_stop)
+        return space.newtuple(self.tolist()[start:stop])
+
+    def descr_getnewargs(self, space):
+        return space.newtuple([space.newtuple(self.tolist())])
+
+    def descr_count(self, space, w_obj):
+        """count(obj) -> number of times obj appears in the tuple"""
+        count = 0
+        for w_item in self.tolist():
+            if space.eq_w(w_item, w_obj):
+                count += 1
+        return space.wrap(count)
+
+    @gateway.unwrap_spec(w_start=gateway.WrappedDefault(0),
+                         w_stop=gateway.WrappedDefault(sys.maxint))
+    def descr_index(self, space, w_obj, w_start, w_stop):
+        """index(obj, [start, [stop]]) -> first index that obj appears in the
+        tuple
+        """
+        length = self.length()
+        start, stop = slicetype.unwrap_start_stop(space, length, w_start,
+                                                  w_stop)
+        for i in range(start, min(stop, length)):
+            w_item = self.tolist()[i]
+            if space.eq_w(w_item, w_obj):
+                return space.wrap(i)
+        raise OperationError(space.w_ValueError,
+                             space.wrap("tuple.index(x): x not in tuple"))
+
+
+W_AbstractTupleObject.typedef = StdTypeDef("tuple",
+    __doc__ = '''tuple() -> an empty tuple
+tuple(sequence) -> tuple initialized from sequence's items
+
+If the argument is a tuple, the return value is the same object.''',
+    __new__ = interp2app(W_AbstractTupleObject.descr_new),
+    __repr__ = interp2app(W_AbstractTupleObject.descr_repr),
+    __hash__ = interpindirect2app(W_AbstractTupleObject.descr_hash),
+
+    __eq__ = interpindirect2app(W_AbstractTupleObject.descr_eq),
+    __ne__ = interpindirect2app(W_AbstractTupleObject.descr_ne),
+    __lt__ = interp2app(W_AbstractTupleObject.descr_lt),
+    __le__ = interp2app(W_AbstractTupleObject.descr_le),
+    __gt__ = interp2app(W_AbstractTupleObject.descr_gt),
+    __ge__ = interp2app(W_AbstractTupleObject.descr_ge),
+
+    __len__ = interp2app(W_AbstractTupleObject.descr_len),
+    __iter__ = interp2app(W_AbstractTupleObject.descr_iter),
+    __contains__ = interp2app(W_AbstractTupleObject.descr_contains),
+
+    __add__ = interp2app(W_AbstractTupleObject.descr_add),
+    __mul__ = interp2app(W_AbstractTupleObject.descr_mul),
+    __rmul__ = interp2app(W_AbstractTupleObject.descr_mul),
+
+    __getitem__ = interpindirect2app(W_AbstractTupleObject.descr_getitem),
+    __getslice__ = interp2app(W_AbstractTupleObject.descr_getslice),
+
+    __getnewargs__ = interp2app(W_AbstractTupleObject.descr_getnewargs),
+    count = interp2app(W_AbstractTupleObject.descr_count),
+    index = interp2app(W_AbstractTupleObject.descr_index)
+)
+
+
+
+class W_TupleObject(W_AbstractTupleObject):
+    _immutable_fields_ = ['wrappeditems[*]']
+
+    def __init__(w_self, wrappeditems):
+        make_sure_not_resized(wrappeditems)
+        w_self.wrappeditems = wrappeditems   # a list of wrapped values
+
+    def tolist(self):
+        return self.wrappeditems
+
+    def getitems_copy(self):
+        return self.wrappeditems[:]   # returns a resizable list
+
+    def length(self):
+        return len(self.wrappeditems)
 
     def descr_hash(self, space):
         return space.wrap(hash_tuple(space, self.wrappeditems))
 
+    def descr_eq(self, space, w_other):
+        if not isinstance(w_other, W_AbstractTupleObject):
+            return space.w_NotImplemented
+        return self._descr_eq(space, w_other)
+
     @jit.look_inside_iff(tuple_unroll_condition)
-    def descr_eq(self, space, w_other):
-        if not isinstance(w_other, W_TupleObject):
-            return space.w_NotImplemented
+    def _descr_eq(self, space, w_other):
         items1 = self.wrappeditems
-        items2 = w_other.wrappeditems
+        items2 = w_other.tolist()
         lgt1 = len(items1)
         lgt2 = len(items2)
         if lgt1 != lgt2:
@@ -100,77 +265,9 @@
 
     descr_ne = negate(descr_eq)
 
-    def _make_tuple_comparison(name):
-        import operator
-        op = getattr(operator, name)
-
-        @jit.look_inside_iff(tuple_unroll_condition)
-        def compare_tuples(self, space, w_other):
-            if not isinstance(w_other, W_TupleObject):
-                return space.w_NotImplemented
-            items1 = self.wrappeditems
-            items2 = w_other.wrappeditems
-            ncmp = min(len(items1), len(items2))
-            # Search for the first index where items are different
-            for p in range(ncmp):
-                if not space.eq_w(items1[p], items2[p]):
-                    return getattr(space, name)(items1[p], items2[p])
-            # No more items to compare -- compare sizes
-            return space.newbool(op(len(items1), len(items2)))
-        return func_with_new_name(compare_tuples, name + '__Tuple_Tuple')
-
-    descr_lt = _make_tuple_comparison('lt')
-    descr_le = _make_tuple_comparison('le')
-    descr_gt = _make_tuple_comparison('gt')
-    descr_ge = _make_tuple_comparison('ge')
-
-    def descr_len(self, space):
-        result = len(self.wrappeditems)
-        return wrapint(space, result)
-
-    def descr_iter(self, space):
-        from pypy.objspace.std import iterobject
-        return iterobject.W_FastTupleIterObject(self, self.wrappeditems)
-
-    @jit.look_inside_iff(lambda self, space, w_obj:
-            jit.loop_unrolling_heuristic(self, len(self.wrappeditems), UNROLL_CUTOFF))
-    def descr_contains(self, space, w_obj):
-        for w_item in self.wrappeditems:
-            if space.eq_w(w_item, w_obj):
-                return space.w_True
-        return space.w_False
-
-    def descr_add(self, space, w_other):
-        if not isinstance(w_other, W_TupleObject):
-            return space.w_NotImplemented
-        items1 = self.wrappeditems
-        items2 = w_other.wrappeditems
-        return space.newtuple(items1 + items2)
-
-    def descr_mul(self, space, w_times):
-        try:
-            times = space.getindex_w(w_times, space.w_OverflowError)
-        except OperationError, e:
-            if e.match(space, space.w_TypeError):
-                return space.w_NotImplemented
-            raise
-        if times == 1 and space.type(self) == space.w_tuple:
-            return self
-        items = self.wrappeditems
-        return space.newtuple(items * times)
-
     def descr_getitem(self, space, w_index):
         if isinstance(w_index, W_SliceObject):
-            items = self.wrappeditems
-            length = len(items)
-            start, stop, step, slicelength = w_index.indices4(space, length)
-            assert slicelength >= 0
-            subitems = [None] * slicelength
-            for i in range(slicelength):
-                subitems[i] = items[start]
-                start += step
-            return space.newtuple(subitems)
-
+            return self._getslice(space, w_index)
         index = space.getindex_w(w_index, space.w_IndexError, "tuple index")
         try:
             return self.wrappeditems[index]
@@ -178,68 +275,12 @@
             raise OperationError(space.w_IndexError,
                                  space.wrap("tuple index out of range"))
 
-    def descr_getslice(self, space, w_start, w_stop):
-        length = len(self.wrappeditems)
-        start, stop = normalize_simple_slice(space, length, w_start, w_stop)
-        return space.newtuple(self.wrappeditems[start:stop])
-
-    def descr_getnewargs(self, space):
-        return space.newtuple([space.newtuple(self.wrappeditems)])
-
-    def descr_count(self, space, w_obj):
-        """count(obj) -> number of times obj appears in the tuple"""
-        count = 0
-        for w_item in self.wrappeditems:
-            if space.eq_w(w_item, w_obj):
-                count += 1
-        return space.wrap(count)
-
-    @gateway.unwrap_spec(w_start=gateway.WrappedDefault(0),
-                         w_stop=gateway.WrappedDefault(sys.maxint))
-    def descr_index(self, space, w_obj, w_start, w_stop):
-        """index(obj, [start, [stop]]) -> first index that obj appears in the
-        tuple
-        """
-        length = len(self.wrappeditems)
-        start, stop = slicetype.unwrap_start_stop(space, length, w_start, w_stop)
-        for i in range(start, min(stop, length)):
-            w_item = self.wrappeditems[i]
-            if space.eq_w(w_item, w_obj):
-                return space.wrap(i)
-        raise OperationError(space.w_ValueError,
-                             space.wrap("tuple.index(x): x not in tuple"))
-
-W_TupleObject.typedef = StdTypeDef("tuple",
-    __doc__ = '''tuple() -> an empty tuple
-tuple(sequence) -> tuple initialized from sequence's items
-
-If the argument is a tuple, the return value is the same object.''',
-    __new__ = gateway.interp2app(W_TupleObject.descr_new),
-    __repr__ = gateway.interp2app(W_TupleObject.descr_repr),
-    __hash__ = gateway.interp2app(W_TupleObject.descr_hash),
-
-    __eq__ = gateway.interp2app(W_TupleObject.descr_eq),
-    __ne__ = gateway.interp2app(W_TupleObject.descr_ne),
-    __lt__ = gateway.interp2app(W_TupleObject.descr_lt),
-    __le__ = gateway.interp2app(W_TupleObject.descr_le),
-    __gt__ = gateway.interp2app(W_TupleObject.descr_gt),
-    __ge__ = gateway.interp2app(W_TupleObject.descr_ge),
-
-    __len__ = gateway.interp2app(W_TupleObject.descr_len),
-    __iter__ = gateway.interp2app(W_TupleObject.descr_iter),
-    __contains__ = gateway.interp2app(W_TupleObject.descr_contains),
-
-    __add__ = gateway.interp2app(W_TupleObject.descr_add),
-    __mul__ = gateway.interp2app(W_TupleObject.descr_mul),
-    __rmul__ = gateway.interp2app(W_TupleObject.descr_mul),
-
-    __getitem__ = gateway.interp2app(W_TupleObject.descr_getitem),
-    __getslice__ = gateway.interp2app(W_TupleObject.descr_getslice),
-
-    __getnewargs__ = gateway.interp2app(W_TupleObject.descr_getnewargs),
-    count = gateway.interp2app(W_TupleObject.descr_count),
-    index = gateway.interp2app(W_TupleObject.descr_index)
-)
+    def getitem(self, space, index):
+        try:
+            return self.wrappeditems[index]
+        except IndexError:
+            raise OperationError(space.w_IndexError,
+                                 space.wrap("tuple index out of range"))
 
 registerimplementation(W_TupleObject)
 


More information about the pypy-commit mailing list