[pypy-commit] pypy gc-minimark-pinning: try to pass more stuff around nonmovingbuffer
fijal
noreply at buildbot.pypy.org
Mon Apr 23 12:04:07 CEST 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: gc-minimark-pinning
Changeset: r54663:d3ec07c4849c
Date: 2012-04-23 12:02 +0200
http://bitbucket.org/pypy/pypy/changeset/d3ec07c4849c/
Log: try to pass more stuff around nonmovingbuffer
diff --git a/pypy/rlib/runicode.py b/pypy/rlib/runicode.py
--- a/pypy/rlib/runicode.py
+++ b/pypy/rlib/runicode.py
@@ -1481,8 +1481,7 @@
if not final and is_dbcs_lead_byte(s[size-1]):
size -= 1
- dataptr = rffi.get_nonmovingbuffer(s)
- try:
+ with rffi.scoped_nonmoving_unicodebuffer(s) as dataptr:
# first get the size of the result
usize = MultiByteToWideChar(CP_ACP, 0,
dataptr, size,
@@ -1490,19 +1489,12 @@
if usize == 0:
raise rwin32.lastWindowsError()
- raw_buf, gc_buf = rffi.alloc_unicodebuffer(usize)
- try:
+ with rffi.scoped_alloc_unicodebuffer(usize) as buf:
# do the conversion
if MultiByteToWideChar(CP_ACP, 0,
- dataptr, size, raw_buf, usize) == 0:
+ dataptr, size, buf.raw, usize) == 0:
raise rwin32.lastWindowsError()
-
- return (rffi.unicode_from_buffer(raw_buf, gc_buf, usize, usize),
- size)
- finally:
- rffi.keep_unicodebuffer_alive_until_here(raw_buf, gc_buf)
- finally:
- rffi.free_nonmovingbuffer(s, dataptr)
+ return buf.str(usize), size
def unicode_encode_mbcs(p, size, errors, errorhandler=None):
if size == 0:
diff --git a/pypy/rpython/lltypesystem/rffi.py b/pypy/rpython/lltypesystem/rffi.py
--- a/pypy/rpython/lltypesystem/rffi.py
+++ b/pypy/rpython/lltypesystem/rffi.py
@@ -713,24 +713,26 @@
string is already nonmovable. Must be followed by a
free_nonmovingbuffer call.
"""
- rgc.pin(data)
- if rgc.can_move(data) or not we_are_translated():
- count = len(data)
- buf = lltype.malloc(TYPEP.TO, count, flavor='raw')
- for i in range(count):
- buf[i] = data[i]
- return buf
- else:
- ll_s = llstrtype(data)
- data_start = cast_ptr_to_adr(ll_s) + \
- offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0)
- return cast(TYPEP, data_start)
+ pinned = False
+ if rgc.can_move(data):
+ if rgc.pin(data):
+ pinned = True
+ else:
+ count = len(data)
+ buf = lltype.malloc(TYPEP.TO, count, flavor='raw')
+ for i in range(count):
+ buf[i] = data[i]
+ return buf, False, True
+ ll_s = llstrtype(data)
+ data_start = cast_ptr_to_adr(ll_s) + \
+ offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0)
+ return cast(TYPEP, data_start), pinned, False
get_nonmovingbuffer._annenforceargs_ = [strtype]
# (str, char*) -> None
# Can't inline this because of the raw address manipulation.
@jit.dont_look_inside
- def free_nonmovingbuffer(data, buf):
+ def free_nonmovingbuffer(data, buf, pinned, is_raw):
"""
Either free a non-moving buffer or keep the original storage alive.
"""
@@ -739,17 +741,12 @@
# 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.
- ll_data = llstrtype(data)
- data_start = cast_ptr_to_adr(ll_data) + \
- offsetof(STRTYPE, 'chars') + itemoffsetof(STRTYPE.chars, 0)
- followed_2nd_path = (buf == cast(TYPEP, data_start))
keepalive_until_here(data)
- keepalive_until_here(ll_data)
- if followed_2nd_path:
+ if pinned:
rgc.unpin(data)
- else:
+ elif is_raw:
lltype.free(buf, flavor='raw')
- free_nonmovingbuffer._annenforceargs_ = [strtype, None]
+ free_nonmovingbuffer._annenforceargs_ = [strtype, None, bool, bool]
# int -> (char*, str)
def alloc_buffer(count):
@@ -1070,20 +1067,22 @@
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/pypy/rpython/lltypesystem/test/test_rffi.py b/pypy/rpython/lltypesystem/test/test_rffi.py
--- a/pypy/rpython/lltypesystem/test/test_rffi.py
+++ b/pypy/rpython/lltypesystem/test/test_rffi.py
@@ -513,7 +513,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)):
@@ -521,7 +521,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)
@@ -531,13 +531,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/pypy/rpython/module/ll_os.py b/pypy/rpython/module/ll_os.py
--- a/pypy/rpython/module/ll_os.py
+++ b/pypy/rpython/module/ll_os.py
@@ -910,15 +910,12 @@
def os_write_llimpl(fd, data):
count = len(data)
- buf = 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)
return written
def os_write_oofakeimpl(fd, data):
More information about the pypy-commit
mailing list