[pypy-commit] pypy repeatlist_strategy: merge default
Vincent Legoll
pypy.commits at gmail.com
Thu Jan 14 16:53:09 EST 2016
Author: Vincent Legoll <vincent.legoll at idgrilles.fr>
Branch: repeatlist_strategy
Changeset: r81768:5de7752a044a
Date: 2016-01-14 22:19 +0100
http://bitbucket.org/pypy/pypy/changeset/5de7752a044a/
Log: merge default
diff --git a/pypy/doc/whatsnew-head.rst b/pypy/doc/whatsnew-head.rst
--- a/pypy/doc/whatsnew-head.rst
+++ b/pypy/doc/whatsnew-head.rst
@@ -110,3 +110,7 @@
short-running Python callbacks. (CFFI on CPython has a hack to achieve
the same result.) This can also be seen as a bug fix: previously,
thread-local objects would be reset between two such calls.
+
+.. branch: globals-quasiimmut
+
+Optimize global lookups.
diff --git a/pypy/interpreter/eval.py b/pypy/interpreter/eval.py
--- a/pypy/interpreter/eval.py
+++ b/pypy/interpreter/eval.py
@@ -9,8 +9,8 @@
class Code(W_Root):
"""A code is a compiled version of some source code.
Abstract base class."""
- _immutable_ = True
hidden_applevel = False
+ _immutable_fields_ = ['co_name', 'fast_natural_arity', 'hidden_applevel']
# n >= 0 : arity
# FLATPYCALL = 0x100
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -56,11 +56,13 @@
class PyCode(eval.Code):
"CPython-style code objects."
- _immutable_ = True
- _immutable_fields_ = ["co_consts_w[*]", "co_names_w[*]", "co_varnames[*]",
- "co_freevars[*]", "co_cellvars[*]",
- "_args_as_cellvars[*]"]
-
+ _immutable_fields_ = ["_signature", "co_argcount", "co_cellvars[*]",
+ "co_code", "co_consts_w[*]", "co_filename",
+ "co_firstlineno", "co_flags", "co_freevars[*]",
+ "co_lnotab", "co_names_w[*]", "co_nlocals",
+ "co_stacksize", "co_varnames[*]",
+ "_args_as_cellvars[*]", "w_globals?"]
+
def __init__(self, space, argcount, nlocals, stacksize, flags,
code, consts, names, varnames, filename,
name, firstlineno, lnotab, freevars, cellvars,
@@ -84,6 +86,10 @@
self.co_name = name
self.co_firstlineno = firstlineno
self.co_lnotab = lnotab
+ # store the first globals object that the code object is run in in
+ # here. if a frame is run in that globals object, it does not need to
+ # store it at all
+ self.w_globals = None
self.hidden_applevel = hidden_applevel
self.magic = magic
self._signature = cpython_code_signature(self)
@@ -91,6 +97,14 @@
self._init_ready()
self.new_code_hook()
+ def frame_stores_global(self, w_globals):
+ if self.w_globals is None:
+ self.w_globals = w_globals
+ return False
+ if self.w_globals is w_globals:
+ return False
+ return True
+
def new_code_hook(self):
code_hook = self.space.fromcache(CodeHookCache)._code_hook
if code_hook is not None:
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -36,6 +36,7 @@
def __init__(self, pycode):
self.f_lineno = pycode.co_firstlineno
+ self.w_globals = pycode.w_globals
class PyFrame(W_Root):
"""Represents a frame for a regular Python function
@@ -67,7 +68,6 @@
escaped = False # see mark_as_escaped()
debugdata = None
- w_globals = None
pycode = None # code object executed by that frame
locals_cells_stack_w = None # the list of all locals, cells and the valuestack
valuestackdepth = 0 # number of items on valuestack
@@ -90,8 +90,9 @@
self = hint(self, access_directly=True, fresh_virtualizable=True)
assert isinstance(code, pycode.PyCode)
self.space = space
- self.w_globals = w_globals
self.pycode = code
+ if code.frame_stores_global(w_globals):
+ self.getorcreatedebug().w_globals = w_globals
ncellvars = len(code.co_cellvars)
nfreevars = len(code.co_freevars)
size = code.co_nlocals + ncellvars + nfreevars + code.co_stacksize
@@ -116,6 +117,12 @@
self.debugdata = FrameDebugData(self.pycode)
return self.debugdata
+ def get_w_globals(self):
+ debugdata = self.getdebug()
+ if debugdata is not None:
+ return debugdata.w_globals
+ return jit.promote(self.pycode).w_globals
+
def get_w_f_trace(self):
d = self.getdebug()
if d is None:
@@ -201,8 +208,9 @@
if flags & pycode.CO_NEWLOCALS:
self.getorcreatedebug().w_locals = self.space.newdict(module=True)
else:
- assert self.w_globals is not None
- self.getorcreatedebug().w_locals = self.w_globals
+ w_globals = self.get_w_globals()
+ assert w_globals is not None
+ self.getorcreatedebug().w_locals = w_globals
ncellvars = len(code.co_cellvars)
nfreevars = len(code.co_freevars)
@@ -449,7 +457,7 @@
w_blockstack,
w_exc_value, # last_exception
w_tb, #
- self.w_globals,
+ self.get_w_globals(),
w(self.last_instr),
w(self.frame_finished_execution),
w(f_lineno),
@@ -658,6 +666,11 @@
def fget_getdictscope(self, space):
return self.getdictscope()
+ def fget_w_globals(self, space):
+ # bit silly, but GetSetProperty passes a space
+ return self.get_w_globals()
+
+
### line numbers ###
def fget_f_lineno(self, space):
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -837,7 +837,7 @@
w_bases = self.popvalue()
w_name = self.popvalue()
w_metaclass = find_metaclass(self.space, w_bases,
- w_methodsdict, self.w_globals,
+ w_methodsdict, self.get_w_globals(),
self.space.wrap(self.get_builtin()))
w_newclass = self.space.call_function(w_metaclass, w_name,
w_bases, w_methodsdict)
@@ -881,14 +881,14 @@
def STORE_GLOBAL(self, nameindex, next_instr):
varname = self.getname_u(nameindex)
w_newvalue = self.popvalue()
- self.space.setitem_str(self.w_globals, varname, w_newvalue)
+ self.space.setitem_str(self.get_w_globals(), varname, w_newvalue)
def DELETE_GLOBAL(self, nameindex, next_instr):
w_varname = self.getname_w(nameindex)
- self.space.delitem(self.w_globals, w_varname)
+ self.space.delitem(self.get_w_globals(), w_varname)
def LOAD_NAME(self, nameindex, next_instr):
- if self.getorcreatedebug().w_locals is not self.w_globals:
+ if self.getorcreatedebug().w_locals is not self.get_w_globals():
varname = self.getname_u(nameindex)
w_value = self.space.finditem_str(self.getorcreatedebug().w_locals,
varname)
@@ -898,7 +898,7 @@
self.LOAD_GLOBAL(nameindex, next_instr) # fall-back
def _load_global(self, varname):
- w_value = self.space.finditem_str(self.w_globals, varname)
+ w_value = self.space.finditem_str(self.get_w_globals(), varname)
if w_value is None:
# not in the globals, now look in the built-ins
w_value = self.get_builtin().getdictvalue(self.space, varname)
@@ -1029,7 +1029,7 @@
if w_locals is None: # CPython does this
w_locals = space.w_None
w_modulename = space.wrap(modulename)
- w_globals = self.w_globals
+ w_globals = self.get_w_globals()
if w_flag is None:
w_obj = space.call_function(w_import, w_modulename, w_globals,
w_locals, w_fromlist)
@@ -1237,7 +1237,7 @@
w_codeobj = self.popvalue()
codeobj = self.space.interp_w(PyCode, w_codeobj)
defaultarguments = self.popvalues(numdefaults)
- fn = function.Function(self.space, codeobj, self.w_globals,
+ fn = function.Function(self.space, codeobj, self.get_w_globals(),
defaultarguments)
self.pushvalue(self.space.wrap(fn))
@@ -1249,7 +1249,7 @@
freevars = [self.space.interp_w(Cell, cell)
for cell in self.space.fixedview(w_freevarstuple)]
defaultarguments = self.popvalues(numdefaults)
- fn = function.Function(self.space, codeobj, self.w_globals,
+ fn = function.Function(self.space, codeobj, self.get_w_globals(),
defaultarguments, freevars)
self.pushvalue(self.space.wrap(fn))
diff --git a/pypy/interpreter/test/test_pyframe.py b/pypy/interpreter/test/test_pyframe.py
--- a/pypy/interpreter/test/test_pyframe.py
+++ b/pypy/interpreter/test/test_pyframe.py
@@ -34,6 +34,7 @@
import sys
f = sys._getframe()
assert f.f_globals is globals()
+ raises(TypeError, "f.f_globals = globals()")
def test_f_builtins(self):
import sys, __builtin__
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -772,7 +772,7 @@
f_restricted = GetSetProperty(PyFrame.fget_f_restricted),
f_code = GetSetProperty(PyFrame.fget_code),
f_locals = GetSetProperty(PyFrame.fget_getdictscope),
- f_globals = interp_attrproperty_w('w_globals', cls=PyFrame),
+ f_globals = GetSetProperty(PyFrame.fget_w_globals),
)
assert not PyFrame.typedef.acceptable_as_base_class # no __new__
diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py
--- a/pypy/module/__builtin__/compiling.py
+++ b/pypy/module/__builtin__/compiling.py
@@ -93,7 +93,7 @@
if space.is_none(w_locals):
w_locals = w_globals
else:
- w_globals = caller.w_globals
+ w_globals = caller.get_w_globals()
if space.is_none(w_locals):
w_locals = caller.getdictscope()
elif space.is_none(w_locals):
diff --git a/pypy/module/__builtin__/interp_inspect.py b/pypy/module/__builtin__/interp_inspect.py
--- a/pypy/module/__builtin__/interp_inspect.py
+++ b/pypy/module/__builtin__/interp_inspect.py
@@ -2,7 +2,7 @@
def globals(space):
"Return the dictionary containing the current scope's global variables."
ec = space.getexecutioncontext()
- return ec.gettopframe_nohidden().w_globals
+ return ec.gettopframe_nohidden().get_w_globals()
def locals(space):
"""Return a dictionary containing the current scope's local variables.
diff --git a/pypy/module/__pypy__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py
--- a/pypy/module/__pypy__/interp_magic.py
+++ b/pypy/module/__pypy__/interp_magic.py
@@ -93,7 +93,7 @@
Return the underlying strategy currently used by a dict, list or set object
"""
if isinstance(w_obj, W_DictMultiObject):
- name = w_obj.strategy.__class__.__name__
+ name = w_obj.get_strategy().__class__.__name__
elif isinstance(w_obj, W_ListObject):
name = w_obj.strategy.__class__.__name__
elif isinstance(w_obj, W_BaseSetObject):
diff --git a/pypy/module/_cffi_backend/cffi1_module.py b/pypy/module/_cffi_backend/cffi1_module.py
--- a/pypy/module/_cffi_backend/cffi1_module.py
+++ b/pypy/module/_cffi_backend/cffi1_module.py
@@ -2,6 +2,7 @@
from pypy.interpreter.error import oefmt
from pypy.interpreter.module import Module
+from pypy.module import _cffi_backend
from pypy.module._cffi_backend import parse_c_type
from pypy.module._cffi_backend.ffi_obj import W_FFIObject
from pypy.module._cffi_backend.lib_obj import W_LibObject
@@ -27,8 +28,10 @@
version = rffi.cast(lltype.Signed, p[0])
if not (VERSION_MIN <= version <= VERSION_MAX):
raise oefmt(space.w_ImportError,
- "cffi extension module '%s' has unknown version %s",
- name, hex(version))
+ "cffi extension module '%s' uses an unknown version tag %s. "
+ "This module might need a more recent version of PyPy. "
+ "The current PyPy provides CFFI %s.",
+ name, hex(version), _cffi_backend.VERSION)
src_ctx = rffi.cast(parse_c_type.PCTX, p[1])
ffi = W_FFIObject(space, src_ctx)
diff --git a/pypy/module/_warnings/interp_warnings.py b/pypy/module/_warnings/interp_warnings.py
--- a/pypy/module/_warnings/interp_warnings.py
+++ b/pypy/module/_warnings/interp_warnings.py
@@ -75,7 +75,7 @@
frame = ec.getnextframe_nohidden(frame)
stacklevel -= 1
if frame:
- w_globals = frame.w_globals
+ w_globals = frame.get_w_globals()
lineno = frame.get_last_lineno()
else:
w_globals = space.sys.w_dict
diff --git a/pypy/module/cpyext/eval.py b/pypy/module/cpyext/eval.py
--- a/pypy/module/cpyext/eval.py
+++ b/pypy/module/cpyext/eval.py
@@ -30,7 +30,7 @@
currently executing."""
caller = space.getexecutioncontext().gettopframe_nohidden()
if caller is not None:
- w_globals = caller.w_globals
+ w_globals = caller.get_w_globals()
w_builtins = space.getitem(w_globals, space.wrap('__builtins__'))
if not space.isinstance_w(w_builtins, space.w_dict):
w_builtins = w_builtins.getdict(space)
@@ -54,7 +54,7 @@
caller = space.getexecutioncontext().gettopframe_nohidden()
if caller is None:
return None
- return borrow_from(None, caller.w_globals)
+ return borrow_from(None, caller.get_w_globals())
@cpython_api([PyCodeObject, PyObject, PyObject], PyObject)
def PyEval_EvalCode(space, w_code, w_globals, w_locals):
diff --git a/pypy/module/cpyext/frameobject.py b/pypy/module/cpyext/frameobject.py
--- a/pypy/module/cpyext/frameobject.py
+++ b/pypy/module/cpyext/frameobject.py
@@ -34,7 +34,7 @@
frame = space.interp_w(PyFrame, w_obj)
py_frame = rffi.cast(PyFrameObject, py_obj)
py_frame.c_f_code = rffi.cast(PyCodeObject, make_ref(space, frame.pycode))
- py_frame.c_f_globals = make_ref(space, frame.w_globals)
+ py_frame.c_f_globals = make_ref(space, frame.get_w_globals())
rffi.setintfield(py_frame, 'c_f_lineno', frame.getorcreatedebug().f_lineno)
@cpython_api([PyObject], lltype.Void, external=False)
diff --git a/pypy/module/cpyext/import_.py b/pypy/module/cpyext/import_.py
--- a/pypy/module/cpyext/import_.py
+++ b/pypy/module/cpyext/import_.py
@@ -20,7 +20,7 @@
caller = space.getexecutioncontext().gettopframe_nohidden()
# Get the builtins from current globals
if caller is not None:
- w_globals = caller.w_globals
+ w_globals = caller.get_w_globals()
w_builtin = space.getitem(w_globals, space.wrap('__builtins__'))
else:
# No globals -- use standard builtins, and fake globals
diff --git a/pypy/module/pypyjit/test_pypy_c/test_00_model.py b/pypy/module/pypyjit/test_pypy_c/test_00_model.py
--- a/pypy/module/pypyjit/test_pypy_c/test_00_model.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_00_model.py
@@ -526,7 +526,7 @@
log = self.run(f)
loop, = log.loops_by_filename(self.filepath)
call_ops = log.opnames(loop.ops_by_id('call'))
- assert call_ops == ['force_token'] # it does not follow inlining
+ assert call_ops == ['guard_not_invalidated', 'force_token'] # it does not follow inlining
#
add_ops = log.opnames(loop.ops_by_id('add'))
assert add_ops == ['int_add']
@@ -534,9 +534,10 @@
ops = log.opnames(loop.allops())
assert ops == [
# this is the actual loop
- 'int_lt', 'guard_true', 'force_token', 'int_add',
+ 'int_lt', 'guard_true',
+ 'guard_not_invalidated', 'force_token', 'int_add',
# this is the signal checking stuff
- 'guard_not_invalidated', 'getfield_raw_i', 'int_lt', 'guard_false',
+ 'getfield_raw_i', 'int_lt', 'guard_false',
'jump'
]
diff --git a/pypy/module/pypyjit/test_pypy_c/test_call.py b/pypy/module/pypyjit/test_pypy_c/test_call.py
--- a/pypy/module/pypyjit/test_pypy_c/test_call.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_call.py
@@ -72,8 +72,6 @@
# LOAD_GLOBAL of OFFSET
ops = entry_bridge.ops_by_id('cond', opcode='LOAD_GLOBAL')
assert log.opnames(ops) == ["guard_value",
- "guard_value",
- "getfield_gc_r", "guard_value",
"guard_not_invalidated"]
ops = entry_bridge.ops_by_id('add', opcode='LOAD_GLOBAL')
assert log.opnames(ops) == []
@@ -200,6 +198,7 @@
assert log.result == 1000
loop, = log.loops_by_id('call')
assert loop.match_by_id('call', """
+ guard_not_invalidated?
i14 = force_token()
i16 = force_token()
""")
@@ -222,7 +221,7 @@
loop, = log.loops_by_id('call')
ops = log.opnames(loop.ops_by_id('call'))
guards = [ops for ops in ops if ops.startswith('guard')]
- assert guards == ["guard_no_overflow"]
+ assert guards == ["guard_not_invalidated", "guard_no_overflow"]
def test_kwargs(self):
# this is not a very precise test, could be improved
@@ -281,6 +280,7 @@
assert log.result == 13000
loop0, = log.loops_by_id('g1')
assert loop0.match_by_id('g1', """
+ guard_not_invalidated?
i20 = force_token()
i22 = int_add_ovf(i8, 3)
guard_no_overflow(descr=...)
@@ -438,9 +438,6 @@
i22 = getfield_gc_pure_i(p12, descr=<FieldS pypy.objspace.std.intobject.W_IntObject.inst_intval .*>)
i24 = int_lt(i22, 5000)
guard_true(i24, descr=...)
- guard_value(p7, ConstPtr(ptr25), descr=...)
- p26 = getfield_gc_r(p7, descr=<FieldP pypy.objspace.std.dictmultiobject.W_DictMultiObject.inst_strategy .*>)
- guard_value(p26, ConstPtr(ptr27), descr=...)
guard_not_invalidated(descr=...)
p29 = call_r(ConstClass(_ll_1_threadlocalref_get__Ptr_GcStruct_objectLlT_Signed), #, descr=<Callr . i EF=1 OS=5>)
p30 = getfield_gc_r(p29, descr=<FieldP pypy.interpreter.executioncontext.ExecutionContext.inst_topframeref .*>)
@@ -472,6 +469,7 @@
i8 = getfield_gc_pure_i(p6, descr=<FieldS pypy.objspace.std.intobject.W_IntObject.inst_intval .*>)
i10 = int_lt(i8, 5000)
guard_true(i10, descr=...)
+ guard_not_invalidated?
i11 = force_token()
i13 = int_add(i8, 1)
--TICK--
diff --git a/pypy/module/pypyjit/test_pypy_c/test_globals.py b/pypy/module/pypyjit/test_pypy_c/test_globals.py
--- a/pypy/module/pypyjit/test_pypy_c/test_globals.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_globals.py
@@ -16,9 +16,5 @@
assert log.result == 500
loop, = log.loops_by_filename(self.filepath)
assert loop.match_by_id("loadglobal", """
- p12 = getfield_gc_r(p10, descr=<FieldP .*W_DictMultiObject.inst_strategy .*>)
- guard_value(p12, ConstPtr(ptr13), descr=...)
guard_not_invalidated(descr=...)
- p19 = getfield_gc_r(ConstPtr(p17), descr=<FieldP .*W_DictMultiObject.inst_strategy .*>)
- guard_value(p19, ConstPtr(ptr20), descr=...)
""")
diff --git a/pypy/module/pypyjit/test_pypy_c/test_instance.py b/pypy/module/pypyjit/test_pypy_c/test_instance.py
--- a/pypy/module/pypyjit/test_pypy_c/test_instance.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_instance.py
@@ -124,7 +124,7 @@
setfield_gc(ConstPtr(ptr39), i59, descr=...)
i62 = int_lt(i61, 0)
guard_false(i62, descr=...)
- jump(p0, p1, p3, p6, p7, p12, i59, p18, i31, i59, p100, descr=...)
+ jump(..., descr=...)
""")
def test_mutate_class(self):
@@ -183,7 +183,7 @@
setfield_gc(p77, ConstPtr(null), descr=...)
setfield_gc(p77, ConstPtr(ptr42), descr=...)
setfield_gc(ConstPtr(ptr69), p77, descr=...)
- jump(p0, p1, p3, p6, p7, p12, i74, p20, p26, i33, p77, p100, descr=...)
+ jump(..., descr=...)
""")
diff --git a/pypy/module/pypyjit/test_pypy_c/test_misc.py b/pypy/module/pypyjit/test_pypy_c/test_misc.py
--- a/pypy/module/pypyjit/test_pypy_c/test_misc.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_misc.py
@@ -145,9 +145,9 @@
i15 = int_lt(i10, i11)
guard_true(i15, descr=...)
i17 = int_add(i10, 1)
- i18 = force_token()
setfield_gc(p9, i17, descr=<.* .*W_XRangeIterator.inst_current .*>)
guard_not_invalidated(descr=...)
+ i18 = force_token()
i84 = int_sub(i14, 1)
i21 = int_lt(i10, 0)
guard_false(i21, descr=...)
@@ -178,9 +178,9 @@
i16 = int_ge(i11, i12)
guard_false(i16, descr=...)
i20 = int_add(i11, 1)
- i21 = force_token()
setfield_gc(p4, i20, descr=<.* .*W_AbstractSeqIterObject.inst_index .*>)
guard_not_invalidated?
+ i21 = force_token()
i88 = int_sub(i9, 1)
i25 = int_ge(i11, i9)
guard_false(i25, descr=...)
@@ -211,9 +211,9 @@
i17 = int_mul(i11, i14)
i18 = int_add(i15, i17)
i20 = int_add(i11, 1)
- i21 = force_token()
setfield_gc(p4, i20, descr=<.* .*W_AbstractSeqIterObject.inst_index .*>)
guard_not_invalidated?
+ i21 = force_token()
i95 = int_sub(i9, 1)
i23 = int_lt(i18, 0)
guard_false(i23, descr=...)
diff --git a/pypy/module/pypyjit/test_pypy_c/test_weakref.py b/pypy/module/pypyjit/test_pypy_c/test_weakref.py
--- a/pypy/module/pypyjit/test_pypy_c/test_weakref.py
+++ b/pypy/module/pypyjit/test_pypy_c/test_weakref.py
@@ -23,12 +23,8 @@
i60 = int_lt(i58, i31)
guard_true(i60, descr=...)
i61 = int_add(i58, 1)
- p62 = getfield_gc_r(ConstPtr(ptr37), descr=<FieldP pypy.objspace.std.dictmultiobject.W_DictMultiObject.inst_strategy \d+>)
setfield_gc(p18, i61, descr=<FieldS pypy.module.__builtin__.functional.W_XRangeIterator.inst_current 8>)
- guard_value(p62, ConstPtr(ptr39), descr=...)
guard_not_invalidated(descr=...)
- p64 = getfield_gc_r(ConstPtr(ptr40), descr=<FieldP pypy.objspace.std.dictmultiobject.W_DictMultiObject.inst_strategy \d+>)
- guard_value(p64, ConstPtr(ptr42), descr=...)
p65 = getfield_gc_r(p14, descr=<FieldP pypy.objspace.std.mapdict.W_ObjectObjectSize5.inst_map \d+>)
guard_value(p65, ConstPtr(ptr45), descr=...)
p66 = getfield_gc_r(p14, descr=<FieldP pypy.objspace.std.mapdict.W_ObjectObjectSize5.inst__value0 \d+>)
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
@@ -153,7 +153,7 @@
d_new = strategy.unerase(strategy.get_empty_storage())
for key, cell in d.iteritems():
d_new[_wrapkey(space, key)] = unwrap_cell(self.space, cell)
- w_dict.strategy = strategy
+ w_dict.set_strategy(strategy)
w_dict.dstorage = strategy.erase(d_new)
def getiterkeys(self, w_dict):
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
@@ -42,6 +42,14 @@
class W_DictMultiObject(W_Root):
+ """ Abstract base class that does not store a strategy. """
+ def get_strategy(self):
+ raise NotImplementedError("abstract method")
+
+ def set_strategy(self, strategy):
+ raise NotImplementedError("abstract method")
+
+
@staticmethod
def allocate_and_init_instance(space, w_type=None, module=False,
instance=False, strdict=False,
@@ -52,6 +60,10 @@
# every module needs its own strategy, because the strategy stores
# the version tag
strategy = ModuleDictStrategy(space)
+ storage = strategy.get_empty_storage()
+ w_obj = space.allocate_instance(W_ModuleDictObject, space.w_dict)
+ W_ModuleDictObject.__init__(w_obj, space, strategy, storage)
+ return w_obj
elif space.config.objspace.std.withmapdict and instance:
from pypy.objspace.std.mapdict import MapDictStrategy
strategy = space.fromcache(MapDictStrategy)
@@ -68,18 +80,17 @@
w_type = space.w_dict
storage = strategy.get_empty_storage()
- w_obj = space.allocate_instance(W_DictMultiObject, w_type)
- W_DictMultiObject.__init__(w_obj, space, strategy, storage)
+ w_obj = space.allocate_instance(W_DictObject, w_type)
+ W_DictObject.__init__(w_obj, space, strategy, storage)
return w_obj
- def __init__(self, space, strategy, storage):
+ def __init__(self, space, storage):
self.space = space
- self.strategy = strategy
self.dstorage = storage
def __repr__(self):
"""representation for debugging purposes"""
- return "%s(%s)" % (self.__class__.__name__, self.strategy)
+ return "%s(%s)" % (self.__class__.__name__, self.get_strategy())
def unwrap(w_dict, space):
result = {}
@@ -101,7 +112,7 @@
self.setitem(w_k, w_v)
def setitem_str(self, key, w_value):
- self.strategy.setitem_str(self, key, w_value)
+ self.get_strategy().setitem_str(self, key, w_value)
@staticmethod
def descr_new(space, w_dicttype, __args__):
@@ -261,8 +272,9 @@
def nondescr_reversed_dict(self, space):
"""Not exposed directly to app-level, but via __pypy__.reversed_dict().
"""
- if self.strategy.has_iterreversed:
- it = self.strategy.iterreversed(self)
+ strategy = self.get_strategy()
+ if strategy.has_iterreversed:
+ it = strategy.iterreversed(self)
return W_DictMultiIterKeysObject(space, it)
else:
# fall-back
@@ -337,6 +349,37 @@
init_or_update(space, self, __args__, 'dict.update')
+class W_DictObject(W_DictMultiObject):
+ """ a regular dict object """
+ def __init__(self, space, strategy, storage):
+ W_DictMultiObject.__init__(self, space, storage)
+ self.dstrategy = strategy
+
+ def get_strategy(self):
+ return self.dstrategy
+
+ def set_strategy(self, strategy):
+ self.dstrategy = strategy
+
+
+class W_ModuleDictObject(W_DictMultiObject):
+ """ a dict object for a module, that is not expected to change. It stores
+ the strategy as a quasi-immutable field. """
+ _immutable_fields_ = ['mstrategy?']
+
+ def __init__(self, space, strategy, storage):
+ W_DictMultiObject.__init__(self, space, storage)
+ self.mstrategy = strategy
+
+ def get_strategy(self):
+ return self.mstrategy
+
+ def set_strategy(self, strategy):
+ self.mstrategy = strategy
+
+
+
+
def _add_indirections():
dict_methods = "getitem getitem_str setitem setdefault \
popitem delitem clear \
@@ -347,7 +390,7 @@
def make_method(method):
def f(self, *args):
- return getattr(self.strategy, method)(self, *args)
+ return getattr(self.get_strategy(), method)(self, *args)
f.func_name = method
return f
@@ -490,7 +533,7 @@
def clear(self, w_dict):
strategy = self.space.fromcache(EmptyDictStrategy)
storage = strategy.get_empty_storage()
- w_dict.strategy = strategy
+ w_dict.set_strategy(strategy)
w_dict.dstorage = storage
def listview_bytes(self, w_dict):
@@ -556,32 +599,32 @@
def switch_to_bytes_strategy(self, w_dict):
strategy = self.space.fromcache(BytesDictStrategy)
storage = strategy.get_empty_storage()
- w_dict.strategy = strategy
+ w_dict.set_strategy(strategy)
w_dict.dstorage = storage
def switch_to_unicode_strategy(self, w_dict):
strategy = self.space.fromcache(UnicodeDictStrategy)
storage = strategy.get_empty_storage()
- w_dict.strategy = strategy
+ w_dict.set_strategy(strategy)
w_dict.dstorage = storage
def switch_to_int_strategy(self, w_dict):
strategy = self.space.fromcache(IntDictStrategy)
storage = strategy.get_empty_storage()
- w_dict.strategy = strategy
+ w_dict.set_strategy(strategy)
w_dict.dstorage = storage
def switch_to_identity_strategy(self, w_dict):
from pypy.objspace.std.identitydict import IdentityDictStrategy
strategy = self.space.fromcache(IdentityDictStrategy)
storage = strategy.get_empty_storage()
- w_dict.strategy = strategy
+ w_dict.set_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.set_strategy(strategy)
w_dict.dstorage = storage
def getitem(self, w_dict, w_key):
@@ -662,7 +705,7 @@
if self.pos < self.len:
result = getattr(self, 'next_' + TP + '_entry')()
self.pos += 1
- if self.strategy is self.dictimplementation.strategy:
+ if self.strategy is self.dictimplementation.get_strategy():
return result # common case
else:
# waaa, obscure case: the strategy changed, but not the
@@ -804,7 +847,7 @@
else:
return # w_dict is completely empty, nothing to do
count = w_dict.length() - 1
- w_updatedict.strategy.prepare_update(w_updatedict, count)
+ w_updatedict.get_strategy().prepare_update(w_updatedict, count)
# If the strategy is still different, continue the slow way
if not same_strategy(self, w_updatedict):
for key, value, keyhash in iteritemsh:
@@ -825,7 +868,7 @@
def same_strategy(self, w_otherdict):
return (setitem_untyped is not None and
- w_otherdict.strategy is self)
+ w_otherdict.get_strategy() is self)
dictimpl.iterkeys = iterkeys
dictimpl.itervalues = itervalues
@@ -934,7 +977,7 @@
d_new = strategy.unerase(strategy.get_empty_storage())
for key, value in d.iteritems():
d_new[self.wrap(key)] = value
- w_dict.strategy = strategy
+ w_dict.set_strategy(strategy)
w_dict.dstorage = strategy.erase(d_new)
# --------------- iterator interface -----------------
@@ -1178,7 +1221,7 @@
def update1_dict_dict(space, w_dict, w_data):
- w_data.strategy.rev_update1_dict_dict(w_data, w_dict)
+ w_data.get_strategy().rev_update1_dict_dict(w_data, w_dict)
def update1_pairs(space, w_dict, data_w):
diff --git a/pypy/objspace/std/kwargsdict.py b/pypy/objspace/std/kwargsdict.py
--- a/pypy/objspace/std/kwargsdict.py
+++ b/pypy/objspace/std/kwargsdict.py
@@ -18,7 +18,7 @@
def switch_to_bytes_strategy(self, w_dict):
strategy = self.space.fromcache(KwargsDictStrategy)
storage = strategy.get_empty_storage()
- w_dict.strategy = strategy
+ w_dict.set_strategy(strategy)
w_dict.dstorage = storage
@@ -142,7 +142,7 @@
d_new = strategy.unerase(strategy.get_empty_storage())
for i in range(len(keys)):
d_new[self.wrap(keys[i])] = values_w[i]
- w_dict.strategy = strategy
+ w_dict.set_strategy(strategy)
w_dict.dstorage = strategy.erase(d_new)
def switch_to_bytes_strategy(self, w_dict):
@@ -152,7 +152,7 @@
d_new = strategy.unerase(storage)
for i in range(len(keys)):
d_new[keys[i]] = values_w[i]
- w_dict.strategy = strategy
+ w_dict.set_strategy(strategy)
w_dict.dstorage = storage
def view_as_kwargs(self, w_dict):
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
@@ -6,7 +6,8 @@
from pypy.interpreter.baseobjspace import W_Root
from pypy.objspace.std.dictmultiobject import (
W_DictMultiObject, DictStrategy, ObjectDictStrategy, BaseKeyIterator,
- BaseValueIterator, BaseItemIterator, _never_equal_to_string
+ BaseValueIterator, BaseItemIterator, _never_equal_to_string,
+ W_DictObject,
)
from pypy.objspace.std.typeobject import MutableCell
@@ -407,7 +408,7 @@
strategy = space.fromcache(MapDictStrategy)
storage = strategy.erase(self)
- w_dict = W_DictMultiObject(space, strategy, storage)
+ w_dict = W_DictObject(space, strategy, storage)
flag = self._get_mapdict_map().write(self, ("dict", SPECIAL), w_dict)
assert flag
return w_dict
@@ -422,8 +423,8 @@
# new dict. If the old dict was using the MapDictStrategy, we
# have to force it now: otherwise it would remain an empty
# shell that continues to delegate to 'self'.
- if type(w_olddict.strategy) is MapDictStrategy:
- w_olddict.strategy.switch_to_object_strategy(w_olddict)
+ if type(w_olddict.get_strategy()) is MapDictStrategy:
+ w_olddict.get_strategy().switch_to_object_strategy(w_olddict)
flag = self._get_mapdict_map().write(self, ("dict", SPECIAL), w_dict)
assert flag
@@ -641,7 +642,7 @@
w_obj = self.unerase(w_dict.dstorage)
strategy = self.space.fromcache(ObjectDictStrategy)
dict_w = strategy.unerase(strategy.get_empty_storage())
- w_dict.strategy = strategy
+ w_dict.set_strategy(strategy)
w_dict.dstorage = strategy.erase(dict_w)
assert w_obj.getdict(self.space) is w_dict or w_obj._get_mapdict_map().terminator.w_cls is None
materialize_r_dict(self.space, w_obj, dict_w)
@@ -750,7 +751,7 @@
def next_key_entry(self):
implementation = self.dictimplementation
- assert isinstance(implementation.strategy, MapDictStrategy)
+ assert isinstance(implementation.get_strategy(), MapDictStrategy)
if self.orig_map is not self.w_obj._get_mapdict_map():
return None
if self.curr_map:
@@ -772,7 +773,7 @@
def next_value_entry(self):
implementation = self.dictimplementation
- assert isinstance(implementation.strategy, MapDictStrategy)
+ assert isinstance(implementation.get_strategy(), MapDictStrategy)
if self.orig_map is not self.w_obj._get_mapdict_map():
return None
if self.curr_map:
@@ -793,7 +794,7 @@
def next_item_entry(self):
implementation = self.dictimplementation
- assert isinstance(implementation.strategy, MapDictStrategy)
+ assert isinstance(implementation.get_strategy(), MapDictStrategy)
if self.orig_map is not self.w_obj._get_mapdict_map():
return None, None
if self.curr_map:
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
@@ -18,7 +18,7 @@
from pypy.objspace.std.bytearrayobject import W_BytearrayObject
from pypy.objspace.std.bytesobject import W_AbstractBytesObject, W_BytesObject, wrapstr
from pypy.objspace.std.complexobject import W_ComplexObject
-from pypy.objspace.std.dictmultiobject import W_DictMultiObject
+from pypy.objspace.std.dictmultiobject import W_DictMultiObject, W_DictObject
from pypy.objspace.std.floatobject import W_FloatObject
from pypy.objspace.std.intobject import W_IntObject, setup_prebuilt, wrapint
from pypy.objspace.std.iterobject import W_AbstractSeqIterObject, W_SeqIterObject
@@ -439,7 +439,7 @@
# and isinstance() for others. See test_listobject.test_uses_custom...
if type(w_obj) is W_ListObject:
return w_obj.getitems_bytes()
- if type(w_obj) is W_DictMultiObject:
+ if type(w_obj) is W_DictObject:
return w_obj.listview_bytes()
if type(w_obj) is W_SetObject or type(w_obj) is W_FrozensetObject:
return w_obj.listview_bytes()
@@ -454,7 +454,7 @@
# and isinstance() for others. See test_listobject.test_uses_custom...
if type(w_obj) is W_ListObject:
return w_obj.getitems_unicode()
- if type(w_obj) is W_DictMultiObject:
+ if type(w_obj) is W_DictObject:
return w_obj.listview_unicode()
if type(w_obj) is W_SetObject or type(w_obj) is W_FrozensetObject:
return w_obj.listview_unicode()
@@ -467,7 +467,7 @@
def listview_int(self, w_obj):
if type(w_obj) is W_ListObject:
return w_obj.getitems_int()
- if type(w_obj) is W_DictMultiObject:
+ if type(w_obj) is W_DictObject:
return w_obj.listview_int()
if type(w_obj) is W_SetObject or type(w_obj) is W_FrozensetObject:
return w_obj.listview_int()
@@ -485,7 +485,7 @@
return None
def view_as_kwargs(self, w_dict):
- if type(w_dict) is W_DictMultiObject:
+ if type(w_dict) is W_DictObject:
return w_dict.view_as_kwargs()
return (None, None)
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
@@ -1,7 +1,7 @@
import py
from pypy.objspace.std.celldict import ModuleDictStrategy
-from pypy.objspace.std.dictmultiobject import W_DictMultiObject
+from pypy.objspace.std.dictmultiobject import W_DictObject, W_ModuleDictObject
from pypy.objspace.std.test.test_dictmultiobject import (
BaseTestRDictImplementation, BaseTestDevolvedDictImplementation, FakeSpace,
FakeString)
@@ -14,7 +14,7 @@
def test_basic_property_cells(self):
strategy = ModuleDictStrategy(space)
storage = strategy.get_empty_storage()
- d = W_DictMultiObject(space, strategy, storage)
+ d = W_ModuleDictObject(space, strategy, storage)
v1 = strategy.version
key = "a"
@@ -23,30 +23,30 @@
v2 = strategy.version
assert v1 is not v2
assert d.getitem(w_key) == 1
- assert d.strategy.getdictvalue_no_unwrapping(d, key) == 1
+ assert d.get_strategy().getdictvalue_no_unwrapping(d, key) == 1
d.setitem(w_key, 2)
v3 = strategy.version
assert v2 is not v3
assert d.getitem(w_key) == 2
- assert d.strategy.getdictvalue_no_unwrapping(d, key).w_value == 2
+ assert d.get_strategy().getdictvalue_no_unwrapping(d, key).w_value == 2
d.setitem(w_key, 3)
v4 = strategy.version
assert v3 is v4
assert d.getitem(w_key) == 3
- assert d.strategy.getdictvalue_no_unwrapping(d, key).w_value == 3
+ assert d.get_strategy().getdictvalue_no_unwrapping(d, key).w_value == 3
d.delitem(w_key)
v5 = strategy.version
assert v5 is not v4
assert d.getitem(w_key) is None
- assert d.strategy.getdictvalue_no_unwrapping(d, key) is None
+ assert d.get_strategy().getdictvalue_no_unwrapping(d, key) is None
def test_same_key_set_twice(self):
strategy = ModuleDictStrategy(space)
storage = strategy.get_empty_storage()
- d = W_DictMultiObject(space, strategy, storage)
+ d = W_ModuleDictObject(space, strategy, storage)
v1 = strategy.version
x = object()
@@ -134,7 +134,7 @@
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)
+ cls.w_d = W_ModuleDictObject(cls.space, strategy, storage)
def test_popitem(self):
import __pypy__
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
@@ -2,14 +2,14 @@
import py
from pypy.objspace.std.dictmultiobject import (W_DictMultiObject,
- BytesDictStrategy, ObjectDictStrategy)
+ W_DictObject, BytesDictStrategy, ObjectDictStrategy)
class TestW_DictObject(object):
def test_empty(self):
d = self.space.newdict()
assert not self.space.is_true(d)
- assert type(d.strategy) is not ObjectDictStrategy
+ assert type(d.get_strategy()) is not ObjectDictStrategy
def test_nonempty(self):
space = self.space
@@ -1050,7 +1050,7 @@
return l
def newlist_bytes(self, l):
return l
- DictObjectCls = W_DictMultiObject
+ DictObjectCls = W_DictObject
def type(self, w_obj):
if isinstance(w_obj, FakeString):
return str
@@ -1076,7 +1076,7 @@
return tuple(l)
def newdict(self, module=False, instance=False):
- return W_DictMultiObject.allocate_and_init_instance(
+ return W_DictObject.allocate_and_init_instance(
self, module=module, instance=instance)
def view_as_kwargs(self, w_d):
@@ -1105,7 +1105,7 @@
w_float = float
StringObjectCls = FakeString
UnicodeObjectCls = FakeUnicode
- w_dict = W_DictMultiObject
+ w_dict = W_DictObject
iter = iter
fixedview = list
listview = list
@@ -1149,8 +1149,8 @@
def get_impl(self):
strategy = self.StrategyClass(self.fakespace)
storage = strategy.get_empty_storage()
- w_dict = self.fakespace.allocate_instance(W_DictMultiObject, None)
- W_DictMultiObject.__init__(w_dict, self.fakespace, strategy, storage)
+ w_dict = self.fakespace.allocate_instance(W_DictObject, None)
+ W_DictObject.__init__(w_dict, self.fakespace, strategy, storage)
return w_dict
def fill_impl(self):
@@ -1159,7 +1159,7 @@
def check_not_devolved(self):
#XXX check if strategy changed!?
- assert type(self.impl.strategy) is self.StrategyClass
+ assert type(self.impl.get_strategy()) is self.StrategyClass
#assert self.impl.r_dict_content is None
def test_popitem(self):
@@ -1246,7 +1246,7 @@
for x in xrange(100):
impl.setitem(self.fakespace.str_w(str(x)), x)
impl.setitem(x, x)
- assert type(impl.strategy) is ObjectDictStrategy
+ assert type(impl.get_strategy()) is ObjectDictStrategy
def test_setdefault_fast(self):
on_pypy = "__pypy__" in sys.builtin_module_names
@@ -1308,7 +1308,7 @@
class BaseTestDevolvedDictImplementation(BaseTestRDictImplementation):
def fill_impl(self):
BaseTestRDictImplementation.fill_impl(self)
- self.impl.strategy.switch_to_object_strategy(self.impl)
+ self.impl.get_strategy().switch_to_object_strategy(self.impl)
def check_not_devolved(self):
pass
@@ -1320,5 +1320,5 @@
def test_module_uses_strdict():
fakespace = FakeSpace()
d = fakespace.newdict(module=True)
- assert type(d.strategy) is BytesDictStrategy
+ assert type(d.get_strategy()) is BytesDictStrategy
diff --git a/pypy/objspace/std/test/test_kwargsdict.py b/pypy/objspace/std/test/test_kwargsdict.py
--- a/pypy/objspace/std/test/test_kwargsdict.py
+++ b/pypy/objspace/std/test/test_kwargsdict.py
@@ -1,5 +1,5 @@
import py
-from pypy.objspace.std.test.test_dictmultiobject import FakeSpace, W_DictMultiObject
+from pypy.objspace.std.test.test_dictmultiobject import FakeSpace, W_DictObject
from pypy.objspace.std.kwargsdict import *
space = FakeSpace()
@@ -9,7 +9,7 @@
keys = ["a", "b", "c"]
values = [1, 2, 3]
storage = strategy.erase((keys, values))
- d = W_DictMultiObject(space, strategy, storage)
+ d = W_DictObject(space, strategy, storage)
assert d.getitem_str("a") == 1
assert d.getitem_str("b") == 2
assert d.getitem_str("c") == 3
@@ -23,7 +23,7 @@
keys = ["a", "b", "c"]
values = [1, 2, 3]
storage = strategy.erase((keys, values))
- d = W_DictMultiObject(space, strategy, storage)
+ d = W_DictObject(space, strategy, storage)
assert d.getitem_str("a") == 1
assert d.getitem_str("b") == 2
assert d.getitem_str("c") == 3
@@ -52,7 +52,7 @@
keys = ["a", "b", "c"]
values = [1, 2, 3]
storage = strategy.erase((keys, values))
- d = W_DictMultiObject(space, strategy, storage)
+ d = W_DictObject(space, strategy, storage)
assert d.getitem_str("a") == 1
assert d.getitem_str("b") == 2
assert d.getitem_str("c") == 3
@@ -69,11 +69,11 @@
def test_limit_size():
storage = strategy.get_empty_storage()
- d = W_DictMultiObject(space, strategy, storage)
+ d = W_DictObject(space, strategy, storage)
for i in range(100):
assert d.setitem_str("d%s" % i, 4) is None
- assert d.strategy is not strategy
- assert "BytesDictStrategy" == d.strategy.__class__.__name__
+ assert d.get_strategy() is not strategy
+ assert "BytesDictStrategy" == d.get_strategy().__class__.__name__
def test_keys_doesnt_wrap():
space = FakeSpace()
@@ -82,7 +82,7 @@
keys = ["a", "b", "c"]
values = [1, 2, 3]
storage = strategy.erase((keys, values))
- d = W_DictMultiObject(space, strategy, storage)
+ d = W_DictObject(space, strategy, storage)
w_l = d.w_keys() # does not crash
def test_view_as_kwargs():
@@ -91,26 +91,27 @@
keys = ["a", "b", "c"]
values = [1, 2, 3]
storage = strategy.erase((keys, values))
- d = W_DictMultiObject(space, strategy, storage)
+ d = W_DictObject(space, strategy, storage)
assert (space.view_as_kwargs(d) == keys, values)
strategy = EmptyDictStrategy(space)
storage = strategy.get_empty_storage()
- d = W_DictMultiObject(space, strategy, storage)
+ d = W_DictObject(space, strategy, storage)
assert (space.view_as_kwargs(d) == [], [])
def test_from_empty_to_kwargs():
strategy = EmptyKwargsDictStrategy(space)
storage = strategy.get_empty_storage()
- d = W_DictMultiObject(space, strategy, storage)
+ d = W_DictObject(space, strategy, storage)
d.setitem_str("a", 3)
- assert isinstance(d.strategy, KwargsDictStrategy)
+ assert isinstance(d.get_strategy(), KwargsDictStrategy)
from pypy.objspace.std.test.test_dictmultiobject import BaseTestRDictImplementation, BaseTestDevolvedDictImplementation
def get_impl(self):
storage = strategy.erase(([], []))
- return W_DictMultiObject(space, strategy, storage)
+ return W_DictObject(space, strategy, storage)
+
class TestKwargsDictImplementation(BaseTestRDictImplementation):
StrategyClass = KwargsDictStrategy
get_impl = get_impl
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
@@ -1,4 +1,4 @@
-from pypy.objspace.std.test.test_dictmultiobject import FakeSpace, W_DictMultiObject
+from pypy.objspace.std.test.test_dictmultiobject import FakeSpace, W_DictObject
from pypy.objspace.std.mapdict import *
class Config:
@@ -309,7 +309,7 @@
obj.setdictvalue(space, "c", 7)
assert obj.storage == [50, 60, 70, 5, 6, 7]
- class FakeDict(W_DictMultiObject):
+ class FakeDict(W_DictObject):
def __init__(self, d):
self.dstorage = d
@@ -368,7 +368,7 @@
def devolve_dict(space, obj):
w_d = obj.getdict(space)
- w_d.strategy.switch_to_object_strategy(w_d)
+ w_d.get_strategy().switch_to_object_strategy(w_d)
def test_get_setdictvalue_after_devolve():
cls = Class()
@@ -1127,7 +1127,7 @@
def test_newdict_instance():
w_dict = space.newdict(instance=True)
- assert type(w_dict.strategy) is MapDictStrategy
+ assert type(w_dict.get_strategy()) is MapDictStrategy
class TestMapDictImplementationUsingnewdict(BaseTestRDictImplementation):
StrategyClass = MapDictStrategy
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -478,12 +478,12 @@
def getdict(w_self, space): # returning a dict-proxy!
from pypy.objspace.std.dictproxyobject import DictProxyStrategy
- from pypy.objspace.std.dictmultiobject import W_DictMultiObject
+ from pypy.objspace.std.dictmultiobject import W_DictObject
if w_self.lazyloaders:
w_self._cleanup_() # force un-lazification
strategy = space.fromcache(DictProxyStrategy)
storage = strategy.erase(w_self)
- return W_DictMultiObject(space, strategy, storage)
+ return W_DictObject(space, strategy, storage)
def is_heaptype(w_self):
return w_self.flag_heaptype
@@ -1139,7 +1139,7 @@
space = w_self.space
caller = space.getexecutioncontext().gettopframe_nohidden()
if caller is not None:
- w_globals = caller.w_globals
+ w_globals = caller.get_w_globals()
w_name = space.finditem(w_globals, space.wrap('__name__'))
if w_name is not None:
w_self.dict_w['__module__'] = w_name
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
@@ -63,7 +63,7 @@
for key, w_value in vars.items():
space.setitem(self.w_locals, space.wrap(key), w_value)
if isinstance(code, str):
- return space.eval(code, self.w_globals, self.w_locals)
+ return space.eval(code, self.get_w_globals(), self.w_locals)
pyc = pycode.PyCode._from_code(space, code)
return pyc.exec_host_bytecode(self.w_globals, self.w_locals)
exec_ = eval
@@ -248,7 +248,7 @@
#if filename.endswith("pyc"):
# filename = filename[:-1]
try:
- space.exec_(str(source), frame.w_globals, w_locals,
+ space.exec_(str(source), frame.get_w_globals(), w_locals,
filename=filename)
except OperationError, e:
if e.match(space, w_ExpectedException):
diff --git a/rpython/jit/metainterp/optimizeopt/heap.py b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -32,8 +32,8 @@
# 1. 'cached_infos' is a list listing all the infos that are
# caching this descr
#
- # 2. we just did one setfield, which is delayed (and thus
- # not synchronized). 'lazy_setfield' is the delayed
+ # 2. we just did one set(field/arrayitem), which is delayed (and thus
+ # not synchronized). '_lazy_set' is the delayed
# ResOperation. In this state, 'cached_infos' contains
# out-of-date information. More precisely, the field
# value pending in the ResOperation is *not* visible in
@@ -41,7 +41,7 @@
#
self.cached_infos = []
self.cached_structs = []
- self._lazy_setfield = None
+ self._lazy_set = None
def register_info(self, structop, info):
# invariant: every struct or array ptr info, that is not virtual and
@@ -53,27 +53,27 @@
def produce_potential_short_preamble_ops(self, optimizer, shortboxes,
descr, index=-1):
- assert self._lazy_setfield is None
+ assert self._lazy_set is None
for i, info in enumerate(self.cached_infos):
structbox = optimizer.get_box_replacement(self.cached_structs[i])
info.produce_short_preamble_ops(structbox, descr, index, optimizer,
shortboxes)
def possible_aliasing(self, optheap, opinfo):
- # If lazy_setfield is set and contains a setfield on a different
+ # If lazy_set is set and contains a setfield on a different
# structvalue, then we are annoyed, because it may point to either
# the same or a different structure at runtime.
# XXX constants?
- return (self._lazy_setfield is not None
+ return (self._lazy_set is not None
and (not optheap.getptrinfo(
- self._lazy_setfield.getarg(0)).same_info(opinfo)))
+ self._lazy_set.getarg(0)).same_info(opinfo)))
def do_setfield(self, optheap, op):
# Update the state with the SETFIELD_GC/SETARRAYITEM_GC operation 'op'.
structinfo = optheap.ensure_ptr_info_arg0(op)
arg1 = optheap.get_box_replacement(self._get_rhs_from_set_op(op))
if self.possible_aliasing(optheap, structinfo):
- self.force_lazy_setfield(optheap, op.getdescr())
+ self.force_lazy_set(optheap, op.getdescr())
assert not self.possible_aliasing(optheap, structinfo)
cached_field = self._getfield(structinfo, op.getdescr(), optheap, False)
if cached_field is not None:
@@ -86,27 +86,27 @@
# cached_fieldvalue = self._cached_fields.get(structvalue, None)
if not cached_field or not cached_field.same_box(arg1):
- # common case: store the 'op' as lazy_setfield
- self._lazy_setfield = op
+ # common case: store the 'op' as lazy_set
+ self._lazy_set = op
else:
# this is the case where the pending setfield ends up
# storing precisely the value that is already there,
# as proved by 'cached_fields'. In this case, we don't
- # need any _lazy_setfield: the heap value is already right.
- # Note that this may reset to None a non-None lazy_setfield,
+ # need any _lazy_set: the heap value is already right.
+ # Note that this may reset to None a non-None lazy_set,
# cancelling its previous effects with no side effect.
# Now, we have to force the item in the short preamble
self._getfield(structinfo, op.getdescr(), optheap)
- self._lazy_setfield = None
+ self._lazy_set = None
def getfield_from_cache(self, optheap, opinfo, descr):
# Returns the up-to-date field's value, or None if not cached.
if self.possible_aliasing(optheap, opinfo):
- self.force_lazy_setfield(optheap, descr)
- if self._lazy_setfield is not None:
- op = self._lazy_setfield
+ self.force_lazy_set(optheap, descr)
+ if self._lazy_set is not None:
+ op = self._lazy_set
return optheap.get_box_replacement(self._get_rhs_from_set_op(op))
else:
res = self._getfield(opinfo, descr, optheap)
@@ -114,15 +114,15 @@
return res.get_box_replacement()
return None
- def force_lazy_setfield(self, optheap, descr, can_cache=True):
- op = self._lazy_setfield
+ def force_lazy_set(self, optheap, descr, can_cache=True):
+ op = self._lazy_set
if op is not None:
- # This is the way _lazy_setfield is usually reset to None.
+ # This is the way _lazy_set is usually reset to None.
# Now we clear _cached_fields, because actually doing the
# setfield might impact any of the stored result (because of
# possible aliasing).
self.invalidate(descr)
- self._lazy_setfield = None
+ self._lazy_set = None
if optheap.postponed_op:
for a in op.getarglist():
if a is optheap.postponed_op:
@@ -250,7 +250,7 @@
def flush(self):
self.cached_dict_reads.clear()
self.corresponding_array_descrs.clear()
- self.force_all_lazy_setfields_and_arrayitems()
+ self.force_all_lazy_sets()
self.emit_postponed_op()
def emit_postponed_op(self):
@@ -326,7 +326,7 @@
return
if op.is_guard():
self.optimizer.pendingfields = (
- self.force_lazy_setfields_and_arrayitems_for_guard())
+ self.force_lazy_sets_for_guard())
return
opnum = op.getopnum()
if (opnum == rop.SETFIELD_GC or # handled specially
@@ -354,7 +354,7 @@
if not effectinfo.has_random_effects():
self.force_from_effectinfo(effectinfo)
return
- self.force_all_lazy_setfields_and_arrayitems()
+ self.force_all_lazy_sets()
self.clean_caches()
def optimize_CALL_I(self, op):
@@ -432,7 +432,7 @@
# XXX we can get the wrong complexity here, if the lists
# XXX stored on effectinfo are large
for fielddescr in effectinfo.readonly_descrs_fields:
- self.force_lazy_setfield(fielddescr)
+ self.force_lazy_set(fielddescr)
for arraydescr in effectinfo.readonly_descrs_arrays:
self.force_lazy_setarrayitem(arraydescr)
for fielddescr in effectinfo.write_descrs_fields:
@@ -442,7 +442,7 @@
del self.cached_dict_reads[fielddescr]
except KeyError:
pass
- self.force_lazy_setfield(fielddescr, can_cache=False)
+ self.force_lazy_set(fielddescr, can_cache=False)
for arraydescr in effectinfo.write_descrs_arrays:
self.force_lazy_setarrayitem(arraydescr, can_cache=False)
if arraydescr in self.corresponding_array_descrs:
@@ -453,16 +453,16 @@
pass # someone did it already
if effectinfo.check_forces_virtual_or_virtualizable():
vrefinfo = self.optimizer.metainterp_sd.virtualref_info
- self.force_lazy_setfield(vrefinfo.descr_forced)
+ self.force_lazy_set(vrefinfo.descr_forced)
# ^^^ we only need to force this field; the other fields
# of virtualref_info and virtualizable_info are not gcptrs.
- def force_lazy_setfield(self, descr, can_cache=True):
+ def force_lazy_set(self, descr, can_cache=True):
try:
cf = self.cached_fields[descr]
except KeyError:
return
- cf.force_lazy_setfield(self, descr, can_cache)
+ cf.force_lazy_set(self, descr, can_cache)
def force_lazy_setarrayitem(self, arraydescr, indexb=None, can_cache=True):
try:
@@ -471,35 +471,35 @@
return
for idx, cf in submap.iteritems():
if indexb is None or indexb.contains(idx):
- cf.force_lazy_setfield(self, None, can_cache)
+ cf.force_lazy_set(self, None, can_cache)
- def force_all_lazy_setfields_and_arrayitems(self):
+ def force_all_lazy_sets(self):
items = self.cached_fields.items()
if not we_are_translated():
items.sort(key=str, reverse=True)
for descr, cf in items:
- cf.force_lazy_setfield(self, descr)
+ cf.force_lazy_set(self, descr)
for submap in self.cached_arrayitems.itervalues():
for index, cf in submap.iteritems():
- cf.force_lazy_setfield(self, None)
+ cf.force_lazy_set(self, None)
- def force_lazy_setfields_and_arrayitems_for_guard(self):
+ def force_lazy_sets_for_guard(self):
pendingfields = []
items = self.cached_fields.items()
if not we_are_translated():
items.sort(key=str, reverse=True)
for descr, cf in items:
- op = cf._lazy_setfield
+ op = cf._lazy_set
if op is None:
continue
val = op.getarg(1)
if self.optimizer.is_virtual(val):
pendingfields.append(op)
continue
- cf.force_lazy_setfield(self, descr)
+ cf.force_lazy_set(self, descr)
for descr, submap in self.cached_arrayitems.iteritems():
for index, cf in submap.iteritems():
- op = cf._lazy_setfield
+ op = cf._lazy_set
if op is None:
continue
# the only really interesting case that we need to handle in the
@@ -511,7 +511,7 @@
if self.optimizer.is_virtual(op.getarg(2)):
pendingfields.append(op)
else:
- cf.force_lazy_setfield(self, descr)
+ cf.force_lazy_set(self, descr)
return pendingfields
def optimize_GETFIELD_GC_I(self, op):
diff --git a/rpython/jit/metainterp/optimizeopt/info.py b/rpython/jit/metainterp/optimizeopt/info.py
--- a/rpython/jit/metainterp/optimizeopt/info.py
+++ b/rpython/jit/metainterp/optimizeopt/info.py
@@ -528,6 +528,7 @@
if self._items is None:
self._items = [None] * (index + 1)
if index >= len(self._items):
+ assert not self.is_virtual()
self._items = self._items + [None] * (index - len(self._items) + 1)
self._items[index] = op
if cf is not None:
More information about the pypy-commit
mailing list