[pypy-commit] pypy use-gc-del-3: Revert the "track_allocations=False" change. Instead, add logic so that

arigo pypy.commits at gmail.com
Fri May 6 03:21:26 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: use-gc-del-3
Changeset: r84248:7f438ed57c13
Date: 2016-05-06 09:21 +0200
http://bitbucket.org/pypy/pypy/changeset/7f438ed57c13/

Log:	Revert the "track_allocations=False" change. Instead, add logic so
	that the leakfinder at the end of app-level tests tries not only to
	call gc.collect(), but also to call the UserDelAction.

diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -141,6 +141,12 @@
             actionflag.action_dispatcher(self, frame)     # slow path
     bytecode_trace._always_inline_ = True
 
+    def _run_finalizers_now(self):
+        # Tests only: run the actions now, to ensure that the
+        # finalizable objects are really finalized.  Used notably by
+        # pypy.tool.pytest.apptest.
+        self.space.actionflag.action_dispatcher(self, None)
+
     def bytecode_only_trace(self, frame):
         """
         Like bytecode_trace() but doesn't invoke any other events besides the
diff --git a/pypy/module/_hashlib/interp_hashlib.py b/pypy/module/_hashlib/interp_hashlib.py
--- a/pypy/module/_hashlib/interp_hashlib.py
+++ b/pypy/module/_hashlib/interp_hashlib.py
@@ -65,8 +65,7 @@
         # and use a custom lock only when needed.
         self.lock = Lock(space)
 
-        ctx = lltype.malloc(ropenssl.EVP_MD_CTX.TO, flavor='raw',
-                            track_allocation=False)
+        ctx = lltype.malloc(ropenssl.EVP_MD_CTX.TO, flavor='raw')
         rgc.add_memory_pressure(ropenssl.HASH_MALLOC_SIZE + self.digest_size)
         try:
             if copy_from:
@@ -75,7 +74,7 @@
                 ropenssl.EVP_DigestInit(ctx, digest_type)
             self.ctx = ctx
         except:
-            lltype.free(ctx, flavor='raw', track_allocation=False)
+            lltype.free(ctx, flavor='raw')
             raise
         self.register_finalizer(space)
 
@@ -84,7 +83,7 @@
         if ctx:
             self.ctx = lltype.nullptr(ropenssl.EVP_MD_CTX.TO)
             ropenssl.EVP_MD_CTX_cleanup(ctx)
-            lltype.free(ctx, flavor='raw', track_allocation=False)
+            lltype.free(ctx, flavor='raw')
 
     def digest_type_by_name(self, space):
         digest_type = ropenssl.EVP_get_digestbyname(self.name)
diff --git a/pypy/tool/pytest/apptest.py b/pypy/tool/pytest/apptest.py
--- a/pypy/tool/pytest/apptest.py
+++ b/pypy/tool/pytest/apptest.py
@@ -7,7 +7,7 @@
 # ...unless the -A option ('runappdirect') is passed.
 
 import py
-import sys, textwrap, types
+import sys, textwrap, types, gc
 from pypy.interpreter.gateway import app2interp_temp
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.function import Method
@@ -32,6 +32,7 @@
         return traceback
 
     def execute_appex(self, space, target, *args):
+        self.space = space
         try:
             target(*args)
         except OperationError as e:
@@ -64,6 +65,13 @@
         code = getattr(func, 'im_func', func).func_code
         return "[%s:%s]" % (code.co_filename, code.co_firstlineno)
 
+    def track_allocations_collect(self):
+        gc.collect()
+        # must also invoke finalizers now; UserDelAction
+        # would not run at all unless invoked explicitly
+        if hasattr(self, 'space'):
+            self.space.getexecutioncontext()._run_finalizers_now()
+
 
 class AppTestMethod(AppTestFunction):
     def setup(self):
diff --git a/rpython/conftest.py b/rpython/conftest.py
--- a/rpython/conftest.py
+++ b/rpython/conftest.py
@@ -82,7 +82,13 @@
             return
         if (not getattr(item.obj, 'dont_track_allocations', False)
             and leakfinder.TRACK_ALLOCATIONS):
-            item._pypytest_leaks = leakfinder.stop_tracking_allocations(False)
+            kwds = {}
+            try:
+                kwds['do_collection'] = item.track_allocations_collect
+            except AttributeError:
+                pass
+            item._pypytest_leaks = leakfinder.stop_tracking_allocations(False,
+                                                                        **kwds)
         else:            # stop_tracking_allocations() already called
             item._pypytest_leaks = None
 
diff --git a/rpython/tool/leakfinder.py b/rpython/tool/leakfinder.py
--- a/rpython/tool/leakfinder.py
+++ b/rpython/tool/leakfinder.py
@@ -37,13 +37,13 @@
     ALLOCATED.clear()
     return result
 
-def stop_tracking_allocations(check, prev=None):
+def stop_tracking_allocations(check, prev=None, do_collection=gc.collect):
     global TRACK_ALLOCATIONS
     assert TRACK_ALLOCATIONS
     for i in range(5):
         if not ALLOCATED:
             break
-        gc.collect()
+        do_collection()
     result = ALLOCATED.copy()
     ALLOCATED.clear()
     if prev is None:


More information about the pypy-commit mailing list