[pypy-commit] pypy celldict-versions: merge default
cfbolz
noreply at buildbot.pypy.org
Mon Jul 4 16:52:34 CEST 2011
Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: celldict-versions
Changeset: r45339:5d58831ea9ce
Date: 2011-07-04 16:12 +0200
http://bitbucket.org/pypy/pypy/changeset/5d58831ea9ce/
Log: merge default
diff --git a/lib-python/modified-2.7/test/test_descr.py b/lib-python/modified-2.7/test/test_descr.py
--- a/lib-python/modified-2.7/test/test_descr.py
+++ b/lib-python/modified-2.7/test/test_descr.py
@@ -4400,7 +4400,10 @@
self.assertTrue(l.__add__ != l.__mul__)
self.assertTrue(l.__add__.__name__ == '__add__')
self.assertTrue(l.__add__.__self__ is l)
- self.assertTrue(l.__add__.__objclass__ is list)
+ if hasattr(l.__add__, '__objclass__'): # CPython
+ self.assertTrue(l.__add__.__objclass__ is list)
+ else: # PyPy
+ self.assertTrue(l.__add__.im_class is list)
self.assertEqual(l.__add__.__doc__, list.__add__.__doc__)
try:
hash(l.__add__)
diff --git a/lib_pypy/pwd.py b/lib_pypy/pwd.py
--- a/lib_pypy/pwd.py
+++ b/lib_pypy/pwd.py
@@ -16,6 +16,7 @@
from ctypes_support import standard_c_lib as libc
from ctypes import Structure, POINTER, c_int, c_char_p, c_long
+from _structseq import structseqtype, structseqfield
try: from __pypy__ import builtinify
except ImportError: builtinify = lambda f: f
@@ -68,7 +69,7 @@
yield self.pw_dir
yield self.pw_shell
-class struct_passwd(tuple):
+class struct_passwd:
"""
pwd.struct_passwd: Results from getpw*() routines.
@@ -76,15 +77,15 @@
(pw_name,pw_passwd,pw_uid,pw_gid,pw_gecos,pw_dir,pw_shell)
or via the object attributes as named in the above tuple.
"""
- def __init__(self, passwd):
- self.pw_name = passwd.pw_name
- self.pw_passwd = passwd.pw_passwd
- self.pw_uid = passwd.pw_uid
- self.pw_gid = passwd.pw_gid
- self.pw_gecos = passwd.pw_gecos
- self.pw_dir = passwd.pw_dir
- self.pw_shell = passwd.pw_shell
- tuple.__init__(self, passwd)
+ __metaclass__ = structseqtype
+ name = "pwd.struct_passwd"
+ pw_name = structseqfield(0)
+ pw_passwd = structseqfield(1)
+ pw_uid = structseqfield(2)
+ pw_gid = structseqfield(3)
+ pw_gecos = structseqfield(4)
+ pw_dir = structseqfield(5)
+ pw_shell = structseqfield(6)
passwd_p = POINTER(passwd)
diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py
--- a/pypy/interpreter/function.py
+++ b/pypy/interpreter/function.py
@@ -465,19 +465,23 @@
space.abstract_isinstance_w(w_firstarg, self.w_class)):
pass # ok
else:
- myname = self.getname(space,"")
- clsdescr = self.w_class.getname(space,"")
+ myname = self.getname(space, "")
+ clsdescr = self.w_class.getname(space, "")
if clsdescr:
- clsdescr+=" "
+ clsdescr += " instance"
+ else:
+ clsdescr = "instance"
if w_firstarg is None:
instdescr = "nothing"
else:
- instname = space.abstract_getclass(w_firstarg).getname(space,"")
+ instname = space.abstract_getclass(w_firstarg).getname(space,
+ "")
if instname:
- instname += " "
- instdescr = "%sinstance" %instname
- msg = ("unbound method %s() must be called with %s"
- "instance as first argument (got %s instead)")
+ instdescr = instname + " instance"
+ else:
+ instdescr = "instance"
+ msg = ("unbound method %s() must be called with %s "
+ "as first argument (got %s instead)")
raise operationerrfmt(space.w_TypeError, msg,
myname, clsdescr, instdescr)
return space.call_args(self.w_function, args)
diff --git a/pypy/interpreter/test/test_executioncontext.py b/pypy/interpreter/test/test_executioncontext.py
--- a/pypy/interpreter/test/test_executioncontext.py
+++ b/pypy/interpreter/test/test_executioncontext.py
@@ -106,7 +106,7 @@
if isinstance(seen[0], Method):
found = 'method %s of %s' % (
seen[0].w_function.name,
- seen[0].w_class.getname(space, '?'))
+ seen[0].w_class.getname(space))
else:
assert isinstance(seen[0], Function)
found = 'builtin %s' % seen[0].name
diff --git a/pypy/interpreter/test/test_typedef.py b/pypy/interpreter/test/test_typedef.py
--- a/pypy/interpreter/test/test_typedef.py
+++ b/pypy/interpreter/test/test_typedef.py
@@ -210,10 +210,20 @@
def m(self):
"aaa"
m.x = 3
+ class B(A):
+ pass
- bm = A().m
+ bm = B().m
assert bm.__func__ is bm.im_func
assert bm.__self__ is bm.im_self
+ assert bm.im_class is B
assert bm.__doc__ == "aaa"
assert bm.x == 3
raises(AttributeError, setattr, bm, 'x', 15)
+ l = []
+ assert l.append.__self__ is l
+ assert l.__add__.__self__ is l
+ # note: 'l.__add__.__objclass__' is not defined in pypy
+ # because it's a regular method, and .__objclass__
+ # differs from .im_class in case the method is
+ # defined in some parent class of l's actual class
diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -765,6 +765,7 @@
"""
short_preamble = None
failed_states = None
+ retraced_count = 0
terminating = False # see TerminatingLoopToken in compile.py
outermost_jitdriver_sd = None
# and more data specified by the backend when the loop is compiled
diff --git a/pypy/jit/metainterp/optimizeopt/__init__.py b/pypy/jit/metainterp/optimizeopt/__init__.py
--- a/pypy/jit/metainterp/optimizeopt/__init__.py
+++ b/pypy/jit/metainterp/optimizeopt/__init__.py
@@ -3,7 +3,7 @@
from pypy.jit.metainterp.optimizeopt.intbounds import OptIntBounds
from pypy.jit.metainterp.optimizeopt.virtualize import OptVirtualize
from pypy.jit.metainterp.optimizeopt.heap import OptHeap
-from pypy.jit.metainterp.optimizeopt.string import OptString
+from pypy.jit.metainterp.optimizeopt.vstring import OptString
from pypy.jit.metainterp.optimizeopt.unroll import optimize_unroll, OptInlineShortPreamble
from pypy.jit.metainterp.optimizeopt.fficall import OptFfiCall
from pypy.jit.metainterp.optimizeopt.simplify import OptSimplify
@@ -21,15 +21,14 @@
unroll_all_opts = unrolling_iterable(ALL_OPTS)
ALL_OPTS_DICT = dict.fromkeys([name for name, _ in ALL_OPTS])
-
+ALL_OPTS_LIST = [name for name, _ in ALL_OPTS]
ALL_OPTS_NAMES = ':'.join([name for name, _ in ALL_OPTS])
-PARAMETERS['enable_opts'] = ALL_OPTS_NAMES
def build_opt_chain(metainterp_sd, enable_opts,
inline_short_preamble=True, retraced=False):
config = metainterp_sd.config
optimizations = []
- unroll = 'unroll' in enable_opts
+ unroll = 'unroll' in enable_opts # 'enable_opts' is normally a dict
for name, opt in unroll_all_opts:
if name in enable_opts:
if opt is not None:
diff --git a/pypy/jit/metainterp/optimizeopt/fficall.py b/pypy/jit/metainterp/optimizeopt/fficall.py
--- a/pypy/jit/metainterp/optimizeopt/fficall.py
+++ b/pypy/jit/metainterp/optimizeopt/fficall.py
@@ -4,7 +4,7 @@
from pypy.rlib.debug import debug_start, debug_stop, debug_print, have_debug_prints
from pypy.jit.codewriter.effectinfo import EffectInfo
from pypy.jit.metainterp.resoperation import rop, ResOperation
-from pypy.jit.metainterp.optimizeopt.util import _findall
+from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method
from pypy.jit.metainterp.optimizeopt.optimizer import Optimization
from pypy.jit.backend.llsupport.ffisupport import UnsupportedKind
@@ -203,13 +203,7 @@
def propagate_forward(self, op):
if self.logops is not None:
debug_print(self.logops.repr_of_resop(op))
- opnum = op.getopnum()
- for value, func in optimize_ops:
- if opnum == value:
- func(self, op)
- break
- else:
- self.emit_operation(op)
+ dispatch_opt(self, op)
def _get_oopspec(self, op):
effectinfo = op.getdescr().get_extra_info()
@@ -220,4 +214,5 @@
def _get_funcval(self, op):
return self.getvalue(op.getarg(1))
-optimize_ops = _findall(OptFfiCall, 'optimize_')
+dispatch_opt = make_dispatcher_method(OptFfiCall, 'optimize_',
+ default=OptFfiCall.emit_operation)
diff --git a/pypy/jit/metainterp/optimizeopt/heap.py b/pypy/jit/metainterp/optimizeopt/heap.py
--- a/pypy/jit/metainterp/optimizeopt/heap.py
+++ b/pypy/jit/metainterp/optimizeopt/heap.py
@@ -1,5 +1,5 @@
import os
-from pypy.jit.metainterp.optimizeopt.util import _findall
+from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method
from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.rlib.objectmodel import we_are_translated
from pypy.jit.metainterp.jitexc import JitException
@@ -431,13 +431,7 @@
self._seen_guard_not_invalidated = True
self.emit_operation(op)
- def propagate_forward(self, op):
- opnum = op.getopnum()
- for value, func in optimize_ops:
- if opnum == value:
- func(self, op)
- break
- else:
- self.emit_operation(op)
-optimize_ops = _findall(OptHeap, 'optimize_')
+dispatch_opt = make_dispatcher_method(OptHeap, 'optimize_',
+ default=OptHeap.emit_operation)
+OptHeap.propagate_forward = dispatch_opt
diff --git a/pypy/jit/metainterp/optimizeopt/intbounds.py b/pypy/jit/metainterp/optimizeopt/intbounds.py
--- a/pypy/jit/metainterp/optimizeopt/intbounds.py
+++ b/pypy/jit/metainterp/optimizeopt/intbounds.py
@@ -1,5 +1,5 @@
from pypy.jit.metainterp.optimizeopt.optimizer import Optimization, CONST_1, CONST_0
-from pypy.jit.metainterp.optimizeopt.util import _findall
+from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method
from pypy.jit.metainterp.optimizeopt.intutils import (IntBound, IntUnbounded,
IntLowerBound, IntUpperBound)
from pypy.jit.metainterp.history import Const, ConstInt
@@ -34,14 +34,11 @@
op = self.posponedop
self.posponedop = None
- opnum = op.getopnum()
- for value, func in optimize_ops:
- if opnum == value:
- func(self, op)
- break
- else:
- assert not op.is_ovf()
- self.emit_operation(op)
+ dispatch_opt(self, op)
+
+ def opt_default(self, op):
+ assert not op.is_ovf()
+ self.emit_operation(op)
def propagate_bounds_backward(self, box):
@@ -57,11 +54,7 @@
op = self.optimizer.producer[box]
except KeyError:
return
- opnum = op.getopnum()
- for value, func in propagate_bounds_ops:
- if opnum == value:
- func(self, op)
- break
+ dispatch_bounds_ops(self, op)
def optimize_GUARD_TRUE(self, op):
self.emit_operation(op)
@@ -382,6 +375,18 @@
v1.intbound.make_gt(IntBound(0, 0))
self.propagate_bounds_backward(op.getarg(0))
+ def propagate_bounds_INT_IS_ZERO(self, op):
+ r = self.getvalue(op.result)
+ if r.is_constant():
+ if r.box.same_constant(CONST_1):
+ v1 = self.getvalue(op.getarg(0))
+ # Clever hack, we can't use self.make_constant_int yet because
+ # the args aren't in the values dictionary yet so it runs into
+ # an assert, this is a clever way of expressing the same thing.
+ v1.intbound.make_ge(IntBound(0, 0))
+ v1.intbound.make_lt(IntBound(1, 1))
+ self.propagate_bounds_backward(op.getarg(0))
+
def propagate_bounds_INT_ADD(self, op):
v1 = self.getvalue(op.getarg(0))
v2 = self.getvalue(op.getarg(1))
@@ -428,5 +433,6 @@
propagate_bounds_INT_MUL_OVF = propagate_bounds_INT_MUL
-optimize_ops = _findall(OptIntBounds, 'optimize_')
-propagate_bounds_ops = _findall(OptIntBounds, 'propagate_bounds_')
+dispatch_opt = make_dispatcher_method(OptIntBounds, 'optimize_',
+ default=OptIntBounds.opt_default)
+dispatch_bounds_ops = make_dispatcher_method(OptIntBounds, 'propagate_bounds_')
diff --git a/pypy/jit/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py
--- a/pypy/jit/metainterp/optimizeopt/optimizer.py
+++ b/pypy/jit/metainterp/optimizeopt/optimizer.py
@@ -4,7 +4,7 @@
from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.jit.metainterp import jitprof
from pypy.jit.metainterp.executor import execute_nonspec
-from pypy.jit.metainterp.optimizeopt.util import _findall, sort_descrs
+from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method, sort_descrs
from pypy.jit.metainterp.optimizeopt.util import descrlist_dict, args_dict
from pypy.jit.metainterp.optimize import InvalidLoop
from pypy.jit.metainterp import resume, compile
@@ -434,14 +434,7 @@
def propagate_forward(self, op):
self.producer[op.result] = op
- opnum = op.getopnum()
- for value, func in optimize_ops:
- if opnum == value:
- func(self, op)
- break
- else:
- self.optimize_default(op)
- #print '\n'.join([str(o) for o in self.newoperations]) + '\n---\n'
+ dispatch_opt(self, op)
def test_emittable(self, op):
return True
@@ -569,7 +562,8 @@
def optimize_DEBUG_MERGE_POINT(self, op):
self.emit_operation(op)
-optimize_ops = _findall(Optimizer, 'optimize_')
+dispatch_opt = make_dispatcher_method(Optimizer, 'optimize_',
+ default=Optimizer.optimize_default)
diff --git a/pypy/jit/metainterp/optimizeopt/rewrite.py b/pypy/jit/metainterp/optimizeopt/rewrite.py
--- a/pypy/jit/metainterp/optimizeopt/rewrite.py
+++ b/pypy/jit/metainterp/optimizeopt/rewrite.py
@@ -1,7 +1,7 @@
from pypy.jit.metainterp.optimizeopt.optimizer import *
from pypy.jit.metainterp.resoperation import opboolinvers, opboolreflex
from pypy.jit.metainterp.history import ConstInt
-from pypy.jit.metainterp.optimizeopt.util import _findall
+from pypy.jit.metainterp.optimizeopt.util import _findall, make_dispatcher_method
from pypy.jit.metainterp.resoperation import rop, ResOperation
from pypy.jit.codewriter.effectinfo import EffectInfo
from pypy.jit.metainterp.optimizeopt.intutils import IntBound
@@ -21,18 +21,13 @@
if self.find_rewritable_bool(op, args):
return
- opnum = op.getopnum()
- for value, func in optimize_ops:
- if opnum == value:
- func(self, op)
- break
- else:
- self.emit_operation(op)
+ dispatch_opt(self, op)
def test_emittable(self, op):
opnum = op.getopnum()
- for value, func in optimize_guards:
+ for value, cls, func in optimize_guards:
if opnum == value:
+ assert isinstance(op, cls)
try:
func(self, op, dryrun=True)
return self.is_emittable(op)
@@ -477,5 +472,6 @@
self.emit_operation(op)
-optimize_ops = _findall(OptRewrite, 'optimize_')
+dispatch_opt = make_dispatcher_method(OptRewrite, 'optimize_',
+ default=OptRewrite.emit_operation)
optimize_guards = _findall(OptRewrite, 'optimize_', 'GUARD')
diff --git a/pypy/jit/metainterp/optimizeopt/simplify.py b/pypy/jit/metainterp/optimizeopt/simplify.py
--- a/pypy/jit/metainterp/optimizeopt/simplify.py
+++ b/pypy/jit/metainterp/optimizeopt/simplify.py
@@ -1,7 +1,7 @@
from pypy.jit.metainterp.resoperation import ResOperation, rop
from pypy.jit.metainterp.optimizeopt.optimizer import Optimization
-from pypy.jit.metainterp.optimizeopt.util import _findall
+from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method
class OptSimplify(Optimization):
def optimize_CALL_PURE(self, op):
@@ -25,13 +25,7 @@
# but it's a bit hard to implement robustly if heap.py is also run
pass
- def propagate_forward(self, op):
- opnum = op.getopnum()
- for value, func in optimize_ops:
- if opnum == value:
- func(self, op)
- break
- else:
- self.emit_operation(op)
-optimize_ops = _findall(OptSimplify, 'optimize_')
+dispatch_opt = make_dispatcher_method(OptSimplify, 'optimize_',
+ default=OptSimplify.emit_operation)
+OptSimplify.propagate_forward = dispatch_opt
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizebasic.py
@@ -439,6 +439,23 @@
"""
self.optimize_loop(ops, expected)
+ def test_int_is_zero_int_is_true(self):
+ ops = """
+ [i0]
+ i1 = int_is_zero(i0)
+ guard_true(i1) []
+ i2 = int_is_true(i0)
+ guard_false(i2) []
+ jump(i0)
+ """
+ expected = """
+ [i0]
+ i1 = int_is_zero(i0)
+ guard_true(i1) []
+ jump(0)
+ """
+ self.optimize_loop(ops, expected)
+
def test_ooisnull_oononnull_2(self):
ops = """
[p0]
@@ -4123,7 +4140,6 @@
# ----------
def optimize_strunicode_loop_extradescrs(self, ops, optops):
- from pypy.jit.metainterp.optimizeopt import string
class FakeCallInfoCollection:
def callinfo_for_oopspec(self, oopspecindex):
calldescrtype = type(LLtypeMixin.strequaldescr)
diff --git a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/optimizeopt/test/test_optimizeopt.py
@@ -5373,7 +5373,6 @@
# ----------
def optimize_strunicode_loop_extradescrs(self, ops, optops, preamble=None):
- from pypy.jit.metainterp.optimizeopt import string
class FakeCallInfoCollection:
def callinfo_for_oopspec(self, oopspecindex):
calldescrtype = type(LLtypeMixin.strequaldescr)
diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -676,24 +676,28 @@
jumpop = self.optimizer.newoperations.pop()
assert jumpop.getopnum() == rop.JUMP
for guard in extra_guards:
- descr = sh.start_resumedescr.clone_if_mutable()
- self.inliner.inline_descr_inplace(descr)
- guard.setdescr(descr)
+ d = sh.start_resumedescr.clone_if_mutable()
+ self.inliner.inline_descr_inplace(d)
+ guard.setdescr(d)
self.emit_operation(guard)
self.optimizer.newoperations.append(jumpop)
return
- retraced_count = len(short)
- if descr.failed_states:
- retraced_count += len(descr.failed_states)
+ retraced_count = descr.retraced_count
+ descr.retraced_count += 1
limit = self.optimizer.metainterp_sd.warmrunnerdesc.memory_manager.retrace_limit
if not self.retraced and retraced_count<limit:
if not descr.failed_states:
+ debug_print("Retracing (%d of %d)" % (retraced_count,
+ limit))
raise RetraceLoop
for failed in descr.failed_states:
if failed.generalization_of(virtual_state):
# Retracing once more will most likely fail again
break
else:
+ debug_print("Retracing (%d of %d)" % (retraced_count,
+ limit))
+
raise RetraceLoop
else:
if not descr.failed_states:
diff --git a/pypy/jit/metainterp/optimizeopt/util.py b/pypy/jit/metainterp/optimizeopt/util.py
--- a/pypy/jit/metainterp/optimizeopt/util.py
+++ b/pypy/jit/metainterp/optimizeopt/util.py
@@ -20,9 +20,25 @@
if op_prefix and not name.startswith(op_prefix):
continue
if hasattr(Class, name_prefix + name):
- result.append((value, getattr(Class, name_prefix + name)))
+ opclass = resoperation.opclasses[getattr(rop, name)]
+ print value, name, opclass
+ result.append((value, opclass, getattr(Class, name_prefix + name)))
return unrolling_iterable(result)
+def make_dispatcher_method(Class, name_prefix, op_prefix=None, default=None):
+ ops = _findall(Class, name_prefix, op_prefix)
+ def dispatch(self, op, *args):
+ opnum = op.getopnum()
+ for value, cls, func in ops:
+ if opnum == value:
+ assert isinstance(op, cls)
+ return func(self, op, *args)
+ if default:
+ return default(self, op, *args)
+ dispatch.func_name = "dispatch_" + name_prefix
+ return dispatch
+
+
def partition(array, left, right):
last_item = array[right]
pivot = last_item.sort_key()
diff --git a/pypy/jit/metainterp/optimizeopt/virtualize.py b/pypy/jit/metainterp/optimizeopt/virtualize.py
--- a/pypy/jit/metainterp/optimizeopt/virtualize.py
+++ b/pypy/jit/metainterp/optimizeopt/virtualize.py
@@ -1,7 +1,7 @@
from pypy.jit.metainterp.history import Const, ConstInt, BoxInt
from pypy.jit.metainterp.resoperation import rop, ResOperation
-from pypy.jit.metainterp.optimizeopt.util import _findall, sort_descrs
-from pypy.jit.metainterp.optimizeopt.util import descrlist_dict
+from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method
+from pypy.jit.metainterp.optimizeopt.util import descrlist_dict, sort_descrs
from pypy.rlib.objectmodel import we_are_translated
from pypy.jit.metainterp.optimizeopt import optimizer
from pypy.jit.metainterp.executor import execute
@@ -456,13 +456,8 @@
###self.heap_op_optimizer.optimize_SETARRAYITEM_GC(op, value, fieldvalue)
self.emit_operation(op)
- def propagate_forward(self, op):
- opnum = op.getopnum()
- for value, func in optimize_ops:
- if opnum == value:
- func(self, op)
- break
- else:
- self.emit_operation(op)
-optimize_ops = _findall(OptVirtualize, 'optimize_')
+dispatch_opt = make_dispatcher_method(OptVirtualize, 'optimize_',
+ default=OptVirtualize.emit_operation)
+
+OptVirtualize.propagate_forward = dispatch_opt
diff --git a/pypy/jit/metainterp/optimizeopt/string.py b/pypy/jit/metainterp/optimizeopt/vstring.py
rename from pypy/jit/metainterp/optimizeopt/string.py
rename to pypy/jit/metainterp/optimizeopt/vstring.py
--- a/pypy/jit/metainterp/optimizeopt/string.py
+++ b/pypy/jit/metainterp/optimizeopt/vstring.py
@@ -8,7 +8,7 @@
from pypy.jit.metainterp.optimizeopt import optimizer, virtualize
from pypy.jit.metainterp.optimizeopt.optimizer import CONST_0, CONST_1
from pypy.jit.metainterp.optimizeopt.optimizer import llhelper
-from pypy.jit.metainterp.optimizeopt.util import _findall
+from pypy.jit.metainterp.optimizeopt.util import make_dispatcher_method
from pypy.jit.codewriter.effectinfo import EffectInfo
from pypy.jit.codewriter import heaptracker
from pypy.rlib.unroll import unrolling_iterable
@@ -649,16 +649,11 @@
self.emit_operation(op)
return
- opnum = op.getopnum()
- for value, func in optimize_ops:
- if opnum == value:
- func(self, op)
- break
- else:
- self.emit_operation(op)
+ dispatch_opt(self, op)
-optimize_ops = _findall(OptString, 'optimize_')
+dispatch_opt = make_dispatcher_method(OptString, 'optimize_',
+ default=OptString.emit_operation)
def _findall_call_oopspec():
prefix = 'opt_call_stroruni_'
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -1676,8 +1676,8 @@
return a1.val + b1.val
res = self.meta_interp(g, [6, 14])
assert res == g(6, 14)
- self.check_loop_count(9)
- self.check_loops(getarrayitem_gc=8, everywhere=True)
+ self.check_loop_count(8)
+ self.check_loops(getarrayitem_gc=7, everywhere=True)
py.test.skip("for the following, we need setarrayitem(varindex)")
self.check_loops(getarrayitem_gc=6, everywhere=True)
@@ -2314,6 +2314,67 @@
assert res == -2
#self.check_loops(getarrayitem_gc=0, setarrayitem_gc=0) -- xxx?
+ def test_retrace_ending_up_retrazing_another_loop(self):
+
+ myjitdriver = JitDriver(greens = ['pc'], reds = ['n', 'i', 'sa'])
+ bytecode = "0+sI0+SI"
+ def f(n):
+ myjitdriver.set_param('threshold', 3)
+ myjitdriver.set_param('trace_eagerness', 1)
+ myjitdriver.set_param('retrace_limit', 5)
+ myjitdriver.set_param('function_threshold', -1)
+ pc = sa = i = 0
+ while pc < len(bytecode):
+ myjitdriver.jit_merge_point(pc=pc, n=n, sa=sa, i=i)
+ n = hint(n, promote=True)
+ op = bytecode[pc]
+ if op == '0':
+ i = 0
+ elif op == '+':
+ i += 1
+ elif op == 's':
+ sa += i
+ elif op == 'S':
+ sa += 2
+ elif op == 'I':
+ if i < n:
+ pc -= 2
+ myjitdriver.can_enter_jit(pc=pc, n=n, sa=sa, i=i)
+ continue
+ pc += 1
+ return sa
+
+ def g(n1, n2):
+ for i in range(10):
+ f(n1)
+ for i in range(10):
+ f(n2)
+
+ nn = [10, 3]
+ assert self.meta_interp(g, nn) == g(*nn)
+
+ # The attempts of retracing first loop will end up retracing the
+ # second and thus fail 5 times, saturating the retrace_count. Instead a
+ # bridge back to the preamble of the first loop is produced. A guard in
+ # this bridge is later traced resulting in a retrace of the second loop.
+ # Thus we end up with:
+ # 1 preamble and 1 specialized version of first loop
+ # 1 preamble and 2 specialized version of second loop
+ self.check_tree_loop_count(2 + 3)
+
+ # FIXME: Add a gloabl retrace counter and test that we are not trying more than 5 times.
+
+ def g(n):
+ for i in range(n):
+ for j in range(10):
+ f(n-i)
+
+ res = self.meta_interp(g, [10])
+ assert res == g(10)
+ # 1 preamble and 6 speciealized versions of each loop
+ self.check_tree_loop_count(2*(1 + 6))
+
+
class TestOOtype(BasicTests, OOJitMixin):
def test_oohash(self):
diff --git a/pypy/jit/metainterp/warmstate.py b/pypy/jit/metainterp/warmstate.py
--- a/pypy/jit/metainterp/warmstate.py
+++ b/pypy/jit/metainterp/warmstate.py
@@ -237,7 +237,7 @@
d = {}
if NonConstant(False):
value = 'blah' # not a constant ''
- if value is None:
+ if value is None or value == 'all':
value = ALL_OPTS_NAMES
for name in value.split(":"):
if name:
diff --git a/pypy/module/__builtin__/interp_classobj.py b/pypy/module/__builtin__/interp_classobj.py
--- a/pypy/module/__builtin__/interp_classobj.py
+++ b/pypy/module/__builtin__/interp_classobj.py
@@ -12,7 +12,7 @@
def raise_type_err(space, argument, expected, w_obj):
- type_name = space.type(w_obj).getname(space, '?')
+ type_name = space.type(w_obj).getname(space)
raise operationerrfmt(space.w_TypeError,
"argument %s must be %s, not %s",
argument, expected, type_name)
diff --git a/pypy/module/_codecs/interp_codecs.py b/pypy/module/_codecs/interp_codecs.py
--- a/pypy/module/_codecs/interp_codecs.py
+++ b/pypy/module/_codecs/interp_codecs.py
@@ -186,7 +186,7 @@
text = u'\ufffd' * size
return space.newtuple([space.wrap(text), w_end])
else:
- typename = space.type(w_exc).getname(space, '?')
+ typename = space.type(w_exc).getname(space)
raise operationerrfmt(space.w_TypeError,
"don't know how to handle %s in error callback", typename)
@@ -207,7 +207,7 @@
pos += 1
return space.newtuple([space.wrap(builder.build()), w_end])
else:
- typename = space.type(w_exc).getname(space, '?')
+ typename = space.type(w_exc).getname(space)
raise operationerrfmt(space.w_TypeError,
"don't know how to handle %s in error callback", typename)
@@ -240,7 +240,7 @@
pos += 1
return space.newtuple([space.wrap(builder.build()), w_end])
else:
- typename = space.type(w_exc).getname(space, '?')
+ typename = space.type(w_exc).getname(space)
raise operationerrfmt(space.w_TypeError,
"don't know how to handle %s in error callback", typename)
diff --git a/pypy/module/_io/interp_bufferedio.py b/pypy/module/_io/interp_bufferedio.py
--- a/pypy/module/_io/interp_bufferedio.py
+++ b/pypy/module/_io/interp_bufferedio.py
@@ -175,7 +175,7 @@
return space.call_method(self.w_raw, "isatty")
def repr_w(self, space):
- typename = space.type(self).getname(space, '?')
+ typename = space.type(self).getname(space)
module = space.str_w(space.type(self).get_module())
try:
w_name = space.getattr(self, space.wrap("name"))
diff --git a/pypy/module/_io/interp_io.py b/pypy/module/_io/interp_io.py
--- a/pypy/module/_io/interp_io.py
+++ b/pypy/module/_io/interp_io.py
@@ -119,7 +119,7 @@
if buffering < 0:
buffering = DEFAULT_BUFFER_SIZE
- if "st_blksize" in STAT_FIELD_TYPES:
+ if space.config.translation.type_system == 'lltype' and 'st_blksize' in STAT_FIELD_TYPES:
fileno = space.int_w(space.call_method(w_raw, "fileno"))
try:
st = os.fstat(fileno)
diff --git a/pypy/module/_io/interp_iobase.py b/pypy/module/_io/interp_iobase.py
--- a/pypy/module/_io/interp_iobase.py
+++ b/pypy/module/_io/interp_iobase.py
@@ -155,7 +155,7 @@
raise operationerrfmt(
space.w_IOError,
"peek() should have returned a bytes object, "
- "not '%s'", space.type(w_readahead).getname(space, '?'))
+ "not '%s'", space.type(w_readahead).getname(space))
length = space.len_w(w_readahead)
if length > 0:
n = 0
@@ -181,7 +181,7 @@
raise operationerrfmt(
space.w_IOError,
"peek() should have returned a bytes object, "
- "not '%s'", space.type(w_read).getname(space, '?'))
+ "not '%s'", space.type(w_read).getname(space))
read = space.str_w(w_read)
if not read:
break
diff --git a/pypy/module/_io/interp_stringio.py b/pypy/module/_io/interp_stringio.py
--- a/pypy/module/_io/interp_stringio.py
+++ b/pypy/module/_io/interp_stringio.py
@@ -129,7 +129,7 @@
if not space.isinstance_w(w_obj, space.w_unicode):
raise operationerrfmt(space.w_TypeError,
"string argument expected, got '%s'",
- space.type(w_obj).getname(space, '?'))
+ space.type(w_obj).getname(space))
self._check_closed(space)
orig_size = space.len_w(w_obj)
diff --git a/pypy/module/_lsprof/interp_lsprof.py b/pypy/module/_lsprof/interp_lsprof.py
--- a/pypy/module/_lsprof/interp_lsprof.py
+++ b/pypy/module/_lsprof/interp_lsprof.py
@@ -212,7 +212,7 @@
module += '.'
return '{%s%s}' % (module, w_arg.name)
else:
- class_name = space.type(w_arg).getname(space, '?')
+ class_name = space.type(w_arg).getname(space)
return "{'%s' object}" % (class_name,)
def lsprof_call(space, w_self, frame, event, w_arg):
diff --git a/pypy/module/_multiprocessing/interp_connection.py b/pypy/module/_multiprocessing/interp_connection.py
--- a/pypy/module/_multiprocessing/interp_connection.py
+++ b/pypy/module/_multiprocessing/interp_connection.py
@@ -360,7 +360,7 @@
conn_type = ["read-only", "write-only", "read-write"][self.flags]
return space.wrap("<%s %s, handle %zd>" % (
- conn_type, space.type(self).getname(space, '?'), self.do_fileno()))
+ conn_type, space.type(self).getname(space), self.do_fileno()))
def is_valid(self):
return self.handle != self.INVALID_HANDLE_VALUE
diff --git a/pypy/module/_stackless/interp_coroutine.py b/pypy/module/_stackless/interp_coroutine.py
--- a/pypy/module/_stackless/interp_coroutine.py
+++ b/pypy/module/_stackless/interp_coroutine.py
@@ -40,7 +40,7 @@
raise operationerrfmt(
space.w_TypeError,
"'%s' object is not callable",
- space.type(w_obj).getname(space, '?'))
+ space.type(w_obj).getname(space))
self.w_func = w_obj
self.args = args
diff --git a/pypy/module/_weakref/interp__weakref.py b/pypy/module/_weakref/interp__weakref.py
--- a/pypy/module/_weakref/interp__weakref.py
+++ b/pypy/module/_weakref/interp__weakref.py
@@ -129,7 +129,7 @@
if w_obj is None:
state = '; dead'
else:
- typename = space.type(w_obj).getname(space, '?')
+ typename = space.type(w_obj).getname(space)
objname = w_obj.getname(space, '')
if objname:
state = "; to '%s' (%s)" % (typename, objname)
diff --git a/pypy/module/cpyext/methodobject.py b/pypy/module/cpyext/methodobject.py
--- a/pypy/module/cpyext/methodobject.py
+++ b/pypy/module/cpyext/methodobject.py
@@ -122,7 +122,7 @@
return self.space.unwrap(self.descr_method_repr())
def descr_method_repr(self):
- return self.getrepr(self.space, "built-in method '%s' of '%s' object" % (self.name, self.w_objclass.getname(self.space, '?')))
+ return self.getrepr(self.space, "built-in method '%s' of '%s' object" % (self.name, self.w_objclass.getname(self.space)))
PyCFunction_Check, PyCFunction_CheckExact = build_type_checkers("CFunction", W_PyCFunctionObject)
@@ -151,7 +151,7 @@
def descr_method_repr(self):
return self.space.wrap("<slot wrapper '%s' of '%s' objects>" % (self.method_name,
- self.w_objclass.getname(self.space, '?')))
+ self.w_objclass.getname(self.space)))
def cwrapper_descr_call(space, w_self, __args__):
self = space.interp_w(W_PyCWrapperObject, w_self)
diff --git a/pypy/module/cpyext/typeobject.py b/pypy/module/cpyext/typeobject.py
--- a/pypy/module/cpyext/typeobject.py
+++ b/pypy/module/cpyext/typeobject.py
@@ -450,7 +450,7 @@
PyObject_Del.api_func.get_wrapper(space))
pto.c_tp_alloc = llhelper(PyType_GenericAlloc.api_func.functype,
PyType_GenericAlloc.api_func.get_wrapper(space))
- pto.c_tp_name = rffi.str2charp(w_type.getname(space, "?"))
+ pto.c_tp_name = rffi.str2charp(w_type.getname(space))
pto.c_tp_basicsize = -1 # hopefully this makes malloc bail out
pto.c_tp_itemsize = 0
# uninitialized fields:
diff --git a/pypy/module/exceptions/interp_exceptions.py b/pypy/module/exceptions/interp_exceptions.py
--- a/pypy/module/exceptions/interp_exceptions.py
+++ b/pypy/module/exceptions/interp_exceptions.py
@@ -136,7 +136,7 @@
args_repr = space.str_w(space.repr(space.newtuple(self.args_w)))
else:
args_repr = "()"
- clsname = self.getclass(space).getname(space, '?')
+ clsname = self.getclass(space).getname(space)
return space.wrap(clsname + args_repr)
def descr_getargs(self, space):
@@ -546,7 +546,7 @@
w_tuple = space.newtuple(values_w + [self.w_lastlineno])
args_w = [self.args_w[0], w_tuple]
args_repr = space.str_w(space.repr(space.newtuple(args_w)))
- clsname = self.getclass(space).getname(space, '?')
+ clsname = self.getclass(space).getname(space)
return space.wrap(clsname + args_repr)
else:
return W_StandardError.descr_repr(self, space)
diff --git a/pypy/module/oracle/interp_variable.py b/pypy/module/oracle/interp_variable.py
--- a/pypy/module/oracle/interp_variable.py
+++ b/pypy/module/oracle/interp_variable.py
@@ -1484,7 +1484,7 @@
raise OperationError(
moduledict.w_NotSupportedError,
space.wrap("Variable_TypeByValue(): unhandled data type %s" %
- (space.type(w_value).getname(space, '?'),)))
+ (space.type(w_value).getname(space),)))
def newByInputTypeHandler(space, cursor, w_inputTypeHandler, w_value, numElements):
w_var = space.call(w_inputTypeHandler,
diff --git a/pypy/module/pyexpat/__init__.py b/pypy/module/pyexpat/__init__.py
--- a/pypy/module/pyexpat/__init__.py
+++ b/pypy/module/pyexpat/__init__.py
@@ -2,6 +2,22 @@
from pypy.interpreter.mixedmodule import MixedModule
+class ErrorsModule(MixedModule):
+ "Definition of pyexpat.errors module."
+
+ appleveldefs = {
+ }
+
+ interpleveldefs = {
+ }
+
+ def setup_after_space_initialization(self):
+ from pypy.module.pyexpat import interp_pyexpat
+ for name in interp_pyexpat.xml_error_list:
+ self.space.setattr(self, self.space.wrap(name),
+ interp_pyexpat.ErrorString(self.space,
+ getattr(interp_pyexpat, name)))
+
class Module(MixedModule):
"Python wrapper for Expat parser."
@@ -21,6 +37,10 @@
'version_info': 'interp_pyexpat.get_expat_version_info(space)',
}
+ submodules = {
+ 'errors': ErrorsModule,
+ }
+
for name in ['XML_PARAM_ENTITY_PARSING_NEVER',
'XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE',
'XML_PARAM_ENTITY_PARSING_ALWAYS']:
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
@@ -31,6 +31,48 @@
XML_Content_Ptr = lltype.Ptr(lltype.ForwardReference())
XML_Parser = rffi.COpaquePtr(typedef='XML_Parser')
+xml_error_list = [
+ "XML_ERROR_NO_MEMORY",
+ "XML_ERROR_SYNTAX",
+ "XML_ERROR_NO_ELEMENTS",
+ "XML_ERROR_INVALID_TOKEN",
+ "XML_ERROR_UNCLOSED_TOKEN",
+ "XML_ERROR_PARTIAL_CHAR",
+ "XML_ERROR_TAG_MISMATCH",
+ "XML_ERROR_DUPLICATE_ATTRIBUTE",
+ "XML_ERROR_JUNK_AFTER_DOC_ELEMENT",
+ "XML_ERROR_PARAM_ENTITY_REF",
+ "XML_ERROR_UNDEFINED_ENTITY",
+ "XML_ERROR_RECURSIVE_ENTITY_REF",
+ "XML_ERROR_ASYNC_ENTITY",
+ "XML_ERROR_BAD_CHAR_REF",
+ "XML_ERROR_BINARY_ENTITY_REF",
+ "XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF",
+ "XML_ERROR_MISPLACED_XML_PI",
+ "XML_ERROR_UNKNOWN_ENCODING",
+ "XML_ERROR_INCORRECT_ENCODING",
+ "XML_ERROR_UNCLOSED_CDATA_SECTION",
+ "XML_ERROR_EXTERNAL_ENTITY_HANDLING",
+ "XML_ERROR_NOT_STANDALONE",
+ "XML_ERROR_UNEXPECTED_STATE",
+ "XML_ERROR_ENTITY_DECLARED_IN_PE",
+ "XML_ERROR_FEATURE_REQUIRES_XML_DTD",
+ "XML_ERROR_CANT_CHANGE_FEATURE_ONCE_PARSING",
+ # Added in Expat 1.95.7.
+ "XML_ERROR_UNBOUND_PREFIX",
+ # Added in Expat 1.95.8.
+ "XML_ERROR_UNDECLARING_PREFIX",
+ "XML_ERROR_INCOMPLETE_PE",
+ "XML_ERROR_XML_DECL",
+ "XML_ERROR_TEXT_DECL",
+ "XML_ERROR_PUBLICID",
+ "XML_ERROR_SUSPENDED",
+ "XML_ERROR_NOT_SUSPENDED",
+ "XML_ERROR_ABORTED",
+ "XML_ERROR_FINISHED",
+ "XML_ERROR_SUSPEND_PE",
+ ]
+
class CConfigure:
_compilation_info_ = eci
XML_Content = rffi_platform.Struct('XML_Content', [
@@ -56,6 +98,9 @@
XML_FALSE = rffi_platform.ConstantInteger('XML_FALSE')
XML_TRUE = rffi_platform.ConstantInteger('XML_TRUE')
+ for name in xml_error_list:
+ locals()[name] = rffi_platform.ConstantInteger(name)
+
for k, v in rffi_platform.configure(CConfigure).items():
globals()[k] = v
@@ -298,7 +343,8 @@
XML_GetErrorCode = expat_external(
'XML_GetErrorCode', [XML_Parser], rffi.INT)
XML_ErrorString = expat_external(
- 'XML_ErrorString', [rffi.INT], rffi.CCHARP)
+ 'XML_ErrorString', [rffi.INT],
+ rffi.CCHARP)
XML_GetCurrentLineNumber = expat_external(
'XML_GetCurrentLineNumber', [XML_Parser], rffi.INT)
XML_GetErrorLineNumber = XML_GetCurrentLineNumber
@@ -691,7 +737,7 @@
elif space.is_true(space.isinstance(w_encoding, space.w_str)):
encoding = space.str_w(w_encoding)
else:
- type_name = space.type(w_encoding).getname(space, '?')
+ type_name = space.type(w_encoding).getname(space)
raise OperationError(
space.w_TypeError,
space.wrap('ParserCreate() argument 1 must be string or None,'
@@ -711,7 +757,7 @@
space.wrap('namespace_separator must be at most one character,'
' omitted, or None'))
else:
- type_name = space.type(w_namespace_separator).getname(space, '?')
+ type_name = space.type(w_namespace_separator).getname(space)
raise OperationError(
space.w_TypeError,
space.wrap('ParserCreate() argument 2 must be string or None,'
diff --git a/pypy/module/pyexpat/test/test_parser.py b/pypy/module/pyexpat/test/test_parser.py
--- a/pypy/module/pyexpat/test/test_parser.py
+++ b/pypy/module/pyexpat/test/test_parser.py
@@ -38,7 +38,7 @@
parser = pyexpat.ParserCreate()
raises(pyexpat.ExpatError, "parser.Parse(xml, True)")
- def test_encoding(self):
+ def test_encoding_argument(self):
import pyexpat
for encoding_arg in (None, 'utf-8', 'iso-8859-1'):
for namespace_arg in (None, '{'):
@@ -68,7 +68,7 @@
assert p.buffer_size == 150
raises(TypeError, setattr, p, 'buffer_size', sys.maxint + 1)
- def test_encoding(self):
+ def test_encoding_xml(self):
# use one of the few encodings built-in in expat
xml = "<?xml version='1.0' encoding='iso-8859-1'?><s>caf\xe9</s>"
import pyexpat
@@ -120,3 +120,14 @@
return True
p.ExternalEntityRefHandler = handler
p.Parse(xml)
+
+ def test_errors(self):
+ import types
+ import pyexpat
+ assert isinstance(pyexpat.errors, types.ModuleType)
+ # check a few random errors
+ assert pyexpat.errors.XML_ERROR_SYNTAX == 'syntax error'
+ assert (pyexpat.errors.XML_ERROR_INCORRECT_ENCODING ==
+ 'encoding specified in XML declaration is incorrect')
+ assert (pyexpat.errors.XML_ERROR_XML_DECL ==
+ 'XML declaration not well-formed')
diff --git a/pypy/module/pypyjit/interp_jit.py b/pypy/module/pypyjit/interp_jit.py
--- a/pypy/module/pypyjit/interp_jit.py
+++ b/pypy/module/pypyjit/interp_jit.py
@@ -176,6 +176,8 @@
'''Configure the tunable JIT parameters.
* set_param(name=value, ...) # as keyword arguments
* set_param("name=value,name=value") # as a user-supplied string
+ * set_param("off") # disable the jit
+ * set_param("default") # restore all defaults
'''
# XXXXXXXXX
args_w, kwds_w = __args__.unpack()
diff --git a/pypy/module/pypyjit/test/test_jit_setup.py b/pypy/module/pypyjit/test/test_jit_setup.py
--- a/pypy/module/pypyjit/test/test_jit_setup.py
+++ b/pypy/module/pypyjit/test/test_jit_setup.py
@@ -9,21 +9,42 @@
# this just checks that the module is setting up things correctly, and
# the resulting code makes sense on top of CPython.
import pypyjit
- pypyjit.set_param(threshold=5, inlining=1)
- pypyjit.set_param("trace_eagerness=3,inlining=0")
+ try:
+ pypyjit.set_param(threshold=5, inlining=1)
+ pypyjit.set_param("trace_eagerness=3,inlining=0")
- def f(x, y):
- return x*y+1
+ def f(x, y):
+ return x*y+1
- assert f(6, 7) == 43
+ assert f(6, 7) == 43
- def gen(x):
- i = 0
- while i < x:
- yield i*i
- i += 1
+ def gen(x):
+ i = 0
+ while i < x:
+ yield i*i
+ i += 1
- assert list(gen(3)) == [0, 1, 4]
+ assert list(gen(3)) == [0, 1, 4]
+ finally:
+ pypyjit.set_param('default')
+
+ def test_no_jit(self):
+ import pypyjit
+ was_called = []
+ def should_not_be_called(*args, **kwds):
+ was_called.append((args, kwds))
+ try:
+ pypyjit.set_param('off')
+ pypyjit.set_compile_hook(should_not_be_called)
+ def f():
+ pass
+ for i in range(2500):
+ f()
+ assert not was_called
+ finally:
+ pypyjit.set_compile_hook(None)
+ pypyjit.set_param('default')
+
def test_interface_residual_call():
space = gettestobjspace(usemodules=['pypyjit'])
diff --git a/pypy/module/pypyjit/test_pypy_c/test_containers.py b/pypy/module/pypyjit/test_pypy_c/test_containers.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/pypyjit/test_pypy_c/test_containers.py
@@ -0,0 +1,25 @@
+
+import py, sys
+from pypy.module.pypyjit.test_pypy_c.test_00_model import BaseTestPyPyC
+
+
+class TestDicts(BaseTestPyPyC):
+ def test_strdict(self):
+ def fn(n):
+ import sys
+ d = {}
+ class A(object):
+ pass
+ a = A()
+ a.x = 1
+ for s in sys.modules.keys() * 1000:
+ inc = a.x # ID: look
+ d[s] = d.get(s, 0) + inc
+ return sum(d.values())
+ #
+ log = self.run(fn, [1000])
+ assert log.result % 1000 == 0
+ loop, = log.loops_by_filename(self.filepath)
+ ops = loop.ops_by_id('look')
+ assert log.opnames(ops) == ['setfield_gc',
+ 'guard_not_invalidated']
diff --git a/pypy/module/sys/vm.py b/pypy/module/sys/vm.py
--- a/pypy/module/sys/vm.py
+++ b/pypy/module/sys/vm.py
@@ -57,7 +57,8 @@
raise OperationError(space.w_ValueError,
space.wrap("recursion limit must be positive"))
space.sys.recursionlimit = new_limit
- _stack_set_length_fraction(new_limit * 0.001)
+ if space.config.translation.type_system == 'lltype':
+ _stack_set_length_fraction(new_limit * 0.001)
def getrecursionlimit(space):
"""Return the last value set by setrecursionlimit().
diff --git a/pypy/module/test_lib_pypy/test_pwd.py b/pypy/module/test_lib_pypy/test_pwd.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/test_lib_pypy/test_pwd.py
@@ -0,0 +1,12 @@
+from pypy.conftest import gettestobjspace
+
+class AppTestPwd:
+ def setup_class(cls):
+ cls.space = gettestobjspace(usemodules=('_ffi', '_rawffi'))
+ cls.space.appexec((), "(): import pwd")
+
+ def test_getpwuid(self):
+ import os, pwd
+ passwd_info = pwd.getpwuid(os.getuid())
+ assert type(passwd_info).__name__ == 'struct_passwd'
+ assert repr(passwd_info).startswith("pwd.struct_passwd(pw_name=")
diff --git a/pypy/objspace/descroperation.py b/pypy/objspace/descroperation.py
--- a/pypy/objspace/descroperation.py
+++ b/pypy/objspace/descroperation.py
@@ -416,7 +416,7 @@
# obscure circumstances.
return default_identity_hash(space, w_obj)
if space.is_w(w_hash, space.w_None):
- typename = space.type(w_obj).getname(space, '?')
+ typename = space.type(w_obj).getname(space)
raise operationerrfmt(space.w_TypeError,
"'%s' objects are unhashable", typename)
w_result = space.get_and_call_function(w_hash, w_obj)
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
@@ -374,7 +374,7 @@
raise operationerrfmt(
space.w_TypeError,
"sequence item %d: expected string, %s "
- "found", i, space.type(w_s).getname(space, '?'))
+ "found", i, space.type(w_s).getname(space))
if data and i != 0:
newdata.extend(data)
diff --git a/pypy/objspace/std/celldict.py b/pypy/objspace/std/celldict.py
--- a/pypy/objspace/std/celldict.py
+++ b/pypy/objspace/std/celldict.py
@@ -139,6 +139,12 @@
iterator = self.unerase(w_dict.dstorage).clear()
self.mutated()
+ def popitem(self, w_dict):
+ d = self.unerase(w_dict.dstorage)
+ key, w_value = d.popitem()
+ self.mutated()
+ return self.space.wrap(key), unwrap_cell(w_value)
+
def switch_to_object_strategy(self, w_dict):
d = self.unerase(w_dict.dstorage)
strategy = self.space.fromcache(ObjectDictStrategy)
diff --git a/pypy/objspace/std/dictmultiobject.py b/pypy/objspace/std/dictmultiobject.py
--- a/pypy/objspace/std/dictmultiobject.py
+++ b/pypy/objspace/std/dictmultiobject.py
@@ -6,7 +6,7 @@
from pypy.interpreter.argument import Signature
from pypy.interpreter.error import OperationError, operationerrfmt
-from pypy.rlib.objectmodel import r_dict, we_are_translated
+from pypy.rlib.objectmodel import r_dict, we_are_translated, specialize
from pypy.rlib.debug import mark_dict_non_null
from pypy.rlib import rerased
@@ -155,9 +155,6 @@
erase = staticmethod(erase)
unerase = staticmethod(unerase)
- def __init__(self, space):
- self.space = space
-
def get_empty_storage(self):
return self.erase(None)
@@ -165,15 +162,25 @@
#XXX implement other strategies later
if type(w_key) is self.space.StringObjectCls:
self.switch_to_string_strategy(w_dict)
- return
+ elif self.space.is_w(self.space.type(w_key), self.space.w_int):
+ self.switch_to_int_strategy(w_dict)
+ else:
+ self.switch_to_object_strategy(w_dict)
- strategy = self.space.fromcache(ObjectDictStrategy)
+ def switch_to_string_strategy(self, w_dict):
+ strategy = self.space.fromcache(StringDictStrategy)
storage = strategy.get_empty_storage()
w_dict.strategy = strategy
w_dict.dstorage = storage
- def switch_to_string_strategy(self, w_dict):
- strategy = self.space.fromcache(StringDictStrategy)
+ def switch_to_int_strategy(self, w_dict):
+ strategy = self.space.fromcache(IntDictStrategy)
+ storage = strategy.get_empty_storage()
+ w_dict.strategy = strategy
+ w_dict.dstorage = storage
+
+ def switch_to_object_strategy(self, w_dict):
+ strategy = self.space.fromcache(ObjectDictStrategy)
storage = strategy.get_empty_storage()
w_dict.strategy = strategy
w_dict.dstorage = storage
@@ -268,7 +275,7 @@
# concrete subclasses of the above
-class AbtractTypedStrategy(object):
+class AbstractTypedStrategy(object):
_mixin_ = True
@staticmethod
@@ -291,6 +298,9 @@
def get_empty_storage(self):
raise NotImplementedError("abstract base class")
+ def _never_equal_to(self, w_lookup_type):
+ raise NotImplementedError("abstract base class")
+
def setitem(self, w_dict, w_key, w_value):
space = self.space
if self.is_correct_type(w_key):
@@ -333,6 +343,8 @@
if self.is_correct_type(w_key):
return self.unerase(w_dict.dstorage).get(self.unwrap(w_key), None)
+ elif self._never_equal_to(space.type(w_key)):
+ return None
else:
self.switch_to_object_strategy(w_dict)
return w_dict.getitem(w_key)
@@ -365,8 +377,7 @@
w_dict.strategy = strategy
w_dict.dstorage = strategy.erase(d_new)
-
-class ObjectDictStrategy(AbtractTypedStrategy, DictStrategy):
+class ObjectDictStrategy(AbstractTypedStrategy, DictStrategy):
erase, unerase = rerased.new_erasing_pair("object")
erase = staticmethod(erase)
@@ -386,21 +397,21 @@
force_non_null=True)
return self.erase(new_dict)
+ def _never_equal_to(self, w_lookup_type):
+ return False
+
def iter(self, w_dict):
- return RDictIteratorImplementation(self.space, self, w_dict)
+ return ObjectIteratorImplementation(self.space, self, w_dict)
def keys(self, w_dict):
return self.unerase(w_dict.dstorage).keys()
-class StringDictStrategy(AbtractTypedStrategy, DictStrategy):
+class StringDictStrategy(AbstractTypedStrategy, DictStrategy):
erase, unerase = rerased.new_erasing_pair("string")
erase = staticmethod(erase)
unerase = staticmethod(unerase)
- def __init__(self, space):
- self.space = space
-
def wrap(self, unwrapped):
return self.space.wrap(unwrapped)
@@ -416,6 +427,9 @@
mark_dict_non_null(res)
return self.erase(res)
+ def _never_equal_to(self, w_lookup_type):
+ return _never_equal_to_string(self.space, w_lookup_type)
+
def setitem_str(self, w_dict, key, w_value):
assert key is not None
self.unerase(w_dict.dstorage)[key] = w_value
@@ -426,14 +440,7 @@
if type(w_key) is space.StringObjectCls:
return self.getitem_str(w_dict, w_key.unwrap(space))
# -- End of performance hack --
-
- if self.is_correct_type(w_key):
- return self.unerase(w_dict.dstorage).get(self.unwrap(w_key), None)
- elif _never_equal_to_string(space, space.type(w_key)):
- return None
- else:
- self.switch_to_object_strategy(w_dict)
- return w_dict.getitem(w_key)
+ return AbstractTypedStrategy.getitem(self, w_dict, w_key)
def getitem_str(self, w_dict, key):
assert key is not None
@@ -446,27 +453,67 @@
class StrIteratorImplementation(IteratorImplementation):
def __init__(self, space, strategy, dictimplementation):
IteratorImplementation.__init__(self, space, dictimplementation)
- dict_w = strategy.unerase(dictimplementation.dstorage)
- self.iterator = dict_w.iteritems()
+ self.iterator = strategy.unerase(dictimplementation.dstorage).iteritems()
def next_entry(self):
# note that this 'for' loop only runs once, at most
- for str, w_value in self.iterator:
- return self.space.wrap(str), w_value
+ for key, w_value in self.iterator:
+ return self.space.wrap(key), w_value
else:
return None, None
-class RDictIteratorImplementation(IteratorImplementation):
+class IntDictStrategy(AbstractTypedStrategy, DictStrategy):
+ erase, unerase = rerased.new_erasing_pair("int")
+ erase = staticmethod(erase)
+ unerase = staticmethod(unerase)
+
+ def wrap(self, unwrapped):
+ return self.space.wrap(unwrapped)
+
+ def unwrap(self, wrapped):
+ return self.space.int_w(wrapped)
+
+ def get_empty_storage(self):
+ return self.erase({})
+
+ def is_correct_type(self, w_obj):
+ space = self.space
+ return space.is_w(space.type(w_obj), space.w_int)
+
+ def _never_equal_to(self, w_lookup_type):
+ space = self.space
+ # XXX there are many more types
+ return (space.is_w(w_lookup_type, space.w_NoneType) or
+ space.is_w(w_lookup_type, space.w_str) or
+ space.is_w(w_lookup_type, space.w_unicode)
+ )
+
+ def iter(self, w_dict):
+ return IntIteratorImplementation(self.space, self, w_dict)
+
+class IntIteratorImplementation(IteratorImplementation):
def __init__(self, space, strategy, dictimplementation):
IteratorImplementation.__init__(self, space, dictimplementation)
- d = strategy.unerase(dictimplementation.dstorage)
- self.iterator = d.iteritems()
+ self.iterator = strategy.unerase(dictimplementation.dstorage).iteritems()
def next_entry(self):
# note that this 'for' loop only runs once, at most
- for item in self.iterator:
- return item
+ for key, w_value in self.iterator:
+ return self.space.wrap(key), w_value
+ else:
+ return None, None
+
+
+class ObjectIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, strategy, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = strategy.unerase(dictimplementation.dstorage).iteritems()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for w_key, w_value in self.iterator:
+ return w_key, w_value
else:
return None, None
@@ -775,7 +822,7 @@
def repr__DictViewKeys(space, w_dictview):
w_seq = space.call_function(space.w_list, w_dictview)
w_repr = space.repr(w_seq)
- return space.wrap("%s(%s)" % (space.type(w_dictview).getname(space, "?"),
+ return space.wrap("%s(%s)" % (space.type(w_dictview).getname(space),
space.str_w(w_repr)))
repr__DictViewItems = repr__DictViewKeys
repr__DictViewValues = repr__DictViewKeys
diff --git a/pypy/objspace/std/mapdict.py b/pypy/objspace/std/mapdict.py
--- a/pypy/objspace/std/mapdict.py
+++ b/pypy/objspace/std/mapdict.py
@@ -670,6 +670,8 @@
def popitem(self, w_dict):
curr = self.unerase(w_dict.dstorage)._get_mapdict_map().search(DICT)
+ if curr is None:
+ raise KeyError
key = curr.selector[0]
w_value = self.getitem_str(w_dict, key)
w_key = self.space.wrap(key)
diff --git a/pypy/objspace/std/objspace.py b/pypy/objspace/std/objspace.py
--- a/pypy/objspace/std/objspace.py
+++ b/pypy/objspace/std/objspace.py
@@ -255,7 +255,7 @@
w_result = self.wrap_exception_cls(x)
if w_result is not None:
return w_result
- from fake import fake_object
+ from pypy.objspace.std.fake import fake_object
return fake_object(self, x)
def wrap_exception_cls(self, x):
diff --git a/pypy/objspace/std/ropeunicodeobject.py b/pypy/objspace/std/ropeunicodeobject.py
--- a/pypy/objspace/std/ropeunicodeobject.py
+++ b/pypy/objspace/std/ropeunicodeobject.py
@@ -986,7 +986,7 @@
## return space.wrap(0)
## return space.wrap(result)
-import unicodetype
+from pypy.objspace.std import unicodetype
register_all(vars(), unicodetype)
# str.strip(unicode) needs to convert self to unicode and call unicode.strip we
@@ -997,7 +997,7 @@
# methods?
class str_methods:
- import stringtype
+ from pypy.objspace.std import stringtype
W_RopeUnicodeObject = W_RopeUnicodeObject
from pypy.objspace.std.ropeobject import W_RopeObject
def str_strip__Rope_RopeUnicode(space, w_self, w_chars):
diff --git a/pypy/objspace/std/test/test_celldict.py b/pypy/objspace/std/test/test_celldict.py
--- a/pypy/objspace/std/test/test_celldict.py
+++ b/pypy/objspace/std/test/test_celldict.py
@@ -105,3 +105,33 @@
string = "int"
string2 = "isinstance"
+
+class AppTestCellDict(object):
+ OPTIONS = {"objspace.std.withcelldict": True}
+
+ def setup_class(cls):
+ if option.runappdirect:
+ py.test.skip("__repr__ doesn't work on appdirect")
+ strategy = ModuleDictStrategy(cls.space)
+ storage = strategy.get_empty_storage()
+ cls.w_d = W_DictMultiObject(cls.space, strategy, storage)
+
+ def test_popitem(self):
+ import __pypy__
+
+ d = self.d
+ assert "ModuleDict" in __pypy__.internal_repr(d)
+ raises(KeyError, d.popitem)
+ d["a"] = 3
+ x = d.popitem()
+ assert x == ("a", 3)
+
+ def test_degenerate(self):
+ import __pypy__
+
+ d = self.d
+ assert "ModuleDict" in __pypy__.internal_repr(d)
+ d["a"] = 3
+ del d["a"]
+ d[object()] = 5
+ assert d.values() == [5]
\ No newline at end of file
diff --git a/pypy/objspace/std/test/test_dictmultiobject.py b/pypy/objspace/std/test/test_dictmultiobject.py
--- a/pypy/objspace/std/test/test_dictmultiobject.py
+++ b/pypy/objspace/std/test/test_dictmultiobject.py
@@ -137,31 +137,31 @@
cls.w_on_pypy = cls.space.wrap("__pypy__" in sys.builtin_module_names)
def test_equality(self):
- d = {1:2}
- f = {1:2}
+ d = {1: 2}
+ f = {1: 2}
assert d == f
- assert d != {1:3}
+ assert d != {1: 3}
def test_clear(self):
- d = {1:2, 3:4}
+ d = {1: 2, 3: 4}
d.clear()
assert len(d) == 0
def test_copy(self):
- d = {1:2, 3:4}
+ d = {1: 2, 3: 4}
dd = d.copy()
assert d == dd
assert not d is dd
def test_get(self):
- d = {1:2, 3:4}
+ d = {1: 2, 3: 4}
assert d.get(1) == 2
- assert d.get(1,44) == 2
+ assert d.get(1, 44) == 2
assert d.get(33) == None
- assert d.get(33,44) == 44
+ assert d.get(33, 44) == 44
def test_pop(self):
- d = {1:2, 3:4}
+ d = {1: 2, 3: 4}
dd = d.copy()
result = dd.pop(1)
assert result == 2
@@ -176,18 +176,18 @@
raises(KeyError, dd.pop, 33)
def test_has_key(self):
- d = {1:2, 3:4}
+ d = {1: 2, 3: 4}
assert d.has_key(1)
assert not d.has_key(33)
def test_items(self):
- d = {1:2, 3:4}
+ d = {1: 2, 3: 4}
its = d.items()
its.sort()
- assert its == [(1,2),(3,4)]
+ assert its == [(1, 2), (3, 4)]
def test_iteritems(self):
- d = {1:2, 3:4}
+ d = {1: 2, 3: 4}
dd = d.copy()
for k, v in d.iteritems():
assert v == dd[k]
@@ -195,33 +195,33 @@
assert not dd
def test_iterkeys(self):
- d = {1:2, 3:4}
+ d = {1: 2, 3: 4}
dd = d.copy()
for k in d.iterkeys():
del dd[k]
assert not dd
def test_itervalues(self):
- d = {1:2, 3:4}
+ d = {1: 2, 3: 4}
values = []
for k in d.itervalues():
values.append(k)
assert values == d.values()
def test_keys(self):
- d = {1:2, 3:4}
+ d = {1: 2, 3: 4}
kys = d.keys()
kys.sort()
- assert kys == [1,3]
+ assert kys == [1, 3]
def test_popitem(self):
- d = {1:2, 3:4}
+ d = {1: 2, 3: 4}
it = d.popitem()
assert len(d) == 1
- assert it==(1,2) or it==(3,4)
+ assert it == (1, 2) or it == (3, 4)
it1 = d.popitem()
assert len(d) == 0
- assert (it!=it1) and (it1==(1,2) or it1==(3,4))
+ assert (it != it1) and (it1 == (1, 2) or it1 == (3, 4))
raises(KeyError, d.popitem)
def test_popitem_2(self):
@@ -235,16 +235,16 @@
def test_popitem3(self):
#object
- d = {"a": 1, 2:2, "c":3}
+ d = {"a": 1, 2: 2, "c": 3}
l = []
while True:
try:
l.append(d.popitem())
except KeyError:
break;
- assert ("a",1) in l
- assert (2,2) in l
- assert ("c",3) in l
+ assert ("a", 1) in l
+ assert (2, 2) in l
+ assert ("c", 3) in l
#string
d = {"a": 1, "b":2, "c":3}
@@ -254,12 +254,12 @@
l.append(d.popitem())
except KeyError:
break;
- assert ("a",1) in l
- assert ("b",2) in l
- assert ("c",3) in l
+ assert ("a", 1) in l
+ assert ("b", 2) in l
+ assert ("c", 3) in l
def test_setdefault(self):
- d = {1:2, 3:4}
+ d = {1: 2, 3: 4}
dd = d.copy()
x = dd.setdefault(1, 99)
assert d == dd
@@ -292,12 +292,12 @@
assert k.calls == 1
def test_update(self):
- d = {1:2, 3:4}
+ d = {1: 2, 3: 4}
dd = d.copy()
d.update({})
assert d == dd
- d.update({3:5, 6:7})
- assert d == {1:2, 3:5, 6:7}
+ d.update({3: 5, 6: 7})
+ assert d == {1: 2, 3: 5, 6: 7}
def test_update_iterable(self):
d = {}
@@ -322,15 +322,15 @@
assert d == {'foo': 'bar', 'baz': 1}
def test_values(self):
- d = {1:2, 3:4}
+ d = {1: 2, 3: 4}
vals = d.values()
vals.sort()
assert vals == [2,4]
def test_eq(self):
- d1 = {1:2, 3:4}
- d2 = {1:2, 3:4}
- d3 = {1:2}
+ d1 = {1: 2, 3: 4}
+ d2 = {1: 2, 3: 4}
+ d3 = {1: 2}
bool = d1 == d2
assert bool == True
bool = d1 == d3
@@ -341,10 +341,10 @@
assert bool == True
def test_lt(self):
- d1 = {1:2, 3:4}
- d2 = {1:2, 3:4}
- d3 = {1:2, 3:5}
- d4 = {1:2}
+ d1 = {1: 2, 3: 4}
+ d2 = {1: 2, 3: 4}
+ d3 = {1: 2, 3: 5}
+ d4 = {1: 2}
bool = d1 < d2
assert bool == False
bool = d1 < d3
@@ -391,21 +391,17 @@
def test_new(self):
d = dict()
assert d == {}
- args = [['a',2], [23,45]]
+ args = [['a', 2], [23, 45]]
d = dict(args)
- assert d == {'a':2, 23:45}
+ assert d == {'a': 2, 23: 45}
d = dict(args, a=33, b=44)
- assert d == {'a':33, 'b':44, 23:45}
+ assert d == {'a': 33, 'b': 44, 23: 45}
d = dict(a=33, b=44)
- assert d == {'a':33, 'b':44}
- d = dict({'a':33, 'b':44})
- assert d == {'a':33, 'b':44}
- try: d = dict(23)
- except (TypeError, ValueError): pass
- else: self.fail("dict(23) should raise!")
- try: d = dict([[1,2,3]])
- except (TypeError, ValueError): pass
- else: self.fail("dict([[1,2,3]]) should raise!")
+ assert d == {'a': 33, 'b': 44}
+ d = dict({'a': 33, 'b': 44})
+ assert d == {'a': 33, 'b': 44}
+ raises((TypeError, ValueError), dict, 23)
+ raises((TypeError, ValueError), dict, [[1, 2, 3]])
def test_fromkeys(self):
assert {}.fromkeys([1, 2], 1) == {1: 1, 2: 1}
@@ -734,9 +730,6 @@
set([('a', 1), ('b', 2), ('d', 4), ('e', 5)]))
- if option.runappdirect:
- py.test.skip("__repr__ doesn't work on appdirect")
-
class AppTestStrategies(object):
def setup_class(cls):
if option.runappdirect:
@@ -761,7 +754,12 @@
o.a = 1
assert "StringDictStrategy" in self.get_strategy(d)
-
+ def test_empty_to_int(self):
+ import sys
+ d = {}
+ d[1] = "hi"
+ assert "IntDictStrategy" in self.get_strategy(d)
+ assert d[1L] == "hi"
class FakeString(str):
@@ -802,6 +800,10 @@
assert isinstance(string, str)
return string
+ def int_w(self, integer):
+ assert isinstance(integer, int)
+ return integer
+
def wrap(self, obj):
return obj
diff --git a/pypy/objspace/std/test/test_mapdict.py b/pypy/objspace/std/test/test_mapdict.py
--- a/pypy/objspace/std/test/test_mapdict.py
+++ b/pypy/objspace/std/test/test_mapdict.py
@@ -479,6 +479,7 @@
it2 = a.__dict__.popitem()
assert it2 == ("x", 5)
assert a.__dict__ == {}
+ raises(KeyError, a.__dict__.popitem)
@@ -622,6 +623,14 @@
assert a.__dict__ is d
assert isinstance(a, B)
+ def test_setdict(self):
+ class A(object):
+ pass
+
+ a = A()
+ a.__dict__ = {}
+ a.__dict__ = {}
+
class AppTestWithMapDictAndCounters(object):
def setup_class(cls):
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
@@ -937,7 +937,7 @@
return formatter.format_string(space.unicode_w(w_unicode))
-import unicodetype
+from pypy.objspace.std import unicodetype
register_all(vars(), unicodetype)
# str.strip(unicode) needs to convert self to unicode and call unicode.strip we
@@ -948,7 +948,7 @@
# methods?
class str_methods:
- import stringtype
+ from pypy.objspace.std import stringtype
W_UnicodeObject = W_UnicodeObject
from pypy.objspace.std.stringobject import W_StringObject
from pypy.objspace.std.ropeobject import W_RopeObject
diff --git a/pypy/objspace/taint.py b/pypy/objspace/taint.py
--- a/pypy/objspace/taint.py
+++ b/pypy/objspace/taint.py
@@ -92,8 +92,8 @@
w_realtype = space.type(w_obj)
if not space.is_w(w_realtype, w_expectedtype):
#msg = "expected an object of type '%s'" % (
- # w_expectedtype.getname(space, '?'),)
- # #w_realtype.getname(space, '?'))
+ # w_expectedtype.getname(space),)
+ # #w_realtype.getname(space))
raise OperationError(space.w_TaintError, space.w_None)
return w_obj
app_untaint = gateway.interp2app(untaint)
diff --git a/pypy/rlib/jit.py b/pypy/rlib/jit.py
--- a/pypy/rlib/jit.py
+++ b/pypy/rlib/jit.py
@@ -292,12 +292,13 @@
'function_threshold': 1617, # slightly more than one above
'trace_eagerness': 200,
'trace_limit': 12000,
- 'inlining': 0,
+ 'inlining': 1,
'loop_longevity': 1000,
'retrace_limit': 5,
- 'enable_opts': None, # patched later by optimizeopt/__init__.py
+ 'enable_opts': 'all',
}
unroll_parameters = unrolling_iterable(PARAMETERS.items())
+DEFAULT = object()
# ____________________________________________________________
@@ -352,22 +353,33 @@
def _set_param(self, name, value):
# special-cased by ExtRegistryEntry
# (internal, must receive a constant 'name')
+ # if value is DEFAULT, sets the default value.
assert name in PARAMETERS
@specialize.arg(0, 1)
def set_param(self, name, value):
"""Set one of the tunable JIT parameter."""
- for name1, _ in unroll_parameters:
- if name1 == name:
- self._set_param(name1, value)
- return
- raise ValueError("no such parameter")
+ self._set_param(name, value)
+
+ @specialize.arg(0, 1)
+ def set_param_to_default(self, name):
+ """Reset one of the tunable JIT parameters to its default value."""
+ self._set_param(name, DEFAULT)
def set_user_param(self, text):
"""Set the tunable JIT parameters from a user-supplied string
- following the format 'param=value,param=value'. For programmatic
- setting of parameters, use directly JitDriver.set_param().
+ following the format 'param=value,param=value', or 'off' to
+ disable the JIT. For programmatic setting of parameters, use
+ directly JitDriver.set_param().
"""
+ if text == 'off':
+ self.set_param('threshold', -1)
+ self.set_param('function_threshold', -1)
+ return
+ if text == 'default':
+ for name1, _ in unroll_parameters:
+ self.set_param_to_default(name1)
+ return
for s in text.split(','):
s = s.strip(' ')
parts = s.split('=')
@@ -590,15 +602,17 @@
def compute_result_annotation(self, s_name, s_value):
from pypy.annotation import model as annmodel
assert s_name.is_constant()
- if s_name.const == 'enable_opts':
- assert annmodel.SomeString(can_be_None=True).contains(s_value)
- else:
- assert annmodel.SomeInteger().contains(s_value)
+ if not self.bookkeeper.immutablevalue(DEFAULT).contains(s_value):
+ if s_name.const == 'enable_opts':
+ assert annmodel.SomeString(can_be_None=True).contains(s_value)
+ else:
+ assert annmodel.SomeInteger().contains(s_value)
return annmodel.s_None
def specialize_call(self, hop):
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.lltypesystem.rstr import string_repr
+ from pypy.objspace.flow.model import Constant
hop.exception_cannot_occur()
driver = self.instance.im_self
@@ -607,7 +621,12 @@
repr = string_repr
else:
repr = lltype.Signed
- v_value = hop.inputarg(repr, arg=1)
+ if (isinstance(hop.args_v[1], Constant) and
+ hop.args_v[1].value is DEFAULT):
+ value = PARAMETERS[name]
+ v_value = hop.inputconst(repr, value)
+ else:
+ v_value = hop.inputarg(repr, arg=1)
vlist = [hop.inputconst(lltype.Void, "set_param"),
hop.inputconst(lltype.Void, driver),
hop.inputconst(lltype.Void, name),
diff --git a/pypy/rpython/ootypesystem/rclass.py b/pypy/rpython/ootypesystem/rclass.py
--- a/pypy/rpython/ootypesystem/rclass.py
+++ b/pypy/rpython/ootypesystem/rclass.py
@@ -264,7 +264,8 @@
for name, attrdef in selfattrs.iteritems():
if not attrdef.readonly and self.is_quasi_immutable(name):
- ootype.addFields(self.lowleveltype, {'mutable_'+name: OBJECT})
+ name = mangle('mutable_' + name, self.rtyper.getconfig())
+ ootype.addFields(self.lowleveltype, {name: OBJECT})
classattributes = {}
baseInstance = self.lowleveltype._superclass
diff --git a/pypy/tool/pytest/appsupport.py b/pypy/tool/pytest/appsupport.py
--- a/pypy/tool/pytest/appsupport.py
+++ b/pypy/tool/pytest/appsupport.py
@@ -83,7 +83,7 @@
def __init__(self, space, operr):
self.space = space
self.operr = operr
- self.typename = operr.w_type.getname(space, "?")
+ self.typename = operr.w_type.getname(space)
self.traceback = AppTraceback(space, self.operr.get_traceback())
debug_excs = getattr(operr, 'debug_excs', [])
if debug_excs:
diff --git a/pypy/translator/goal/app_main.py b/pypy/translator/goal/app_main.py
--- a/pypy/translator/goal/app_main.py
+++ b/pypy/translator/goal/app_main.py
@@ -143,6 +143,7 @@
for key, value in items:
print ' --jit %s=N %slow-level JIT parameter (default %s)' % (
key, ' '*(18-len(key)), value)
+ print ' --jit off turn off the JIT'
def print_version(*args):
print "Python", sys.version
diff --git a/pypy/translator/jvm/opcodes.py b/pypy/translator/jvm/opcodes.py
--- a/pypy/translator/jvm/opcodes.py
+++ b/pypy/translator/jvm/opcodes.py
@@ -98,6 +98,7 @@
'jit_marker': Ignore,
'jit_force_virtualizable': Ignore,
'jit_force_virtual': DoNothing,
+ 'jit_force_quasi_immutable': Ignore,
'debug_assert': [], # TODO: implement?
'debug_start_traceback': Ignore,
diff --git a/pypy/translator/jvm/src/pypy/PyPy.java b/pypy/translator/jvm/src/pypy/PyPy.java
--- a/pypy/translator/jvm/src/pypy/PyPy.java
+++ b/pypy/translator/jvm/src/pypy/PyPy.java
@@ -964,12 +964,15 @@
return a + File.separator + b;
}
- public String ll_strtod_formatd(String format, double d)
+ public String ll_strtod_formatd(double d, char code, int precision, int flags)
{
// XXX: this is really a quick hack to make things work.
// it should disappear, because this function is not
// supported by ootypesystem.
- return Double.toString(d); // XXX: we are ignoring "format"
+ DecimalFormat format = new DecimalFormat("0.###");
+ format.setMinimumFractionDigits(precision);
+ format.setMaximumFractionDigits(precision);
+ return format.format(d);
}
// ----------------------------------------------------------------------
diff --git a/pypy/translator/jvm/test/test_float.py b/pypy/translator/jvm/test/test_float.py
--- a/pypy/translator/jvm/test/test_float.py
+++ b/pypy/translator/jvm/test/test_float.py
@@ -22,3 +22,14 @@
def test_r_singlefloat(self):
py.test.skip("not implemented: single-precision floats")
+
+ def test_format_float(self):
+ from pypy.rlib.rfloat import _formatd
+ def fn(precision):
+ return _formatd(10.01, 'd', precision, 0)
+
+ res = self.interpret(fn, [2])
+ assert res == "10.01"
+
+ res = self.interpret(fn, [1])
+ assert res == "10.0"
More information about the pypy-commit
mailing list