[pypy-commit] pypy remove-list-smm-2: hg merge default
Manuel Jacob
noreply at buildbot.pypy.org
Sun May 19 13:56:46 CEST 2013
Author: Manuel Jacob
Branch: remove-list-smm-2
Changeset: r64323:79cd4b4f08fc
Date: 2013-05-19 13:54 +0200
http://bitbucket.org/pypy/pypy/changeset/79cd4b4f08fc/
Log: hg merge default
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -121,12 +121,10 @@
__import__(name)
except (ImportError, CompilationError, py.test.skip.Exception), e:
errcls = e.__class__.__name__
- config.add_warning(
+ raise Exception(
"The module %r is disabled\n" % (modname,) +
"because importing %s raised %s\n" % (name, errcls) +
str(e))
- raise ConflictConfigError("--withmod-%s: %s" % (modname,
- errcls))
return validator
else:
return None
diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst
--- a/pypy/doc/coding-guide.rst
+++ b/pypy/doc/coding-guide.rst
@@ -339,8 +339,9 @@
+ methods and other class attributes do not change after startup
+ single inheritance is fully supported
-+ simple mixins work too, but the mixed in class needs a ``_mixin_ = True``
- class attribute
++ simple mixins somewhat work too, but the mixed in class needs a
+ ``_mixin_ = True`` class attribute. isinstance checks against the
+ mixin type will fail when translated.
+ classes are first-class objects too
diff --git a/pypy/doc/how-to-contribute.rst b/pypy/doc/how-to-contribute.rst
--- a/pypy/doc/how-to-contribute.rst
+++ b/pypy/doc/how-to-contribute.rst
@@ -28,7 +28,8 @@
Layers
------
-PyPy has layers. Those layers help us keep the respective parts separated enough
+PyPy has layers. Just like Ogres or onions.
+Those layers help us keep the respective parts separated enough
to be worked on independently and make the complexity manageable. This is,
again, just a sanity requirement for such a complex project. For example writing
a new optimization for the JIT usually does **not** involve touching a Python
diff --git a/pypy/goal/targetpypystandalone.py b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -10,6 +10,8 @@
from rpython.config.config import ConflictConfigError
from pypy.tool.option import make_objspace
from pypy.conftest import pypydir
+from rpython.rlib import rthread
+from pypy.module.thread import os_thread
thisdir = py.path.local(__file__).dirpath()
@@ -120,6 +122,15 @@
source = rffi.charp2str(ll_source)
return _pypy_execute_source(source)
+ @entrypoint('main', [], c_name='pypy_init_threads')
+ def pypy_init_threads():
+ os_thread.setup_threads(space)
+ rffi.aroundstate.before()
+
+ @entrypoint('main', [], c_name='pypy_thread_attach')
+ def pypy_thread_attach():
+ rthread.gc_thread_start()
+
w_globals = space.newdict()
space.setitem(w_globals, space.wrap('__builtins__'),
space.builtin_modules['__builtin__'])
@@ -137,6 +148,8 @@
return 0
return entry_point, {'pypy_execute_source': pypy_execute_source,
+ 'pypy_init_threads': pypy_init_threads,
+ 'pypy_thread_attach': pypy_thread_attach,
'pypy_setup_home': pypy_setup_home}
def call_finish(space):
diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -853,9 +853,10 @@
self.emit_jump(ops.JUMP_IF_FALSE_OR_POP, cleanup, True)
if i < (ops_count - 1):
comp.comparators[i].walkabout(self)
- comp.comparators[-1].walkabout(self)
- last_kind = compare_operations(comp.ops[-1])
- self.emit_op_arg(ops.COMPARE_OP, last_kind)
+ last_op, last_comparator = comp.ops[-1], comp.comparators[-1]
+ if not self._optimize_comparator(last_op, last_comparator):
+ last_comparator.walkabout(self)
+ self.emit_op_arg(ops.COMPARE_OP, compare_operations(last_op))
if ops_count > 1:
end = self.new_block()
self.emit_jump(ops.JUMP_FORWARD, end)
@@ -864,6 +865,37 @@
self.emit_op(ops.POP_TOP)
self.use_next_block(end)
+ def _optimize_comparator(self, op, node):
+ """Fold lists/sets of constants in the context of "in"/"not in".
+
+ lists are folded into tuples, sets into frozensets, otherwise
+ returns False
+ """
+ if op in (ast.In, ast.NotIn):
+ is_list = isinstance(node, ast.List)
+ if is_list or isinstance(node, ast.Set):
+ w_const = self._tuple_of_consts(node.elts)
+ if w_const is not None:
+ if not is_list:
+ from pypy.objspace.std.setobject import (
+ W_FrozensetObject)
+ w_const = W_FrozensetObject(self.space, w_const)
+ self.load_const(w_const)
+ return True
+ return False
+
+ def _tuple_of_consts(self, elts):
+ """Return a tuple of consts from elts if possible, or None"""
+ count = len(elts) if elts is not None else 0
+ consts_w = [None] * count
+ for i in range(count):
+ w_value = elts[i].as_constant()
+ if w_value is None:
+ # Not all constants
+ return None
+ consts_w[i] = w_value
+ return self.space.newtuple(consts_w)
+
def visit_IfExp(self, ifexp):
self.update_position(ifexp.lineno)
end = self.new_block()
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -973,3 +973,30 @@
counts = self.count_instructions(source3)
assert counts[ops.BUILD_LIST] == 1
assert ops.BUILD_LIST_FROM_ARG not in counts
+
+ def test_folding_of_list_constants(self):
+ for source in (
+ # in/not in constants with BUILD_LIST should be folded to a tuple:
+ 'a in [1,2,3]',
+ 'a not in ["a","b","c"]',
+ 'a in [None, 1, None]',
+ 'a not in [(1, 2), 3, 4]',
+ ):
+ source = 'def f(): %s' % source
+ counts = self.count_instructions(source)
+ assert ops.BUILD_LIST not in counts
+ assert ops.LOAD_CONST in counts
+
+ def test_folding_of_set_constants(self):
+ for source in (
+ # in/not in constants with BUILD_SET should be folded to a frozenset:
+ 'a in {1,2,3}',
+ 'a not in {"a","b","c"}',
+ 'a in {None, 1, None}',
+ 'a not in {(1, 2), 3, 4}',
+ 'a in {1, 2, 3, 3, 2, 1}',
+ ):
+ source = 'def f(): %s' % source
+ counts = self.count_instructions(source)
+ assert ops.BUILD_SET not in counts
+ assert ops.LOAD_CONST in counts
diff --git a/pypy/interpreter/test/test_app_main.py b/pypy/interpreter/test/test_app_main.py
--- a/pypy/interpreter/test/test_app_main.py
+++ b/pypy/interpreter/test/test_app_main.py
@@ -903,24 +903,35 @@
expected_path = [str(prefix.join(subdir).ensure(dir=1))
for subdir in ('lib_pypy',
'lib-python/%s' % cpy_ver)]
+ # an empty directory from where we can't find the stdlib
+ tmp_dir = str(udir.join('tmp').ensure(dir=1))
self.w_goal_dir = self.space.wrap(goal_dir)
self.w_fake_exe = self.space.wrap(str(fake_exe))
self.w_expected_path = self.space.wrap(expected_path)
self.w_trunkdir = self.space.wrap(os.path.dirname(pypydir))
+ self.w_tmp_dir = self.space.wrap(tmp_dir)
+
foo_py = prefix.join('foo.py').write("pass")
self.w_foo_py = self.space.wrap(str(foo_py))
def test_setup_bootstrap_path(self):
- import sys
+ # Check how sys.path is handled depending on if we can find a copy of
+ # the stdlib in setup_bootstrap_path.
+ import sys, os
old_sys_path = sys.path[:]
+ old_cwd = os.getcwd()
+
sys.path.append(self.goal_dir)
+ # make sure cwd does not contain a stdlib
+ os.chdir(self.tmp_dir)
+ tmp_pypy_c = os.path.join(self.tmp_dir, 'pypy-c')
try:
import app_main
- app_main.setup_bootstrap_path('/tmp/pypy-c') # stdlib not found
+ app_main.setup_bootstrap_path(tmp_pypy_c) # stdlib not found
assert sys.executable == ''
- assert sys.path == old_sys_path
+ assert sys.path == old_sys_path + [self.goal_dir]
app_main.setup_bootstrap_path(self.fake_exe)
assert sys.executable == self.fake_exe
@@ -933,6 +944,7 @@
assert newpath[:len(self.expected_path)] == self.expected_path
finally:
sys.path[:] = old_sys_path
+ os.chdir(old_cwd)
def test_trunk_can_be_prefix(self):
import sys
diff --git a/pypy/interpreter/test/test_compiler.py b/pypy/interpreter/test/test_compiler.py
--- a/pypy/interpreter/test/test_compiler.py
+++ b/pypy/interpreter/test/test_compiler.py
@@ -936,6 +936,21 @@
output = s.getvalue()
assert "LOAD_GLOBAL" not in output
+ def test_folding_of_list_constants(self):
+ source = 'a in [1, 2, 3]'
+ co = compile(source, '', 'exec')
+ i = co.co_consts.index((1, 2, 3))
+ assert i > -1
+ assert isinstance(co.co_consts[i], tuple)
+
+ def test_folding_of_set_constants(self):
+ source = 'a in {1, 2, 3}'
+ co = compile(source, '', 'exec')
+ i = co.co_consts.index(set([1, 2, 3]))
+ assert i > -1
+ assert isinstance(co.co_consts[i], frozenset)
+
+
class AppTestCallMethod(object):
spaceconfig = {'objspace.opcodes.CALL_METHOD': True}
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
@@ -1,15 +1,16 @@
-from pypy.interpreter import gateway
from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.error import OperationError, operationerrfmt
+from pypy.interpreter.gateway import (
+ WrappedDefault, applevel, interp2app, unwrap_spec)
from pypy.interpreter.mixedmodule import MixedModule
from pypy.interpreter.signature import Signature
from pypy.objspace.std.stdtypedef import StdTypeDef
from pypy.objspace.std.util import negate
-from rpython.rlib import rerased, jit
+from rpython.rlib import jit, rerased
from rpython.rlib.debug import mark_dict_non_null
-from rpython.rlib.objectmodel import r_dict, specialize, newlist_hint
-from rpython.tool.sourcetools import func_with_new_name
+from rpython.rlib.objectmodel import newlist_hint, r_dict, specialize
+from rpython.tool.sourcetools import func_renamer, func_with_new_name
UNROLL_CUTOFF = 5
@@ -19,7 +20,7 @@
return space.is_w(space.type(w_key), space.w_str)
def _never_equal_to_string(space, w_lookup_type):
- """ Handles the case of a non string key lookup.
+ """Handles the case of a non string key lookup.
Types that have a sane hash/eq function should allow us to return True
directly to signal that the key is not in the dict in any case.
XXX The types should provide such a flag. """
@@ -33,7 +34,7 @@
@specialize.call_location()
def w_dict_unrolling_heuristic(w_dct):
- """ In which cases iterating over dict items can be unrolled.
+ """In which cases iterating over dict items can be unrolled.
Note that w_dct is an instance of W_DictMultiObject, not necesarilly
an actual dict
"""
@@ -44,8 +45,8 @@
class W_DictMultiObject(W_Root):
@staticmethod
def allocate_and_init_instance(space, w_type=None, module=False,
- instance=False, strdict=False, kwargs=False):
-
+ instance=False, strdict=False,
+ kwargs=False):
if space.config.objspace.std.withcelldict and module:
from pypy.objspace.std.celldict import ModuleDictStrategy
assert w_type is None
@@ -55,11 +56,9 @@
elif space.config.objspace.std.withmapdict and instance:
from pypy.objspace.std.mapdict import MapDictStrategy
strategy = space.fromcache(MapDictStrategy)
-
elif instance or strdict or module:
assert w_type is None
strategy = space.fromcache(StringDictStrategy)
-
elif kwargs:
assert w_type is None
from pypy.objspace.std.kwargsdict import EmptyKwargsDictStrategy
@@ -80,7 +79,7 @@
self.dstorage = storage
def __repr__(w_self):
- """ representation for debugging purposes """
+ """representation for debugging purposes"""
return "%s(%s)" % (w_self.__class__.__name__, w_self.strategy)
def unwrap(w_dict, space):
@@ -93,12 +92,10 @@
def missing_method(w_dict, space, w_key):
if not space.is_w(space.type(w_dict), space.w_dict):
- w_missing = space.lookup(w_dict, "__missing__")
- if w_missing is None:
- return None
- return space.get_and_call_function(w_missing, w_dict, w_key)
- else:
- return None
+ w_missing = space.lookup(w_dict, '__missing__')
+ if w_missing is not None:
+ return space.get_and_call_function(w_missing, w_dict, w_key)
+ return None
def initialize_content(w_self, list_pairs_w):
for w_k, w_v in list_pairs_w:
@@ -151,7 +148,7 @@
if self.length() != w_other.length():
return space.w_False
iteratorimplementation = self.iteritems()
- while 1:
+ while True:
w_key, w_val = iteratorimplementation.next_item()
if w_key is None:
break
@@ -228,7 +225,8 @@
space.raise_key_error(w_key)
def descr_reversed(self, space):
- raise OperationError(space.w_TypeError, space.wrap('argument to reversed() must be a sequence'))
+ raise OperationError(space.w_TypeError, space.wrap(
+ 'argument to reversed() must be a sequence'))
def descr_copy(self, space):
"""D.copy() -> a shallow copy of D"""
@@ -280,16 +278,13 @@
"""D.clear() -> None. Remove all items from D."""
self.clear()
- @gateway.unwrap_spec(w_default=gateway.WrappedDefault(None))
+ @unwrap_spec(w_default=WrappedDefault(None))
def descr_get(self, space, w_key, w_default):
"""D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None."""
w_value = self.getitem(w_key)
- if w_value is not None:
- return w_value
- else:
- return w_default
+ return w_value if w_value is not None else w_default
- @gateway.unwrap_spec(defaults_w='args_w')
+ @unwrap_spec(defaults_w='args_w')
def descr_pop(self, space, w_key, defaults_w):
"""D.pop(k[,d]) -> v, remove specified key and return the
corresponding value\nIf key is not found, d is returned if given,
@@ -320,7 +315,7 @@
space.wrap("popitem(): dictionary is empty"))
return space.newtuple([w_key, w_value])
- @gateway.unwrap_spec(w_default=gateway.WrappedDefault(None))
+ @unwrap_spec(w_default=WrappedDefault(None))
def descr_setdefault(self, space, w_key, w_default):
"""D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D"""
return self.setdefault(w_key, w_default)
@@ -352,7 +347,7 @@
_add_indirections()
-app = gateway.applevel('''
+app = applevel('''
def dictrepr(currently_in_repr, d):
if len(d) == 0:
return "{}"
@@ -388,46 +383,46 @@
d[k] = v
dict(**kwargs) -> new dictionary initialized with the name=value pairs
in the keyword argument list. For example: dict(one=1, two=2)''',
- __new__ = gateway.interp2app(W_DictMultiObject.descr_new),
- fromkeys = gateway.interp2app(W_DictMultiObject.descr_fromkeys,
- as_classmethod=True),
+ __new__ = interp2app(W_DictMultiObject.descr_new),
+ fromkeys = interp2app(W_DictMultiObject.descr_fromkeys,
+ as_classmethod=True),
__hash__ = None,
- __repr__ = gateway.interp2app(W_DictMultiObject.descr_repr),
- __init__ = gateway.interp2app(W_DictMultiObject.descr_init),
+ __repr__ = interp2app(W_DictMultiObject.descr_repr),
+ __init__ = interp2app(W_DictMultiObject.descr_init),
- __eq__ = gateway.interp2app(W_DictMultiObject.descr_eq),
- __ne__ = gateway.interp2app(W_DictMultiObject.descr_ne),
- __lt__ = gateway.interp2app(W_DictMultiObject.descr_lt),
- __le__ = gateway.interp2app(W_DictMultiObject.descr_le),
- __gt__ = gateway.interp2app(W_DictMultiObject.descr_gt),
- __ge__ = gateway.interp2app(W_DictMultiObject.descr_ge),
+ __eq__ = interp2app(W_DictMultiObject.descr_eq),
+ __ne__ = interp2app(W_DictMultiObject.descr_ne),
+ __lt__ = interp2app(W_DictMultiObject.descr_lt),
+ __le__ = interp2app(W_DictMultiObject.descr_le),
+ __gt__ = interp2app(W_DictMultiObject.descr_gt),
+ __ge__ = interp2app(W_DictMultiObject.descr_ge),
- __len__ = gateway.interp2app(W_DictMultiObject.descr_len),
- __iter__ = gateway.interp2app(W_DictMultiObject.descr_iter),
- __contains__ = gateway.interp2app(W_DictMultiObject.descr_contains),
+ __len__ = interp2app(W_DictMultiObject.descr_len),
+ __iter__ = interp2app(W_DictMultiObject.descr_iter),
+ __contains__ = interp2app(W_DictMultiObject.descr_contains),
- __getitem__ = gateway.interp2app(W_DictMultiObject.descr_getitem),
- __setitem__ = gateway.interp2app(W_DictMultiObject.descr_setitem),
- __delitem__ = gateway.interp2app(W_DictMultiObject.descr_delitem),
+ __getitem__ = interp2app(W_DictMultiObject.descr_getitem),
+ __setitem__ = interp2app(W_DictMultiObject.descr_setitem),
+ __delitem__ = interp2app(W_DictMultiObject.descr_delitem),
- __reversed__ = gateway.interp2app(W_DictMultiObject.descr_reversed),
- copy = gateway.interp2app(W_DictMultiObject.descr_copy),
- items = gateway.interp2app(W_DictMultiObject.descr_items),
- keys = gateway.interp2app(W_DictMultiObject.descr_keys),
- values = gateway.interp2app(W_DictMultiObject.descr_values),
- iteritems = gateway.interp2app(W_DictMultiObject.descr_iteritems),
- iterkeys = gateway.interp2app(W_DictMultiObject.descr_iterkeys),
- itervalues = gateway.interp2app(W_DictMultiObject.descr_itervalues),
- viewkeys = gateway.interp2app(W_DictMultiObject.descr_viewkeys),
- viewitems = gateway.interp2app(W_DictMultiObject.descr_viewitems),
- viewvalues = gateway.interp2app(W_DictMultiObject.descr_viewvalues),
- has_key = gateway.interp2app(W_DictMultiObject.descr_has_key),
- clear = gateway.interp2app(W_DictMultiObject.descr_clear),
- get = gateway.interp2app(W_DictMultiObject.descr_get),
- pop = gateway.interp2app(W_DictMultiObject.descr_pop),
- popitem = gateway.interp2app(W_DictMultiObject.descr_popitem),
- setdefault = gateway.interp2app(W_DictMultiObject.descr_setdefault),
- update = gateway.interp2app(W_DictMultiObject.descr_update),
+ __reversed__ = interp2app(W_DictMultiObject.descr_reversed),
+ copy = interp2app(W_DictMultiObject.descr_copy),
+ items = interp2app(W_DictMultiObject.descr_items),
+ keys = interp2app(W_DictMultiObject.descr_keys),
+ values = interp2app(W_DictMultiObject.descr_values),
+ iteritems = interp2app(W_DictMultiObject.descr_iteritems),
+ iterkeys = interp2app(W_DictMultiObject.descr_iterkeys),
+ itervalues = interp2app(W_DictMultiObject.descr_itervalues),
+ viewkeys = interp2app(W_DictMultiObject.descr_viewkeys),
+ viewitems = interp2app(W_DictMultiObject.descr_viewitems),
+ viewvalues = interp2app(W_DictMultiObject.descr_viewvalues),
+ has_key = interp2app(W_DictMultiObject.descr_has_key),
+ clear = interp2app(W_DictMultiObject.descr_clear),
+ get = interp2app(W_DictMultiObject.descr_get),
+ pop = interp2app(W_DictMultiObject.descr_pop),
+ popitem = interp2app(W_DictMultiObject.descr_popitem),
+ setdefault = interp2app(W_DictMultiObject.descr_setdefault),
+ update = interp2app(W_DictMultiObject.descr_update),
)
@@ -441,7 +436,7 @@
def w_keys(self, w_dict):
iterator = self.iterkeys(w_dict)
result = newlist_hint(self.length(w_dict))
- while 1:
+ while True:
w_key = iterator.next_key()
if w_key is not None:
result.append(w_key)
@@ -451,7 +446,7 @@
def values(self, w_dict):
iterator = self.itervalues(w_dict)
result = newlist_hint(self.length(w_dict))
- while 1:
+ while True:
w_value = iterator.next_value()
if w_value is not None:
result.append(w_value)
@@ -461,7 +456,7 @@
def items(self, w_dict):
iterator = self.iteritems(w_dict)
result = newlist_hint(self.length(w_dict))
- while 1:
+ while True:
w_key, w_value = iterator.next_item()
if w_key is not None:
result.append(self.space.newtuple([w_key, w_value]))
@@ -503,7 +498,7 @@
unerase = staticmethod(unerase)
def get_empty_storage(self):
- return self.erase(None)
+ return self.erase(None)
def switch_to_correct_strategy(self, w_dict, w_key):
withidentitydict = self.space.config.objspace.std.withidentitydict
@@ -606,7 +601,7 @@
# Iterator Implementation base classes
def _new_next(TP):
- if TP == 'key' or TP == 'value':
+ if TP in ('key', 'value'):
EMPTY = None
else:
EMPTY = None, None
@@ -614,10 +609,12 @@
def next(self):
if self.dictimplementation is None:
return EMPTY
+ space = self.space
if self.len != self.dictimplementation.length():
self.len = -1 # Make this error state sticky
- raise OperationError(self.space.w_RuntimeError,
- self.space.wrap("dictionary changed size during iteration"))
+ msg = "dictionary changed size during iteration"
+ raise OperationError(space.w_RuntimeError, space.wrap(msg))
+
# look for the next entry
if self.pos < self.len:
result = getattr(self, 'next_' + TP + '_entry')()
@@ -635,8 +632,8 @@
w_value = self.dictimplementation.getitem(w_key)
if w_value is None:
self.len = -1 # Make this error state sticky
- raise OperationError(self.space.w_RuntimeError,
- self.space.wrap("dictionary changed during iteration"))
+ msg = "dictionary changed during iteration"
+ raise OperationError(space.w_RuntimeError, space.wrap(msg))
return (w_key, w_value)
# no more entries
self.dictimplementation = None
@@ -769,7 +766,8 @@
def setdefault(self, w_dict, w_key, w_default):
if self.is_correct_type(w_key):
- return self.unerase(w_dict.dstorage).setdefault(self.unwrap(w_key), w_default)
+ return self.unerase(w_dict.dstorage).setdefault(self.unwrap(w_key),
+ w_default)
else:
self.switch_to_object_strategy(w_dict)
return w_dict.setdefault(w_key, w_default)
@@ -809,7 +807,7 @@
space = self.space
dict_w = self.unerase(w_dict.dstorage)
return [space.newtuple([self.wrap(key), w_value])
- for (key, w_value) in dict_w.iteritems()]
+ for (key, w_value) in dict_w.iteritems()]
def popitem(self, w_dict):
key, value = self.unerase(w_dict.dstorage).popitem()
@@ -854,9 +852,9 @@
return True
def get_empty_storage(self):
- new_dict = r_dict(self.space.eq_w, self.space.hash_w,
- force_non_null=True)
- return self.erase(new_dict)
+ new_dict = r_dict(self.space.eq_w, self.space.hash_w,
+ force_non_null=True)
+ return self.erase(new_dict)
def _never_equal_to(self, w_lookup_type):
return False
@@ -1056,7 +1054,7 @@
w_dict_unrolling_heuristic(w_data))
def update1_dict_dict(space, w_dict, w_data):
iterator = w_data.iteritems()
- while 1:
+ while True:
w_key, w_value = iterator.next_item()
if w_key is None:
break
@@ -1094,16 +1092,18 @@
update1(space, w_dict, w_kwds)
def characterize(space, w_a, w_b):
- """ (similar to CPython)
- returns the smallest key in acontent for which b's value is different or absent and this value """
+ """(similar to CPython)
+ returns the smallest key in acontent for which b's value is
+ different or absent and this value"""
w_smallest_diff_a_key = None
w_its_value = None
iteratorimplementation = w_a.iteritems()
- while 1:
+ while True:
w_key, w_val = iteratorimplementation.next_item()
if w_key is None:
break
- if w_smallest_diff_a_key is None or space.is_true(space.lt(w_key, w_smallest_diff_a_key)):
+ if w_smallest_diff_a_key is None or space.is_true(space.lt(
+ w_key, w_smallest_diff_a_key)):
w_bvalue = w_b.getitem(w_key)
if w_bvalue is None:
w_its_value = w_val
@@ -1151,7 +1151,7 @@
w_mod = space.getbuiltinmodule('_pickle_support')
mod = space.interp_w(MixedModule, w_mod)
new_inst = mod.get('dictiter_surrogate_new')
- w_typeobj = space.gettypeobject(W_BaseDictMultiIterObject.typedef)
+ w_typeobj = space.type(self)
raise OperationError(
space.w_TypeError,
@@ -1159,12 +1159,15 @@
# XXXXXX get that working again
# we cannot call __init__ since we don't have the original dict
- if isinstance(self, W_DictIter_Keys):
- w_clone = space.allocate_instance(W_DictIter_Keys, w_typeobj)
- elif isinstance(self, W_DictIter_Values):
- w_clone = space.allocate_instance(W_DictIter_Values, w_typeobj)
- elif isinstance(self, W_DictIter_Items):
- w_clone = space.allocate_instance(W_DictIter_Items, w_typeobj)
+ if isinstance(self, W_DictMultiIterKeysObject):
+ w_clone = space.allocate_instance(W_DictMultiIterKeysObject,
+ w_typeobj)
+ elif isinstance(self, W_DictMultiIterValuesObject):
+ w_clone = space.allocate_instance(W_DictMultiIterValuesObject,
+ w_typeobj)
+ elif isinstance(self, W_DictMultiIterItemsObject):
+ w_clone = space.allocate_instance(W_DictMultiIterItemsObject,
+ w_typeobj)
else:
msg = "unsupported dictiter type '%s' during pickling" % (self,)
raise OperationError(space.w_TypeError, space.wrap(msg))
@@ -1179,10 +1182,7 @@
w_clone.pos += 1
stuff = [w_clone.next_entry() for i in range(w_clone.pos, w_clone.len)]
w_res = space.newlist(stuff)
- tup = [
- w_res
- ]
- w_ret = space.newtuple([new_inst, space.newtuple(tup)])
+ w_ret = space.newtuple([new_inst, space.newtuple([w_res])])
return w_ret
@@ -1212,23 +1212,26 @@
W_DictMultiIterItemsObject.typedef = StdTypeDef(
"dict_iteritems",
- __iter__ = gateway.interp2app(W_DictMultiIterItemsObject.descr_iter),
- next = gateway.interp2app(W_DictMultiIterItemsObject.descr_next),
- __length_hint__ = gateway.interp2app(W_BaseDictMultiIterObject.descr_length_hint)
+ __iter__ = interp2app(W_DictMultiIterItemsObject.descr_iter),
+ next = interp2app(W_DictMultiIterItemsObject.descr_next),
+ __length_hint__ = interp2app(W_BaseDictMultiIterObject.descr_length_hint),
+ __reduce__ = interp2app(W_BaseDictMultiIterObject.descr_reduce),
)
W_DictMultiIterKeysObject.typedef = StdTypeDef(
"dict_iterkeys",
- __iter__ = gateway.interp2app(W_DictMultiIterKeysObject.descr_iter),
- next = gateway.interp2app(W_DictMultiIterKeysObject.descr_next),
- __length_hint__ = gateway.interp2app(W_BaseDictMultiIterObject.descr_length_hint)
+ __iter__ = interp2app(W_DictMultiIterKeysObject.descr_iter),
+ next = interp2app(W_DictMultiIterKeysObject.descr_next),
+ __length_hint__ = interp2app(W_BaseDictMultiIterObject.descr_length_hint),
+ __reduce__ = interp2app(W_BaseDictMultiIterObject.descr_reduce),
)
W_DictMultiIterValuesObject.typedef = StdTypeDef(
"dict_itervalues",
- __iter__ = gateway.interp2app(W_DictMultiIterValuesObject.descr_iter),
- next = gateway.interp2app(W_DictMultiIterValuesObject.descr_next),
- __length_hint__ = gateway.interp2app(W_BaseDictMultiIterObject.descr_length_hint)
+ __iter__ = interp2app(W_DictMultiIterValuesObject.descr_iter),
+ next = interp2app(W_DictMultiIterValuesObject.descr_next),
+ __length_hint__ = interp2app(W_BaseDictMultiIterObject.descr_length_hint),
+ __reduce__ = interp2app(W_BaseDictMultiIterObject.descr_reduce),
)
@@ -1245,45 +1248,88 @@
return space.wrap("%s(%s)" % (space.type(self).getname(space),
space.str_w(w_repr)))
- def descr_eq(self, space, w_otherview):
- if not space.eq_w(space.len(self), space.len(w_otherview)):
- return space.w_False
-
- w_iter = space.iter(self)
- while True:
- try:
- w_item = space.next(w_iter)
- except OperationError, e:
- if not e.match(space, space.w_StopIteration):
- raise
- break
- if not space.is_true(space.contains(w_otherview, w_item)):
- return space.w_False
- return space.w_True
-
def descr_len(self, space):
return space.len(self.w_dict)
- def descr_and(self, space, w_otherview):
- w_set = space.call_function(space.w_set, self)
- space.call_method(w_set, "intersection_update", w_otherview)
- return w_set
+def _all_contained_in(space, w_dictview, w_other):
+ w_iter = space.iter(w_dictview)
+ for w_item in space.iteriterable(w_iter):
+ if not space.is_true(space.contains(w_other, w_item)):
+ return space.w_False
+ return space.w_True
- def descr_or(self, space, w_otherview):
- w_set = space.call_function(space.w_set, self)
- space.call_method(w_set, "update", w_otherview)
- return w_set
+def _is_set_like(w_other):
+ from pypy.objspace.std.setobject import W_BaseSetObject
+ return (isinstance(w_other, W_BaseSetObject) or
+ isinstance(w_other, W_DictViewKeysObject) or
+ isinstance(w_other, W_DictViewItemsObject))
- def descr_xor(self, space, w_otherview):
- w_set = space.call_function(space.w_set, self)
- space.call_method(w_set, "symmetric_difference_update", w_otherview)
- return w_set
+class SetLikeDictView(object):
+ _mixin_ = True
-class W_DictViewItemsObject(W_DictViewObject):
+ def descr_eq(self, space, w_other):
+ if not _is_set_like(w_other):
+ return space.w_NotImplemented
+ if space.len_w(self) == space.len_w(w_other):
+ return _all_contained_in(space, self, w_other)
+ return space.w_False
+
+ def descr_ne(self, space, w_other):
+ if not _is_set_like(w_other):
+ return space.w_NotImplemented
+ return space.not_(space.eq(self, w_other))
+
+ def descr_lt(self, space, w_other):
+ if not _is_set_like(w_other):
+ return space.w_NotImplemented
+ if space.len_w(self) < space.len_w(w_other):
+ return _all_contained_in(space, self, w_other)
+ return space.w_False
+
+ def descr_le(self, space, w_other):
+ if not _is_set_like(w_other):
+ return space.w_NotImplemented
+ if space.len_w(self) <= space.len_w(w_other):
+ return _all_contained_in(space, self, w_other)
+ return space.w_False
+
+ def descr_gt(self, space, w_other):
+ if not _is_set_like(w_other):
+ return space.w_NotImplemented
+ if space.len_w(self) > space.len_w(w_other):
+ return _all_contained_in(space, w_other, self)
+ return space.w_False
+
+ def descr_ge(self, space, w_other):
+ if not _is_set_like(w_other):
+ return space.w_NotImplemented
+ if space.len_w(self) >= space.len_w(w_other):
+ return _all_contained_in(space, w_other, self)
+ return space.w_False
+
+ def _as_set_op(name, methname):
+ @func_renamer('descr_' + name)
+ def op(self, space, w_other):
+ w_set = space.call_function(space.w_set, self)
+ space.call_method(w_set, methname, w_other)
+ return w_set
+ @func_renamer('descr_r' + name)
+ def rop(self, space, w_other):
+ w_set = space.call_function(space.w_set, w_other)
+ space.call_method(w_set, methname, self)
+ return w_set
+ return op, rop
+
+ descr_sub, descr_rsub = _as_set_op('sub', 'difference_update')
+ descr_and, descr_rand = _as_set_op('and', 'intersection_update')
+ descr_or, descr_ror = _as_set_op('or', 'update')
+ descr_xor, descr_rxor = _as_set_op('xor', 'symmetric_difference_update')
+
+class W_DictViewItemsObject(W_DictViewObject, SetLikeDictView):
def descr_iter(self, space):
return W_DictMultiIterItemsObject(space, self.w_dict.iteritems())
-class W_DictViewKeysObject(W_DictViewObject):
+class W_DictViewKeysObject(W_DictViewObject, SetLikeDictView):
def descr_iter(self, space):
return W_DictMultiIterKeysObject(space, self.w_dict.iterkeys())
@@ -1293,33 +1339,53 @@
W_DictViewItemsObject.typedef = StdTypeDef(
"dict_items",
- __repr__ = gateway.interp2app(W_DictViewItemsObject.descr_repr),
- __eq__ = gateway.interp2app(W_DictViewItemsObject.descr_eq),
- __len__ = gateway.interp2app(W_DictViewItemsObject.descr_len),
- __iter__ = gateway.interp2app(W_DictViewItemsObject.descr_iter),
- __and__ = gateway.interp2app(W_DictViewItemsObject.descr_and),
- __or__ = gateway.interp2app(W_DictViewItemsObject.descr_or),
- __xor__ = gateway.interp2app(W_DictViewItemsObject.descr_xor)
+ __repr__ = interp2app(W_DictViewItemsObject.descr_repr),
+ __len__ = interp2app(W_DictViewItemsObject.descr_len),
+ __iter__ = interp2app(W_DictViewItemsObject.descr_iter),
+
+ __eq__ = interp2app(W_DictViewItemsObject.descr_eq),
+ __ne__ = interp2app(W_DictViewItemsObject.descr_ne),
+ __lt__ = interp2app(W_DictViewItemsObject.descr_lt),
+ __le__ = interp2app(W_DictViewItemsObject.descr_le),
+ __gt__ = interp2app(W_DictViewItemsObject.descr_gt),
+ __ge__ = interp2app(W_DictViewItemsObject.descr_ge),
+
+ __sub__ = interp2app(W_DictViewItemsObject.descr_sub),
+ __rsub__ = interp2app(W_DictViewItemsObject.descr_rsub),
+ __and__ = interp2app(W_DictViewItemsObject.descr_and),
+ __rand__ = interp2app(W_DictViewItemsObject.descr_rand),
+ __or__ = interp2app(W_DictViewItemsObject.descr_or),
+ __ror__ = interp2app(W_DictViewItemsObject.descr_ror),
+ __xor__ = interp2app(W_DictViewItemsObject.descr_xor),
+ __rxor__ = interp2app(W_DictViewItemsObject.descr_rxor),
)
W_DictViewKeysObject.typedef = StdTypeDef(
"dict_keys",
- __repr__ = gateway.interp2app(W_DictViewKeysObject.descr_repr),
- __eq__ = gateway.interp2app(W_DictViewKeysObject.descr_eq),
- __len__ = gateway.interp2app(W_DictViewKeysObject.descr_len),
- __iter__ = gateway.interp2app(W_DictViewKeysObject.descr_iter),
- __and__ = gateway.interp2app(W_DictViewKeysObject.descr_and),
- __or__ = gateway.interp2app(W_DictViewKeysObject.descr_or),
- __xor__ = gateway.interp2app(W_DictViewKeysObject.descr_xor)
+ __repr__ = interp2app(W_DictViewKeysObject.descr_repr),
+ __len__ = interp2app(W_DictViewKeysObject.descr_len),
+ __iter__ = interp2app(W_DictViewKeysObject.descr_iter),
+
+ __eq__ = interp2app(W_DictViewKeysObject.descr_eq),
+ __ne__ = interp2app(W_DictViewKeysObject.descr_ne),
+ __lt__ = interp2app(W_DictViewKeysObject.descr_lt),
+ __le__ = interp2app(W_DictViewKeysObject.descr_le),
+ __gt__ = interp2app(W_DictViewKeysObject.descr_gt),
+ __ge__ = interp2app(W_DictViewKeysObject.descr_ge),
+
+ __sub__ = interp2app(W_DictViewKeysObject.descr_sub),
+ __rsub__ = interp2app(W_DictViewKeysObject.descr_rsub),
+ __and__ = interp2app(W_DictViewKeysObject.descr_and),
+ __rand__ = interp2app(W_DictViewKeysObject.descr_rand),
+ __or__ = interp2app(W_DictViewKeysObject.descr_or),
+ __ror__ = interp2app(W_DictViewKeysObject.descr_ror),
+ __xor__ = interp2app(W_DictViewKeysObject.descr_xor),
+ __rxor__ = interp2app(W_DictViewKeysObject.descr_rxor),
)
W_DictViewValuesObject.typedef = StdTypeDef(
"dict_values",
- __repr__ = gateway.interp2app(W_DictViewValuesObject.descr_repr),
- __eq__ = gateway.interp2app(W_DictViewValuesObject.descr_eq),
- __len__ = gateway.interp2app(W_DictViewValuesObject.descr_len),
- __iter__ = gateway.interp2app(W_DictViewValuesObject.descr_iter),
- __and__ = gateway.interp2app(W_DictViewValuesObject.descr_and),
- __or__ = gateway.interp2app(W_DictViewValuesObject.descr_or),
- __xor__ = gateway.interp2app(W_DictViewValuesObject.descr_xor)
+ __repr__ = interp2app(W_DictViewValuesObject.descr_repr),
+ __len__ = interp2app(W_DictViewValuesObject.descr_len),
+ __iter__ = interp2app(W_DictViewValuesObject.descr_iter),
)
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
@@ -696,6 +696,7 @@
assert d.viewkeys() == e.viewkeys()
del e["a"]
assert d.viewkeys() != e.viewkeys()
+ assert not d.viewkeys() == 42
def test_dict_items(self):
d = {1: 10, "a": "ABC"}
@@ -720,6 +721,7 @@
assert d.viewitems() == e.viewitems()
e["a"] = "def"
assert d.viewitems() != e.viewitems()
+ assert not d.viewitems() == 42
def test_dict_mixed_keys_items(self):
d = {(1, 1): 11, (2, 2): 22}
@@ -732,6 +734,7 @@
values = d.viewvalues()
assert set(values) == set([10, "ABC"])
assert len(values) == 2
+ assert not values == 42
def test_dict_repr(self):
d = {1: 10, "a": "ABC"}
@@ -774,6 +777,13 @@
assert d1.viewkeys() ^ set(d2.viewkeys()) == set('ac')
assert d1.viewkeys() ^ set(d3.viewkeys()) == set('abde')
+ assert d1.viewkeys() - d1.viewkeys() == set()
+ assert d1.viewkeys() - d2.viewkeys() == set('a')
+ assert d1.viewkeys() - d3.viewkeys() == set('ab')
+ assert d1.viewkeys() - set(d1.viewkeys()) == set()
+ assert d1.viewkeys() - set(d2.viewkeys()) == set('a')
+ assert d1.viewkeys() - set(d3.viewkeys()) == set('ab')
+
def test_items_set_operations(self):
d1 = {'a': 1, 'b': 2}
d2 = {'a': 2, 'b': 2}
@@ -802,6 +812,113 @@
assert (d1.viewitems() ^ d3.viewitems() ==
set([('a', 1), ('b', 2), ('d', 4), ('e', 5)]))
+ assert d1.viewitems() - d1.viewitems() == set()
+ assert d1.viewitems() - d2.viewitems() == set([('a', 1)])
+ assert d1.viewitems() - d3.viewitems() == set([('a', 1), ('b', 2)])
+
+ def test_keys_set_operations_any_type(self):
+ d = {1: u'a', 2: u'b', 3: u'c'}
+ assert d.viewkeys() & set([1]) == set([1])
+ assert d.viewkeys() & {1: u'foo'} == set([1])
+ assert d.viewkeys() & [1, 2] == set([1, 2])
+ #
+ assert set([1]) & d.viewkeys() == set([1])
+ assert {1: u'foo'} & d.viewkeys() == set([1])
+ assert [1, 2] & d.viewkeys() == set([1, 2])
+ #
+ assert d.viewkeys() - set([1]) == set([2, 3])
+ assert set([1, 4]) - d.viewkeys() == set([4])
+ #
+ assert d.viewkeys() == set([1, 2, 3])
+ # XXX: The following 4 commented out are CPython 2.7 bugs
+ #assert set([1, 2, 3]) == d.viewkeys()
+ assert d.viewkeys() == frozenset(set([1, 2, 3]))
+ #assert frozenset(set([1, 2, 3])) == d.viewkeys()
+ assert not d.viewkeys() != set([1, 2, 3])
+ #assert not set([1, 2, 3]) != d.viewkeys()
+ assert not d.viewkeys() != frozenset(set([1, 2, 3]))
+ #assert not frozenset(set([1, 2, 3])) != d.viewkeys()
+
+ def test_items_set_operations_any_type(self):
+ d = {1: u'a', 2: u'b', 3: u'c'}
+ assert d.viewitems() & set([(1, u'a')]) == set([(1, u'a')])
+ assert d.viewitems() & {(1, u'a'): u'foo'} == set([(1, u'a')])
+ assert d.viewitems() & [(1, u'a'), (2, u'b')] == set([(1, u'a'), (2, u'b')])
+ #
+ assert set([(1, u'a')]) & d.viewitems() == set([(1, u'a')])
+ assert {(1, u'a'): u'foo'} & d.viewitems() == set([(1, u'a')])
+ assert [(1, u'a'), (2, u'b')] & d.viewitems() == set([(1, u'a'), (2, u'b')])
+ #
+ assert d.viewitems() - set([(1, u'a')]) == set([(2, u'b'), (3, u'c')])
+ assert set([(1, u'a'), 4]) - d.viewitems() == set([4])
+ #
+ assert d.viewitems() == set([(1, u'a'), (2, u'b'), (3, u'c')])
+ # XXX: The following 4 commented out are CPython 2.7 bugs
+ #assert set([(1, u'a'), (2, u'b'), (3, u'c')]) == d.viewitems()
+ assert d.viewitems() == frozenset(set([(1, u'a'), (2, u'b'), (3, u'c')]))
+ #assert frozenset(set([(1, u'a'), (2, u'b'), (3, u'c')])) == d.viewitems()
+ assert not d.viewitems() != set([(1, u'a'), (2, u'b'), (3, u'c')])
+ #assert not set([(1, u'a'), (2, u'b'), (3, u'c')]) != d.viewitems()
+ assert not d.viewitems() != frozenset(set([(1, u'a'), (2, u'b'), (3, u'c')]))
+ #assert not frozenset(set([(1, u'a'), (2, u'b'), (3, u'c')])) != d.viewitems()
+
+ def test_dictviewset_unhashable_values(self):
+ class C:
+ def __eq__(self, other):
+ return True
+ d = {1: C()}
+ assert d.viewitems() <= d.viewitems()
+
+ def test_compare_keys_and_items(self):
+ d1 = {1: 2}
+ d2 = {(1, 2): 'foo'}
+ assert d1.viewitems() == d2.viewkeys()
+
+ def test_keys_items_contained(self):
+ def helper(fn):
+ empty = fn(dict())
+ empty2 = fn(dict())
+ smaller = fn({1:1, 2:2})
+ larger = fn({1:1, 2:2, 3:3})
+ larger2 = fn({1:1, 2:2, 3:3})
+ larger3 = fn({4:1, 2:2, 3:3})
+
+ assert smaller < larger
+ assert smaller <= larger
+ assert larger > smaller
+ assert larger >= smaller
+
+ assert not smaller >= larger
+ assert not smaller > larger
+ assert not larger <= smaller
+ assert not larger < smaller
+
+ assert not smaller < larger3
+ assert not smaller <= larger3
+ assert not larger3 > smaller
+ assert not larger3 >= smaller
+
+ # Inequality strictness
+ assert larger2 >= larger
+ assert larger2 <= larger
+ assert not larger2 > larger
+ assert not larger2 < larger
+
+ assert larger == larger2
+ assert smaller != larger
+
+ # There is an optimization on the zero-element case.
+ assert empty == empty2
+ assert not empty != empty2
+ assert not empty == smaller
+ assert empty != smaller
+
+ # With the same size, an elementwise compare happens
+ assert larger != larger3
+ assert not larger == larger3
+
+ helper(lambda x: x.viewkeys())
+ helper(lambda x: x.viewitems())
class AppTestStrategies(object):
def setup_class(cls):
diff --git a/rpython/memory/gc/env.py b/rpython/memory/gc/env.py
--- a/rpython/memory/gc/env.py
+++ b/rpython/memory/gc/env.py
@@ -1,9 +1,10 @@
"""
Utilities to get environ variables and platform-specific memory-related values.
"""
-import os, sys
+import os, sys, platform
from rpython.rlib.rarithmetic import r_uint
from rpython.rlib.debug import debug_print, debug_start, debug_stop
+from rpython.rlib.rstring import assert_str0
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.rtyper.lltypesystem.lloperation import llop
@@ -130,7 +131,22 @@
# ---------- Linux2 ----------
-def get_L2cache_linux2(filename="/proc/cpuinfo"):
+def get_L2cache_linux2():
+ arch = platform.machine()
+ if arch.endswith('86') or arch == 'x86_64':
+ return get_L2cache_linux2_cpuinfo()
+ if arch in ('alpha', 'ppc', 'ppc64'):
+ return get_L2cache_linux2_cpuinfo(label='L2 cache')
+ if arch == 'ia64':
+ return get_L2cache_linux2_ia64()
+ if arch in ('parisc', 'parisc64'):
+ return get_L2cache_linux2_cpuinfo(label='D-cache')
+ if arch in ('sparc', 'sparc64'):
+ return get_L2cache_linux2_sparc()
+ return -1
+
+
+def get_L2cache_linux2_cpuinfo(filename="/proc/cpuinfo", label='cache size'):
debug_start("gc-hardware")
L2cache = sys.maxint
try:
@@ -149,12 +165,8 @@
else:
data = ''.join(data)
linepos = 0
- # Currently on ARM-linux we won't find any information about caches in
- # cpuinfo
- if _detect_arm_cpu(data):
- return -1
while True:
- start = _findend(data, '\ncache size', linepos)
+ start = _findend(data, '\n' + label, linepos)
if start < 0:
break # done
linepos = _findend(data, '\n', start)
@@ -194,6 +206,104 @@
"Warning: cannot find your CPU L2 cache size in /proc/cpuinfo")
return -1
+def get_L2cache_linux2_sparc():
+ debug_start("gc-hardware")
+ cpu = 0
+ L2cache = sys.maxint
+ while True:
+ try:
+ fd = os.open('/sys/devices/system/cpu/cpu' + assert_str0(str(cpu))
+ + '/l2_cache_size', os.O_RDONLY, 0644)
+ try:
+ number = int(os.read(fd, 4096))
+ finally:
+ os.close(fd)
+ except OSError:
+ break
+ if number < L2cache:
+ L2cache = number
+ cpu += 1
+
+ debug_print("L2cache =", L2cache)
+ debug_stop("gc-hardware")
+ if L2cache < sys.maxint:
+ return L2cache
+ else:
+ # Print a top-level warning even in non-debug builds
+ llop.debug_print(lltype.Void,
+ "Warning: cannot find your CPU L2 cache size in "
+ "/sys/devices/system/cpu/cpuX/l2_cache_size")
+ return -1
+
+def get_L2cache_linux2_ia64():
+ debug_start("gc-hardware")
+ cpu = 0
+ L2cache = sys.maxint
+ L3cache = sys.maxint
+ while True:
+ cpudir = '/sys/devices/system/cpu/cpu' + assert_str0(str(cpu))
+ index = 0
+ while True:
+ cachedir = cpudir + '/cache/index' + assert_str0(str(index))
+ try:
+ fd = os.open(cachedir + '/level', os.O_RDONLY, 0644)
+ try:
+ level = int(os.read(fd, 4096)[:-1])
+ finally:
+ os.close(fd)
+ except OSError:
+ break
+ if level not in (2, 3):
+ index += 1
+ continue
+ try:
+ fd = os.open(cachedir + '/size', os.O_RDONLY, 0644)
+ try:
+ data = os.read(fd, 4096)
+ finally:
+ os.close(fd)
+ except OSError:
+ break
+
+ end = 0
+ while '0' <= data[end] <= '9':
+ end += 1
+ if end == 0:
+ index += 1
+ continue
+ if data[end] not in ('K', 'k'): # assume kilobytes for now
+ index += 1
+ continue
+
+ number = int(data[:end])
+ number *= 1024
+
+ if level == 2:
+ if number < L2cache:
+ L2cache = number
+ if level == 3:
+ if number < L3cache:
+ L3cache = number
+
+ index += 1
+
+ if index == 0:
+ break
+ cpu += 1
+
+ mangled = L2cache + L3cache
+ debug_print("L2cache =", mangled)
+ debug_stop("gc-hardware")
+ if mangled > 0:
+ return mangled
+ else:
+ # Print a top-level warning even in non-debug builds
+ llop.debug_print(lltype.Void,
+ "Warning: cannot find your CPU L2 & L3 cache size in "
+ "/sys/devices/system/cpu/cpuX/cache")
+ return -1
+
+
def _findend(data, pattern, pos):
pos = data.find(pattern, pos)
if pos < 0:
@@ -205,11 +315,6 @@
pos += 1
return pos
-def _detect_arm_cpu(data):
- # check for the presence of a 'Processor' entry
- p = _findend(data, 'Processor', 0)
- return p >= 0 and _findend(data, 'ARMv', p) > 0
-
# ---------- Darwin ----------
sysctlbyname = rffi.llexternal('sysctlbyname',
diff --git a/rpython/memory/gc/test/test_env.py b/rpython/memory/gc/test/test_env.py
--- a/rpython/memory/gc/test/test_env.py
+++ b/rpython/memory/gc/test/test_env.py
@@ -159,25 +159,5 @@
fpu : yes
etc.
""")
- result = env.get_L2cache_linux2(str(filepath))
+ result = env.get_L2cache_linux2_cpuinfo(str(filepath))
assert result == 3072 * 1024
-
-def test_estimate_best_nursery_size_linux2_arm():
- filepath = udir.join('estimate_best_nursery_size_linux2')
- filepath.write("""\
-Processor : ARMv6-compatible processor rev 7 (v6l)
-# this is not actually from cpuinfo, but here for the test
-cache size : 3072 KB
-...
-""")
- result = env.get_L2cache_linux2(str(filepath))
- assert result == -1
-
-def test__detect_arm():
- assert env._detect_arm_cpu("Processor : ARMv6-compatible processor rev 7 (v6l)")
- assert not env._detect_arm_cpu("""\
-processor : 0
-vendor_id : GenuineIntel
-cpu family : 6
-model : 37
-""")
diff --git a/rpython/rlib/rbigint.py b/rpython/rlib/rbigint.py
--- a/rpython/rlib/rbigint.py
+++ b/rpython/rlib/rbigint.py
@@ -447,11 +447,11 @@
@jit.elidable
def repr(self):
- return _format(self, BASE10, '', 'L')
+ return _format_decimal(self, addL=True)
@jit.elidable
def str(self):
- return _format(self, BASE10)
+ return _format_decimal(self)
@jit.elidable
def eq(self, other):
@@ -2101,6 +2101,101 @@
return ''.join(s[p:])
+DECIMAL_SHIFT = 0 # computed as max(E such that 10**E fits in a digit)
+while 10 ** (DECIMAL_SHIFT + 1) <= 2 ** SHIFT:
+ DECIMAL_SHIFT += 1
+DECIMAL_BASE = 10 ** DECIMAL_SHIFT
+
+# an RPython trick: this creates a nested sequence of calls that are
+# all inlined into each other, making an unrolled loop. Moreover the
+# calls are done in the "wrong" order to be written as a regular loop:
+# the first digit that is append-ed to the builder is the most
+# significant one (corresponding to the innermost call).
+_succ = specialize.memo()(lambda n: n + 1)
+ at specialize.arg(3)
+def _add_decimal_digits(builder, value, ndigits, digit_index=1):
+ assert value >= 0
+ if digit_index < ndigits:
+ assert digit_index < DECIMAL_SHIFT
+ _add_decimal_digits(builder, value // 10, ndigits, _succ(digit_index))
+ builder.append(chr(ord('0') + value % 10))
+ else:
+ assert value < 10
+ builder.append(chr(ord('0') + value))
+_add_decimal_digits._always_inline_ = True
+
+
+def _format_decimal(a, addL=False):
+ """ Optimized version of _format(a, BASE10, '', 'L' if addL else ''). """
+ if a.sign == 0:
+ if addL:
+ return "0L"
+ else:
+ return "0"
+
+ size_a = a.numdigits()
+ negative = a.sign < 0
+
+ # quick and dirty upper bound for the number of digits
+ # required to express a in base DECIMAL_BASE:
+ #
+ # #digits = 1 + floor(log2(a) / log2(DECIMAL_BASE))
+ #
+ # But log2(a) < size_a * PyLong_SHIFT, and
+ # log2(DECIMAL_BASE) = log2(10) * DECIMAL_SHIFT
+ # > 3 * DECIMAL_SHIFT
+
+ size = 1 + size_a * SHIFT // (3 * DECIMAL_SHIFT)
+ pout = [NULLDIGIT] * size
+
+ # convert array of base _PyLong_BASE digits in pin to an array of
+ # base _PyLong_DECIMAL_BASE digits in pout, following Knuth (TAOCP,
+ # Volume 2 (3rd edn), section 4.4, Method 1b).
+ size = 0
+ for i in range(size_a-1, -1, -1):
+ hi = a.digit(i)
+ for j in range(size):
+ z = (_widen_digit(pout[j]) << SHIFT) | hi
+ hi = _store_digit(z // DECIMAL_BASE)
+ pout[j] = _store_digit(z - _widen_digit(hi) * DECIMAL_BASE)
+ assert hi >= 0
+ while hi:
+ pout[size] = hi % DECIMAL_BASE
+ hi //= DECIMAL_BASE
+ size += 1
+ sizem1 = size - 1
+ assert sizem1 >= 0
+
+ # calculate exact length of output string, and allocate
+ decimal_digits_in_last_part = 1
+ rem = pout[sizem1]
+ tenpow = 10
+ while rem >= tenpow:
+ tenpow *= 10
+ decimal_digits_in_last_part += 1
+ strlen = (addL + negative +
+ decimal_digits_in_last_part + (sizem1) * DECIMAL_SHIFT)
+
+ builder = StringBuilder(strlen)
+
+ # start with the negative sign, if needed
+ if negative:
+ builder.append('-')
+
+ # pout[size-1] produces 'decimal_digits_in_last_part' digits.
+ # Then the remaining pout[size-2] through pout[0] contribute exactly
+ # DECIMAL_SHIFT digits each.
+ decimal_digits = decimal_digits_in_last_part
+ for i in range(sizem1, -1, -1):
+ _add_decimal_digits(builder, pout[i], decimal_digits)
+ decimal_digits = DECIMAL_SHIFT
+
+ # done
+ if addL:
+ builder.append('L')
+ return builder.build()
+
+
def _bitwise(a, op, b): # '&', '|', '^'
""" Bitwise and/or/xor operations """
diff --git a/rpython/translator/c/src/stacklet/tests.c b/rpython/translator/c/src/stacklet/tests.c
--- a/rpython/translator/c/src/stacklet/tests.c
+++ b/rpython/translator/c/src/stacklet/tests.c
@@ -31,7 +31,7 @@
assert(status == 0);
status = 1;
assert(h != EMPTY_STACKLET_HANDLE);
- h = stacklet_switch(thrd, h);
+ h = stacklet_switch(h);
assert(status == 2);
assert(h != EMPTY_STACKLET_HANDLE);
status = 3;
@@ -45,7 +45,7 @@
assert(h != EMPTY_STACKLET_HANDLE);
assert(status == 1);
status = 2;
- h = stacklet_switch(thrd, h);
+ h = stacklet_switch(h);
assert(status == 3);
assert(h == EMPTY_STACKLET_HANDLE);
}
@@ -148,7 +148,7 @@
//printf("switch to %d\n", n);
h = handles[n];
handles[n] = NULL;
- h = stacklet_switch(thrd, h);
+ h = stacklet_switch(h);
}
//printf("back in self = %d, coming from %d\n", self, comefrom);
assert(nextstep == status);
diff --git a/rpython/translator/platform/freebsd.py b/rpython/translator/platform/freebsd.py
--- a/rpython/translator/platform/freebsd.py
+++ b/rpython/translator/platform/freebsd.py
@@ -12,3 +12,11 @@
class Freebsd_64(Freebsd):
shared_only = ('-fPIC',)
+
+class GNUkFreebsd(Freebsd):
+ DEFAULT_CC = 'cc'
+ extra_libs = ('-lrt',)
+
+class GNUkFreebsd_64(Freebsd_64):
+ DEFAULT_CC = 'cc'
+ extra_libs = ('-lrt',)
More information about the pypy-commit
mailing list