Commits

Tobias Pape committed 0365f15 Merge

merge default

Comments (0)

Files changed (9)

pypy/doc/whatsnew-head.rst

 
 .. branch: test-58c3d8552833
 Fix for getarrayitem_gc_pure optimization
+
+.. branch: simple-range-strategy
+Implements SimpleRangeListStrategy for case range(n) where n is a positive number.
+Makes some traces nicer by getting rid of multiplication for calculating loop counter
+and propagates that n > 0 further to get rid of guards.

pypy/module/__pypy__/test/test_special.py

         l = [1.1, 2.2, 3.3]
         assert list_strategy(l) == "float"
         l = range(3)
+        assert list_strategy(l) == "simple_range"
+        l = range(1, 2)
         assert list_strategy(l) == "range"
         l = [1, "b", 3]
         assert list_strategy(l) == "object"

pypy/module/_pypyjson/targetjson.py

 sys.path.insert(0, str(ROOT))
 
 import time
-from rpython.rlib.streamio import open_file_as_stream
 from pypy.interpreter.error import OperationError
 from pypy.module._pypyjson.interp_decoder import loads
 
 
-
 ## MSG = open('msg.json').read()
 
 class W_Root(object):
 
     def wrapfloat(self, x):
         return W_Float(x)
-    
+
     def wrap(self, x):
         if isinstance(x, int):
             return W_Int(x)
 
 def myloads(msg):
     return loads(fakespace, W_String(msg))
-    
 
 def bench(title, N, fn, arg):
     a = time.clock()
         return 1
     filename = argv[1]
     N = int(argv[2])
-    f = open_file_as_stream(filename)
-    msg = f.readall()
-    
+    f = open(filename)
+    msg = f.read()
+
     try:
         bench('loads     ', N, myloads,  msg)
     except OperationError, e:
         print 'Error', e._compute_value(fakespace)
-        
+
     return 0
 
 # _____ Define and setup target ___

pypy/module/gc/interp_gc.py

 from pypy.interpreter.gateway import unwrap_spec
 from pypy.interpreter.error import OperationError
 from rpython.rlib import rgc
-from rpython.rlib.streamio import open_file_as_stream
+
 
 @unwrap_spec(generation=int)
 def collect(space, generation=0):
     if not tb:
         raise OperationError(space.w_RuntimeError,
                              space.wrap("Wrong GC"))
-    f = open_file_as_stream(filename, mode="w")
+    f = open(filename, mode="w")
     for i in range(len(tb)):
         f.write("%d %d " % (tb[i].count, tb[i].size))
         f.write(",".join([str(tb[i].links[j]) for j in range(len(tb))]) + "\n")

pypy/module/gc/test/test_gc.py

 import py
 
+
 class AppTestGC(object):
     def test_collect(self):
         import gc
         gc.enable()
         assert gc.isenabled()
 
+
 class AppTestGcDumpHeap(object):
     pytestmark = py.test.mark.xfail(run=False)
 
                 self.count = count
                 self.size = size
                 self.links = links
-        
+
         def fake_heap_stats():
             return [X(1, 12, [0, 0]), X(2, 10, [10, 0])]
-        
+
         cls._heap_stats = rgc._heap_stats
         rgc._heap_stats = fake_heap_stats
         fname = udir.join('gcdump.log')
     def teardown_class(cls):
         import py
         from rpython.rlib import rgc
-        
+
         rgc._heap_stats = cls._heap_stats
         assert py.path.local(cls._fname).read() == '1 12 0,0\n2 10 10,0\n'
-    
+
     def test_gc_heap_stats(self):
         import gc
         gc.dump_heap_stats(self.fname)
         for r in rlist:
             assert r() is None
 
+
 class AppTestGcMapDictIndexCache(AppTestGcMethodCache):
     spaceconfig = {"objspace.std.withmethodcache": True,
                    "objspace.std.withmapdict": True}

pypy/objspace/std/listobject.py

     if length <= 0:
         strategy = space.fromcache(EmptyListStrategy)
         storage = strategy.erase(None)
+    elif start == 0 and step == 1:
+        strategy = space.fromcache(SimpleRangeListStrategy)
+        assert length > 0
+        storage = strategy.erase((length,))
     else:
         strategy = space.fromcache(RangeListStrategy)
         storage = strategy.erase((start, step, length))
         self.sizehint = hint
 
 
-class RangeListStrategy(ListStrategy):
-    """RangeListStrategy is used when a list is created using the range method.
-    The storage is a tuple containing only three integers start, step and
-    length and elements are calculated based on these values.  On any operation
-    destroying the range (inserting, appending non-ints) the strategy is
-    switched to IntegerListStrategy."""
-
-    _applevel_repr = "range"
-
+class BaseRangeListStrategy(ListStrategy):
     def switch_to_integer_strategy(self, w_list):
         items = self._getitems_range(w_list, False)
         strategy = w_list.strategy = self.space.fromcache(IntegerListStrategy)
     def init_from_list_w(self, w_list, list_w):
         raise NotImplementedError
 
-    erase, unerase = rerased.new_erasing_pair("range")
-    erase = staticmethod(erase)
-    unerase = staticmethod(unerase)
-
     def clone(self, w_list):
         storage = w_list.lstorage  # lstorage is tuple, no need to clone
         w_clone = W_ListObject.from_storage_and_strategy(self.space, storage,
         w_other.strategy = self
         w_other.lstorage = w_list.lstorage
 
+    def getitem(self, w_list, i):
+        return self.wrap(self._getitem_unwrapped(w_list, i))
+
+    def getitems_int(self, w_list):
+        return self._getitems_range(w_list, False)
+
+    def getitems_copy(self, w_list):
+        return self._getitems_range(w_list, True)
+
+    def getstorage_copy(self, w_list):
+        # tuple is immutable
+        return w_list.lstorage
+
+    @jit.dont_look_inside
+    def getitems_fixedsize(self, w_list):
+        return self._getitems_range_unroll(w_list, True)
+
+    def getitems_unroll(self, w_list):
+        return self._getitems_range_unroll(w_list, True)
+
+    def getslice(self, w_list, start, stop, step, length):
+        self.switch_to_integer_strategy(w_list)
+        return w_list.getslice(start, stop, step, length)
+
+    def append(self, w_list, w_item):
+        if type(w_item) is W_IntObject:
+            self.switch_to_integer_strategy(w_list)
+        else:
+            w_list.switch_to_object_strategy()
+        w_list.append(w_item)
+
+    def inplace_mul(self, w_list, times):
+        self.switch_to_integer_strategy(w_list)
+        w_list.inplace_mul(times)
+
+    def deleteslice(self, w_list, start, step, slicelength):
+        self.switch_to_integer_strategy(w_list)
+        w_list.deleteslice(start, step, slicelength)
+
+    def setitem(self, w_list, index, w_item):
+        self.switch_to_integer_strategy(w_list)
+        w_list.setitem(index, w_item)
+
+    def setslice(self, w_list, start, step, slicelength, sequence_w):
+        self.switch_to_integer_strategy(w_list)
+        w_list.setslice(start, step, slicelength, sequence_w)
+
+    def insert(self, w_list, index, w_item):
+        self.switch_to_integer_strategy(w_list)
+        w_list.insert(index, w_item)
+
+    def extend(self, w_list, w_any):
+        self.switch_to_integer_strategy(w_list)
+        w_list.extend(w_any)
+
+    def reverse(self, w_list):
+        self.switch_to_integer_strategy(w_list)
+        w_list.reverse()
+
+    def sort(self, w_list, reverse):
+        step = self.step(w_list)
+        if step > 0 and reverse or step < 0 and not reverse:
+            self.switch_to_integer_strategy(w_list)
+            w_list.sort(reverse)
+
+
+class SimpleRangeListStrategy(BaseRangeListStrategy):
+    """SimpleRangeListStrategy is used when a list is created using the range
+       method providing only positive length. The storage is a one element tuple
+       with positive integer storing length."""
+
+    _applevel_repr = "simple_range"
+
+    erase, unerase = rerased.new_erasing_pair("simple_range")
+    erase = staticmethod(erase)
+    unerase = staticmethod(unerase)
+
+    def find(self, w_list, w_obj, startindex, stopindex):
+        if type(w_obj) is W_IntObject:
+            obj = self.unwrap(w_obj)
+            length = self.unerase(w_list.lstorage)[0]
+            if 0 <= obj < length and startindex <= obj < stopindex:
+                return obj
+            else:
+                raise ValueError
+        return ListStrategy.find(self, w_list, w_obj, startindex, stopindex)
+
+    def length(self, w_list):
+        return self.unerase(w_list.lstorage)[0]
+
+    def step(self, w_list):
+        return 1
+
+    def _getitem_unwrapped(self, w_list, i):
+        length = self.unerase(w_list.lstorage)[0]
+        assert length > 0
+        if 0 <= i < length:
+            return i
+        else:
+            raise IndexError
+
+    @specialize.arg(2)
+    def _getitems_range(self, w_list, wrap_items):
+        length = self.unerase(w_list.lstorage)[0]
+        if wrap_items:
+            r = [None] * length
+        else:
+            r = [0] * length
+        i = 0
+        while i < length:
+            if wrap_items:
+                r[i] = self.wrap(i)
+            else:
+                r[i] = i
+            i += 1
+
+        return r
+
+    _getitems_range_unroll = jit.unroll_safe(
+            func_with_new_name(_getitems_range, "_getitems_range_unroll"))
+
+    def pop_end(self, w_list):
+        new_length = self.unerase(w_list.lstorage)[0] - 1
+        w_result = self.wrap(new_length)
+        if new_length > 0:
+            w_list.lstorage = self.erase((new_length,))
+        else:
+            strategy = w_list.strategy = self.space.fromcache(EmptyListStrategy)
+            w_list.lstorage = strategy.erase(None)
+        return w_result
+
+    def pop(self, w_list, index):
+        self.switch_to_integer_strategy(w_list)
+        return w_list.pop(index)
+
+
+class RangeListStrategy(BaseRangeListStrategy):
+    """RangeListStrategy is used when a list is created using the range method.
+    The storage is a tuple containing only three integers start, step and
+    length and elements are calculated based on these values.  On any operation
+    destroying the range (inserting, appending non-ints) the strategy is
+    switched to IntegerListStrategy."""
+
+    _applevel_repr = "range"
+
+    erase, unerase = rerased.new_erasing_pair("range")
+    erase = staticmethod(erase)
+    unerase = staticmethod(unerase)
+
     def find(self, w_list, w_obj, startindex, stopindex):
         if type(w_obj) is W_IntObject:
             obj = self.unwrap(w_obj)
     def length(self, w_list):
         return self.unerase(w_list.lstorage)[2]
 
+    def step(self, w_list):
+        return self.unerase(w_list.lstorage)[1]
+
     def _getitem_unwrapped(self, w_list, i):
         v = self.unerase(w_list.lstorage)
         start = v[0]
             raise IndexError
         return start + i * step
 
-    def getitems_int(self, w_list):
-        return self._getitems_range(w_list, False)
-
-    def getitem(self, w_list, i):
-        return self.wrap(self._getitem_unwrapped(w_list, i))
-
-    def getitems_copy(self, w_list):
-        return self._getitems_range(w_list, True)
-
-    def getstorage_copy(self, w_list):
-        # tuple is unmutable
-        return w_list.lstorage
-
     @specialize.arg(2)
     def _getitems_range(self, w_list, wrap_items):
         l = self.unerase(w_list.lstorage)
 
         return r
 
-    @jit.dont_look_inside
-    def getitems_fixedsize(self, w_list):
-        return self._getitems_range_unroll(w_list, True)
-
-    def getitems_unroll(self, w_list):
-        return self._getitems_range_unroll(w_list, True)
     _getitems_range_unroll = jit.unroll_safe(
             func_with_new_name(_getitems_range, "_getitems_range_unroll"))
 
-    def getslice(self, w_list, start, stop, step, length):
-        self.switch_to_integer_strategy(w_list)
-        return w_list.getslice(start, stop, step, length)
-
-    def append(self, w_list, w_item):
-        if type(w_item) is W_IntObject:
-            self.switch_to_integer_strategy(w_list)
-        else:
-            w_list.switch_to_object_strategy()
-        w_list.append(w_item)
-
-    def inplace_mul(self, w_list, times):
-        self.switch_to_integer_strategy(w_list)
-        w_list.inplace_mul(times)
-
-    def deleteslice(self, w_list, start, step, slicelength):
-        self.switch_to_integer_strategy(w_list)
-        w_list.deleteslice(start, step, slicelength)
-
     def pop_end(self, w_list):
         start, step, length = self.unerase(w_list.lstorage)
         w_result = self.wrap(start + (length - 1) * step)
             self.switch_to_integer_strategy(w_list)
             return w_list.pop(index)
 
-    def setitem(self, w_list, index, w_item):
-        self.switch_to_integer_strategy(w_list)
-        w_list.setitem(index, w_item)
-
-    def setslice(self, w_list, start, step, slicelength, sequence_w):
-        self.switch_to_integer_strategy(w_list)
-        w_list.setslice(start, step, slicelength, sequence_w)
-
-    def sort(self, w_list, reverse):
-        step = self.unerase(w_list.lstorage)[1]
-        if step > 0 and reverse or step < 0 and not reverse:
-            self.switch_to_integer_strategy(w_list)
-            w_list.sort(reverse)
-
-    def insert(self, w_list, index, w_item):
-        self.switch_to_integer_strategy(w_list)
-        w_list.insert(index, w_item)
-
-    def extend(self, w_list, w_any):
-        self.switch_to_integer_strategy(w_list)
-        w_list.extend(w_any)
-
-    def reverse(self, w_list):
-        self.switch_to_integer_strategy(w_list)
-        w_list.reverse()
-
 
 class AbstractUnwrappedStrategy(object):
 
     _base_extend_from_list = _extend_from_list
 
     def _extend_from_list(self, w_list, w_other):
-        if w_other.strategy is self.space.fromcache(RangeListStrategy):
+        if isinstance(w_other.strategy, BaseRangeListStrategy):
             l = self.unerase(w_list.lstorage)
             other = w_other.getitems_int()
             assert other is not None

pypy/objspace/std/test/test_liststrategies.py

 import sys
-from pypy.objspace.std.listobject import W_ListObject, EmptyListStrategy, ObjectListStrategy, IntegerListStrategy, FloatListStrategy, BytesListStrategy, RangeListStrategy, make_range_list, UnicodeListStrategy
+from pypy.objspace.std.listobject import (
+    W_ListObject, EmptyListStrategy, ObjectListStrategy, IntegerListStrategy,
+    FloatListStrategy, BytesListStrategy, RangeListStrategy,
+    SimpleRangeListStrategy, make_range_list, UnicodeListStrategy)
 from pypy.objspace.std import listobject
 from pypy.objspace.std.test.test_listobject import TestW_ListObject
 
                           UnicodeListStrategy)
         assert isinstance(W_ListObject(space, [w(u'a'), w('b')]).strategy,
                           ObjectListStrategy) # mixed unicode and bytes
-                                       
+
     def test_empty_to_any(self):
         space = self.space
         w = space.wrap
     def test_setslice(self):
         space = self.space
         w = space.wrap
-        
+
         l = W_ListObject(space, [])
         assert isinstance(l.strategy, EmptyListStrategy)
         l.setslice(0, 1, 2, W_ListObject(space, [w(1), w(2), w(3)]))
     def test_empty_setslice_with_objectlist(self):
         space = self.space
         w = space.wrap
-        
+
         l = W_ListObject(space, [])
         o = W_ListObject(space, [space.wrap(1), space.wrap("2"), space.wrap(3)])
         l.setslice(0, 1, o.length(), o)
 
         empty = W_ListObject(space, [])
         assert isinstance(empty.strategy, EmptyListStrategy)
+        r = make_range_list(space, 0, 1, 10)
+        empty.extend(r)
+        assert isinstance(empty.strategy, SimpleRangeListStrategy)
+        assert space.is_true(space.eq(empty.getitem(1), w(1)))
+
+        empty = W_ListObject(space, [])
+        assert isinstance(empty.strategy, EmptyListStrategy)
         empty.extend(W_ListObject(space, [w(1), w(2), w(3)]))
         assert isinstance(empty.strategy, IntegerListStrategy)
 
         l.append(self.space.wrap(19))
         assert isinstance(l.strategy, IntegerListStrategy)
 
+    def test_simplerangelist(self):
+        l = make_range_list(self.space, 0, 1, 10)
+        assert isinstance(l.strategy, SimpleRangeListStrategy)
+        v = l.pop(5)
+        assert self.space.eq_w(v, self.space.wrap(5))
+        assert isinstance(l.strategy, IntegerListStrategy)
+
+        l = make_range_list(self.space, 0, 1, 10)
+        assert isinstance(l.strategy, SimpleRangeListStrategy)
+        v = l.pop(0)
+        assert self.space.eq_w(v, self.space.wrap(0))
+        assert isinstance(l.strategy, IntegerListStrategy)
+
+        l = make_range_list(self.space, 0, 1, 10)
+        assert isinstance(l.strategy, SimpleRangeListStrategy)
+        v = l.pop_end()
+        assert self.space.eq_w(v, self.space.wrap(9))
+        assert isinstance(l.strategy, SimpleRangeListStrategy)
+        v = l.pop_end()
+        assert self.space.eq_w(v, self.space.wrap(8))
+        assert isinstance(l.strategy, SimpleRangeListStrategy)
+
+        l = make_range_list(self.space, 0, 1, 5)
+        assert isinstance(l.strategy, SimpleRangeListStrategy)
+        l.append(self.space.wrap("string"))
+        assert isinstance(l.strategy, ObjectListStrategy)
+
+        l = make_range_list(self.space, 0,1,5)
+        assert isinstance(l.strategy, SimpleRangeListStrategy)
+        l.append(self.space.wrap(19))
+        assert isinstance(l.strategy, IntegerListStrategy)
+
+        l = make_range_list(self.space, 0,1,5)
+        assert isinstance(l.strategy, SimpleRangeListStrategy)
+        assert l.find(self.space.wrap(0)) == 0
+        assert l.find(self.space.wrap(4)) == 4
+
+        try:
+            l.find(self.space.wrap(5))
+        except ValueError:
+            pass
+        else:
+            assert False, "Did not raise ValueError"
+
+        try:
+            l.find(self.space.wrap(0), 5, 6)
+        except ValueError:
+            pass
+        else:
+            assert False, "Did not raise ValueError"
+
+        assert l.length() == 5
+
+        l = make_range_list(self.space, 0, 1, 1)
+        assert self.space.eq_w(l.pop(0), self.space.wrap(0))
+
+        l = make_range_list(self.space, 0, 1, 10)
+        l.sort(False)
+        assert isinstance(l.strategy, SimpleRangeListStrategy)
+
+        assert self.space.eq_w(l.getitem(5), self.space.wrap(5))
+
+        l = make_range_list(self.space, 0, 1, 1)
+        assert self.space.eq_w(l.pop_end(), self.space.wrap(0))
+        assert isinstance(l.strategy, EmptyListStrategy)
+
     def test_keep_range(self):
         # simple list
         l = make_range_list(self.space, 1,1,5)

pypy/objspace/std/test/test_rangeobject.py

         r.sort(key=lambda x: -x)
         assert r == range(9, -1, -1)
     def test_pop(self):
+        # RangeListStrategy
+        r = range(1, 10)
+        res = r.pop()
+        assert res == 9
+        assert self.not_forced(r)
+        assert repr(r) == repr(range(1, 9))
+        res = r.pop(0)
+        assert res == 1
+        assert self.not_forced(r)
+        assert repr(r) == repr(range(2, 9))
+        res = r.pop(len(r) - 1)
+        assert res == 8
+        assert self.not_forced(r)
+        assert repr(r) == repr(range(2, 8))
+        res = r.pop(2)
+        assert res == 4
+        assert not self.not_forced(r)
+        assert r == [2, 3, 5, 6, 7]
+        res = r.pop(2)
+        assert res == 5
+        assert not self.not_forced(r)
+        assert r == [2, 3, 6, 7]
+
+        # SimpleRangeListStrategy
         r = range(10)
         res = r.pop()
         assert res == 9
         assert self.not_forced(r)
-        assert repr(r) == repr(range(9))
+        res = r.pop()
+        assert res == 8
+        assert repr(r) == repr(range(8))
+        assert self.not_forced(r)
         res = r.pop(0)
         assert res == 0
-        assert self.not_forced(r)
-        assert repr(r) == repr(range(1, 9))
-        res = r.pop(len(r) - 1)
-        assert res == 8
-        assert self.not_forced(r)
-        assert repr(r) == repr(range(1, 8))
-        res = r.pop(2)
-        assert res == 3
         assert not self.not_forced(r)
-        assert r == [1, 2, 4, 5, 6, 7]
-        res = r.pop(2)
-        assert res == 4
-        assert not self.not_forced(r)
-        assert r == [1, 2, 5, 6, 7]
-       
+        assert r == [1, 2, 3, 4, 5, 6, 7]
+
     def test_reduce(self):
         it = iter(range(10))
         assert it.next() == 0

pypy/tool/gdb_pypy.py

 (gdb) python execfile('/path/to/gdb_pypy.py')
 """
 
-from __future__ import with_statement
-
 import re
 import sys
 import os.path
         """
         Returns a mapping offset --> description
         """
+        import tempfile
+        import zlib
         vname = 'pypy_g_rpython_memory_gctypelayout_GCData.gcd_inst_typeids_z'
         length = int(self.gdb.parse_and_eval('*(long*)%s' % vname))
         vstart = '(char*)(((long*)%s)+1)' % vname
-        self.gdb.execute('dump binary memory /tmp/typeids.txt.z %s %s+%d'
-                         % (vstart, vstart, length))
-        s = open('/tmp/typeids.txt.z', 'rb').read()
-        import zlib; typeids_txt = zlib.decompress(s)
-        typeids = TypeIdsMap(typeids_txt.splitlines(True), self.gdb)
-        return typeids
+        with tempfile.NamedTemporaryFile('rb') as fobj:
+            self.gdb.execute('dump binary memory %s %s %s+%d' %
+                             (fobj.name, vstart, vstart, length))
+            data = fobj.read()
+        return TypeIdsMap(zlib.decompress(data).splitlines(True), self.gdb)
 
 
 class TypeIdsMap(object):