[pypy-commit] pypy gc-incminimark-pinning: introducing scoped_nonmovingbuffer/scoped_nonmoving_unicodebuffer.

groggi noreply at buildbot.pypy.org
Mon Jun 2 17:24:26 CEST 2014


Author: Gregor Wegberg <code at gregorwegberg.com>
Branch: gc-incminimark-pinning
Changeset: r71841:36698a8ec959
Date: 2014-05-20 21:50 +0200
http://bitbucket.org/pypy/pypy/changeset/36698a8ec959/

Log:	introducing scoped_nonmovingbuffer/scoped_nonmoving_unicodebuffer.

	This is based on the same construct used in gc-minimark-pinning

diff --git a/pypy/module/_multibytecodec/c_codecs.py b/pypy/module/_multibytecodec/c_codecs.py
--- a/pypy/module/_multibytecodec/c_codecs.py
+++ b/pypy/module/_multibytecodec/c_codecs.py
@@ -127,8 +127,7 @@
 def decodeex(decodebuf, stringdata, errors="strict", errorcb=None, namecb=None,
              ignore_error=0):
     inleft = len(stringdata)
-    inbuf = rffi.get_nonmovingbuffer(stringdata)
-    try:
+    with rffi.scoped_nonmovingbuffer(stringdata) as inbuf:
         if pypy_cjk_dec_init(decodebuf, inbuf, inleft) < 0:
             raise MemoryError
         while True:
@@ -140,9 +139,6 @@
         src = pypy_cjk_dec_outbuf(decodebuf)
         length = pypy_cjk_dec_outlen(decodebuf)
         return rffi.wcharpsize2unicode(src, length)
-    #
-    finally:
-        rffi.free_nonmovingbuffer(stringdata, inbuf)
 
 def multibytecodec_decerror(decodebuf, e, errors,
                             errorcb, namecb, stringdata):
@@ -171,11 +167,8 @@
         assert errorcb
         replace, end = errorcb(errors, namecb, reason,
                                stringdata, start, end)
-    inbuf = rffi.get_nonmoving_unicodebuffer(replace)
-    try:
+    with rffi.scoped_nonmoving_unicodebuffer(replace) as inbuf:
         r = pypy_cjk_dec_replace_on_error(decodebuf, inbuf, len(replace), end)
-    finally:
-        rffi.free_nonmoving_unicodebuffer(replace, inbuf)
     if r == MBERR_NOMEMORY:
         raise MemoryError
 
@@ -222,8 +215,7 @@
 def encodeex(encodebuf, unicodedata, errors="strict", errorcb=None,
              namecb=None, ignore_error=0):
     inleft = len(unicodedata)
-    inbuf = rffi.get_nonmoving_unicodebuffer(unicodedata)
-    try:
+    with rffi.scoped_nonmoving_unicodebuffer(unicodedata) as inbuf:
         if pypy_cjk_enc_init(encodebuf, inbuf, inleft) < 0:
             raise MemoryError
         if ignore_error == 0:
@@ -245,9 +237,6 @@
         src = pypy_cjk_enc_outbuf(encodebuf)
         length = pypy_cjk_enc_outlen(encodebuf)
         return rffi.charpsize2str(src, length)
-    #
-    finally:
-        rffi.free_nonmoving_unicodebuffer(unicodedata, inbuf)
 
 def multibytecodec_encerror(encodebuf, e, errors,
                             errorcb, namecb, unicodedata):
@@ -287,10 +276,7 @@
             assert retu is not None
             codec = pypy_cjk_enc_getcodec(encodebuf)
             replace = encode(codec, retu, "strict", errorcb, namecb)
-    inbuf = rffi.get_nonmovingbuffer(replace)
-    try:
+    with rffi.scoped_nonmovingbuffer(replace) as inbuf:
         r = pypy_cjk_enc_replace_on_error(encodebuf, inbuf, len(replace), end)
-    finally:
-        rffi.free_nonmovingbuffer(replace, inbuf)
     if r == MBERR_NOMEMORY:
         raise MemoryError
diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -446,11 +446,8 @@
 
     count = space.len_w(w_str)
     data = space.str_w(w_str)
-    buf = rffi.get_nonmovingbuffer(data)
-    try:
+    with rffi.scoped_nonmovingbuffer(data) as buf:
         fwrite(buf, 1, count, fp)
-    finally:
-        rffi.free_nonmovingbuffer(data, buf)
     return 0
 
 
diff --git a/rpython/rlib/rfile.py b/rpython/rlib/rfile.py
--- a/rpython/rlib/rfile.py
+++ b/rpython/rlib/rfile.py
@@ -133,8 +133,7 @@
         if not ll_file:
             raise ValueError("I/O operation on closed file")
         assert value is not None
-        ll_value, is_pinned, is_raw = rffi.get_nonmovingbuffer(value)
-        try:
+        with rffi.scoped_nonmovingbuffer(value) as ll_value:
             # note that since we got a nonmoving buffer, it is either raw
             # or already cannot move, so the arithmetics below are fine
             length = len(value)
@@ -142,8 +141,6 @@
             if bytes != length:
                 errno = rposix.get_errno()
                 raise OSError(errno, os.strerror(errno))
-        finally:
-            rffi.free_nonmovingbuffer(value, ll_value, is_pinned, is_raw)
 
     def close(self):
         """Closes the described file.
diff --git a/rpython/rlib/rsocket.py b/rpython/rlib/rsocket.py
--- a/rpython/rlib/rsocket.py
+++ b/rpython/rlib/rsocket.py
@@ -878,19 +878,15 @@
         """Send a data string to the socket.  For the optional flags
         argument, see the Unix manual.  Return the number of bytes
         sent; this may be less than len(data) if the network is busy."""
-        dataptr, is_pinned, is_raw = rffi.get_nonmovingbuffer(data)
-        try:
+        with rffi.scoped_nonmovingbuffer(data) as dataptr:
             return self.send_raw(dataptr, len(data), flags)
-        finally:
-            rffi.free_nonmovingbuffer(data, dataptr, is_pinned, is_raw)
 
     def sendall(self, data, flags=0, signal_checker=None):
         """Send a data string to the socket.  For the optional flags
         argument, see the Unix manual.  This calls send() repeatedly
         until all data is sent.  If an error occurs, it's impossible
         to tell how much data has been sent."""
-        dataptr, is_pinned, is_raw = rffi.get_nonmovingbuffer(data)
-        try:
+        with rffi.scoped_nonmovingbuffer(data) as dataptr:
             remaining = len(data)
             p = dataptr
             while remaining > 0:
@@ -903,8 +899,6 @@
                         raise
                 if signal_checker is not None:
                     signal_checker()
-        finally:
-            rffi.free_nonmovingbuffer(data, dataptr, is_pinned, is_raw)
 
     def sendto(self, data, flags, address):
         """Like send(data, flags) but allows specifying the destination
@@ -1303,8 +1297,7 @@
             raise RSocketError("unknown address family")
         if len(packed) != srcsize:
             raise ValueError("packed IP wrong length for inet_ntop")
-        srcbuf = rffi.get_nonmovingbuffer(packed, is_pinned, is_raw)
-        try:
+        with rffi.scoped_nonmovingbuffer(packed) as srcbuf:
             dstbuf = mallocbuf(dstsize)
             try:
                 res = _c.inet_ntop(family, srcbuf, dstbuf, dstsize)
@@ -1313,8 +1306,6 @@
                 return rffi.charp2str(res)
             finally:
                 lltype.free(dstbuf, flavor='raw')
-        finally:
-            rffi.free_nonmovingbuffer(packed, srcbuf, is_pinned, is_raw)
 
 def setdefaulttimeout(timeout):
     if timeout < 0.0:
diff --git a/rpython/rlib/rzlib.py b/rpython/rlib/rzlib.py
--- a/rpython/rlib/rzlib.py
+++ b/rpython/rlib/rzlib.py
@@ -171,11 +171,8 @@
     Compute the CRC32 checksum of the string, possibly with the given
     start value, and return it as a unsigned 32 bit integer.
     """
-    bytes = rffi.get_nonmovingbuffer(string)
-    try:
+    with rffi.scoped_nonmovingbuffer(string) as bytes:
         checksum = _crc32(start, rffi.cast(Bytefp, bytes), len(string))
-    finally:
-        rffi.free_nonmovingbuffer(string, bytes)
     return checksum
 
 
@@ -186,11 +183,8 @@
     Compute the Adler-32 checksum of the string, possibly with the given
     start value, and return it as a unsigned 32 bit integer.
     """
-    bytes = rffi.get_nonmovingbuffer(string)
-    try:
+    with rffi.scoped_nonmovingbuffer(string) as bytes:
         checksum = _adler32(start, rffi.cast(Bytefp, bytes), len(string))
-    finally:
-        rffi.free_nonmovingbuffer(string, bytes)
     return checksum
 
 # ____________________________________________________________
diff --git a/rpython/rtyper/lltypesystem/rffi.py b/rpython/rtyper/lltypesystem/rffi.py
--- a/rpython/rtyper/lltypesystem/rffi.py
+++ b/rpython/rtyper/lltypesystem/rffi.py
@@ -1133,20 +1133,19 @@
     def __init__(self, data):
         self.data = data
     def __enter__(self):
-        self.buf = get_nonmovingbuffer(self.data)
+        self.buf, self.pinned, self.is_raw = get_nonmovingbuffer(self.data)
         return self.buf
     def __exit__(self, *args):
-        free_nonmovingbuffer(self.data, self.buf)
-
+        free_nonmovingbuffer(self.data, self.buf, self.pinned, self.is_raw)
 
 class scoped_nonmoving_unicodebuffer:
     def __init__(self, data):
         self.data = data
     def __enter__(self):
-        self.buf = get_nonmoving_unicodebuffer(self.data)
+        self.buf, self.pinned, self.is_raw = get_nonmoving_unicodebuffer(self.data)
         return self.buf
     def __exit__(self, *args):
-        free_nonmoving_unicodebuffer(self.data, self.buf)
+        free_nonmoving_unicodebuffer(self.data, self.buf, self.pinned, self.is_raw)
 
 class scoped_alloc_buffer:
     def __init__(self, size):
diff --git a/rpython/rtyper/lltypesystem/test/test_rffi.py b/rpython/rtyper/lltypesystem/test/test_rffi.py
--- a/rpython/rtyper/lltypesystem/test/test_rffi.py
+++ b/rpython/rtyper/lltypesystem/test/test_rffi.py
@@ -512,7 +512,7 @@
     def test_nonmovingbuffer(self):
         d = 'some cool data that should not move'
         def f():
-            buf = get_nonmovingbuffer(d)
+            buf, is_pinned, is_raw = get_nonmovingbuffer(d)
             try:
                 counter = 0
                 for i in range(len(d)):
@@ -520,7 +520,7 @@
                         counter += 1
                 return counter
             finally:
-                free_nonmovingbuffer(d, buf)
+                free_nonmovingbuffer(d, buf, is_pinned, is_raw)
         assert f() == len(d)
         fn = self.compile(f, [], gcpolicy='ref')
         assert fn() == len(d)
@@ -530,13 +530,13 @@
         def f():
             counter = 0
             for n in range(32):
-                buf = get_nonmovingbuffer(d)
+                buf, is_pinned, is_raw = get_nonmovingbuffer(d)
                 try:
                     for i in range(len(d)):
                         if buf[i] == d[i]:
                             counter += 1
                 finally:
-                    free_nonmovingbuffer(d, buf)
+                    free_nonmovingbuffer(d, buf, is_pinned, is_raw)
             return counter
         fn = self.compile(f, [], gcpolicy='semispace')
         # The semispace gc uses raw_malloc for its internal data structs
diff --git a/rpython/rtyper/module/ll_os.py b/rpython/rtyper/module/ll_os.py
--- a/rpython/rtyper/module/ll_os.py
+++ b/rpython/rtyper/module/ll_os.py
@@ -1028,15 +1028,12 @@
         def os_write_llimpl(fd, data):
             count = len(data)
             rposix.validate_fd(fd)
-            buf, is_pinned, is_raw = rffi.get_nonmovingbuffer(data)
-            try:
+            with rffi.scoped_nonmovingbuffer(data) as buf:
                 written = rffi.cast(lltype.Signed, os_write(
                     rffi.cast(rffi.INT, fd),
                     buf, rffi.cast(rffi.SIZE_T, count)))
                 if written < 0:
                     raise OSError(rposix.get_errno(), "os_write failed")
-            finally:
-                rffi.free_nonmovingbuffer(data, buf, is_pinned, is_raw)
             return written
 
         return extdef([int, str], SomeInteger(nonneg=True),


More information about the pypy-commit mailing list