[pypy-commit] pypy concurrent-marksweep: Also try to sweep the large objects.

arigo noreply at buildbot.pypy.org
Fri Oct 7 17:17:17 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: concurrent-marksweep
Changeset: r47859:513203521539
Date: 2011-10-07 17:17 +0200
http://bitbucket.org/pypy/pypy/changeset/513203521539/

Log:	Also try to sweep the large objects.

diff --git a/pypy/rpython/memory/gc/concurrentms.py b/pypy/rpython/memory/gc/concurrentms.py
--- a/pypy/rpython/memory/gc/concurrentms.py
+++ b/pypy/rpython/memory/gc/concurrentms.py
@@ -86,6 +86,7 @@
         # 1-35: free list of non-allocated locations; 0: unused
         self.free_lists    = list_of_addresses_per_small_size()
         # 1-35: head and tail of the free list built by the collector thread
+        # 0: head and tail of the linked list of surviving large objects
         self.collect_heads = list_of_addresses_per_small_size()
         self.collect_tails = list_of_addresses_per_small_size()
         #
@@ -136,12 +137,16 @@
 
     def _teardown(self):
         "NOT_RPYTHON.  Stop the collector thread after tests have run."
+        if self._teardown_now:
+            return
         self.wait_for_the_end_of_collection()
         #
         # start the next collection, but with "stop" in _teardown_now,
         # which should shut down the collector thread
         self._teardown_now.append("stop")
-        self.collect()
+        self.ready_to_start_lock.release()
+        self.acquire(self.finished_lock)
+        del self.ready_to_start_lock, self.finished_lock
 
     def get_type_id(self, obj):
         return self.header(obj).typeid16
@@ -390,7 +395,7 @@
             # Grab the results of the last collection: read the collector's
             # 'collect_heads/collect_tails' and merge them with the mutator's
             # 'free_lists'.
-            n = 1
+            n = 0
             while n < self.pagelists_length:
                 if self.collect_tails[n] != NULL:
                     self.collect_tails[n].address[0] = self.free_lists[n]
@@ -545,18 +550,40 @@
         self.gray_objects.append(root.address[0])
 
     def collector_sweep(self):
+        self._collect_sweep_large_objects()
         n = 1
         while n < self.pagelists_length:
             self._collect_sweep_pages(n)
             n += 1
 
+    def _collect_sweep_large_objects(self):
+        block = self.collect_pages[0]
+        nonmarked = self.other_mark(self.current_mark)
+        linked_list = NULL
+        first_block_in_linked_list = NULL
+        while block != llmemory.NULL:
+            hdr = block + size_of_addr
+            if maybe_read_mark_byte(hdr) == nonmarked:
+                # the object is still not marked.  Free it.
+                llarena.arena_free(block)
+                #
+            else:
+                # the object was marked: relink it
+                block.address[0] = linked_list
+                linked_list = block
+                if first_block_in_linked_list == NULL:
+                    first_block_in_linked_list = block
+        #
+        self.collect_heads[0] = linked_list
+        self.collect_tails[0] = first_block_in_linked_list
+
     def _collect_sweep_pages(self, n):
         # sweep all pages from the linked list starting at 'page',
         # containing objects of fixed size 'object_size'.
         page = self.collect_pages[n]
         object_size = n << WORD_POWER_2
         linked_list = NULL
-        first_freed_object = NULL
+        first_loc_in_linked_list = NULL
         nonmarked = self.other_mark(self.current_mark)
         while page != llmemory.NULL:
             i = self.page_size - object_size
@@ -573,8 +600,8 @@
                     llarena.arena_reserve(hdr, size_of_addr)
                     hdr.address[0] = linked_list
                     linked_list = hdr
-                    if first_freed_object == NULL:
-                        first_freed_object = hdr
+                    if first_loc_in_linked_list == NULL:
+                        first_loc_in_linked_list = hdr
                     # XXX detect when the whole page is freed again
                     #
                     # Clear the data, in prevision for the following
@@ -587,7 +614,7 @@
             page = page.address[0]
         #
         self.collect_heads[n] = linked_list
-        self.collect_tails[n] = first_freed_object
+        self.collect_tails[n] = first_loc_in_linked_list
 
 
 def maybe_read_mark_byte(addr):


More information about the pypy-commit mailing list