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