Author: Armin Rigo <ar...@tunes.org> Branch: gc-del-2 Changeset: r66283:c37e00e43d40 Date: 2013-08-21 19:04 +0200 http://bitbucket.org/pypy/pypy/changeset/c37e00e43d40/
Log: in-progress diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py --- a/rpython/memory/gc/minimark.py +++ b/rpython/memory/gc/minimark.py @@ -321,8 +321,9 @@ # finalizers, they are made young again. self.young_objects_not_in_nursery = self.null_address_dict() # - # A list of all objects with finalizers (these are never young). - self.objects_with_finalizers = self.AddressDeque() + # 4 lists of all objects with finalizers, young or old, light or not. + self.young_objects_with_finalizers = self.AddressDeque() + self.old_objects_with_finalizers = self.AddressDeque() self.young_objects_with_light_finalizers = self.AddressStack() self.old_objects_with_light_finalizers = self.AddressStack() # @@ -526,18 +527,10 @@ totalsize = size_gc_header + size rawtotalsize = raw_malloc_usage(totalsize) # - # If the object needs a finalizer, ask for a rawmalloc. - # The following check should be constant-folded. - if needs_finalizer and not is_finalizer_light: - ll_assert(not contains_weakptr, - "'needs_finalizer' and 'contains_weakptr' both specified") - obj = self.external_malloc(typeid, 0, can_make_young=False) - self.objects_with_finalizers.append(obj) - # # If totalsize is greater than nonlarge_max (which should never be # the case in practice), ask for a rawmalloc. The following check # should be constant-folded. - elif rawtotalsize > self.nonlarge_max: + if rawtotalsize > self.nonlarge_max: ll_assert(not contains_weakptr, "'contains_weakptr' specified for a large object") obj = self.external_malloc(typeid, 0) @@ -559,14 +552,19 @@ # Build the object. llarena.arena_reserve(result, totalsize) obj = result + size_gc_header - if is_finalizer_light: - 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(obj) # + # More checks for recording, constant-folded + if needs_finalizer: + if is_finalizer_light: + self.young_objects_with_light_finalizers.append(obj) + else: + self.young_objects_with_finalizers.append(obj) + # return llmemory.cast_adr_to_ptr(obj, llmemory.GCREF) @@ -683,9 +681,9 @@ collect_and_reserve._dont_inline_ = True - def external_malloc(self, typeid, length, can_make_young=True): - """Allocate a large object using the ArenaCollection or - raw_malloc(), possibly as an object with card marking enabled, + def external_malloc(self, typeid, length): + """Allocate a large object using raw_malloc(), + possibly as an object with card marking enabled, if it has gc pointers in its var-sized part. 'length' should be specified as 0 if the object is not varsized. The returned object is fully initialized and zero-filled.""" @@ -722,28 +720,9 @@ self.minor_collection() self.major_collection(raw_malloc_usage(totalsize)) # - # Check if the object would fit in the ArenaCollection. - if raw_malloc_usage(totalsize) <= self.small_request_threshold: - # - # Yes. Round up 'totalsize' (it cannot overflow and it - # must remain <= self.small_request_threshold.) - totalsize = llarena.round_up_for_allocation(totalsize) - ll_assert(raw_malloc_usage(totalsize) <= - self.small_request_threshold, - "rounding up made totalsize > small_request_threshold") - # - # Allocate from the ArenaCollection and clear the memory returned. - result = self.ac.malloc(totalsize) - llmemory.raw_memclear(result, totalsize) - # - # An object allocated from ArenaCollection is always old, even - # if 'can_make_young'. The interesting case of 'can_make_young' - # is for large objects, bigger than the 'large_objects' threshold, - # which are raw-malloced but still young. - extra_flags = GCFLAG_TRACK_YOUNG_PTRS - # - else: - # No, so proceed to allocate it externally with raw_malloc(). + # (preserves the indentation of the following block) + if 1: + # Allocate the object externally with raw_malloc(). # Check if we need to introduce the card marker bits area. if (self.card_page_indices <= 0 # <- this check is constant-folded or not self.has_gcptr_in_varsize(typeid) or @@ -1336,7 +1315,7 @@ 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() + self.deal_with_young_objects_with_light_finalizers() # # Clear this mapping. if self.nursery_objects_shadows.length() > 0: @@ -1654,10 +1633,10 @@ # # Finalizer support: adds the flag GCFLAG_VISITED to all objects # with a finalizer and all objects reachable from there (and also - # moves some objects from 'objects_with_finalizers' to + # moves some objects from 'old_objects_with_finalizers' to # 'run_finalizers'). - if self.objects_with_finalizers.non_empty(): - self.deal_with_objects_with_finalizers() + if self.old_objects_with_finalizers.non_empty(): + self.deal_with_old_objects_with_finalizers() # self.objects_to_trace.delete() # @@ -1665,7 +1644,7 @@ 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() + self.deal_with_old_objects_with_light_finalizers() # # Walk all rawmalloced objects and free the ones that don't @@ -1921,7 +1900,7 @@ # ---------- # Finalizers - def deal_with_young_objects_with_finalizers(self): + def deal_with_young_objects_with_light_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 @@ -1937,7 +1916,7 @@ obj = self.get_forwarding_address(obj) self.old_objects_with_light_finalizers.append(obj) - def deal_with_old_objects_with_finalizers(self): + def deal_with_old_objects_with_light_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 @@ -1957,7 +1936,7 @@ self.old_objects_with_light_finalizers.delete() self.old_objects_with_light_finalizers = new_objects - def deal_with_objects_with_finalizers(self): + def deal_with_old_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 # finalizers and make it survive, to make the finalizer runnable. diff --git a/rpython/memory/test/test_minimark_gc.py b/rpython/memory/test/test_minimark_gc.py --- a/rpython/memory/test/test_minimark_gc.py +++ b/rpython/memory/test/test_minimark_gc.py @@ -16,6 +16,7 @@ def test_finalizer_young_obj(self): class A: def __del__(self): + State() # so that it is not a light finalizer state.seen += 1 class State: pass @@ -72,7 +73,7 @@ def __init__(self, n, next): self.n = n self.next = next - def __del__(self): + def __del__(self): # not a light finalizer state.freed.append(self.n) class State: pass _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit