Author: Armin Rigo <ar...@tunes.org> Branch: gc-del-2 Changeset: r66073:a33d2133a535 Date: 2013-08-11 18:04 +0200 http://bitbucket.org/pypy/pypy/changeset/a33d2133a535/
Log: Renamings and new flag. Preparation work 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 @@ -124,7 +124,13 @@ # note that GCFLAG_CARDS_SET is the most significant bit of a byte: # this is required for the JIT (x86) -_GCFLAG_FIRST_UNUSED = first_gcflag << 8 # the first unused bit +# The following flag is used to distinguish the two categories of objects +# in 'young_objects_not_in_nursery'. Set on a new object that is young and +# raw-malloced. It may be set or not on old raw-malloced objects. It must +# never be set on objects in the minimarkpage arena. +GCFLAG_YOUNG_RAW_MALLOCED = first_gcflag << 8 + +_GCFLAG_FIRST_UNUSED = first_gcflag << 9 # the first unused bit FORWARDSTUB = lltype.GcStruct('forwarding_stub', @@ -304,11 +310,17 @@ # we implement differently anyway. So directly call GCBase.setup(). GCBase.setup(self) # - # Two lists of all raw_malloced objects (the objects too large) - self.young_rawmalloced_objects = self.null_address_dict() + # A list of the old raw_malloced objects (the objects too large) self.old_rawmalloced_objects = self.AddressStack() self.rawmalloced_total_size = r_uint(0) # + # A dict that contains all young objects not in the nursery. These + # are often young big objects allocated directly with raw_malloc, + # but may also contain objects from the minimarkpage arena: if they + # are found to be only reachable from unreferenced objects with + # 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() self.young_objects_with_light_finalizers = self.AddressStack() @@ -788,9 +800,10 @@ # The object is young or old depending on the argument. self.rawmalloced_total_size += r_uint(allocsize) if can_make_young: - if not self.young_rawmalloced_objects: - self.young_rawmalloced_objects = self.AddressDict() - self.young_rawmalloced_objects.add(result + size_gc_header) + if not self.young_objects_not_in_nursery: + self.young_objects_not_in_nursery = self.AddressDict() + self.young_objects_not_in_nursery.add(result + size_gc_header) + extra_flags |= GCFLAG_YOUNG_RAW_MALLOCED else: self.old_rawmalloced_objects.append(result + size_gc_header) extra_flags |= GCFLAG_TRACK_YOUNG_PTRS @@ -923,9 +936,9 @@ if self.nursery <= addr < self.nursery_real_top: return True # addr is in the nursery # - # Else, it may be in the set 'young_rawmalloced_objects' - return (bool(self.young_rawmalloced_objects) and - self.young_rawmalloced_objects.contains(addr)) + # Else, it may be in the set 'young_objects_not_in_nursery' + return (bool(self.young_objects_not_in_nursery) and + self.young_objects_not_in_nursery.contains(addr)) appears_to_be_young._always_inline_ = True def debug_is_old_object(self, addr): @@ -981,8 +994,8 @@ def debug_check_consistency(self): if self.DEBUG: - ll_assert(not self.young_rawmalloced_objects, - "young raw-malloced objects in a major collection") + ll_assert(not self.young_objects_not_in_nursery, + "young objects not in nursery in a major collection") ll_assert(not self.young_objects_with_weakrefs.non_empty(), "young objects with weakrefs in a major collection") MovingGCBase.debug_check_consistency(self) @@ -1286,7 +1299,7 @@ # # Before everything else, remove from 'old_objects_pointing_to_young' # the young arrays. - if self.young_rawmalloced_objects: + if self.young_objects_not_in_nursery: self.remove_young_arrays_from_old_objects_pointing_to_young() # # First, find the roots that point to young objects. All nursery @@ -1331,8 +1344,8 @@ # # Walk the list of young raw-malloced objects, and either free # them or make them old. - if self.young_rawmalloced_objects: - self.free_young_rawmalloced_objects() + if self.young_objects_not_in_nursery: + self.free_young_objects_not_in_nursery() # # All live nursery objects are out, and the rest dies. Fill # the nursery up to the cleanup point with zeros @@ -1468,13 +1481,13 @@ # that we must set GCFLAG_VISITED on young raw-malloced objects. if not self.is_in_nursery(obj): # cache usage trade-off: I think that it is a better idea to - # check if 'obj' is in young_rawmalloced_objects with an access + # check if 'obj' is in young_objects_not_in_nursery with an access # to this (small) dictionary, rather than risk a lot of cache # misses by reading a flag in the header of all the 'objs' that # arrive here. - if (bool(self.young_rawmalloced_objects) - and self.young_rawmalloced_objects.contains(obj)): - self._visit_young_rawmalloced_object(obj) + if (bool(self.young_objects_not_in_nursery) + and self.young_objects_not_in_nursery.contains(obj)): + self._visit_young_object_not_in_nursery(obj) return # size_gc_header = self.gcheaderbuilder.size_gc_header @@ -1535,7 +1548,7 @@ self.old_objects_pointing_to_young.append(newobj) _trace_drag_out._always_inline_ = True - def _visit_young_rawmalloced_object(self, obj): + def _visit_young_object_not_in_nursery(self, obj): # 'obj' points to a young, raw-malloced object. # Any young rawmalloced object never seen by the code here # will end up without GCFLAG_VISITED, and be freed at the @@ -1590,23 +1603,26 @@ self.old_rawmalloced_objects.append(arena + size_gc_header) return arena - def free_young_rawmalloced_objects(self): - self.young_rawmalloced_objects.foreach( - self._free_young_rawmalloced_obj, None) - self.young_rawmalloced_objects.delete() - self.young_rawmalloced_objects = self.null_address_dict() + def free_young_objects_not_in_nursery(self): + self.young_objects_not_in_nursery.foreach( + self._free_young_object_not_in_nursery, None) + self.young_objects_not_in_nursery.delete() + self.young_objects_not_in_nursery = self.null_address_dict() - def _free_young_rawmalloced_obj(self, obj, ignored1, ignored2): + def _free_young_object_not_in_nursery(self, obj, ignored1, ignored2): # If 'obj' has GCFLAG_VISITED, it was seen by _trace_drag_out # and survives. Otherwise, it dies. - self.free_rawmalloced_object_if_unvisited(obj) + if self.header(obj).tid & GCFLAG_YOUNG_RAW_MALLOCED: + self.free_rawmalloced_object_if_unvisited(obj) + else: + xxxxx def remove_young_arrays_from_old_objects_pointing_to_young(self): self.old_objects_pointing_to_young.filter(self._filter_young_array, None) def _filter_young_array(self, obj, ignored): - return not self.young_rawmalloced_objects.contains(obj) + return not self.young_objects_not_in_nursery.contains(obj) # ---------- # Full collection @@ -2062,8 +2078,8 @@ (obj + offset).address[0] = llmemory.NULL continue # no need to remember this weakref any longer # - elif (bool(self.young_rawmalloced_objects) and - self.young_rawmalloced_objects.contains(pointing_to)): + elif (bool(self.young_objects_not_in_nursery) and + self.young_objects_not_in_nursery.contains(pointing_to)): # young weakref to a young raw-malloced object if self.header(pointing_to).tid & GCFLAG_VISITED: pass # survives, but does not move _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit