[pypy-commit] pypy gc-del-3: in-progress

arigo pypy.commits at gmail.com
Mon May 2 13:49:21 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: gc-del-3
Changeset: r84137:1d403288f1ac
Date: 2016-05-02 19:48 +0200
http://bitbucket.org/pypy/pypy/changeset/1d403288f1ac/

Log:	in-progress

diff --git a/rpython/translator/backendopt/finalizer.py b/rpython/translator/backendopt/finalizer.py
--- a/rpython/translator/backendopt/finalizer.py
+++ b/rpython/translator/backendopt/finalizer.py
@@ -5,25 +5,30 @@
 class FinalizerError(Exception):
     """__del__() is used for lightweight RPython destructors,
     but the FinalizerAnalyzer found that it is not lightweight.
+
+    The set of allowed operations is restrictive for a good reason
+    - it's better to be safe. Specifically disallowed operations:
+
+    * anything that escapes self
+    * anything that can allocate
     """
 
 class FinalizerAnalyzer(graphanalyze.BoolGraphAnalyzer):
     """ Analyzer that determines whether a finalizer is lightweight enough
     so it can be called without all the complicated logic in the garbage
-    collector. The set of operations here is restrictive for a good reason
-    - it's better to be safe. Specifically disallowed operations:
-
-    * anything that escapes self
-    * anything that can allocate
+    collector.
     """
     ok_operations = ['ptr_nonzero', 'ptr_eq', 'ptr_ne', 'free', 'same_as',
                      'direct_ptradd', 'force_cast', 'track_alloc_stop',
                      'raw_free', 'adr_eq', 'adr_ne']
 
     def check_light_finalizer(self, graph):
+        self._origin = graph
         result = self.analyze_direct_call(graph)
+        del self._origin
         if result is self.top_result():
-            raise FinalizerError(FinalizerError.__doc__, graph)
+            msg = '%s\nIn %r' % (FinalizerError.__doc__, graph)
+            raise FinalizerError(msg)
 
     def analyze_simple_operation(self, op, graphinfo):
         if op.opname in self.ok_operations:
@@ -41,4 +46,10 @@
             if not isinstance(TP, lltype.Ptr) or TP.TO._gckind == 'raw':
                 # primitive type
                 return self.bottom_result()
-        return self.top_result()
+
+        if not hasattr(self, '_origin'):    # for tests
+            return self.top_result()
+        msg = '%s\nFound this forbidden operation:\n%r\nin %r\nfrom %r' % (
+            FinalizerError.__doc__, op, graphinfo,
+            getattr(self, '_origin', '?'))
+        raise FinalizerError(msg)
diff --git a/rpython/translator/backendopt/test/test_finalizer.py b/rpython/translator/backendopt/test/test_finalizer.py
--- a/rpython/translator/backendopt/test/test_finalizer.py
+++ b/rpython/translator/backendopt/test/test_finalizer.py
@@ -26,8 +26,12 @@
             t.view()
         a = FinalizerAnalyzer(t)
         fgraph = graphof(t, func_to_analyze)
-        result = a.analyze_light_finalizer(fgraph)
-        return result
+        try:
+            a.check_light_finalizer(fgraph)
+        except FinalizerError as e:
+            print e
+            return a.top_result()   # True
+        return a.bottom_result()    # False
 
     def test_nothing(self):
         def f():


More information about the pypy-commit mailing list