[pypy-commit] pypy lightweight-finalizers: Make it work with generation & hybrid. Improve the test
fijal
noreply at buildbot.pypy.org
Fri Sep 30 17:34:51 CEST 2011
Author: Maciej Fijalkowski <fijall at 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
More information about the pypy-commit
mailing list