[pypy-commit] pypy win64-stage1: Merge with default (13 days)
ctismer
noreply at buildbot.pypy.org
Tue Mar 13 00:37:44 CET 2012
Author: Christian Tismer <tismer at stackless.com>
Branch: win64-stage1
Changeset: r53390:a79ccf1294ef
Date: 2012-03-12 16:36 -0700
http://bitbucket.org/pypy/pypy/changeset/a79ccf1294ef/
Log: Merge with default (13 days)
diff --git a/lib-python/modified-2.7/ctypes/test/test_arrays.py b/lib-python/modified-2.7/ctypes/test/test_arrays.py
--- a/lib-python/modified-2.7/ctypes/test/test_arrays.py
+++ b/lib-python/modified-2.7/ctypes/test/test_arrays.py
@@ -1,12 +1,23 @@
import unittest
from ctypes import *
+from test.test_support import impl_detail
formats = "bBhHiIlLqQfd"
+# c_longdouble commented out for PyPy, look at the commend in test_longdouble
formats = c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint, \
- c_long, c_ulonglong, c_float, c_double, c_longdouble
+ c_long, c_ulonglong, c_float, c_double #, c_longdouble
class ArrayTestCase(unittest.TestCase):
+
+ @impl_detail('long double not supported by PyPy', pypy=False)
+ def test_longdouble(self):
+ """
+ This test is empty. It's just here to remind that we commented out
+ c_longdouble in "formats". If pypy will ever supports c_longdouble, we
+ should kill this test and uncomment c_longdouble inside formats.
+ """
+
def test_simple(self):
# create classes holding simple numeric types, and check
# various properties.
diff --git a/pypy/interpreter/pyparser/parsestring.py b/pypy/interpreter/pyparser/parsestring.py
--- a/pypy/interpreter/pyparser/parsestring.py
+++ b/pypy/interpreter/pyparser/parsestring.py
@@ -1,5 +1,6 @@
from pypy.interpreter.error import OperationError
from pypy.interpreter import unicodehelper
+from pypy.rlib.rstring import StringBuilder
def parsestr(space, encoding, s, unicode_literals=False):
# compiler.transformer.Transformer.decode_literal depends on what
@@ -115,21 +116,23 @@
the string is UTF-8 encoded and should be re-encoded in the
specified encoding.
"""
- lis = []
+ builder = StringBuilder(len(s))
ps = 0
end = len(s)
- while ps < end:
- if s[ps] != '\\':
- # note that the C code has a label here.
- # the logic is the same.
+ while 1:
+ ps2 = ps
+ while ps < end and s[ps] != '\\':
if recode_encoding and ord(s[ps]) & 0x80:
w, ps = decode_utf8(space, s, ps, end, recode_encoding)
- # Append bytes to output buffer.
- lis.append(w)
+ builder.append(w)
+ ps2 = ps
else:
- lis.append(s[ps])
ps += 1
- continue
+ if ps > ps2:
+ builder.append_slice(s, ps2, ps)
+ if ps == end:
+ break
+
ps += 1
if ps == end:
raise_app_valueerror(space, 'Trailing \\ in string')
@@ -140,25 +143,25 @@
if ch == '\n':
pass
elif ch == '\\':
- lis.append('\\')
+ builder.append('\\')
elif ch == "'":
- lis.append("'")
+ builder.append("'")
elif ch == '"':
- lis.append('"')
+ builder.append('"')
elif ch == 'b':
- lis.append("\010")
+ builder.append("\010")
elif ch == 'f':
- lis.append('\014') # FF
+ builder.append('\014') # FF
elif ch == 't':
- lis.append('\t')
+ builder.append('\t')
elif ch == 'n':
- lis.append('\n')
+ builder.append('\n')
elif ch == 'r':
- lis.append('\r')
+ builder.append('\r')
elif ch == 'v':
- lis.append('\013') # VT
+ builder.append('\013') # VT
elif ch == 'a':
- lis.append('\007') # BEL, not classic C
+ builder.append('\007') # BEL, not classic C
elif ch in '01234567':
# Look for up to two more octal digits
span = ps
@@ -168,13 +171,13 @@
# emulate a strange wrap-around behavior of CPython:
# \400 is the same as \000 because 0400 == 256
num = int(octal, 8) & 0xFF
- lis.append(chr(num))
+ builder.append(chr(num))
ps = span
elif ch == 'x':
if ps+2 <= end and isxdigit(s[ps]) and isxdigit(s[ps + 1]):
hexa = s[ps : ps + 2]
num = int(hexa, 16)
- lis.append(chr(num))
+ builder.append(chr(num))
ps += 2
else:
raise_app_valueerror(space, 'invalid \\x escape')
@@ -184,13 +187,13 @@
# this was not an escape, so the backslash
# has to be added, and we start over in
# non-escape mode.
- lis.append('\\')
+ builder.append('\\')
ps -= 1
assert ps >= 0
continue
# an arbitry number of unescaped UTF-8 bytes may follow.
- buf = ''.join(lis)
+ buf = builder.build()
return buf
diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -769,11 +769,19 @@
self.generate_function('malloc_unicode', malloc_unicode,
[lltype.Signed])
- # Rarely called: allocate a fixed-size amount of bytes, but
- # not in the nursery, because it is too big. Implemented like
- # malloc_nursery_slowpath() above.
- self.generate_function('malloc_fixedsize', malloc_nursery_slowpath,
- [lltype.Signed])
+ # Never called as far as I can tell, but there for completeness:
+ # allocate a fixed-size object, but not in the nursery, because
+ # it is too big.
+ def malloc_big_fixedsize(size, tid):
+ if self.DEBUG:
+ self._random_usage_of_xmm_registers()
+ type_id = llop.extract_ushort(llgroup.HALFWORD, tid)
+ check_typeid(type_id)
+ return llop1.do_malloc_fixedsize_clear(llmemory.GCREF,
+ type_id, size,
+ False, False, False)
+ self.generate_function('malloc_big_fixedsize', malloc_big_fixedsize,
+ [lltype.Signed] * 2)
def _bh_malloc(self, sizedescr):
from pypy.rpython.memory.gctypelayout import check_typeid
diff --git a/pypy/jit/backend/llsupport/rewrite.py b/pypy/jit/backend/llsupport/rewrite.py
--- a/pypy/jit/backend/llsupport/rewrite.py
+++ b/pypy/jit/backend/llsupport/rewrite.py
@@ -96,8 +96,10 @@
def handle_new_fixedsize(self, descr, op):
assert isinstance(descr, SizeDescr)
size = descr.size
- self.gen_malloc_nursery(size, op.result)
- self.gen_initialize_tid(op.result, descr.tid)
+ if self.gen_malloc_nursery(size, op.result):
+ self.gen_initialize_tid(op.result, descr.tid)
+ else:
+ self.gen_malloc_fixedsize(size, descr.tid, op.result)
def handle_new_array(self, arraydescr, op):
v_length = op.getarg(0)
@@ -112,8 +114,8 @@
pass # total_size is still -1
elif arraydescr.itemsize == 0:
total_size = arraydescr.basesize
- if 0 <= total_size <= 0xffffff: # up to 16MB, arbitrarily
- self.gen_malloc_nursery(total_size, op.result)
+ if (total_size >= 0 and
+ self.gen_malloc_nursery(total_size, op.result)):
self.gen_initialize_tid(op.result, arraydescr.tid)
self.gen_initialize_len(op.result, v_length, arraydescr.lendescr)
elif self.gc_ll_descr.kind == 'boehm':
@@ -147,13 +149,22 @@
# mark 'v_result' as freshly malloced
self.recent_mallocs[v_result] = None
- def gen_malloc_fixedsize(self, size, v_result):
- """Generate a CALL_MALLOC_GC(malloc_fixedsize_fn, Const(size)).
- Note that with the framework GC, this should be called very rarely.
+ def gen_malloc_fixedsize(self, size, typeid, v_result):
+ """Generate a CALL_MALLOC_GC(malloc_fixedsize_fn, ...).
+ Used on Boehm, and on the framework GC for large fixed-size
+ mallocs. (For all I know this latter case never occurs in
+ practice, but better safe than sorry.)
"""
- addr = self.gc_ll_descr.get_malloc_fn_addr('malloc_fixedsize')
- self._gen_call_malloc_gc([ConstInt(addr), ConstInt(size)], v_result,
- self.gc_ll_descr.malloc_fixedsize_descr)
+ if self.gc_ll_descr.fielddescr_tid is not None: # framework GC
+ assert (size & (WORD-1)) == 0, "size not aligned?"
+ addr = self.gc_ll_descr.get_malloc_fn_addr('malloc_big_fixedsize')
+ args = [ConstInt(addr), ConstInt(size), ConstInt(typeid)]
+ descr = self.gc_ll_descr.malloc_big_fixedsize_descr
+ else: # Boehm
+ addr = self.gc_ll_descr.get_malloc_fn_addr('malloc_fixedsize')
+ args = [ConstInt(addr), ConstInt(size)]
+ descr = self.gc_ll_descr.malloc_fixedsize_descr
+ self._gen_call_malloc_gc(args, v_result, descr)
def gen_boehm_malloc_array(self, arraydescr, v_num_elem, v_result):
"""Generate a CALL_MALLOC_GC(malloc_array_fn, ...) for Boehm."""
@@ -211,8 +222,7 @@
"""
size = self.round_up_for_allocation(size)
if not self.gc_ll_descr.can_use_nursery_malloc(size):
- self.gen_malloc_fixedsize(size, v_result)
- return
+ return False
#
op = None
if self._op_malloc_nursery is not None:
@@ -238,6 +248,7 @@
self._previous_size = size
self._v_last_malloced_nursery = v_result
self.recent_mallocs[v_result] = None
+ return True
def gen_initialize_tid(self, v_newgcobj, tid):
if self.gc_ll_descr.fielddescr_tid is not None:
diff --git a/pypy/jit/backend/llsupport/test/test_rewrite.py b/pypy/jit/backend/llsupport/test/test_rewrite.py
--- a/pypy/jit/backend/llsupport/test/test_rewrite.py
+++ b/pypy/jit/backend/llsupport/test/test_rewrite.py
@@ -119,12 +119,19 @@
jump()
""", """
[]
- p0 = call_malloc_gc(ConstClass(malloc_fixedsize), \
- %(adescr.basesize + 10 * adescr.itemsize)d, \
- descr=malloc_fixedsize_descr)
- setfield_gc(p0, 10, descr=alendescr)
+ p0 = call_malloc_gc(ConstClass(malloc_array), \
+ %(adescr.basesize)d, \
+ 10, \
+ %(adescr.itemsize)d, \
+ %(adescr.lendescr.offset)d, \
+ descr=malloc_array_descr)
jump()
""")
+## should ideally be:
+## p0 = call_malloc_gc(ConstClass(malloc_fixedsize), \
+## %(adescr.basesize + 10 * adescr.itemsize)d, \
+## descr=malloc_fixedsize_descr)
+## setfield_gc(p0, 10, descr=alendescr)
def test_new_array_variable(self):
self.check_rewrite("""
@@ -178,13 +185,20 @@
jump()
""", """
[i1]
- p0 = call_malloc_gc(ConstClass(malloc_fixedsize), \
- %(unicodedescr.basesize + \
- 10 * unicodedescr.itemsize)d, \
- descr=malloc_fixedsize_descr)
- setfield_gc(p0, 10, descr=unicodelendescr)
+ p0 = call_malloc_gc(ConstClass(malloc_array), \
+ %(unicodedescr.basesize)d, \
+ 10, \
+ %(unicodedescr.itemsize)d, \
+ %(unicodelendescr.offset)d, \
+ descr=malloc_array_descr)
jump()
""")
+## should ideally be:
+## p0 = call_malloc_gc(ConstClass(malloc_fixedsize), \
+## %(unicodedescr.basesize + \
+## 10 * unicodedescr.itemsize)d, \
+## descr=malloc_fixedsize_descr)
+## setfield_gc(p0, 10, descr=unicodelendescr)
class TestFramework(RewriteTests):
@@ -203,7 +217,7 @@
#
class FakeCPU(object):
def sizeof(self, STRUCT):
- descr = SizeDescrWithVTable(102)
+ descr = SizeDescrWithVTable(104)
descr.tid = 9315
return descr
self.cpu = FakeCPU()
@@ -368,11 +382,9 @@
jump()
""", """
[]
- p0 = call_malloc_gc(ConstClass(malloc_fixedsize), \
- %(bdescr.basesize + 104)d, \
- descr=malloc_fixedsize_descr)
- setfield_gc(p0, 8765, descr=tiddescr)
- setfield_gc(p0, 103, descr=blendescr)
+ p0 = call_malloc_gc(ConstClass(malloc_array), 1, \
+ %(bdescr.tid)d, 103, \
+ descr=malloc_array_descr)
jump()
""")
@@ -435,9 +447,8 @@
jump()
""", """
[p1]
- p0 = call_malloc_gc(ConstClass(malloc_fixedsize), 104, \
- descr=malloc_fixedsize_descr)
- setfield_gc(p0, 9315, descr=tiddescr)
+ p0 = call_malloc_gc(ConstClass(malloc_big_fixedsize), 104, 9315, \
+ descr=malloc_big_fixedsize_descr)
setfield_gc(p0, ConstClass(o_vtable), descr=vtable_descr)
jump()
""")
diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py
--- a/pypy/jit/metainterp/compile.py
+++ b/pypy/jit/metainterp/compile.py
@@ -289,8 +289,21 @@
assert isinstance(token, TargetToken)
assert token.original_jitcell_token is None
token.original_jitcell_token = trace.original_jitcell_token
-
-
+
+
+def do_compile_loop(metainterp_sd, inputargs, operations, looptoken,
+ log=True, name=''):
+ metainterp_sd.logger_ops.log_loop(inputargs, operations, -2,
+ 'compiling', name=name)
+ return metainterp_sd.cpu.compile_loop(inputargs, operations, looptoken,
+ log=log, name=name)
+
+def do_compile_bridge(metainterp_sd, faildescr, inputargs, operations,
+ original_loop_token, log=True):
+ metainterp_sd.logger_ops.log_bridge(inputargs, operations, -2)
+ return metainterp_sd.cpu.compile_bridge(faildescr, inputargs, operations,
+ original_loop_token, log=log)
+
def send_loop_to_backend(greenkey, jitdriver_sd, metainterp_sd, loop, type):
vinfo = jitdriver_sd.virtualizable_info
if vinfo is not None:
@@ -319,9 +332,9 @@
metainterp_sd.profiler.start_backend()
debug_start("jit-backend")
try:
- asminfo = metainterp_sd.cpu.compile_loop(loop.inputargs, operations,
- original_jitcell_token,
- name=loopname)
+ asminfo = do_compile_loop(metainterp_sd, loop.inputargs,
+ operations, original_jitcell_token,
+ name=loopname)
finally:
debug_stop("jit-backend")
metainterp_sd.profiler.end_backend()
@@ -333,7 +346,6 @@
metainterp_sd.stats.compiled()
metainterp_sd.log("compiled new " + type)
#
- loopname = jitdriver_sd.warmstate.get_location_str(greenkey)
if asminfo is not None:
ops_offset = asminfo.ops_offset
else:
@@ -365,9 +377,9 @@
metainterp_sd.profiler.start_backend()
debug_start("jit-backend")
try:
- asminfo = metainterp_sd.cpu.compile_bridge(faildescr, inputargs,
- operations,
- original_loop_token)
+ asminfo = do_compile_bridge(metainterp_sd, faildescr, inputargs,
+ operations,
+ original_loop_token)
finally:
debug_stop("jit-backend")
metainterp_sd.profiler.end_backend()
diff --git a/pypy/jit/metainterp/logger.py b/pypy/jit/metainterp/logger.py
--- a/pypy/jit/metainterp/logger.py
+++ b/pypy/jit/metainterp/logger.py
@@ -18,6 +18,10 @@
debug_start("jit-log-noopt-loop")
logops = self._log_operations(inputargs, operations, ops_offset)
debug_stop("jit-log-noopt-loop")
+ elif number == -2:
+ debug_start("jit-log-compiling-loop")
+ logops = self._log_operations(inputargs, operations, ops_offset)
+ debug_stop("jit-log-compiling-loop")
else:
debug_start("jit-log-opt-loop")
debug_print("# Loop", number, '(%s)' % name , ":", type,
@@ -31,6 +35,10 @@
debug_start("jit-log-noopt-bridge")
logops = self._log_operations(inputargs, operations, ops_offset)
debug_stop("jit-log-noopt-bridge")
+ elif number == -2:
+ debug_start("jit-log-compiling-bridge")
+ logops = self._log_operations(inputargs, operations, ops_offset)
+ debug_stop("jit-log-compiling-bridge")
else:
debug_start("jit-log-opt-bridge")
debug_print("# bridge out of Guard", number,
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_multilabel.py b/pypy/jit/metainterp/optimizeopt/test/test_multilabel.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_multilabel.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_multilabel.py
@@ -398,6 +398,50 @@
with raises(InvalidLoop):
self.optimize_loop(ops, ops)
+ def test_maybe_issue1045_related(self):
+ ops = """
+ [p8]
+ p54 = getfield_gc(p8, descr=valuedescr)
+ mark_opaque_ptr(p54)
+ i55 = getfield_gc(p54, descr=nextdescr)
+ p57 = new_with_vtable(ConstClass(node_vtable))
+ setfield_gc(p57, i55, descr=otherdescr)
+ p69 = new_with_vtable(ConstClass(node_vtable))
+ setfield_gc(p69, i55, descr=otherdescr)
+ i71 = int_eq(i55, -9223372036854775808)
+ guard_false(i71) []
+ i73 = int_mod(i55, 2)
+ i75 = int_rshift(i73, 63)
+ i76 = int_and(2, i75)
+ i77 = int_add(i73, i76)
+ p79 = new_with_vtable(ConstClass(node_vtable))
+ setfield_gc(p79, i77, descr=otherdescr)
+ i81 = int_eq(i77, 1)
+ guard_false(i81) []
+ i0 = int_ge(i55, 1)
+ guard_true(i0) []
+ label(p57)
+ jump(p57)
+ """
+ expected = """
+ [p8]
+ p54 = getfield_gc(p8, descr=valuedescr)
+ i55 = getfield_gc(p54, descr=nextdescr)
+ i71 = int_eq(i55, -9223372036854775808)
+ guard_false(i71) []
+ i73 = int_mod(i55, 2)
+ i75 = int_rshift(i73, 63)
+ i76 = int_and(2, i75)
+ i77 = int_add(i73, i76)
+ i81 = int_eq(i77, 1)
+ guard_false(i81) []
+ i0 = int_ge(i55, 1)
+ guard_true(i0) []
+ label(i55)
+ jump(i55)
+ """
+ self.optimize_loop(ops, expected)
+
class OptRenameStrlen(Optimization):
def propagate_forward(self, op):
dispatch_opt(self, op)
@@ -457,7 +501,6 @@
jump(p1, i11)
"""
self.optimize_loop(ops, expected)
-
class TestLLtype(OptimizeoptTestMultiLabel, LLtypeMixin):
diff --git a/pypy/jit/metainterp/test/test_quasiimmut.py b/pypy/jit/metainterp/test/test_quasiimmut.py
--- a/pypy/jit/metainterp/test/test_quasiimmut.py
+++ b/pypy/jit/metainterp/test/test_quasiimmut.py
@@ -8,7 +8,7 @@
from pypy.jit.metainterp.quasiimmut import get_current_qmut_instance
from pypy.jit.metainterp.test.support import LLJitMixin
from pypy.jit.codewriter.policy import StopAtXPolicy
-from pypy.rlib.jit import JitDriver, dont_look_inside
+from pypy.rlib.jit import JitDriver, dont_look_inside, unroll_safe
def test_get_current_qmut_instance():
@@ -480,6 +480,32 @@
assert res == 1
self.check_jitcell_token_count(2)
+ def test_for_loop_array(self):
+ myjitdriver = JitDriver(greens=[], reds=["n", "i"])
+ class Foo(object):
+ _immutable_fields_ = ["x?[*]"]
+ def __init__(self, x):
+ self.x = x
+ f = Foo([1, 3, 5, 6])
+ @unroll_safe
+ def g(v):
+ for x in f.x:
+ if x & 1 == 0:
+ v += 1
+ return v
+ def main(n):
+ i = 0
+ while i < n:
+ myjitdriver.jit_merge_point(n=n, i=i)
+ i = g(i)
+ return i
+ res = self.meta_interp(main, [10])
+ assert res == 10
+ self.check_resops({
+ "int_add": 2, "int_lt": 2, "jump": 1, "guard_true": 2,
+ "guard_not_invalidated": 2
+ })
+
class TestLLtypeGreenFieldsTests(QuasiImmutTests, LLJitMixin):
pass
diff --git a/pypy/module/imp/test/test_import.py b/pypy/module/imp/test/test_import.py
--- a/pypy/module/imp/test/test_import.py
+++ b/pypy/module/imp/test/test_import.py
@@ -357,7 +357,7 @@
def test_cannot_write_pyc(self):
import sys, os
- p = os.path.join(sys.path[-1], 'readonly')
+ p = os.path.join(sys.path[0], 'readonly')
try:
os.chmod(p, 0555)
except:
diff --git a/pypy/module/micronumpy/interp_numarray.py b/pypy/module/micronumpy/interp_numarray.py
--- a/pypy/module/micronumpy/interp_numarray.py
+++ b/pypy/module/micronumpy/interp_numarray.py
@@ -779,8 +779,6 @@
"""
Intermediate class for performing binary operations.
"""
- _immutable_fields_ = ['left', 'right']
-
def __init__(self, ufunc, name, shape, calc_dtype, res_dtype, left, right):
VirtualArray.__init__(self, name, shape, res_dtype)
self.ufunc = ufunc
@@ -856,8 +854,6 @@
self.right.create_sig(), done_func)
class AxisReduce(Call2):
- _immutable_fields_ = ['left', 'right']
-
def __init__(self, ufunc, name, identity, shape, dtype, left, right, dim):
Call2.__init__(self, ufunc, name, shape, dtype, dtype,
left, right)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_00_model.py b/pypy/module/pypyjit/test_pypy_c/test_00_model.py
--- a/pypy/module/pypyjit/test_pypy_c/test_00_model.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_00_model.py
@@ -60,6 +60,9 @@
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = pipe.communicate()
+ if getattr(pipe, 'returncode', 0) < 0:
+ raise IOError("subprocess was killed by signal %d" % (
+ pipe.returncode,))
if stderr.startswith('SKIP:'):
py.test.skip(stderr)
if stderr.startswith('debug_alloc.h:'): # lldebug builds
diff --git a/pypy/module/pypyjit/test_pypy_c/test_alloc.py b/pypy/module/pypyjit/test_pypy_c/test_alloc.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/pypyjit/test_pypy_c/test_alloc.py
@@ -0,0 +1,26 @@
+import py, sys
+from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC
+
+class TestAlloc(BaseTestPyPyC):
+
+ SIZES = dict.fromkeys([2 ** n for n in range(26)] + # up to 32MB
+ [2 ** n - 1 for n in range(26)])
+
+ def test_newstr_constant_size(self):
+ for size in TestAlloc.SIZES:
+ yield self.newstr_constant_size, size
+
+ def newstr_constant_size(self, size):
+ src = """if 1:
+ N = %(size)d
+ part_a = 'a' * N
+ part_b = 'b' * N
+ for i in xrange(20):
+ ao = '%%s%%s' %% (part_a, part_b)
+ def main():
+ return 42
+""" % {'size': size}
+ log = self.run(src, [], threshold=10)
+ assert log.result == 42
+ loop, = log.loops_by_filename(self.filepath)
+ # assert did not crash
diff --git a/pypy/module/pypyjit/test_pypy_c/test_instance.py b/pypy/module/pypyjit/test_pypy_c/test_instance.py
--- a/pypy/module/pypyjit/test_pypy_c/test_instance.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_instance.py
@@ -201,3 +201,28 @@
loop, = log.loops_by_filename(self.filepath)
assert loop.match_by_id("compare", "") # optimized away
+ def test_super(self):
+ def main():
+ class A(object):
+ def m(self, x):
+ return x + 1
+ class B(A):
+ def m(self, x):
+ return super(B, self).m(x)
+ i = 0
+ while i < 300:
+ i = B().m(i)
+ return i
+
+ log = self.run(main, [])
+ loop, = log.loops_by_filename(self.filepath)
+ assert loop.match("""
+ i78 = int_lt(i72, 300)
+ guard_true(i78, descr=...)
+ guard_not_invalidated(descr=...)
+ i79 = force_token()
+ i80 = force_token()
+ i81 = int_add(i72, 1)
+ --TICK--
+ jump(..., descr=...)
+ """)
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -103,6 +103,7 @@
'terminator',
'_version_tag?',
'name?',
+ 'mro_w?[*]',
]
# for config.objspace.std.getattributeshortcut
@@ -345,9 +346,9 @@
return w_self._lookup_where(name)
+ @unroll_safe
def lookup_starting_at(w_self, w_starttype, name):
space = w_self.space
- # XXX Optimize this with method cache
look = False
for w_class in w_self.mro_w:
if w_class is w_starttype:
diff --git a/pypy/rpython/lltypesystem/rlist.py b/pypy/rpython/lltypesystem/rlist.py
--- a/pypy/rpython/lltypesystem/rlist.py
+++ b/pypy/rpython/lltypesystem/rlist.py
@@ -392,7 +392,11 @@
('list', r_list.lowleveltype),
('index', Signed)))
self.ll_listiter = ll_listiter
- self.ll_listnext = ll_listnext
+ if (isinstance(r_list, FixedSizeListRepr)
+ and not r_list.listitem.mutated):
+ self.ll_listnext = ll_listnext_foldable
+ else:
+ self.ll_listnext = ll_listnext
self.ll_getnextindex = ll_getnextindex
def ll_listiter(ITERPTR, lst):
@@ -409,5 +413,14 @@
iter.index = index + 1 # cannot overflow because index < l.length
return l.ll_getitem_fast(index)
+def ll_listnext_foldable(iter):
+ from pypy.rpython.rlist import ll_getitem_foldable_nonneg
+ l = iter.list
+ index = iter.index
+ if index >= l.ll_length():
+ raise StopIteration
+ iter.index = index + 1 # cannot overflow because index < l.length
+ return ll_getitem_foldable_nonneg(l, index)
+
def ll_getnextindex(iter):
return iter.index
diff --git a/pypy/rpython/memory/gc/minimark.py b/pypy/rpython/memory/gc/minimark.py
--- a/pypy/rpython/memory/gc/minimark.py
+++ b/pypy/rpython/memory/gc/minimark.py
@@ -608,6 +608,11 @@
specified as 0 if the object is not varsized. The returned
object is fully initialized and zero-filled."""
#
+ # Here we really need a valid 'typeid', not 0 (as the JIT might
+ # try to send us if there is still a bug).
+ ll_assert(bool(self.combine(typeid, 0)),
+ "external_malloc: typeid == 0")
+ #
# Compute the total size, carefully checking for overflows.
size_gc_header = self.gcheaderbuilder.size_gc_header
nonvarsize = size_gc_header + self.fixed_size(typeid)
diff --git a/pypy/rpython/test/test_rlist.py b/pypy/rpython/test/test_rlist.py
--- a/pypy/rpython/test/test_rlist.py
+++ b/pypy/rpython/test/test_rlist.py
@@ -8,6 +8,7 @@
from pypy.rpython.rlist import *
from pypy.rpython.lltypesystem.rlist import ListRepr, FixedSizeListRepr, ll_newlist, ll_fixed_newlist
from pypy.rpython.lltypesystem import rlist as ll_rlist
+from pypy.rpython.llinterp import LLException
from pypy.rpython.ootypesystem import rlist as oo_rlist
from pypy.rpython.rint import signed_repr
from pypy.objspace.flow.model import Constant, Variable
@@ -1477,6 +1478,80 @@
assert func1.oopspec == 'list.getitem_foldable(l, index)'
assert not hasattr(func2, 'oopspec')
+ def test_iterate_over_immutable_list(self):
+ from pypy.rpython import rlist
+ class MyException(Exception):
+ pass
+ lst = list('abcdef')
+ def dummyfn():
+ total = 0
+ for c in lst:
+ total += ord(c)
+ return total
+ #
+ prev = rlist.ll_getitem_foldable_nonneg
+ try:
+ def seen_ok(l, index):
+ if index == 5:
+ raise KeyError # expected case
+ return prev(l, index)
+ rlist.ll_getitem_foldable_nonneg = seen_ok
+ e = raises(LLException, self.interpret, dummyfn, [])
+ assert 'KeyError' in str(e.value)
+ finally:
+ rlist.ll_getitem_foldable_nonneg = prev
+
+ def test_iterate_over_immutable_list_quasiimmut_attr(self):
+ from pypy.rpython import rlist
+ class MyException(Exception):
+ pass
+ class Foo:
+ _immutable_fields_ = ['lst?[*]']
+ lst = list('abcdef')
+ foo = Foo()
+ def dummyfn():
+ total = 0
+ for c in foo.lst:
+ total += ord(c)
+ return total
+ #
+ prev = rlist.ll_getitem_foldable_nonneg
+ try:
+ def seen_ok(l, index):
+ if index == 5:
+ raise KeyError # expected case
+ return prev(l, index)
+ rlist.ll_getitem_foldable_nonneg = seen_ok
+ e = raises(LLException, self.interpret, dummyfn, [])
+ assert 'KeyError' in str(e.value)
+ finally:
+ rlist.ll_getitem_foldable_nonneg = prev
+
+ def test_iterate_over_mutable_list(self):
+ from pypy.rpython import rlist
+ class MyException(Exception):
+ pass
+ lst = list('abcdef')
+ def dummyfn():
+ total = 0
+ for c in lst:
+ total += ord(c)
+ lst[0] = 'x'
+ return total
+ #
+ prev = rlist.ll_getitem_foldable_nonneg
+ try:
+ def seen_ok(l, index):
+ if index == 5:
+ raise KeyError # expected case
+ return prev(l, index)
+ rlist.ll_getitem_foldable_nonneg = seen_ok
+ res = self.interpret(dummyfn, [])
+ assert res == sum(map(ord, 'abcdef'))
+ finally:
+ rlist.ll_getitem_foldable_nonneg = prev
+
+
class TestOOtype(BaseTestRlist, OORtypeMixin):
rlist = oo_rlist
type_system = 'ootype'
More information about the pypy-commit
mailing list