[pypy-svn] r78002 - in pypy/branch/leak-finder/pypy: rlib rpython/lltypesystem rpython/memory/test
arigo at codespeak.net
arigo at codespeak.net
Fri Oct 15 18:35:46 CEST 2010
Author: arigo
Date: Fri Oct 15 18:35:43 2010
New Revision: 78002
Modified:
pypy/branch/leak-finder/pypy/rlib/rgc.py
pypy/branch/leak-finder/pypy/rpython/lltypesystem/rffi.py
pypy/branch/leak-finder/pypy/rpython/memory/test/test_gc.py
Log:
Test and fix for *a real leak*! Yay :-)
Modified: pypy/branch/leak-finder/pypy/rlib/rgc.py
==============================================================================
--- pypy/branch/leak-finder/pypy/rlib/rgc.py (original)
+++ pypy/branch/leak-finder/pypy/rlib/rgc.py Fri Oct 15 18:35:43 2010
@@ -170,7 +170,14 @@
return hop.genop('gc_set_max_heap_size', [v_nbytes],
resulttype=lltype.Void)
-def can_move(p): # NB. must not be called with NULL pointers
+def can_move(p):
+ """Check if the GC object 'p' is at an address that can move.
+ Must not be called with None. With non-moving GCs, it is always False.
+ With some moving GCs like the SemiSpace GC, it is always True.
+ With other moving GCs like the MiniMark GC, it can be True for some
+ time, then False for the same object, when we are sure that it won't
+ move any more.
+ """
return True
class CanMoveEntry(ExtRegistryEntry):
Modified: pypy/branch/leak-finder/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/branch/leak-finder/pypy/rpython/lltypesystem/rffi.py (original)
+++ pypy/branch/leak-finder/pypy/rpython/lltypesystem/rffi.py Fri Oct 15 18:35:43 2010
@@ -644,7 +644,14 @@
"""
Either free a non-moving buffer or keep the original storage alive.
"""
- if rgc.can_move(data):
+ # We cannot rely on rgc.can_move(data) here, because its result
+ # might have changed since get_nonmovingbuffer(). Instead we check
+ # if 'buf' points inside 'data'. This is only possible if we
+ # followed the 2nd case in get_nonmovingbuffer(); in the first case,
+ # 'buf' points to its own raw-malloced memory.
+ data_start = cast_ptr_to_adr(llstrtype(data)) + \
+ offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0)
+ if buf != cast(TYPEP, data_start):
lltype.free(buf, flavor='raw')
else:
keepalive_until_here(data)
Modified: pypy/branch/leak-finder/pypy/rpython/memory/test/test_gc.py
==============================================================================
--- pypy/branch/leak-finder/pypy/rpython/memory/test/test_gc.py (original)
+++ pypy/branch/leak-finder/pypy/rpython/memory/test/test_gc.py Fri Oct 15 18:35:43 2010
@@ -368,6 +368,14 @@
res = self.interpret(f, [4, 42])
assert res == 12
+ def test_print_leak(self):
+ def f(n):
+ for i in range(n):
+ print i
+ return 42
+ res = self.interpret(f, [10])
+ assert res == 42
+
def test_weakref_across_minor_collection(self):
import weakref
class A:
More information about the Pypy-commit
mailing list