Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r88741:b31a6c797a0e
Date: 2016-11-29 15:27 +0100
http://bitbucket.org/pypy/pypy/changeset/b31a6c797a0e/

Log:    Use rgc.may_ignore_finalizer() inside PyPy where it makes sense to

diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -183,6 +183,14 @@
                 assert self._finalize_.im_func is not W_Root._finalize_.im_func
             space.finalizer_queue.register_finalizer(self)
 
+    def may_unregister_rpython_finalizer(self, space):
+        """Optimization hint only: if there is no user-defined __del__()
+        method, pass the hint ``don't call any finalizer'' to rgc.
+        """
+        if not self.getclass(space).hasuserdel:
+            from rpython.rlib import rgc
+            rgc.may_ignore_finalizer(self)
+
     # hooks that the mapdict implementations needs:
     def _get_mapdict_map(self):
         return None
diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -2,7 +2,7 @@
 from pypy.interpreter.error import OperationError, oefmt
 from pypy.interpreter.pyopcode import LoopBlock
 from pypy.interpreter.pycode import CO_YIELD_INSIDE_TRY
-from rpython.rlib import jit
+from rpython.rlib import jit, rgc
 
 
 class GeneratorIterator(W_Root):
@@ -103,11 +103,11 @@
                 w_result = frame.execute_frame(w_arg, operr)
             except OperationError:
                 # errors finish a frame
-                self.frame = None
+                self.frame_is_finished()
                 raise
             # if the frame is now marked as finished, it was RETURNed from
             if frame.frame_finished_execution:
-                self.frame = None
+                self.frame_is_finished()
                 raise OperationError(space.w_StopIteration, space.w_None)
             else:
                 return w_result     # YIELDed
@@ -209,7 +209,7 @@
             finally:
                 frame.f_backref = jit.vref_None
                 self.running = False
-                self.frame = None
+                self.frame_is_finished()
         return unpack_into
     unpack_into = _create_unpack_into()
     unpack_into_w = _create_unpack_into()
@@ -228,6 +228,10 @@
                     break
                 block = block.previous
 
+    def frame_is_finished(self):
+        self.frame = None
+        rgc.may_ignore_finalizer(self)
+
 
 def get_printable_location_genentry(bytecode):
     return '%s <generator>' % (bytecode.get_repr(),)
diff --git a/pypy/module/_cffi_backend/cdataobj.py 
b/pypy/module/_cffi_backend/cdataobj.py
--- a/pypy/module/_cffi_backend/cdataobj.py
+++ b/pypy/module/_cffi_backend/cdataobj.py
@@ -397,7 +397,7 @@
         space = self.space
         if space.is_none(w_destructor):
             if isinstance(self, W_CDataGCP):
-                self.w_destructor = None
+                self.detach_destructor()
                 return space.w_None
             raise oefmt(space.w_TypeError,
                         "Can remove destructor only on a object "
@@ -604,6 +604,10 @@
             self.w_destructor = None
             self.space.call_function(w_destructor, self.w_original_cdata)
 
+    def detach_destructor(self):
+        self.w_destructor = None
+        self.may_unregister_rpython_finalizer(self.space)
+
 
 W_CData.typedef = TypeDef(
     '_cffi_backend.CData',
diff --git a/pypy/module/_cffi_backend/cdlopen.py 
b/pypy/module/_cffi_backend/cdlopen.py
--- a/pypy/module/_cffi_backend/cdlopen.py
+++ b/pypy/module/_cffi_backend/cdlopen.py
@@ -55,6 +55,7 @@
         if not libhandle:
             raise oefmt(self.ffi.w_FFIError, "library '%s' is already closed",
                         self.libname)
+        self.may_unregister_rpython_finalizer(self.ffi.space)
 
         # Clear the dict to force further accesses to do cdlopen_fetch()
         # again, and fail because the library was closed.  Note that the
diff --git a/pypy/module/_file/interp_file.py b/pypy/module/_file/interp_file.py
--- a/pypy/module/_file/interp_file.py
+++ b/pypy/module/_file/interp_file.py
@@ -172,6 +172,7 @@
             self.newlines = self.stream.getnewlines()
             self.stream = None
             self.fd = -1
+            self.may_unregister_rpython_finalizer(self.space)
             openstreams = getopenstreams(self.space)
             try:
                 del openstreams[stream]
diff --git a/pypy/module/_socket/interp_socket.py 
b/pypy/module/_socket/interp_socket.py
--- a/pypy/module/_socket/interp_socket.py
+++ b/pypy/module/_socket/interp_socket.py
@@ -233,6 +233,7 @@
         except SocketError:
             # cpython doesn't return any errors on close
             pass
+        self.may_unregister_rpython_finalizer(space)
 
     def connect_w(self, space, w_addr):
         """connect(address)
diff --git a/pypy/module/select/interp_epoll.py 
b/pypy/module/select/interp_epoll.py
--- a/pypy/module/select/interp_epoll.py
+++ b/pypy/module/select/interp_epoll.py
@@ -79,6 +79,7 @@
 
 class W_Epoll(W_Root):
     def __init__(self, space, epfd):
+        self.space = space
         self.epfd = epfd
         self.register_finalizer(space)
 
@@ -113,6 +114,7 @@
         if not self.get_closed():
             socketclose(self.epfd)
             self.epfd = -1
+            self.may_unregister_rpython_finalizer(self.space)
 
     def epoll_ctl(self, space, ctl, w_fd, eventmask, ignore_ebadf=False):
         fd = space.c_filedescriptor_w(w_fd)
diff --git a/pypy/module/select/interp_kqueue.py 
b/pypy/module/select/interp_kqueue.py
--- a/pypy/module/select/interp_kqueue.py
+++ b/pypy/module/select/interp_kqueue.py
@@ -108,6 +108,7 @@
 
 class W_Kqueue(W_Root):
     def __init__(self, space, kqfd):
+        self.space = space
         self.kqfd = kqfd
         self.register_finalizer(space)
 
@@ -132,6 +133,7 @@
             kqfd = self.kqfd
             self.kqfd = -1
             socketclose_no_errno(kqfd)
+            self.may_unregister_rpython_finalizer(self.space)
 
     def check_closed(self, space):
         if self.get_closed():
diff --git a/pypy/module/zlib/interp_zlib.py b/pypy/module/zlib/interp_zlib.py
--- a/pypy/module/zlib/interp_zlib.py
+++ b/pypy/module/zlib/interp_zlib.py
@@ -202,6 +202,7 @@
                 if mode == rzlib.Z_FINISH:    # release the data structures now
                     rzlib.deflateEnd(self.stream)
                     self.stream = rzlib.null_stream
+                    self.may_unregister_rpython_finalizer(space)
             finally:
                 self.unlock()
         except rzlib.RZlibError as e:
diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py
--- a/pypy/objspace/fake/objspace.py
+++ b/pypy/objspace/fake/objspace.py
@@ -66,15 +66,16 @@
 class W_MyType(W_MyObject):
     name = "foobar"
     flag_map_or_seq = '?'
+    hasuserdel = False
 
     def __init__(self):
         self.mro_w = [w_some_obj(), w_some_obj()]
         self.dict_w = {'__str__': w_some_obj()}
+        self.hasuserdel = True
 
     def get_module(self):
         return w_some_obj()
 
-
     def getname(self, space):
         return self.name
 
diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py
--- a/rpython/rlib/rfile.py
+++ b/rpython/rlib/rfile.py
@@ -4,7 +4,7 @@
 """
 
 import os, stat, errno, sys
-from rpython.rlib import rposix
+from rpython.rlib import rposix, rgc
 from rpython.rlib.objectmodel import enforceargs
 from rpython.rlib.rarithmetic import intmask
 from rpython.rlib.rstring import StringBuilder
@@ -294,6 +294,7 @@
         if ll_file:
             # double close is allowed
             self._ll_file = lltype.nullptr(FILEP.TO)
+            rgc.may_ignore_finalizer(self)
             do_close = self._close2[0]
             try:
                 if do_close:
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to