Author: Armin Rigo <[email protected]>
Branch: cpyext-gc-support
Changeset: r80295:e7d59747605b
Date: 2015-10-16 21:03 +0200
http://bitbucket.org/pypy/pypy/changeset/e7d59747605b/

Log:    Need more care in handling rrc_p_dict to make sure
        rawrefcount_from_obj() really returns NULL on unlinked objects. Use
        NULL-valued entries.

diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -2781,6 +2781,9 @@
         assert self.rrc_p_list_old  .length() == 0
         assert self.rrc_o_list_young.length() == 0
         assert self.rrc_o_list_old  .length() == 0
+        def check_value_is_null(key, value, ignore):
+            assert value == llmemory.NULL
+        self.rrc_p_dict.foreach(check_value_is_null, None)
 
     def rawrefcount_create_link_pypy(self, gcobj, pyobject):
         ll_assert(self.rrc_enabled, "rawrefcount.init not called")
@@ -2844,14 +2847,14 @@
     def _rrc_minor_free(self, pyobject, surviving_list, surviving_dict):
         intobj = self._pyobj(pyobject).ob_pypy_link
         obj = llmemory.cast_int_to_adr(intobj)
+        if surviving_dict:
+            surviving_dict.setitem(obj, llmemory.NULL)
         if self.is_in_nursery(obj):
             if self.is_forwarded(obj):
                 # Common case: survives and moves
                 obj = self.get_forwarding_address(obj)
                 intobj = llmemory.cast_adr_to_int(obj, mode="symbolic")
                 self._pyobj(pyobject).ob_pypy_link = intobj
-                if surviving_dict:
-                    surviving_dict.setitem(obj, pyobject)
                 surviving = True
             else:
                 surviving = False
@@ -2859,13 +2862,14 @@
               self.young_rawmalloced_objects.contains(pointing_to)):
             # young weakref to a young raw-malloced object
             if self.header(pointing_to).tid & GCFLAG_VISITED_RMY:
-                # surviving_dict is already up-to-date: the key doesn't move
                 surviving = True    # survives, but does not move
             else:
                 surviving = False
         #
         if surviving:
             surviving_list.append(pyobject)
+            if surviving_dict:
+                surviving_dict.setitem(obj, pyobject)
         else:
             self._rrc_free(pyobject)
 
@@ -2907,19 +2911,15 @@
             self.visit_all_objects()
 
     def rrc_major_collection_free(self):
+        length_estimate = self.rrc_p_dict.length()
+        self.rrc_p_dict.delete()
+        self.rrc_p_dict = new_p_dict = self.AddressDict(length_estimate)
         new_p_list = self.AddressStack()
-        if self.rrc_p_dict.length() > self.rrc_p_list_old.length() * 2 + 30:
-            new_p_dict = self.AddressDict()
-        else:
-            new_p_dict = self.null_address_dict()
         while self.rrc_p_list_old.non_empty():
             self._rrc_major_free(self.rrc_p_list_old.pop(), new_p_list,
                                                             new_p_dict)
         self.rrc_p_list_old.delete()
         self.rrc_p_list_old = new_p_list
-        if new_p_dict:
-            self.rrc_p_dict.delete()
-            self.rrc_p_dict = new_p_dict
         #
         new_o_list = self.AddressStack()
         no_o_dict = self.null_address_dict()
@@ -2935,6 +2935,6 @@
         if self.header(obj).tid & GCFLAG_VISITED:
             surviving_list.append(pyobject)
             if surviving_dict:
-                surviving_dict.setitem(obj, pyobject)
+                surviving_dict.insertclean(obj, pyobject)
         else:
             self._rrc_free(pyobject)
diff --git a/rpython/memory/gc/test/test_rawrefcount.py 
b/rpython/memory/gc/test/test_rawrefcount.py
--- a/rpython/memory/gc/test/test_rawrefcount.py
+++ b/rpython/memory/gc/test/test_rawrefcount.py
@@ -55,10 +55,6 @@
             if not is_pyobj:
                 assert self.gc.rawrefcount_from_obj(p1ref) == r1addr
             else:
-                # NB. this is not strictly always the case, because of
-                # dead entries remaining behind; but for these simple
-                # tests it is useful to detect unexpected rrc_p_dict
-                # entries
                 assert self.gc.rawrefcount_from_obj(p1ref) == llmemory.NULL
             return p1
         return p1, p1ref, r1, r1addr, check_alive
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to