[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