Author: Maciej Fijalkowski <fij...@gmail.com> Branch: lightweight-finalizers Changeset: r48442:e09c7b3e1296 Date: 2011-10-25 16:59 +0200 http://bitbucket.org/pypy/pypy/changeset/e09c7b3e1296/
Log: Use a list instead of checking each time the type id data 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 @@ -291,6 +291,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() + self.old_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 @@ -1588,6 +1589,9 @@ # Weakref support: clear the weak pointers to dying objects if self.old_objects_with_weakrefs.non_empty(): self.invalidate_old_weakrefs() + if self.old_objects_with_light_finalizers.non_empty(): + self.deal_with_old_objects_with_finalizers() + # # Walk all rawmalloced objects and free the ones that don't # have the GCFLAG_VISITED flag. @@ -1653,11 +1657,7 @@ if self.header(obj).tid & GCFLAG_VISITED: 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 + return True # dies def _reset_gcflag_visited(self, obj, ignored): self.header(obj).tid &= ~GCFLAG_VISITED @@ -1670,9 +1670,6 @@ 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 @@ -1852,6 +1849,26 @@ ll_assert(bool(finalizer), "no light finalizer found") finalizer(obj, llmemory.NULL) + def deal_with_old_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.old_objects_with_light_finalizers.non_empty(): + obj = self.old_objects_with_light_finalizers.pop() + if self.header(obj).tid & GCFLAG_VISITED: + # surviving + new_objects.append(obj) + else: + # dying + finalizer = self.getlightfinalizer(self.get_type_id(obj)) + ll_assert(bool(finalizer), "no light finalizer found") + finalizer(obj, llmemory.NULL) + self.old_objects_with_light_finalizers.delete() + self.old_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 _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit