Author: Maciej Fijalkowski <fij...@gmail.com> Branch: lightweight-finalizers Changeset: r47718:f290c558b3be Date: 2011-09-30 11:31 -0300 http://bitbucket.org/pypy/pypy/changeset/f290c558b3be/
Log: Make it work with generation & hybrid. Improve the test diff --git a/pypy/rpython/memory/gc/base.py b/pypy/rpython/memory/gc/base.py --- a/pypy/rpython/memory/gc/base.py +++ b/pypy/rpython/memory/gc/base.py @@ -353,6 +353,12 @@ finally: self.finalizer_lock_count -= 1 + def _free_raw_mem_from(self, addr): + typeid = self.get_type_id(addr) + p = (addr + self.ofs_to_raw_mem_ptr(typeid)).ptr[0] + if p: + lltype.free(p, flavor='raw') + class MovingGCBase(GCBase): moving_gc = True diff --git a/pypy/rpython/memory/gc/generation.py b/pypy/rpython/memory/gc/generation.py --- a/pypy/rpython/memory/gc/generation.py +++ b/pypy/rpython/memory/gc/generation.py @@ -87,6 +87,7 @@ self.last_generation_root_objects = self.AddressStack() self.young_objects_with_id = self.AddressDict() + self.young_objects_with_raw_mem = self.AddressStack() SemiSpaceGC.setup(self) self.set_nursery_size(self.initial_nursery_size) # the GC is fully setup now. The rest can make use of it. @@ -188,6 +189,8 @@ llarena.arena_reserve(result, totalsize) # GCFLAG_NO_YOUNG_PTRS is never set on young objs self.init_gc_object(result, typeid, flags=0) + if self.has_raw_mem_ptr(typeid): + self.young_objects_with_raw_mem.append(result + size_gc_header) self.nursery_free = result + totalsize if contains_weakptr: self.young_objects_with_weakrefs.append(result + size_gc_header) @@ -265,6 +268,7 @@ def semispace_collect(self, size_changing=False): self.reset_young_gcflags() # we are doing a full collection anyway self.weakrefs_grow_older() + self.raw_mem_grow_older() self.ids_grow_older() self.reset_nursery() SemiSpaceGC.semispace_collect(self, size_changing) @@ -299,6 +303,11 @@ obj = self.young_objects_with_weakrefs.pop() self.objects_with_weakrefs.append(obj) + def raw_mem_grow_older(self): + while self.young_objects_with_raw_mem.non_empty(): + obj = self.young_objects_with_raw_mem.pop() + self.objects_with_raw_mem.append(obj) + def collect_roots(self): """GenerationGC: collects all roots. HybridGC: collects all roots, excluding the generation 3 ones. @@ -358,6 +367,8 @@ self.invalidate_young_weakrefs() if self.young_objects_with_id.length() > 0: self.update_young_objects_with_id() + if self.young_objects_with_raw_mem.non_empty(): + self.deal_with_young_objects_with_raw_mem() # mark the nursery as free and fill it with zeroes again llarena.arena_reset(self.nursery, self.nursery_size, 2) debug_print("survived (fraction of the size):", @@ -560,6 +571,18 @@ # minimal size, which is actually a good idea: a large, mostly-empty # table is bad for the next call to 'foreach'. + def deal_with_young_objects_with_raw_mem(self): + new_objs_with_raw_mem = self.AddressStack() + while self.young_objects_with_raw_mem.non_empty(): + addr = self.young_objects_with_raw_mem.pop() + if self.surviving(addr): + new_objs_with_raw_mem.append(self.get_forwarding_address(addr)) + else: + self._free_raw_mem_from(addr) + + self.young_objects_with_raw_mem.delete() + self.young_objects_with_raw_mem = new_objs_with_raw_mem + def ids_grow_older(self): self.young_objects_with_id.foreach(self._id_grow_older, None) self.young_objects_with_id.clear() diff --git a/pypy/rpython/memory/gc/marksweep.py b/pypy/rpython/memory/gc/marksweep.py --- a/pypy/rpython/memory/gc/marksweep.py +++ b/pypy/rpython/memory/gc/marksweep.py @@ -363,10 +363,7 @@ self.write_free_statistics(typeid, obj) freed_size += estimate if self.has_raw_mem_ptr(typeid): - p = (addr + size_gc_header + - self.ofs_to_raw_mem_ptr(typeid)).ptr[0] - if p: - lltype.free(p, flavor='raw') + self._free_raw_mem_from(addr + size_gc_header) raw_free(addr) hdr = next ppnext.address[0] = llmemory.NULL diff --git a/pypy/rpython/memory/gc/semispace.py b/pypy/rpython/memory/gc/semispace.py --- a/pypy/rpython/memory/gc/semispace.py +++ b/pypy/rpython/memory/gc/semispace.py @@ -82,7 +82,7 @@ self.free = self.tospace MovingGCBase.setup(self) self.objects_with_finalizers = self.AddressDeque() - self.objects_with_raw_mem = self.AddressDeque() + self.objects_with_raw_mem = self.AddressStack() self.objects_with_weakrefs = self.AddressStack() def _teardown(self): @@ -529,17 +529,13 @@ return scan def deal_with_objects_with_raw_mem(self): - new_with_raw_mem = self.AddressDeque() + new_with_raw_mem = self.AddressStack() while self.objects_with_raw_mem.non_empty(): - addr = self.objects_with_raw_mem.popleft() + addr = self.objects_with_raw_mem.pop() if self.surviving(addr): new_with_raw_mem.append(self.get_forwarding_address(addr)) else: - typeid = self.get_type_id(addr) - p = (addr + self.ofs_to_raw_mem_ptr(typeid)).ptr[0] - if p: - lltype.free(p, flavor='raw') - self.objects_with_raw_mem.delete() + self._free_raw_mem_from(addr) self.objects_with_raw_mem = new_with_raw_mem diff --git a/pypy/rpython/memory/test/test_gc.py b/pypy/rpython/memory/test/test_gc.py --- a/pypy/rpython/memory/test/test_gc.py +++ b/pypy/rpython/memory/test/test_gc.py @@ -142,15 +142,19 @@ self.p = lltype.malloc(T, flavor='raw') def f(): + a = AClass(0) for i in range(3): - AClass(3) + a = AClass(3) AClass(0) llop.gc__collect(lltype.Void) + assert a.p + del a + llop.gc__collect(lltype.Void) # assert did not crash with malloc mismatch, ie those things # has been freed self.interpret(f, []) - + def test_finalizer(self): class B(object): pass _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit