[pypy-commit] pypy lightweight-finalizers: add this optimization to minimark. unclear if more tests are needed
fijal
noreply at buildbot.pypy.org
Sun Oct 9 19:04:38 CEST 2011
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: lightweight-finalizers
Changeset: r47903:cfa63208b692
Date: 2011-10-09 19:04 +0200
http://bitbucket.org/pypy/pypy/changeset/cfa63208b692/
Log: add this optimization to minimark. unclear if more tests are needed
diff --git a/pypy/rpython/memory/gc/minimark.py b/pypy/rpython/memory/gc/minimark.py
--- a/pypy/rpython/memory/gc/minimark.py
+++ b/pypy/rpython/memory/gc/minimark.py
@@ -290,6 +290,7 @@
#
# A list of all objects with finalizers (these are never young).
self.objects_with_finalizers = self.AddressDeque()
+ self.young_objects_with_light_finalizers = self.AddressStack()
#
# Two lists of the objects with weakrefs. No weakref can be an
# old object weakly pointing to a young object: indeed, weakrefs
@@ -466,7 +467,7 @@
#
# If the object needs a finalizer, ask for a rawmalloc.
# The following check should be constant-folded.
- if needs_finalizer:
+ if needs_finalizer and not has_light_finalizer:
ll_assert(not contains_weakptr,
"'needs_finalizer' and 'contains_weakptr' both specified")
obj = self.external_malloc(typeid, 0, can_make_young=False)
@@ -496,12 +497,14 @@
#
# Build the object.
llarena.arena_reserve(result, totalsize)
+ obj = result + size_gc_header
+ if has_light_finalizer:
+ self.young_objects_with_light_finalizers.append(obj)
self.init_gc_object(result, typeid, flags=0)
#
# If it is a weakref, record it (check constant-folded).
if contains_weakptr:
- self.young_objects_with_weakrefs.append(result+size_gc_header)
- obj = result + size_gc_header
+ self.young_objects_with_weakrefs.append(obj)
#
return llmemory.cast_adr_to_ptr(obj, llmemory.GCREF)
@@ -1265,6 +1268,8 @@
# weakrefs' targets.
if self.young_objects_with_weakrefs.non_empty():
self.invalidate_young_weakrefs()
+ if self.young_objects_with_light_finalizers.non_empty():
+ self.deal_with_young_objects_with_finalizers()
#
# Clear this mapping.
if self.nursery_objects_shadows.length() > 0:
@@ -1649,6 +1654,9 @@
self.header(obj).tid &= ~GCFLAG_VISITED
return False # survives
else:
+ finalizer = self.getlightfinalizer(self.get_type_id(obj))
+ if finalizer:
+ finalizer(obj, llmemory.NULL)
return True # dies
def _reset_gcflag_visited(self, obj, ignored):
@@ -1662,6 +1670,9 @@
size_gc_header = self.gcheaderbuilder.size_gc_header
totalsize = size_gc_header + self.get_size(obj)
allocsize = raw_malloc_usage(totalsize)
+ finalizer = self.getlightfinalizer(self.get_type_id(obj))
+ if finalizer:
+ finalizer(obj, llmemory.NULL)
arena = llarena.getfakearenaaddress(obj - size_gc_header)
#
# Must also include the card marker area, if any
@@ -1828,6 +1839,23 @@
# ----------
# Finalizers
+ def deal_with_young_objects_with_finalizers(self):
+ """ This is a much simpler version of dealing with finalizers
+ and an optimization - we can reasonably assume that those finalizers
+ don't do anything fancy and *just* call them. Among other things
+ they won't resurrect objects
+ """
+ new_objects = self.AddressStack()
+ while self.young_objects_with_light_finalizers.non_empty():
+ obj = self.young_objects_with_light_finalizers.pop()
+ if self.is_forwarded(obj):
+ new_objects.append(self.get_forwarding_address(obj))
+ else:
+ finalizer = self.getlightfinalizer(self.get_type_id(obj))
+ ll_assert(finalizer, "no light finalizer found")
+ finalizer(obj, llmemory.NULL)
+ self.objects_with_light_finalizers = new_objects
+
def deal_with_objects_with_finalizers(self):
# Walk over list of objects with finalizers.
# If it is not surviving, add it to the list of to-be-called
More information about the pypy-commit
mailing list