[pypy-commit] pypy gc-del-3: update semispace
arigo
pypy.commits at gmail.com
Wed May 4 12:11:15 EDT 2016
Author: Armin Rigo <arigo at tunes.org>
Branch: gc-del-3
Changeset: r84191:6343ed75104e
Date: 2016-05-04 18:11 +0200
http://bitbucket.org/pypy/pypy/changeset/6343ed75104e/
Log: update semispace
diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py
--- a/rpython/memory/gc/base.py
+++ b/rpython/memory/gc/base.py
@@ -347,6 +347,32 @@
i += 1
enum_pending_finalizers._annspecialcase_ = 'specialize:arg(1)'
+ def _copy_pending_finalizers_deque(self, deque, copy_fn):
+ tmp = self.AddressDeque()
+ while deque.non_empty():
+ obj = deque.popleft()
+ tmp.append(copy_fn(obj))
+ while tmp.non_empty():
+ deque.append(tmp.popleft())
+ tmp.delete()
+
+ def copy_pending_finalizers(self, copy_fn):
+ "NOTE: not very efficient, but only for SemiSpaceGC and subclasses"
+ self._copy_pending_finalizers_deque(
+ self.run_old_style_finalizers, copy_fn)
+ handlers = self.finalizer_handlers()
+ i = 0
+ while i < len(handlers):
+ h = handlers[i]
+ self._copy_pending_finalizers_deque(
+ self._adr2deque(h.deque), copy_fn)
+ i += 1
+
+ def call_destructor(self, obj):
+ destructor = self.destructor_or_custom_trace(self.get_type_id(obj))
+ ll_assert(bool(destructor), "no destructor found")
+ destructor(obj)
+
def debug_check_consistency(self):
"""To use after a collection. If self.DEBUG is set, this
enumerates all roots and traces all objects to check if we didn't
@@ -402,8 +428,6 @@
while self.run_old_style_finalizers.non_empty():
obj = self.run_old_style_finalizers.popleft()
typeid = self.get_type_id(obj)
- ll_assert(self.is_old_style_finalizer(typeid),
- "bogus old-style finalizer")
finalizer = self.destructor_or_custom_trace(typeid)
finalizer(obj)
finally:
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
@@ -2602,11 +2602,6 @@
# ----------
# Finalizers
- def call_destructor(self, obj):
- destructor = self.destructor_or_custom_trace(self.get_type_id(obj))
- ll_assert(bool(destructor), "no destructor found")
- destructor(obj)
-
def deal_with_young_objects_with_destructors(self):
"""We can reasonably assume that destructors don't do
anything fancy and *just* call them. Among other things
diff --git a/rpython/memory/gc/semispace.py b/rpython/memory/gc/semispace.py
--- a/rpython/memory/gc/semispace.py
+++ b/rpython/memory/gc/semispace.py
@@ -111,7 +111,9 @@
# self.objects_with_light_finalizers.append(result + size_gc_header)
#else:
if has_finalizer:
+ from rpython.rtyper.lltypesystem import rffi
self.objects_with_finalizers.append(result + size_gc_header)
+ self.objects_with_finalizers.append(rffi.cast(llmemory.Address, -1))
if contains_weakptr:
self.objects_with_weakrefs.append(result + size_gc_header)
return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF)
@@ -149,6 +151,13 @@
else:
return False
+ def register_finalizer(self, fq_index, gcobj):
+ from rpython.rtyper.lltypesystem import rffi
+ obj = llmemory.cast_ptr_to_adr(gcobj)
+ fq_index = rffi.cast(llmemory.Address, fq_index)
+ self.objects_with_finalizers.append(obj)
+ self.objects_with_finalizers.append(fq_index)
+
def obtain_free_space(self, needed):
# a bit of tweaking to maximize the performance and minimize the
# amount of code in an inlined version of malloc_fixedsize_clear()
@@ -268,8 +277,7 @@
scan = self.free = tospace
self.starting_full_collect()
self.collect_roots()
- if self.run_finalizers.non_empty():
- self.update_run_finalizers()
+ self.copy_pending_finalizers(self.copy)
scan = self.scan_copied(scan)
if self.objects_with_light_finalizers.non_empty():
self.deal_with_objects_with_light_finalizers()
@@ -499,8 +507,7 @@
if self.surviving(obj):
new_objects.append(self.get_forwarding_address(obj))
else:
- finalizer = self.getfinalizer(self.get_type_id(obj))
- finalizer(obj)
+ self.call_destructor(obj)
self.objects_with_light_finalizers.delete()
self.objects_with_light_finalizers = new_objects
@@ -517,12 +524,15 @@
self.tmpstack = self.AddressStack()
while self.objects_with_finalizers.non_empty():
x = self.objects_with_finalizers.popleft()
+ fq_nr = self.objects_with_finalizers.popleft()
ll_assert(self._finalization_state(x) != 1,
"bad finalization state 1")
if self.surviving(x):
new_with_finalizer.append(self.get_forwarding_address(x))
+ new_with_finalizer.append(fq_nr)
continue
marked.append(x)
+ marked.append(fq_nr)
pending.append(x)
while pending.non_empty():
y = pending.pop()
@@ -537,17 +547,21 @@
while marked.non_empty():
x = marked.popleft()
+ fq_nr = marked.popleft()
state = self._finalization_state(x)
ll_assert(state >= 2, "unexpected finalization state < 2")
newx = self.get_forwarding_address(x)
if state == 2:
- self.run_finalizers.append(newx)
+ from rpython.rtyper.lltypesystem import rffi
+ fq_index = rffi.cast(lltype.Signed, fq_nr)
+ self.mark_finalizer_to_run(fq_index, newx)
# we must also fix the state from 2 to 3 here, otherwise
# we leave the GCFLAG_FINALIZATION_ORDERING bit behind
# which will confuse the next collection
self._recursively_bump_finalization_state_from_2_to_3(x)
else:
new_with_finalizer.append(newx)
+ new_with_finalizer.append(fq_nr)
self.tmpstack.delete()
pending.delete()
@@ -627,16 +641,6 @@
self.objects_with_weakrefs.delete()
self.objects_with_weakrefs = new_with_weakref
- def update_run_finalizers(self):
- # we are in an inner collection, caused by a finalizer
- # the run_finalizers objects need to be copied
- new_run_finalizer = self.AddressDeque()
- while self.run_finalizers.non_empty():
- obj = self.run_finalizers.popleft()
- new_run_finalizer.append(self.copy(obj))
- self.run_finalizers.delete()
- self.run_finalizers = new_run_finalizer
-
def _is_external(self, obj):
return (self.header(obj).tid & GCFLAG_EXTERNAL) != 0
More information about the pypy-commit
mailing list