[pypy-svn] r55034 - in pypy/branch/hybrid-io/pypy/rpython/memory: . gc test

arigo at codespeak.net arigo at codespeak.net
Tue May 20 19:36:28 CEST 2008


Author: arigo
Date: Tue May 20 19:36:26 2008
New Revision: 55034

Modified:
   pypy/branch/hybrid-io/pypy/rpython/memory/gc/hybrid.py
   pypy/branch/hybrid-io/pypy/rpython/memory/support.py
   pypy/branch/hybrid-io/pypy/rpython/memory/test/test_support.py
Log:
Use a remove() method on the AddressStack to cheaply locate and
remove an address that we expect to be near the top.


Modified: pypy/branch/hybrid-io/pypy/rpython/memory/gc/hybrid.py
==============================================================================
--- pypy/branch/hybrid-io/pypy/rpython/memory/gc/hybrid.py	(original)
+++ pypy/branch/hybrid-io/pypy/rpython/memory/gc/hybrid.py	Tue May 20 19:36:26 2008
@@ -234,7 +234,7 @@
         oldlength = (addr + lengthofs).signed[0]
         old_tot_size = size_gc_header + fixedsize + oldlength * itemsize
         source_addr = addr - size_gc_header
-        self._remove_addr_from_resizable_objects(addr)
+        self.gen2_resizable_objects.remove(addr)
         if grow:
             result = llop.raw_realloc_grow(llmemory.Address, source_addr,
                                            old_tot_size, tot_size)
@@ -254,16 +254,6 @@
         (result + size_gc_header + lengthofs).signed[0] = newlength
         return llmemory.cast_adr_to_ptr(result + size_gc_header, llmemory.GCREF)
 
-    def _remove_addr_from_resizable_objects(self, addr):
-        objects = self.gen2_resizable_objects
-        newstack = self.AddressStack()
-        while objects.non_empty():
-            obj = objects.pop()
-            if obj != addr:
-                newstack.append(obj)
-        objects.delete()
-        self.gen2_resizable_objects = newstack
-
     def can_move(self, addr):
         tid = self.header(addr).tid
         return not (tid & GCFLAG_EXTERNAL)

Modified: pypy/branch/hybrid-io/pypy/rpython/memory/support.py
==============================================================================
--- pypy/branch/hybrid-io/pypy/rpython/memory/support.py	(original)
+++ pypy/branch/hybrid-io/pypy/rpython/memory/support.py	Tue May 20 19:36:26 2008
@@ -138,6 +138,22 @@
             self.foreach(_add_in_dict, result)
             return result
 
+        def remove(self, addr):
+            """Remove 'addr' from the stack.  The addr *must* be in the list,
+            and preferrably near the top.
+            """
+            got = self.pop()
+            chunk = self.chunk
+            count = self.used_in_last_chunk
+            while got != addr:
+                count -= 1
+                if count < 0:
+                    chunk = chunk.next
+                    count = chunk_size - 1
+                next = chunk.items[count]
+                chunk.items[count] = got
+                got = next
+
     cache[chunk_size] = AddressStack
     return AddressStack
 

Modified: pypy/branch/hybrid-io/pypy/rpython/memory/test/test_support.py
==============================================================================
--- pypy/branch/hybrid-io/pypy/rpython/memory/test/test_support.py	(original)
+++ pypy/branch/hybrid-io/pypy/rpython/memory/test/test_support.py	Tue May 20 19:36:26 2008
@@ -78,6 +78,22 @@
         ll.foreach(callback, 42)
         assert seen == addrs or seen[::-1] == addrs   # order not guaranteed
 
+    def test_remove(self):
+        AddressStack = get_address_stack()
+        addrs = [raw_malloc(llmemory.sizeof(lltype.Signed))
+                 for i in range(2200)]
+        ll = AddressStack()
+        for i in range(2200):
+            ll.append(addrs[i])
+        ll.remove(addrs[-400])
+        expected = range(2200)
+        del expected[-400]
+        expected.reverse()
+        for i in expected:
+            a = ll.pop()
+            assert a == addrs[i]
+        assert not ll.non_empty()
+
 
 class TestAddressDeque:
     def test_big_access(self):



More information about the Pypy-commit mailing list