[pypy-commit] pypy cpyext-gc-support: Tweak the dictionary pypy->pyobj: split it into two dicts, should
arigo
noreply at buildbot.pypy.org
Tue Oct 20 10:48:56 EDT 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: cpyext-gc-support
Changeset: r80355:c5471ee4a011
Date: 2015-10-20 16:48 +0200
http://bitbucket.org/pypy/pypy/changeset/c5471ee4a011/
Log: Tweak the dictionary pypy->pyobj: split it into two dicts, should
avoid the dict filling quickly with many NULLs until the next major
collection
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
@@ -2770,7 +2770,8 @@
self.rrc_p_list_old = self.AddressStack()
self.rrc_o_list_young = self.AddressStack()
self.rrc_o_list_old = self.AddressStack()
- self.rrc_p_dict = self.AddressDict()
+ self.rrc_p_dict = self.AddressDict() # non-nursery keys only
+ self.rrc_p_dict_nurs = self.AddressDict() # nursery keys only
p = lltype.malloc(self._ADDRARRAY, 1, flavor='raw',
track_allocation=False)
self.rrc_singleaddr = llmemory.cast_ptr_to_adr(p)
@@ -2786,17 +2787,23 @@
def check_value_is_null(key, value, ignore):
assert value == llmemory.NULL
self.rrc_p_dict.foreach(check_value_is_null, None)
+ self.rrc_p_dict_nurs.foreach(check_value_is_null, None)
def rawrefcount_create_link_pypy(self, gcobj, pyobject):
ll_assert(self.rrc_enabled, "rawrefcount.init not called")
obj = llmemory.cast_ptr_to_adr(gcobj)
- if self.is_young_object(obj):
- self.rrc_p_list_young.append(pyobject)
- else:
- self.rrc_p_list_old.append(pyobject)
objint = llmemory.cast_adr_to_int(obj, "symbolic")
self._pyobj(pyobject).ob_pypy_link = objint
- self.rrc_p_dict.setitem(obj, pyobject)
+ #
+ lst = self.rrc_p_list_young
+ if self.is_in_nursery(obj):
+ dct = self.rrc_p_dict_nurs
+ else:
+ dct = self.rrc_p_dict
+ if not self.is_young_object(obj):
+ lst = self.rrc_p_list_old
+ lst.append(pyobject)
+ dct.setitem(obj, pyobject)
def rawrefcount_create_link_pyobj(self, gcobj, pyobject):
ll_assert(self.rrc_enabled, "rawrefcount.init not called")
@@ -2811,7 +2818,11 @@
def rawrefcount_from_obj(self, gcobj):
obj = llmemory.cast_ptr_to_adr(gcobj)
- return self.rrc_p_dict.get(obj)
+ if self.is_in_nursery(obj):
+ dct = self.rrc_p_dict_nurs
+ else:
+ dct = self.rrc_p_dict
+ return dct.get(obj)
def rawrefcount_to_obj(self, pyobject):
obj = llmemory.cast_int_to_adr(self._pyobj(pyobject).ob_pypy_link)
@@ -2819,6 +2830,9 @@
def rrc_minor_collection_trace(self):
+ length_estimate = self.rrc_p_dict_nurs.length()
+ self.rrc_p_dict_nurs.delete()
+ self.rrc_p_dict_nurs = self.AddressDict(length_estimate)
self.rrc_p_list_young.foreach(self._rrc_minor_trace,
self.rrc_singleaddr)
@@ -2836,6 +2850,7 @@
self._trace_drag_out(singleaddr, llmemory.NULL)
def rrc_minor_collection_free(self):
+ ll_assert(self.rrc_p_dict_nurs.length() == 0, "p_dict_nurs not empty 1")
lst = self.rrc_p_list_young
while lst.non_empty():
self._rrc_minor_free(lst.pop(), self.rrc_p_list_old,
@@ -2849,8 +2864,6 @@
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
@@ -2858,6 +2871,10 @@
intobj = llmemory.cast_adr_to_int(obj, "symbolic")
self._pyobj(pyobject).ob_pypy_link = intobj
surviving = True
+ if surviving_dict:
+ # Surviving nursery object: was originally in
+ # rrc_p_dict_nurs and now must be put into rrc_p_dict
+ surviving_dict.setitem(obj, pyobject)
else:
surviving = False
elif (bool(self.young_rawmalloced_objects) and
@@ -2867,14 +2884,16 @@
surviving = True # survives, but does not move
else:
surviving = False
+ if surviving_dict:
+ # Dying young large object: was in rrc_p_dict,
+ # must be deleted
+ surviving_dict.setitem(obj, llmemory.NULL)
else:
ll_assert(False, "rrc_X_list_young contains non-young obj")
return
#
if surviving:
surviving_list.append(pyobject)
- if surviving_dict:
- surviving_dict.setitem(obj, pyobject)
else:
self._rrc_free(pyobject)
@@ -2920,6 +2939,7 @@
self.visit_all_objects()
def rrc_major_collection_free(self):
+ ll_assert(self.rrc_p_dict_nurs.length() == 0, "p_dict_nurs not empty 2")
length_estimate = self.rrc_p_dict.length()
self.rrc_p_dict.delete()
self.rrc_p_dict = new_p_dict = self.AddressDict(length_estimate)
More information about the pypy-commit
mailing list