[pypy-commit] pypy win64_gborg: disabled errno check on win64 and py 2.7.2 - ctypes bug
ctismer
noreply at buildbot.pypy.org
Fri Nov 4 14:53:43 CET 2011
Author: Christian Tismer <tismer at stackless.com>
Branch: win64_gborg
Changeset: r48752:bed6d5ad754f
Date: 2011-11-04 14:52 +0100
http://bitbucket.org/pypy/pypy/changeset/bed6d5ad754f/
Log: disabled errno check on win64 and py 2.7.2 - ctypes bug
diff --git a/pypy/jit/metainterp/optimizeopt/vstring.py b/pypy/jit/metainterp/optimizeopt/vstring.py
--- a/pypy/jit/metainterp/optimizeopt/vstring.py
+++ b/pypy/jit/metainterp/optimizeopt/vstring.py
@@ -113,6 +113,33 @@
"""A string built with newstr(const)."""
_lengthbox = None # cache only
+ # Warning: an issue with VStringPlainValue is that sometimes it is
+ # initialized unpredictably by some copystrcontent. When this occurs
+ # we set self._chars to None. Be careful to check for is_valid().
+
+ def is_valid(self):
+ return self._chars is not None
+
+ def _invalidate(self):
+ assert self.is_valid()
+ if self._lengthbox is None:
+ self._lengthbox = ConstInt(len(self._chars))
+ self._chars = None
+
+ def _really_force(self, optforce):
+ VAbstractStringValue._really_force(self, optforce)
+ assert self.box is not None
+ if self.is_valid():
+ for c in self._chars:
+ if c is optimizer.CVAL_UNINITIALIZED_ZERO:
+ # the string has uninitialized null bytes in it, so
+ # assume that it is forced for being further mutated
+ # (e.g. by copystrcontent). So it becomes invalid
+ # as a VStringPlainValue: the _chars must not be used
+ # any longer.
+ self._invalidate()
+ break
+
def setup(self, size):
self._chars = [optimizer.CVAL_UNINITIALIZED_ZERO] * size
@@ -134,6 +161,8 @@
@specialize.arg(1)
def get_constant_string_spec(self, mode):
+ if not self.is_valid():
+ return None
for c in self._chars:
if c is optimizer.CVAL_UNINITIALIZED_ZERO or not c.is_constant():
return None
@@ -141,11 +170,9 @@
for c in self._chars])
def string_copy_parts(self, string_optimizer, targetbox, offsetbox, mode):
- if not self.is_virtual() and targetbox is not self.box:
- lengthbox = self.getstrlen(string_optimizer, mode)
- srcbox = self.force_box(string_optimizer)
- return copy_str_content(string_optimizer, srcbox, targetbox,
- CONST_0, offsetbox, lengthbox, mode)
+ if not self.is_valid():
+ return VAbstractStringValue.string_copy_parts(
+ self, string_optimizer, targetbox, offsetbox, mode)
for i in range(len(self._chars)):
charbox = self._chars[i].force_box(string_optimizer)
if not (isinstance(charbox, Const) and charbox.same_constant(CONST_0)):
@@ -158,6 +185,7 @@
def get_args_for_fail(self, modifier):
if self.box is None and not modifier.already_seen_virtual(self.keybox):
+ assert self.is_valid()
charboxes = [value.get_key_box() for value in self._chars]
modifier.register_virtual_fields(self.keybox, charboxes)
for value in self._chars:
@@ -373,7 +401,8 @@
def optimize_STRSETITEM(self, op):
value = self.getvalue(op.getarg(0))
- if value.is_virtual() and isinstance(value, VStringPlainValue):
+ if (value.is_virtual() and isinstance(value, VStringPlainValue)
+ and value.is_valid()):
indexbox = self.get_constant_box(op.getarg(1))
if indexbox is not None:
value.setitem(indexbox.getint(), self.getvalue(op.getarg(2)))
@@ -404,13 +433,10 @@
value = value.vstr
vindex = self.getvalue(fullindexbox)
#
- if isinstance(value, VStringPlainValue): # even if no longer virtual
+ if (isinstance(value, VStringPlainValue) # even if no longer virtual
+ and value.is_valid()): # but make sure it is valid
if vindex.is_constant():
- res = value.getitem(vindex.box.getint())
- # If it is uninitialized we can't return it, it was set by a
- # COPYSTRCONTENT, not a STRSETITEM
- if res is not optimizer.CVAL_UNINITIALIZED_ZERO:
- return res
+ return value.getitem(vindex.box.getint())
#
resbox = _strgetitem(self, value.force_box(self), vindex.force_box(self), mode)
return self.getvalue(resbox)
@@ -503,19 +529,12 @@
vstart = self.getvalue(op.getarg(2))
vstop = self.getvalue(op.getarg(3))
#
- if (isinstance(vstr, VStringPlainValue) and vstart.is_constant()
- and vstop.is_constant()):
- # slicing with constant bounds of a VStringPlainValue, if any of
- # the characters is unitialized we don't do this special slice, we
- # do the regular copy contents.
- for i in range(vstart.box.getint(), vstop.box.getint()):
- if vstr.getitem(i) is optimizer.CVAL_UNINITIALIZED_ZERO:
- break
- else:
- value = self.make_vstring_plain(op.result, op, mode)
- value.setup_slice(vstr._chars, vstart.box.getint(),
- vstop.box.getint())
- return True
+ if (isinstance(vstr, VStringPlainValue) and vstr.is_valid()
+ and vstart.is_constant() and vstop.is_constant()):
+ value = self.make_vstring_plain(op.result, op, mode)
+ value.setup_slice(vstr._chars, vstart.box.getint(),
+ vstop.box.getint())
+ return True
#
vstr.ensure_nonnull()
lengthbox = _int_sub(self, vstop.force_box(self),
diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py
--- a/pypy/module/__builtin__/functional.py
+++ b/pypy/module/__builtin__/functional.py
@@ -362,7 +362,7 @@
def descr_reversed(self):
lastitem = self.start + (self.len-1) * self.step
return self.space.wrap(W_XRangeIterator(self.space, lastitem,
- self.start - 1, -self.step))
+ self.start, -self.step, True))
def descr_reduce(self):
space = self.space
@@ -389,21 +389,26 @@
)
class W_XRangeIterator(Wrappable):
- def __init__(self, space, start, stop, step):
+ def __init__(self, space, start, stop, step, inclusive=False):
self.space = space
self.current = start
self.stop = stop
self.step = step
+ self.inclusive = inclusive
def descr_iter(self):
return self.space.wrap(self)
def descr_next(self):
- if (self.step > 0 and self.current < self.stop) or (self.step < 0 and self.current > self.stop):
- item = self.current
- self.current = item + self.step
- return self.space.wrap(item)
- raise OperationError(self.space.w_StopIteration, self.space.w_None)
+ if self.inclusive:
+ if not ((self.step > 0 and self.current <= self.stop) or (self.step < 0 and self.current >= self.stop)):
+ raise OperationError(self.space.w_StopIteration, self.space.w_None)
+ else:
+ if not ((self.step > 0 and self.current < self.stop) or (self.step < 0 and self.current > self.stop)):
+ raise OperationError(self.space.w_StopIteration, self.space.w_None)
+ item = self.current
+ self.current = item + self.step
+ return self.space.wrap(item)
#def descr_len(self):
# return self.space.wrap(self.remaining)
diff --git a/pypy/module/__builtin__/test/test_functional.py b/pypy/module/__builtin__/test/test_functional.py
--- a/pypy/module/__builtin__/test/test_functional.py
+++ b/pypy/module/__builtin__/test/test_functional.py
@@ -157,7 +157,8 @@
raises(OverflowError, xrange, a)
raises(OverflowError, xrange, 0, a)
raises(OverflowError, xrange, 0, 1, a)
-
+ assert list(reversed(xrange(-sys.maxint-1, -sys.maxint-1, -2))) == []
+
def test_xrange_reduce(self):
x = xrange(2, 9, 3)
callable, args = x.__reduce__()
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
@@ -206,24 +206,28 @@
@unwrap_spec(size=int)
def direct_readlines(self, size=0):
stream = self.getstream()
- # NB. this implementation is very inefficient for unbuffered
- # streams, but ok if stream.readline() is efficient.
+ # this is implemented as: .read().split('\n')
+ # except that it keeps the \n in the resulting strings
if size <= 0:
- result = []
- while True:
- line = stream.readline()
- if not line:
- break
- result.append(line)
- size -= len(line)
+ data = stream.readall()
else:
- result = []
- while size > 0:
- line = stream.readline()
- if not line:
- break
- result.append(line)
- size -= len(line)
+ data = stream.read(size)
+ result = []
+ splitfrom = 0
+ for i in range(len(data)):
+ if data[i] == '\n':
+ result.append(data[splitfrom : i + 1])
+ splitfrom = i + 1
+ #
+ if splitfrom < len(data):
+ # there is a partial line at the end. If size > 0, it is likely
+ # to be because the 'read(size)' returned data up to the middle
+ # of a line. In that case, use 'readline()' to read until the
+ # end of the current line.
+ data = data[splitfrom:]
+ if size > 0:
+ data += stream.readline()
+ result.append(data)
return result
@unwrap_spec(offset=r_longlong, whence=int)
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
@@ -4,32 +4,44 @@
from pypy.interpreter.error import OperationError
from pypy.tool.sourcetools import func_renamer
from pypy.interpreter.baseobjspace import Wrappable
-from pypy.rpython.lltypesystem import lltype, rffi
+from pypy.rpython.lltypesystem import lltype, llmemory, rffi
+from pypy.rlib import rgc, ropenssl
from pypy.rlib.objectmodel import keepalive_until_here
-from pypy.rlib import ropenssl
from pypy.rlib.rstring import StringBuilder
from pypy.module.thread.os_lock import Lock
algorithms = ('md5', 'sha1', 'sha224', 'sha256', 'sha384', 'sha512')
+# HASH_MALLOC_SIZE is the size of EVP_MD, EVP_MD_CTX plus their points
+# Used for adding memory pressure. Last number is an (under?)estimate of
+# EVP_PKEY_CTX's size.
+# XXX: Make a better estimate here
+HASH_MALLOC_SIZE = ropenssl.EVP_MD_SIZE + ropenssl.EVP_MD_CTX_SIZE \
+ + rffi.sizeof(ropenssl.EVP_MD) * 2 + 208
+
class W_Hash(Wrappable):
ctx = lltype.nullptr(ropenssl.EVP_MD_CTX.TO)
+ _block_size = -1
def __init__(self, space, name):
self.name = name
+ self.digest_size = self.compute_digest_size()
# Allocate a lock for each HASH object.
# An optimization would be to not release the GIL on small requests,
# and use a custom lock only when needed.
self.lock = Lock(space)
+ ctx = lltype.malloc(ropenssl.EVP_MD_CTX.TO, flavor='raw')
+ rgc.add_memory_pressure(HASH_MALLOC_SIZE + self.digest_size)
+ self.ctx = ctx
+
+ def initdigest(self, space, name):
digest = ropenssl.EVP_get_digestbyname(name)
if not digest:
raise OperationError(space.w_ValueError,
space.wrap("unknown hash function"))
- ctx = lltype.malloc(ropenssl.EVP_MD_CTX.TO, flavor='raw')
- ropenssl.EVP_DigestInit(ctx, digest)
- self.ctx = ctx
+ ropenssl.EVP_DigestInit(self.ctx, digest)
def __del__(self):
# self.lock.free()
@@ -65,33 +77,29 @@
"Return the digest value as a string of hexadecimal digits."
digest = self._digest(space)
hexdigits = '0123456789abcdef'
- result = StringBuilder(self._digest_size() * 2)
+ result = StringBuilder(self.digest_size * 2)
for c in digest:
result.append(hexdigits[(ord(c) >> 4) & 0xf])
result.append(hexdigits[ ord(c) & 0xf])
return space.wrap(result.build())
def get_digest_size(self, space):
- return space.wrap(self._digest_size())
+ return space.wrap(self.digest_size)
def get_block_size(self, space):
- return space.wrap(self._block_size())
+ return space.wrap(self.compute_block_size())
def _digest(self, space):
- copy = self.copy(space)
- ctx = copy.ctx
- digest_size = self._digest_size()
- digest = lltype.malloc(rffi.CCHARP.TO, digest_size, flavor='raw')
+ with lltype.scoped_alloc(ropenssl.EVP_MD_CTX.TO) as ctx:
+ with self.lock:
+ ropenssl.EVP_MD_CTX_copy(ctx, self.ctx)
+ digest_size = self.digest_size
+ with lltype.scoped_alloc(rffi.CCHARP.TO, digest_size) as digest:
+ ropenssl.EVP_DigestFinal(ctx, digest, None)
+ ropenssl.EVP_MD_CTX_cleanup(ctx)
+ return rffi.charpsize2str(digest, digest_size)
- try:
- ropenssl.EVP_DigestFinal(ctx, digest, None)
- return rffi.charpsize2str(digest, digest_size)
- finally:
- keepalive_until_here(copy)
- lltype.free(digest, flavor='raw')
-
-
- def _digest_size(self):
+ def compute_digest_size(self):
# XXX This isn't the nicest way, but the EVP_MD_size OpenSSL
# XXX function is defined as a C macro on OS X and would be
# XXX significantly harder to implement in another way.
@@ -105,12 +113,14 @@
'sha512': 64, 'SHA512': 64,
}.get(self.name, 0)
- def _block_size(self):
+ def compute_block_size(self):
+ if self._block_size != -1:
+ return self._block_size
# XXX This isn't the nicest way, but the EVP_MD_CTX_block_size
# XXX OpenSSL function is defined as a C macro on some systems
# XXX and would be significantly harder to implement in
# XXX another way.
- return {
+ self._block_size = {
'md5': 64, 'MD5': 64,
'sha1': 64, 'SHA1': 64,
'sha224': 64, 'SHA224': 64,
@@ -118,6 +128,7 @@
'sha384': 128, 'SHA384': 128,
'sha512': 128, 'SHA512': 128,
}.get(self.name, 0)
+ return self._block_size
W_Hash.typedef = TypeDef(
'HASH',
@@ -135,6 +146,7 @@
@unwrap_spec(name=str, string='bufferstr')
def new(space, name, string=''):
w_hash = W_Hash(space, name)
+ w_hash.initdigest(space, name)
w_hash.update(space, string)
return space.wrap(w_hash)
diff --git a/pypy/module/_multiprocessing/interp_semaphore.py b/pypy/module/_multiprocessing/interp_semaphore.py
--- a/pypy/module/_multiprocessing/interp_semaphore.py
+++ b/pypy/module/_multiprocessing/interp_semaphore.py
@@ -4,6 +4,7 @@
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.error import wrap_oserror, OperationError
from pypy.rpython.lltypesystem import rffi, lltype
+from pypy.rlib import rgc
from pypy.rlib.rarithmetic import r_uint
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.rpython.tool import rffi_platform as platform
@@ -23,6 +24,8 @@
_CreateSemaphore = rwin32.winexternal(
'CreateSemaphoreA', [rffi.VOIDP, rffi.LONG, rffi.LONG, rwin32.LPCSTR],
rwin32.HANDLE)
+ _CloseHandle = rwin32.winexternal('CloseHandle', [rwin32.HANDLE],
+ rwin32.BOOL, threadsafe=False)
_ReleaseSemaphore = rwin32.winexternal(
'ReleaseSemaphore', [rwin32.HANDLE, rffi.LONG, rffi.LONGP],
rwin32.BOOL)
@@ -51,6 +54,7 @@
SEM_FAILED = platform.ConstantInteger('SEM_FAILED')
SEM_VALUE_MAX = platform.ConstantInteger('SEM_VALUE_MAX')
SEM_TIMED_WAIT = platform.Has('sem_timedwait')
+ SEM_T_SIZE = platform.SizeOf('sem_t')
config = platform.configure(CConfig)
TIMEVAL = config['TIMEVAL']
@@ -61,18 +65,21 @@
SEM_FAILED = config['SEM_FAILED'] # rffi.cast(SEM_T, config['SEM_FAILED'])
SEM_VALUE_MAX = config['SEM_VALUE_MAX']
SEM_TIMED_WAIT = config['SEM_TIMED_WAIT']
+ SEM_T_SIZE = config['SEM_T_SIZE']
if sys.platform == 'darwin':
HAVE_BROKEN_SEM_GETVALUE = True
else:
HAVE_BROKEN_SEM_GETVALUE = False
- def external(name, args, result):
+ def external(name, args, result, **kwargs):
return rffi.llexternal(name, args, result,
- compilation_info=eci)
+ compilation_info=eci, **kwargs)
_sem_open = external('sem_open',
[rffi.CCHARP, rffi.INT, rffi.INT, rffi.UINT],
SEM_T)
+ # tread sem_close as not threadsafe for now to be able to use the __del__
+ _sem_close = external('sem_close', [SEM_T], rffi.INT, threadsafe=False)
_sem_unlink = external('sem_unlink', [rffi.CCHARP], rffi.INT)
_sem_wait = external('sem_wait', [SEM_T], rffi.INT)
_sem_trywait = external('sem_trywait', [SEM_T], rffi.INT)
@@ -90,6 +97,11 @@
raise OSError(rposix.get_errno(), "sem_open failed")
return res
+ def sem_close(handle):
+ res = _sem_close(handle)
+ if res < 0:
+ raise OSError(rposix.get_errno(), "sem_close failed")
+
def sem_unlink(name):
res = _sem_unlink(name)
if res < 0:
@@ -205,6 +217,11 @@
raise WindowsError(err, "CreateSemaphore")
return handle
+ def delete_semaphore(handle):
+ if not _CloseHandle(handle):
+ err = rwin32.GetLastError()
+ raise WindowsError(err, "CloseHandle")
+
def semlock_acquire(self, space, block, w_timeout):
if not block:
full_msecs = 0
@@ -291,8 +308,13 @@
sem_unlink(name)
except OSError:
pass
+ else:
+ rgc.add_memory_pressure(SEM_T_SIZE)
return sem
+ def delete_semaphore(handle):
+ sem_close(handle)
+
def semlock_acquire(self, space, block, w_timeout):
if not block:
deadline = lltype.nullptr(TIMESPECP.TO)
@@ -483,6 +505,9 @@
def exit(self, space, __args__):
self.release(space)
+ def __del__(self):
+ delete_semaphore(self.handle)
+
@unwrap_spec(kind=int, value=int, maxvalue=int)
def descr_new(space, w_subtype, kind, value, maxvalue):
if kind != RECURSIVE_MUTEX and kind != SEMAPHORE:
diff --git a/pypy/module/pyexpat/interp_pyexpat.py b/pypy/module/pyexpat/interp_pyexpat.py
--- a/pypy/module/pyexpat/interp_pyexpat.py
+++ b/pypy/module/pyexpat/interp_pyexpat.py
@@ -4,9 +4,9 @@
from pypy.interpreter.gateway import interp2app, unwrap_spec
from pypy.interpreter.error import OperationError
from pypy.objspace.descroperation import object_setattr
+from pypy.rlib import rgc
+from pypy.rlib.unroll import unrolling_iterable
from pypy.rpython.lltypesystem import rffi, lltype
-from pypy.rlib.unroll import unrolling_iterable
-
from pypy.rpython.tool import rffi_platform
from pypy.translator.tool.cbuild import ExternalCompilationInfo
from pypy.translator.platform import platform
@@ -118,6 +118,19 @@
locals()[name] = rffi_platform.ConstantInteger(name)
for name in xml_model_list:
locals()[name] = rffi_platform.ConstantInteger(name)
+ for name in xml_model_list:
+ locals()[name] = rffi_platform.ConstantInteger(name)
+ for name in xml_model_list:
+ locals()[name] = rffi_platform.ConstantInteger(name)
+ for name in xml_model_list:
+ locals()[name] = rffi_platform.ConstantInteger(name)
+ for name in xml_model_list:
+ locals()[name] = rffi_platform.ConstantInteger(name)
+ for name in xml_model_list:
+ locals()[name] = rffi_platform.ConstantInteger(name)
+ for name in xml_model_list:
+ locals()[name] = rffi_platform.ConstantInteger(name)
+ XML_Parser_SIZE = rffi_platform.SizeOf("XML_Parser")
for k, v in rffi_platform.configure(CConfigure).items():
globals()[k] = v
@@ -793,7 +806,10 @@
rffi.cast(rffi.CHAR, namespace_separator))
else:
xmlparser = XML_ParserCreate(encoding)
-
+ # Currently this is just the size of the pointer and some estimated bytes.
+ # The struct isn't actually defined in expat.h - it is in xmlparse.c
+ # XXX: find a good estimate of the XML_ParserStruct
+ rgc.add_memory_pressure(XML_Parser_SIZE + 300)
if not xmlparser:
raise OperationError(space.w_RuntimeError,
space.wrap('XML_ParserCreate failed'))
diff --git a/pypy/module/thread/ll_thread.py b/pypy/module/thread/ll_thread.py
--- a/pypy/module/thread/ll_thread.py
+++ b/pypy/module/thread/ll_thread.py
@@ -2,10 +2,11 @@
from pypy.rpython.lltypesystem import rffi, lltype, llmemory
from pypy.translator.tool.cbuild import ExternalCompilationInfo
import py
-from pypy.rlib import jit
+from pypy.rlib import jit, rgc
from pypy.rlib.debug import ll_assert
from pypy.rlib.objectmodel import we_are_translated
from pypy.rpython.lltypesystem.lloperation import llop
+from pypy.rpython.tool import rffi_platform
from pypy.tool import autopath
class error(Exception):
@@ -49,7 +50,7 @@
TLOCKP = rffi.COpaquePtr('struct RPyOpaque_ThreadLock',
compilation_info=eci)
-
+TLOCKP_SIZE = rffi_platform.sizeof('struct RPyOpaque_ThreadLock', eci)
c_thread_lock_init = llexternal('RPyThreadLockInit', [TLOCKP], rffi.INT,
threadsafe=False) # may add in a global list
c_thread_lock_dealloc_NOAUTO = llexternal('RPyOpaqueDealloc_ThreadLock',
@@ -164,6 +165,9 @@
if rffi.cast(lltype.Signed, res) <= 0:
lltype.free(ll_lock, flavor='raw', track_allocation=False)
raise error("out of resources")
+ # Add some memory pressure for the size of the lock because it is an
+ # Opaque object
+ rgc.add_memory_pressure(TLOCKP_SIZE)
return ll_lock
def free_ll_lock(ll_lock):
diff --git a/pypy/objspace/std/bytearrayobject.py b/pypy/objspace/std/bytearrayobject.py
--- a/pypy/objspace/std/bytearrayobject.py
+++ b/pypy/objspace/std/bytearrayobject.py
@@ -283,17 +283,9 @@
return space.wrap(''.join(w_bytearray.data))
def _convert_idx_params(space, w_self, w_start, w_stop):
- start = slicetype.eval_slice_index(space, w_start)
- stop = slicetype.eval_slice_index(space, w_stop)
length = len(w_self.data)
- if start < 0:
- start += length
- if start < 0:
- start = 0
- if stop < 0:
- stop += length
- if stop < 0:
- stop = 0
+ start, stop = slicetype.unwrap_start_stop(
+ space, length, w_start, w_stop, False)
return start, stop, length
def str_count__Bytearray_Int_ANY_ANY(space, w_bytearray, w_char, w_start, w_stop):
diff --git a/pypy/objspace/std/listobject.py b/pypy/objspace/std/listobject.py
--- a/pypy/objspace/std/listobject.py
+++ b/pypy/objspace/std/listobject.py
@@ -419,8 +419,8 @@
# needs to be safe against eq_w() mutating the w_list behind our back
items = w_list.wrappeditems
size = len(items)
- i = slicetype.adapt_bound(space, size, w_start)
- stop = slicetype.adapt_bound(space, size, w_stop)
+ i, stop = slicetype.unwrap_start_stop(
+ space, size, w_start, w_stop, True)
while i < stop and i < len(items):
if space.eq_w(items[i], w_any):
return space.wrap(i)
diff --git a/pypy/objspace/std/ropeobject.py b/pypy/objspace/std/ropeobject.py
--- a/pypy/objspace/std/ropeobject.py
+++ b/pypy/objspace/std/ropeobject.py
@@ -357,16 +357,8 @@
self = w_self._node
sub = w_sub._node
- if space.is_w(w_start, space.w_None):
- w_start = space.wrap(0)
- if space.is_w(w_end, space.w_None):
- w_end = space.len(w_self)
- if upper_bound:
- start = slicetype.adapt_bound(space, self.length(), w_start)
- end = slicetype.adapt_bound(space, self.length(), w_end)
- else:
- start = slicetype.adapt_lower_bound(space, self.length(), w_start)
- end = slicetype.adapt_lower_bound(space, self.length(), w_end)
+ start, end = slicetype.unwrap_start_stop(
+ space, self.length(), w_start, w_end, upper_bound)
return (self, sub, start, end)
_convert_idx_params._annspecialcase_ = 'specialize:arg(5)'
diff --git a/pypy/objspace/std/sliceobject.py b/pypy/objspace/std/sliceobject.py
--- a/pypy/objspace/std/sliceobject.py
+++ b/pypy/objspace/std/sliceobject.py
@@ -4,7 +4,7 @@
from pypy.interpreter import gateway
from pypy.objspace.std.model import registerimplementation, W_Object
from pypy.objspace.std.register_all import register_all
-from pypy.objspace.std.slicetype import eval_slice_index
+from pypy.objspace.std.slicetype import _eval_slice_index
class W_SliceObject(W_Object):
from pypy.objspace.std.slicetype import slice_typedef as typedef
@@ -25,7 +25,7 @@
if space.is_w(w_slice.w_step, space.w_None):
step = 1
else:
- step = eval_slice_index(space, w_slice.w_step)
+ step = _eval_slice_index(space, w_slice.w_step)
if step == 0:
raise OperationError(space.w_ValueError,
space.wrap("slice step cannot be zero"))
@@ -35,7 +35,7 @@
else:
start = 0
else:
- start = eval_slice_index(space, w_slice.w_start)
+ start = _eval_slice_index(space, w_slice.w_start)
if start < 0:
start += length
if start < 0:
@@ -54,7 +54,7 @@
else:
stop = length
else:
- stop = eval_slice_index(space, w_slice.w_stop)
+ stop = _eval_slice_index(space, w_slice.w_stop)
if stop < 0:
stop += length
if stop < 0:
diff --git a/pypy/objspace/std/slicetype.py b/pypy/objspace/std/slicetype.py
--- a/pypy/objspace/std/slicetype.py
+++ b/pypy/objspace/std/slicetype.py
@@ -3,6 +3,7 @@
from pypy.objspace.std.stdtypedef import StdTypeDef, SMM
from pypy.objspace.std.register_all import register_all
from pypy.interpreter.error import OperationError
+from pypy.rlib.objectmodel import specialize
# indices multimehtod
slice_indices = SMM('indices', 2,
@@ -14,7 +15,9 @@
' normal slices.')
# utility functions
-def eval_slice_index(space, w_int):
+def _eval_slice_index(space, w_int):
+ # note that it is the *callers* responsibility to check for w_None
+ # otherwise you can get funny error messages
try:
return space.getindex_w(w_int, None) # clamp if long integer too large
except OperationError, err:
@@ -25,7 +28,7 @@
"None or have an __index__ method"))
def adapt_lower_bound(space, size, w_index):
- index = eval_slice_index(space, w_index)
+ index = _eval_slice_index(space, w_index)
if index < 0:
index = index + size
if index < 0:
@@ -34,16 +37,29 @@
return index
def adapt_bound(space, size, w_index):
- index = eval_slice_index(space, w_index)
- if index < 0:
- index = index + size
- if index < 0:
- index = 0
+ index = adapt_lower_bound(space, size, w_index)
if index > size:
index = size
assert index >= 0
return index
+ at specialize.arg(4)
+def unwrap_start_stop(space, size, w_start, w_end, upper_bound=False):
+ if space.is_w(w_start, space.w_None):
+ start = 0
+ elif upper_bound:
+ start = adapt_bound(space, size, w_start)
+ else:
+ start = adapt_lower_bound(space, size, w_start)
+
+ if space.is_w(w_end, space.w_None):
+ end = size
+ elif upper_bound:
+ end = adapt_bound(space, size, w_end)
+ else:
+ end = adapt_lower_bound(space, size, w_end)
+ return start, end
+
register_all(vars(), globals())
# ____________________________________________________________
diff --git a/pypy/objspace/std/smalltupleobject.py b/pypy/objspace/std/smalltupleobject.py
--- a/pypy/objspace/std/smalltupleobject.py
+++ b/pypy/objspace/std/smalltupleobject.py
@@ -68,10 +68,10 @@
raise IndexError
def eq(self, space, w_other):
- if self.length() != w_other.length():
+ if n != w_other.length():
return space.w_False
for i in iter_n:
- item1 = self.getitem(i)
+ item1 = getattr(self,'w_value%s' % i)
item2 = w_other.getitem(i)
if not space.eq_w(item1, item2):
return space.w_False
@@ -80,9 +80,9 @@
def hash(self, space):
mult = 1000003
x = 0x345678
- z = self.length()
+ z = n
for i in iter_n:
- w_item = self.getitem(i)
+ w_item = getattr(self, 'w_value%s' % i)
y = space.int_w(space.hash(w_item))
x = (x ^ y) * mult
z -= 1
diff --git a/pypy/objspace/std/stringobject.py b/pypy/objspace/std/stringobject.py
--- a/pypy/objspace/std/stringobject.py
+++ b/pypy/objspace/std/stringobject.py
@@ -4,7 +4,7 @@
from pypy.interpreter.error import OperationError, operationerrfmt
from pypy.interpreter import gateway
from pypy.rlib.rarithmetic import ovfcheck
-from pypy.rlib.objectmodel import we_are_translated, compute_hash
+from pypy.rlib.objectmodel import we_are_translated, compute_hash, specialize
from pypy.objspace.std.inttype import wrapint
from pypy.objspace.std.sliceobject import W_SliceObject, normalize_simple_slice
from pypy.objspace.std import slicetype, newformat
@@ -47,6 +47,7 @@
W_StringObject.PREBUILT = [W_StringObject(chr(i)) for i in range(256)]
del i
+ at specialize.arg(2)
def _is_generic(space, w_self, fun):
v = w_self._value
if len(v) == 0:
@@ -56,14 +57,13 @@
return space.newbool(fun(c))
else:
return _is_generic_loop(space, v, fun)
-_is_generic._annspecialcase_ = "specialize:arg(2)"
+ at specialize.arg(2)
def _is_generic_loop(space, v, fun):
for idx in range(len(v)):
if not fun(v[idx]):
return space.w_False
return space.w_True
-_is_generic_loop._annspecialcase_ = "specialize:arg(2)"
def _upper(ch):
if ch.islower():
@@ -420,22 +420,14 @@
return space.wrap(u_self)
-def _convert_idx_params(space, w_self, w_sub, w_start, w_end, upper_bound=False):
+ at specialize.arg(4)
+def _convert_idx_params(space, w_self, w_start, w_end, upper_bound=False):
self = w_self._value
- sub = w_sub._value
+ lenself = len(self)
- if space.is_w(w_start, space.w_None):
- w_start = space.wrap(0)
- if space.is_w(w_end, space.w_None):
- w_end = space.len(w_self)
- if upper_bound:
- start = slicetype.adapt_bound(space, len(self), w_start)
- end = slicetype.adapt_bound(space, len(self), w_end)
- else:
- start = slicetype.adapt_lower_bound(space, len(self), w_start)
- end = slicetype.adapt_lower_bound(space, len(self), w_end)
- return (self, sub, start, end)
-_convert_idx_params._annspecialcase_ = 'specialize:arg(5)'
+ start, end = slicetype.unwrap_start_stop(
+ space, lenself, w_start, w_end, upper_bound=upper_bound)
+ return (self, start, end)
def contains__String_String(space, w_self, w_sub):
self = w_self._value
@@ -443,13 +435,13 @@
return space.newbool(self.find(sub) >= 0)
def str_find__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end):
- (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end)
- res = self.find(sub, start, end)
+ (self, start, end) = _convert_idx_params(space, w_self, w_start, w_end)
+ res = self.find(w_sub._value, start, end)
return space.wrap(res)
def str_rfind__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end):
- (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end)
- res = self.rfind(sub, start, end)
+ (self, start, end) = _convert_idx_params(space, w_self, w_start, w_end)
+ res = self.rfind(w_sub._value, start, end)
return space.wrap(res)
def str_partition__String_String(space, w_self, w_sub):
@@ -483,8 +475,8 @@
def str_index__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end):
- (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end)
- res = self.find(sub, start, end)
+ (self, start, end) = _convert_idx_params(space, w_self, w_start, w_end)
+ res = self.find(w_sub._value, start, end)
if res < 0:
raise OperationError(space.w_ValueError,
space.wrap("substring not found in string.index"))
@@ -493,8 +485,8 @@
def str_rindex__String_String_ANY_ANY(space, w_self, w_sub, w_start, w_end):
- (self, sub, start, end) = _convert_idx_params(space, w_self, w_sub, w_start, w_end)
- res = self.rfind(sub, start, end)
+ (self, start, end) = _convert_idx_params(space, w_self, w_start, w_end)
+ res = self.rfind(w_sub._value, start, end)
if res < 0:
raise OperationError(space.w_ValueError,
space.wrap("substring not found in string.rindex"))
@@ -636,20 +628,17 @@
return wrapstr(space, u_centered)
def str_count__String_String_ANY_ANY(space, w_self, w_arg, w_start, w_end):
- u_self, u_arg, u_start, u_end = _convert_idx_params(space, w_self, w_arg,
- w_start, w_end)
- return wrapint(space, u_self.count(u_arg, u_start, u_end))
+ u_self, u_start, u_end = _convert_idx_params(space, w_self, w_start, w_end)
+ return wrapint(space, u_self.count(w_arg._value, u_start, u_end))
def str_endswith__String_String_ANY_ANY(space, w_self, w_suffix, w_start, w_end):
- (u_self, suffix, start, end) = _convert_idx_params(space, w_self,
- w_suffix, w_start,
- w_end, True)
- return space.newbool(stringendswith(u_self, suffix, start, end))
+ (u_self, start, end) = _convert_idx_params(space, w_self, w_start,
+ w_end, True)
+ return space.newbool(stringendswith(u_self, w_suffix._value, start, end))
def str_endswith__String_Tuple_ANY_ANY(space, w_self, w_suffixes, w_start, w_end):
- (u_self, _, start, end) = _convert_idx_params(space, w_self,
- space.wrap(''), w_start,
- w_end, True)
+ (u_self, start, end) = _convert_idx_params(space, w_self, w_start,
+ w_end, True)
for w_suffix in space.fixedview(w_suffixes):
if space.isinstance_w(w_suffix, space.w_unicode):
w_u = space.call_function(space.w_unicode, w_self)
@@ -661,14 +650,13 @@
return space.w_False
def str_startswith__String_String_ANY_ANY(space, w_self, w_prefix, w_start, w_end):
- (u_self, prefix, start, end) = _convert_idx_params(space, w_self,
- w_prefix, w_start,
- w_end, True)
- return space.newbool(stringstartswith(u_self, prefix, start, end))
+ (u_self, start, end) = _convert_idx_params(space, w_self, w_start,
+ w_end, True)
+ return space.newbool(stringstartswith(u_self, w_prefix._value, start, end))
def str_startswith__String_Tuple_ANY_ANY(space, w_self, w_prefixes, w_start, w_end):
- (u_self, _, start, end) = _convert_idx_params(space, w_self, space.wrap(''),
- w_start, w_end, True)
+ (u_self, start, end) = _convert_idx_params(space, w_self,
+ w_start, w_end, True)
for w_prefix in space.fixedview(w_prefixes):
if space.isinstance_w(w_prefix, space.w_unicode):
w_u = space.call_function(space.w_unicode, w_self)
diff --git a/pypy/objspace/std/strsliceobject.py b/pypy/objspace/std/strsliceobject.py
--- a/pypy/objspace/std/strsliceobject.py
+++ b/pypy/objspace/std/strsliceobject.py
@@ -60,8 +60,8 @@
def _convert_idx_params(space, w_self, w_sub, w_start, w_end):
length = w_self.stop - w_self.start
sub = w_sub._value
- start = slicetype.adapt_bound(space, length, w_start)
- end = slicetype.adapt_bound(space, length, w_end)
+ start, end = slicetype.unwrap_start_stop(
+ space, length, w_start, w_end, True)
assert start >= 0
assert end >= 0
diff --git a/pypy/objspace/std/test/test_listobject.py b/pypy/objspace/std/test/test_listobject.py
--- a/pypy/objspace/std/test/test_listobject.py
+++ b/pypy/objspace/std/test/test_listobject.py
@@ -2,11 +2,10 @@
from pypy.objspace.std.listobject import W_ListObject
from pypy.interpreter.error import OperationError
-from pypy.conftest import gettestobjspace
+from pypy.conftest import gettestobjspace, option
class TestW_ListObject(object):
-
def test_is_true(self):
w = self.space.wrap
w_list = W_ListObject([])
@@ -343,6 +342,13 @@
class AppTestW_ListObject(object):
+ def setup_class(cls):
+ import sys
+ on_cpython = (option.runappdirect and
+ not hasattr(sys, 'pypy_translation_info'))
+
+ cls.w_on_cpython = cls.space.wrap(on_cpython)
+
def test_call_list(self):
assert list('') == []
assert list('abc') == ['a', 'b', 'c']
@@ -616,6 +622,14 @@
assert c.index(0) == 0
raises(ValueError, c.index, 3)
+ def test_index_cpython_bug(self):
+ if self.on_cpython:
+ skip("cpython has a bug here")
+ c = list('hello world')
+ assert c.index('l', None, None) == 2
+ assert c.index('l', 3, None) == 3
+ assert c.index('l', None, 4) == 2
+
def test_ass_slice(self):
l = range(6)
l[1:3] = 'abc'
diff --git a/pypy/objspace/std/tupleobject.py b/pypy/objspace/std/tupleobject.py
--- a/pypy/objspace/std/tupleobject.py
+++ b/pypy/objspace/std/tupleobject.py
@@ -167,17 +167,8 @@
return space.wrap(count)
def tuple_index__Tuple_ANY_ANY_ANY(space, w_tuple, w_obj, w_start, w_stop):
- start = slicetype.eval_slice_index(space, w_start)
- stop = slicetype.eval_slice_index(space, w_stop)
length = len(w_tuple.wrappeditems)
- if start < 0:
- start += length
- if start < 0:
- start = 0
- if stop < 0:
- stop += length
- if stop < 0:
- stop = 0
+ start, stop = slicetype.unwrap_start_stop(space, length, w_start, w_stop)
for i in range(start, min(stop, length)):
w_item = w_tuple.wrappeditems[i]
if space.eq_w(w_item, w_obj):
diff --git a/pypy/objspace/std/unicodeobject.py b/pypy/objspace/std/unicodeobject.py
--- a/pypy/objspace/std/unicodeobject.py
+++ b/pypy/objspace/std/unicodeobject.py
@@ -10,7 +10,7 @@
from pypy.objspace.std import slicetype, newformat
from pypy.objspace.std.tupleobject import W_TupleObject
from pypy.rlib.rarithmetic import intmask, ovfcheck
-from pypy.rlib.objectmodel import compute_hash
+from pypy.rlib.objectmodel import compute_hash, specialize
from pypy.rlib.rstring import UnicodeBuilder
from pypy.rlib.runicode import unicode_encode_unicode_escape
from pypy.module.unicodedata import unicodedb
@@ -475,42 +475,29 @@
index = length
return index
-def _convert_idx_params(space, w_self, w_sub, w_start, w_end, upper_bound=False):
- assert isinstance(w_sub, W_UnicodeObject)
+ at specialize.arg(4)
+def _convert_idx_params(space, w_self, w_start, w_end, upper_bound=False):
self = w_self._value
- sub = w_sub._value
-
- if space.is_w(w_start, space.w_None):
- w_start = space.wrap(0)
- if space.is_w(w_end, space.w_None):
- w_end = space.len(w_self)
-
- if upper_bound:
- start = slicetype.adapt_bound(space, len(self), w_start)
- end = slicetype.adapt_bound(space, len(self), w_end)
- else:
- start = slicetype.adapt_lower_bound(space, len(self), w_start)
- end = slicetype.adapt_lower_bound(space, len(self), w_end)
- return (self, sub, start, end)
-_convert_idx_params._annspecialcase_ = 'specialize:arg(5)'
+ start, end = slicetype.unwrap_start_stop(
+ space, len(self), w_start, w_end, upper_bound)
+ return (self, start, end)
def unicode_endswith__Unicode_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end):
- self, substr, start, end = _convert_idx_params(space, w_self, w_substr,
+ self, start, end = _convert_idx_params(space, w_self,
w_start, w_end, True)
- return space.newbool(stringendswith(self, substr, start, end))
+ return space.newbool(stringendswith(self, w_substr._value, start, end))
def unicode_startswith__Unicode_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end):
- self, substr, start, end = _convert_idx_params(space, w_self, w_substr,
- w_start, w_end, True)
+ self, start, end = _convert_idx_params(space, w_self, w_start, w_end, True)
# XXX this stuff can be waaay better for ootypebased backends if
# we re-use more of our rpython machinery (ie implement startswith
# with additional parameters as rpython)
- return space.newbool(stringstartswith(self, substr, start, end))
+ return space.newbool(stringstartswith(self, w_substr._value, start, end))
def unicode_startswith__Unicode_Tuple_ANY_ANY(space, w_unistr, w_prefixes,
w_start, w_end):
- unistr, _, start, end = _convert_idx_params(space, w_unistr, space.wrap(u''),
- w_start, w_end, True)
+ unistr, start, end = _convert_idx_params(space, w_unistr,
+ w_start, w_end, True)
for w_prefix in space.fixedview(w_prefixes):
prefix = space.unicode_w(w_prefix)
if stringstartswith(unistr, prefix, start, end):
@@ -519,7 +506,7 @@
def unicode_endswith__Unicode_Tuple_ANY_ANY(space, w_unistr, w_suffixes,
w_start, w_end):
- unistr, _, start, end = _convert_idx_params(space, w_unistr, space.wrap(u''),
+ unistr, start, end = _convert_idx_params(space, w_unistr,
w_start, w_end, True)
for w_suffix in space.fixedview(w_suffixes):
suffix = space.unicode_w(w_suffix)
@@ -625,37 +612,32 @@
return space.newlist(lines)
def unicode_find__Unicode_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end):
- self, substr, start, end = _convert_idx_params(space, w_self, w_substr,
- w_start, w_end)
- return space.wrap(self.find(substr, start, end))
+ self, start, end = _convert_idx_params(space, w_self, w_start, w_end)
+ return space.wrap(self.find(w_substr._value, start, end))
def unicode_rfind__Unicode_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end):
- self, substr, start, end = _convert_idx_params(space, w_self, w_substr,
- w_start, w_end)
- return space.wrap(self.rfind(substr, start, end))
+ self, start, end = _convert_idx_params(space, w_self, w_start, w_end)
+ return space.wrap(self.rfind(w_substr._value, start, end))
def unicode_index__Unicode_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end):
- self, substr, start, end = _convert_idx_params(space, w_self, w_substr,
- w_start, w_end)
- index = self.find(substr, start, end)
+ self, start, end = _convert_idx_params(space, w_self, w_start, w_end)
+ index = self.find(w_substr._value, start, end)
if index < 0:
raise OperationError(space.w_ValueError,
space.wrap('substring not found'))
return space.wrap(index)
def unicode_rindex__Unicode_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end):
- self, substr, start, end = _convert_idx_params(space, w_self, w_substr,
- w_start, w_end)
- index = self.rfind(substr, start, end)
+ self, start, end = _convert_idx_params(space, w_self, w_start, w_end)
+ index = self.rfind(w_substr._value, start, end)
if index < 0:
raise OperationError(space.w_ValueError,
space.wrap('substring not found'))
return space.wrap(index)
def unicode_count__Unicode_Unicode_ANY_ANY(space, w_self, w_substr, w_start, w_end):
- self, substr, start, end = _convert_idx_params(space, w_self, w_substr,
- w_start, w_end)
- return space.wrap(self.count(substr, start, end))
+ self, start, end = _convert_idx_params(space, w_self, w_start, w_end)
+ return space.wrap(self.count(w_substr._value, start, end))
def unicode_split__Unicode_None_ANY(space, w_self, w_none, w_maxsplit):
maxsplit = space.int_w(w_maxsplit)
diff --git a/pypy/rlib/rgc.py b/pypy/rlib/rgc.py
--- a/pypy/rlib/rgc.py
+++ b/pypy/rlib/rgc.py
@@ -259,6 +259,24 @@
except Exception:
return False # don't keep objects whose _freeze_() method explodes
+def add_memory_pressure(estimate):
+ """Add memory pressure for OpaquePtrs."""
+ pass
+
+class AddMemoryPressureEntry(ExtRegistryEntry):
+ _about_ = add_memory_pressure
+
+ def compute_result_annotation(self, s_nbytes):
+ from pypy.annotation import model as annmodel
+ return annmodel.s_None
+
+ def specialize_call(self, hop):
+ [v_size] = hop.inputargs(lltype.Signed)
+ hop.exception_cannot_occur()
+ return hop.genop('gc_add_memory_pressure', [v_size],
+ resulttype=lltype.Void)
+
+
def get_rpy_memory_usage(gcref):
"NOT_RPYTHON"
# approximate implementation using CPython's type info
diff --git a/pypy/rlib/ropenssl.py b/pypy/rlib/ropenssl.py
--- a/pypy/rlib/ropenssl.py
+++ b/pypy/rlib/ropenssl.py
@@ -25,6 +25,7 @@
'openssl/err.h',
'openssl/rand.h',
'openssl/evp.h',
+ 'openssl/ossl_typ.h',
'openssl/x509v3.h']
eci = ExternalCompilationInfo(
@@ -108,7 +109,9 @@
GENERAL_NAME_st = rffi_platform.Struct(
'struct GENERAL_NAME_st',
[('type', rffi.INT),
- ])
+ ])
+ EVP_MD_SIZE = rffi_platform.SizeOf('EVP_MD')
+ EVP_MD_CTX_SIZE = rffi_platform.SizeOf('EVP_MD_CTX')
for k, v in rffi_platform.configure(CConfig).items():
@@ -154,7 +157,7 @@
ssl_external('CRYPTO_set_id_callback',
[lltype.Ptr(lltype.FuncType([], rffi.LONG))],
lltype.Void)
-
+
if HAVE_OPENSSL_RAND:
ssl_external('RAND_add', [rffi.CCHARP, rffi.INT, rffi.DOUBLE], lltype.Void)
ssl_external('RAND_status', [], rffi.INT)
@@ -255,7 +258,7 @@
[BIO, rffi.VOIDP, rffi.VOIDP, rffi.VOIDP], X509)
EVP_MD_CTX = rffi.COpaquePtr('EVP_MD_CTX', compilation_info=eci)
-EVP_MD = rffi.COpaquePtr('EVP_MD')
+EVP_MD = rffi.COpaquePtr('EVP_MD', compilation_info=eci)
OpenSSL_add_all_digests = external(
'OpenSSL_add_all_digests', [], lltype.Void)
diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py
--- a/pypy/rpython/llinterp.py
+++ b/pypy/rpython/llinterp.py
@@ -172,7 +172,7 @@
def checkadr(addr):
assert lltype.typeOf(addr) is llmemory.Address
-
+
def is_inst(inst):
return isinstance(lltype.typeOf(inst), (ootype.Instance, ootype.BuiltinType, ootype.StaticMethod))
@@ -657,7 +657,7 @@
raise TypeError("graph with %r args called with wrong func ptr type: %r" %
(tuple([v.concretetype for v in args_v]), ARGS))
frame = self.newsubframe(graph, args)
- return frame.eval()
+ return frame.eval()
def op_direct_call(self, f, *args):
FTYPE = self.llinterpreter.typer.type_system.derefType(lltype.typeOf(f))
@@ -698,13 +698,13 @@
return ptr
except MemoryError:
self.make_llexception()
-
+
def op_malloc_nonmovable(self, TYPE, flags):
flavor = flags['flavor']
assert flavor == 'gc'
zero = flags.get('zero', False)
return self.heap.malloc_nonmovable(TYPE, zero=zero)
-
+
def op_malloc_nonmovable_varsize(self, TYPE, flags, size):
flavor = flags['flavor']
assert flavor == 'gc'
@@ -716,6 +716,9 @@
track_allocation = flags.get('track_allocation', True)
self.heap.free(obj, flavor='raw', track_allocation=track_allocation)
+ def op_gc_add_memory_pressure(self, size):
+ self.heap.add_memory_pressure(size)
+
def op_shrink_array(self, obj, smallersize):
return self.heap.shrink_array(obj, smallersize)
@@ -1321,7 +1324,7 @@
func_graph = fn.graph
else:
# obj is an instance, we want to call 'method_name' on it
- assert fn is None
+ assert fn is None
self_arg = [obj]
func_graph = obj._TYPE._methods[method_name._str].graph
diff --git a/pypy/rpython/lltypesystem/llheap.py b/pypy/rpython/lltypesystem/llheap.py
--- a/pypy/rpython/lltypesystem/llheap.py
+++ b/pypy/rpython/lltypesystem/llheap.py
@@ -5,8 +5,7 @@
setfield = setattr
from operator import setitem as setarrayitem
-from pypy.rlib.rgc import collect
-from pypy.rlib.rgc import can_move
+from pypy.rlib.rgc import can_move, collect, add_memory_pressure
def setinterior(toplevelcontainer, inneraddr, INNERTYPE, newvalue,
offsets=None):
diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -473,6 +473,7 @@
'gc_is_rpy_instance' : LLOp(),
'gc_dump_rpy_heap' : LLOp(),
'gc_typeids_z' : LLOp(),
+ 'gc_add_memory_pressure': LLOp(),
# ------- JIT & GC interaction, only for some GCs ----------
diff --git a/pypy/rpython/lltypesystem/lltype.py b/pypy/rpython/lltypesystem/lltype.py
--- a/pypy/rpython/lltypesystem/lltype.py
+++ b/pypy/rpython/lltypesystem/lltype.py
@@ -48,7 +48,7 @@
self.TYPE = TYPE
def __repr__(self):
return '<Uninitialized %r>'%(self.TYPE,)
-
+
def saferecursive(func, defl, TLS=TLS):
def safe(*args):
@@ -537,9 +537,9 @@
return "Func ( %s ) -> %s" % (args, self.RESULT)
__str__ = saferecursive(__str__, '...')
- def _short_name(self):
+ def _short_name(self):
args = ', '.join([ARG._short_name() for ARG in self.ARGS])
- return "Func(%s)->%s" % (args, self.RESULT._short_name())
+ return "Func(%s)->%s" % (args, self.RESULT._short_name())
_short_name = saferecursive(_short_name, '...')
def _container_example(self):
@@ -553,7 +553,7 @@
class OpaqueType(ContainerType):
_gckind = 'raw'
-
+
def __init__(self, tag, hints={}):
""" if hints['render_structure'] is set, the type is internal and not considered
to come from somewhere else (it should be rendered as a structure) """
@@ -723,10 +723,10 @@
def __str__(self):
return '* %s' % (self.TO, )
-
+
def _short_name(self):
return 'Ptr %s' % (self.TO._short_name(), )
-
+
def _is_atomic(self):
return self.TO._gckind == 'raw'
diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -377,17 +377,24 @@
self.malloc_varsize_nonmovable_ptr = None
if getattr(GCClass, 'raw_malloc_memory_pressure', False):
- def raw_malloc_memory_pressure(length, itemsize):
+ def raw_malloc_memory_pressure_varsize(length, itemsize):
totalmem = length * itemsize
if totalmem > 0:
gcdata.gc.raw_malloc_memory_pressure(totalmem)
#else: probably an overflow -- the following rawmalloc
# will fail then
+ def raw_malloc_memory_pressure(sizehint):
+ gcdata.gc.raw_malloc_memory_pressure(sizehint)
+ self.raw_malloc_memory_pressure_varsize_ptr = getfn(
+ raw_malloc_memory_pressure_varsize,
+ [annmodel.SomeInteger(), annmodel.SomeInteger()],
+ annmodel.s_None, minimal_transform = False)
self.raw_malloc_memory_pressure_ptr = getfn(
raw_malloc_memory_pressure,
- [annmodel.SomeInteger(), annmodel.SomeInteger()],
+ [annmodel.SomeInteger()],
annmodel.s_None, minimal_transform = False)
+
self.identityhash_ptr = getfn(GCClass.identityhash.im_func,
[s_gc, s_gcref],
annmodel.SomeInteger(),
diff --git a/pypy/rpython/memory/gctransform/transform.py b/pypy/rpython/memory/gctransform/transform.py
--- a/pypy/rpython/memory/gctransform/transform.py
+++ b/pypy/rpython/memory/gctransform/transform.py
@@ -63,7 +63,7 @@
gct.push_alive(v_result, self.llops)
elif opname not in ('direct_call', 'indirect_call'):
gct.push_alive(v_result, self.llops)
-
+
def rename(self, newopname):
@@ -118,7 +118,7 @@
self.minimalgctransformer = self.MinimalGCTransformer(self)
else:
self.minimalgctransformer = None
-
+
def get_lltype_of_exception_value(self):
if self.translator is not None:
exceptiondata = self.translator.rtyper.getexceptiondata()
@@ -399,7 +399,7 @@
def gct_gc_heap_stats(self, hop):
from pypy.rpython.memory.gc.base import ARRAY_TYPEID_MAP
-
+
return hop.cast_result(rmodel.inputconst(lltype.Ptr(ARRAY_TYPEID_MAP),
lltype.nullptr(ARRAY_TYPEID_MAP)))
@@ -427,7 +427,7 @@
assert flavor == 'raw'
assert not flags.get('zero')
return self.parenttransformer.gct_malloc_varsize(hop)
-
+
def gct_free(self, hop):
flags = hop.spaceop.args[1].value
flavor = flags['flavor']
@@ -502,7 +502,7 @@
stack_mh = mallocHelpers()
stack_mh.allocate = lambda size: llop.stack_malloc(llmemory.Address, size)
ll_stack_malloc_fixedsize = stack_mh._ll_malloc_fixedsize
-
+
if self.translator:
self.raw_malloc_fixedsize_ptr = self.inittime_helper(
ll_raw_malloc_fixedsize, [lltype.Signed], llmemory.Address)
@@ -541,7 +541,7 @@
resulttype=llmemory.Address)
if flags.get('zero'):
hop.genop("raw_memclear", [v_raw, c_size])
- return v_raw
+ return v_raw
def gct_malloc_varsize(self, hop, add_flags=None):
flags = hop.spaceop.args[1].value
@@ -559,6 +559,14 @@
def gct_malloc_nonmovable_varsize(self, *args, **kwds):
return self.gct_malloc_varsize(*args, **kwds)
+ def gct_gc_add_memory_pressure(self, hop):
+ if hasattr(self, 'raw_malloc_memory_pressure_ptr'):
+ op = hop.spaceop
+ size = op.args[0]
+ return hop.genop("direct_call",
+ [self.raw_malloc_memory_pressure_ptr,
+ size])
+
def varsize_malloc_helper(self, hop, flags, meth, extraargs):
def intconst(c): return rmodel.inputconst(lltype.Signed, c)
op = hop.spaceop
@@ -590,9 +598,9 @@
def gct_fv_raw_malloc_varsize(self, hop, flags, TYPE, v_length, c_const_size, c_item_size,
c_offset_to_length):
if flags.get('add_memory_pressure', False):
- if hasattr(self, 'raw_malloc_memory_pressure_ptr'):
+ if hasattr(self, 'raw_malloc_memory_pressure_varsize_ptr'):
hop.genop("direct_call",
- [self.raw_malloc_memory_pressure_ptr,
+ [self.raw_malloc_memory_pressure_varsize_ptr,
v_length, c_item_size])
if c_offset_to_length is None:
if flags.get('zero'):
@@ -625,7 +633,7 @@
hop.genop("track_alloc_stop", [v])
hop.genop('raw_free', [v])
else:
- assert False, "%s has no support for free with flavor %r" % (self, flavor)
+ assert False, "%s has no support for free with flavor %r" % (self, flavor)
def gct_gc_can_move(self, hop):
return hop.cast_result(rmodel.inputconst(lltype.Bool, False))
diff --git a/pypy/rpython/memory/gcwrapper.py b/pypy/rpython/memory/gcwrapper.py
--- a/pypy/rpython/memory/gcwrapper.py
+++ b/pypy/rpython/memory/gcwrapper.py
@@ -66,6 +66,10 @@
gctypelayout.zero_gc_pointers(result)
return result
+ def add_memory_pressure(self, size):
+ if hasattr(self.gc, 'raw_malloc_memory_pressure'):
+ self.gc.raw_malloc_memory_pressure(size)
+
def shrink_array(self, p, smallersize):
if hasattr(self.gc, 'shrink_array'):
addr = llmemory.cast_ptr_to_adr(p)
diff --git a/pypy/rpython/memory/test/test_gc.py b/pypy/rpython/memory/test/test_gc.py
--- a/pypy/rpython/memory/test/test_gc.py
+++ b/pypy/rpython/memory/test/test_gc.py
@@ -592,7 +592,7 @@
return rgc.can_move(lltype.malloc(TP, 1))
assert self.interpret(func, []) == self.GC_CAN_MOVE
-
+
def test_malloc_nonmovable(self):
TP = lltype.GcArray(lltype.Char)
def func():
diff --git a/pypy/rpython/memory/test/test_transformed_gc.py b/pypy/rpython/memory/test/test_transformed_gc.py
--- a/pypy/rpython/memory/test/test_transformed_gc.py
+++ b/pypy/rpython/memory/test/test_transformed_gc.py
@@ -27,7 +27,7 @@
t.config.set(**extraconfigopts)
ann = t.buildannotator(policy=annpolicy.StrictAnnotatorPolicy())
ann.build_types(func, inputtypes)
-
+
if specialize:
t.buildrtyper().specialize()
if backendopt:
@@ -44,7 +44,7 @@
GC_CAN_MOVE = False
GC_CAN_MALLOC_NONMOVABLE = True
taggedpointers = False
-
+
def setup_class(cls):
funcs0 = []
funcs2 = []
@@ -155,7 +155,7 @@
return run, gct
else:
return run
-
+
class GenericGCTests(GCTest):
GC_CAN_SHRINK_ARRAY = False
@@ -190,7 +190,7 @@
j += 1
return 0
return malloc_a_lot
-
+
def test_instances(self):
run, statistics = self.runner("instances", statistics=True)
run([])
@@ -276,7 +276,7 @@
for i in range(1, 5):
res = run([i, i - 1])
assert res == i - 1 # crashes if constants are not considered roots
-
+
def define_string_concatenation(cls):
def concat(j, dummy):
lst = []
@@ -656,7 +656,7 @@
# return 2
return func
-
+
def test_malloc_nonmovable(self):
run = self.runner("malloc_nonmovable")
assert int(self.GC_CAN_MALLOC_NONMOVABLE) == run([])
@@ -676,7 +676,7 @@
return 2
return func
-
+
def test_malloc_nonmovable_fixsize(self):
run = self.runner("malloc_nonmovable_fixsize")
assert run([]) == int(self.GC_CAN_MALLOC_NONMOVABLE)
@@ -757,7 +757,7 @@
lltype.free(idarray, flavor='raw')
return 0
return f
-
+
def test_many_ids(self):
if not self.GC_CAN_TEST_ID:
py.test.skip("fails for bad reasons in lltype.py :-(")
@@ -813,7 +813,7 @@
else:
assert 0, "oups, not found"
return f, None, fix_graph_of_g
-
+
def test_do_malloc_operations(self):
run = self.runner("do_malloc_operations")
run([])
@@ -850,7 +850,7 @@
else:
assert 0, "oups, not found"
return f, None, fix_graph_of_g
-
+
def test_do_malloc_operations_in_call(self):
run = self.runner("do_malloc_operations_in_call")
run([])
@@ -861,7 +861,7 @@
l2 = []
l3 = []
l4 = []
-
+
def f():
for i in range(10):
s = lltype.malloc(S)
@@ -1026,7 +1026,7 @@
llop.gc__collect(lltype.Void)
return static.p.x + i
def cleanup():
- static.p = lltype.nullptr(T1)
+ static.p = lltype.nullptr(T1)
return f, cleanup, None
def test_nongc_static_root_minor_collect(self):
@@ -1081,7 +1081,7 @@
return 0
return f
-
+
def test_many_weakrefs(self):
run = self.runner("many_weakrefs")
run([])
@@ -1131,7 +1131,7 @@
def define_adr_of_nursery(cls):
class A(object):
pass
-
+
def f():
# we need at least 1 obj to allocate a nursery
a = A()
@@ -1147,9 +1147,9 @@
assert nt1 > nf1
assert nt1 == nt0
return 0
-
+
return f
-
+
def test_adr_of_nursery(self):
run = self.runner("adr_of_nursery")
res = run([])
@@ -1175,7 +1175,7 @@
def _teardown(self):
self.__ready = False # collecting here is expected
GenerationGC._teardown(self)
-
+
GC_PARAMS = {'space_size': 512*WORD,
'nursery_size': 128*WORD,
'translated_to_c': False}
diff --git a/pypy/translator/c/test/test_newgc.py b/pypy/translator/c/test/test_newgc.py
--- a/pypy/translator/c/test/test_newgc.py
+++ b/pypy/translator/c/test/test_newgc.py
@@ -37,7 +37,7 @@
else:
print res
return 0
-
+
t = Translation(main, standalone=True, gc=cls.gcpolicy,
policy=annpolicy.StrictAnnotatorPolicy(),
taggedpointers=cls.taggedpointers,
@@ -128,10 +128,10 @@
if not args:
args = (-1, )
res = self.allfuncs(name, *args)
- num = self.name_to_func[name]
+ num = self.name_to_func[name]
if self.funcsstr[num]:
return res
- return int(res)
+ return int(res)
def define_empty_collect(cls):
def f():
@@ -228,7 +228,7 @@
T = lltype.GcStruct("T", ('y', lltype.Signed),
('s', lltype.Ptr(S)))
ARRAY_Ts = lltype.GcArray(lltype.Ptr(T))
-
+
def f():
r = 0
for i in range(30):
@@ -250,7 +250,7 @@
def test_framework_varsized(self):
res = self.run('framework_varsized')
assert res == self.run_orig('framework_varsized')
-
+
def define_framework_using_lists(cls):
class A(object):
pass
@@ -271,7 +271,7 @@
N = 1000
res = self.run('framework_using_lists')
assert res == N*(N - 1)/2
-
+
def define_framework_static_roots(cls):
class A(object):
def __init__(self, y):
@@ -318,8 +318,8 @@
def test_framework_void_array(self):
res = self.run('framework_void_array')
assert res == 44
-
-
+
+
def define_framework_malloc_failure(cls):
def f():
a = [1] * (sys.maxint//2)
@@ -342,7 +342,7 @@
def test_framework_array_of_void(self):
res = self.run('framework_array_of_void')
assert res == 43 + 1000000
-
+
def define_framework_opaque(cls):
A = lltype.GcStruct('A', ('value', lltype.Signed))
O = lltype.GcOpaqueType('test.framework')
@@ -437,7 +437,7 @@
b = B()
return 0
return func
-
+
def test_del_raises(self):
self.run('del_raises') # does not raise
@@ -712,7 +712,7 @@
def test_callback_with_collect(self):
assert self.run('callback_with_collect')
-
+
def define_can_move(cls):
class A:
pass
@@ -1255,7 +1255,7 @@
l1 = []
l2 = []
l3 = []
-
+
def f():
for i in range(10):
s = lltype.malloc(S)
@@ -1298,7 +1298,7 @@
def test_string_builder(self):
res = self.run('string_builder')
assert res == "aabcbdddd"
-
+
def definestr_string_builder_over_allocation(cls):
import gc
def fn(_):
@@ -1458,6 +1458,37 @@
res = self.run("nongc_attached_to_gc")
assert res == -99997
+ def define_nongc_opaque_attached_to_gc(cls):
+ from pypy.module._hashlib.interp_hashlib import HASH_MALLOC_SIZE
+ from pypy.rlib import rgc, ropenssl
+ from pypy.rpython.lltypesystem import rffi
+
+ class A:
+ def __init__(self):
+ self.ctx = lltype.malloc(ropenssl.EVP_MD_CTX.TO,
+ flavor='raw')
+ digest = ropenssl.EVP_get_digestbyname('sha1')
+ ropenssl.EVP_DigestInit(self.ctx, digest)
+ rgc.add_memory_pressure(HASH_MALLOC_SIZE + 64)
+
+ def __del__(self):
+ ropenssl.EVP_MD_CTX_cleanup(self.ctx)
+ lltype.free(self.ctx, flavor='raw')
+ A()
+ def f():
+ am1 = am2 = am3 = None
+ for i in range(100000):
+ am3 = am2
+ am2 = am1
+ am1 = A()
+ # what can we use for the res?
+ return 0
+ return f
+
+ def test_nongc_opaque_attached_to_gc(self):
+ res = self.run("nongc_opaque_attached_to_gc")
+ assert res == 0
+
# ____________________________________________________________________
class TaggedPointersTest(object):
More information about the pypy-commit
mailing list