[pypy-commit] pypy store-sink-array: Replace the two lists on PyFrame, 'fastlocals_w' and 'valuestack_w',
arigo
noreply at buildbot.pypy.org
Thu Jun 23 14:00:43 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: store-sink-array
Changeset: r45073:a1843da2fef6
Date: 2011-06-22 10:37 +0200
http://bitbucket.org/pypy/pypy/changeset/a1843da2fef6/
Log: Replace the two lists on PyFrame, 'fastlocals_w' and 'valuestack_w',
with a single unified list 'locals_stack_w' that stores first the
locals and then the stack item.
diff --git a/pypy/interpreter/eval.py b/pypy/interpreter/eval.py
--- a/pypy/interpreter/eval.py
+++ b/pypy/interpreter/eval.py
@@ -100,12 +100,12 @@
@jit.dont_look_inside
def fast2locals(self):
- # Copy values from self.fastlocals_w to self.w_locals
+ # Copy values from the fastlocals to self.w_locals
if self.w_locals is None:
self.w_locals = self.space.newdict()
varnames = self.getcode().getvarnames()
fastscope_w = self.getfastscope()
- for i in range(min(len(varnames), len(fastscope_w))):
+ for i in range(min(len(varnames), self.getfastscopelength())):
name = varnames[i]
w_value = fastscope_w[i]
if w_value is not None:
@@ -114,7 +114,7 @@
@jit.dont_look_inside
def locals2fast(self):
- # Copy values from self.w_locals to self.fastlocals_w
+ # Copy values from self.w_locals to the fastlocals
assert self.w_locals is not None
varnames = self.getcode().getvarnames()
numlocals = self.getfastscopelength()
diff --git a/pypy/interpreter/function.py b/pypy/interpreter/function.py
--- a/pypy/interpreter/function.py
+++ b/pypy/interpreter/function.py
@@ -98,7 +98,7 @@
self.closure)
for i in funccallunrolling:
if i < nargs:
- new_frame.fastlocals_w[i] = args_w[i]
+ new_frame.locals_stack_w[i] = args_w[i]
return new_frame.run()
elif nargs >= 1 and fast_natural_arity == Code.PASSTHROUGHARGS1:
assert isinstance(code, gateway.BuiltinCodePassThroughArguments1)
@@ -158,7 +158,7 @@
self.closure)
for i in xrange(nargs):
w_arg = frame.peekvalue(nargs-1-i)
- new_frame.fastlocals_w[i] = w_arg
+ new_frame.locals_stack_w[i] = w_arg
return new_frame.run()
@@ -169,13 +169,13 @@
self.closure)
for i in xrange(nargs):
w_arg = frame.peekvalue(nargs-1-i)
- new_frame.fastlocals_w[i] = w_arg
+ new_frame.locals_stack_w[i] = w_arg
ndefs = len(self.defs_w)
start = ndefs - defs_to_load
i = nargs
for j in xrange(start, ndefs):
- new_frame.fastlocals_w[i] = self.defs_w[j]
+ new_frame.locals_stack_w[i] = self.defs_w[j]
i += 1
return new_frame.run()
diff --git a/pypy/interpreter/nestedscope.py b/pypy/interpreter/nestedscope.py
--- a/pypy/interpreter/nestedscope.py
+++ b/pypy/interpreter/nestedscope.py
@@ -170,7 +170,7 @@
for i in range(len(args_to_copy)):
argnum = args_to_copy[i]
if argnum >= 0:
- self.cells[i].set(self.fastlocals_w[argnum])
+ self.cells[i].set(self.locals_stack_w[argnum])
def getfreevarname(self, index):
freevarnames = self.pycode.co_cellvars + self.pycode.co_freevars
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -202,7 +202,7 @@
# speed hack
fresh_frame = jit.hint(frame, access_directly=True,
fresh_virtualizable=True)
- args_matched = args.parse_into_scope(None, fresh_frame.fastlocals_w,
+ args_matched = args.parse_into_scope(None, fresh_frame.locals_stack_w,
func.name,
sig, func.defs_w)
fresh_frame.init_cells()
@@ -215,7 +215,7 @@
# speed hack
fresh_frame = jit.hint(frame, access_directly=True,
fresh_virtualizable=True)
- args_matched = args.parse_into_scope(w_obj, fresh_frame.fastlocals_w,
+ args_matched = args.parse_into_scope(w_obj, fresh_frame.locals_stack_w,
func.name,
sig, func.defs_w)
fresh_frame.init_cells()
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -9,7 +9,7 @@
from pypy.interpreter import pytraceback
from pypy.rlib.objectmodel import we_are_translated, instantiate
from pypy.rlib.jit import hint
-from pypy.rlib.debug import make_sure_not_resized
+from pypy.rlib.debug import make_sure_not_resized, check_nonneg
from pypy.rlib.rarithmetic import intmask
from pypy.rlib import jit
from pypy.tool import stdlib_opcode
@@ -56,16 +56,18 @@
assert isinstance(code, pycode.PyCode)
self.pycode = code
eval.Frame.__init__(self, space, w_globals)
- self.valuestack_w = [None] * code.co_stacksize
- self.valuestackdepth = 0
+ self.locals_stack_w = [None] * (code.co_nlocals + code.co_stacksize)
+ self.nlocals = code.co_nlocals
+ self.valuestackdepth = code.co_nlocals
self.lastblock = None
+ make_sure_not_resized(self.locals_stack_w)
+ check_nonneg(self.nlocals)
+ #
if space.config.objspace.honor__builtins__:
self.builtin = space.builtin.pick_builtin(w_globals)
# regular functions always have CO_OPTIMIZED and CO_NEWLOCALS.
# class bodies only have CO_NEWLOCALS.
self.initialize_frame_scopes(closure, code)
- self.fastlocals_w = [None] * code.co_nlocals
- make_sure_not_resized(self.fastlocals_w)
self.f_lineno = code.co_firstlineno
def mark_as_escaped(self):
@@ -184,14 +186,14 @@
# stack manipulation helpers
def pushvalue(self, w_object):
depth = self.valuestackdepth
- self.valuestack_w[depth] = w_object
+ self.locals_stack_w[depth] = w_object
self.valuestackdepth = depth + 1
def popvalue(self):
depth = self.valuestackdepth - 1
- assert depth >= 0, "pop from empty value stack"
- w_object = self.valuestack_w[depth]
- self.valuestack_w[depth] = None
+ assert depth >= self.nlocals, "pop from empty value stack"
+ w_object = self.locals_stack_w[depth]
+ self.locals_stack_w[depth] = None
self.valuestackdepth = depth
return w_object
@@ -217,24 +219,24 @@
def peekvalues(self, n):
values_w = [None] * n
base = self.valuestackdepth - n
- assert base >= 0
+ assert base >= self.nlocals
while True:
n -= 1
if n < 0:
break
- values_w[n] = self.valuestack_w[base+n]
+ values_w[n] = self.locals_stack_w[base+n]
return values_w
@jit.unroll_safe
def dropvalues(self, n):
n = hint(n, promote=True)
finaldepth = self.valuestackdepth - n
- assert finaldepth >= 0, "stack underflow in dropvalues()"
+ assert finaldepth >= self.nlocals, "stack underflow in dropvalues()"
while True:
n -= 1
if n < 0:
break
- self.valuestack_w[finaldepth+n] = None
+ self.locals_stack_w[finaldepth+n] = None
self.valuestackdepth = finaldepth
@jit.unroll_safe
@@ -261,30 +263,30 @@
# Contrast this with CPython where it's PEEK(-1).
index_from_top = hint(index_from_top, promote=True)
index = self.valuestackdepth + ~index_from_top
- assert index >= 0, "peek past the bottom of the stack"
- return self.valuestack_w[index]
+ assert index >= self.nlocals, "peek past the bottom of the stack"
+ return self.locals_stack_w[index]
def settopvalue(self, w_object, index_from_top=0):
index_from_top = hint(index_from_top, promote=True)
index = self.valuestackdepth + ~index_from_top
- assert index >= 0, "settop past the bottom of the stack"
- self.valuestack_w[index] = w_object
+ assert index >= self.nlocals, "settop past the bottom of the stack"
+ self.locals_stack_w[index] = w_object
@jit.unroll_safe
def dropvaluesuntil(self, finaldepth):
depth = self.valuestackdepth - 1
finaldepth = hint(finaldepth, promote=True)
while depth >= finaldepth:
- self.valuestack_w[depth] = None
+ self.locals_stack_w[depth] = None
depth -= 1
self.valuestackdepth = finaldepth
- def savevaluestack(self):
- return self.valuestack_w[:self.valuestackdepth]
+ def save_locals_stack(self):
+ return self.locals_stack_w[:self.valuestackdepth]
- def restorevaluestack(self, items_w):
- assert None not in items_w
- self.valuestack_w[:len(items_w)] = items_w
+ def restore_locals_stack(self, items_w):
+ self.locals_stack_w[:len(items_w)] = items_w
+ self.init_cells()
self.dropvaluesuntil(len(items_w))
def make_arguments(self, nargs):
@@ -314,11 +316,12 @@
else:
f_lineno = self.f_lineno
- values_w = self.valuestack_w[0:self.valuestackdepth]
+ values_w = self.locals_stack_w[self.nlocals:self.valuestackdepth]
w_valuestack = maker.slp_into_tuple_with_nulls(space, values_w)
w_blockstack = nt([block._get_state_(space) for block in self.get_blocklist()])
- w_fastlocals = maker.slp_into_tuple_with_nulls(space, self.fastlocals_w)
+ w_fastlocals = maker.slp_into_tuple_with_nulls(
+ space, self.locals_stack_w[:self.nlocals])
if self.last_exception is None:
w_exc_value = space.w_None
w_tb = space.w_None
@@ -399,7 +402,8 @@
new_frame.last_instr = space.int_w(w_last_instr)
new_frame.frame_finished_execution = space.is_true(w_finished)
new_frame.f_lineno = space.int_w(w_f_lineno)
- new_frame.fastlocals_w = maker.slp_from_tuple_with_nulls(space, w_fastlocals)
+ fastlocals_w = maker.slp_from_tuple_with_nulls(space, w_fastlocals)
+ new_frame.locals_stack_w[:len(fastlocals_w)] = fastlocals_w
if space.is_w(w_f_trace, space.w_None):
new_frame.w_f_trace = None
@@ -423,28 +427,28 @@
@jit.dont_look_inside
def getfastscope(self):
"Get the fast locals as a list."
- return self.fastlocals_w
+ return self.locals_stack_w
@jit.dont_look_inside
def setfastscope(self, scope_w):
"""Initialize the fast locals from a list of values,
where the order is according to self.pycode.signature()."""
scope_len = len(scope_w)
- if scope_len > len(self.fastlocals_w):
+ if scope_len > self.nlocals:
raise ValueError, "new fastscope is longer than the allocated area"
- # don't assign directly to 'fastlocals_w[:scope_len]' to be
+ # don't assign directly to 'locals_stack_w[:scope_len]' to be
# virtualizable-friendly
for i in range(scope_len):
- self.fastlocals_w[i] = scope_w[i]
+ self.locals_stack_w[i] = scope_w[i]
self.init_cells()
def init_cells(self):
- """Initialize cellvars from self.fastlocals_w
+ """Initialize cellvars from self.locals_stack_w.
This is overridden in nestedscope.py"""
pass
def getfastscopelength(self):
- return self.pycode.co_nlocals
+ return self.nlocals
def getclosure(self):
return None
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -324,7 +324,7 @@
def LOAD_FAST(self, varindex, next_instr):
# access a local variable directly
- w_value = self.fastlocals_w[varindex]
+ w_value = self.locals_stack_w[varindex]
if w_value is None:
self._load_fast_failed(varindex)
self.pushvalue(w_value)
@@ -343,7 +343,7 @@
def STORE_FAST(self, varindex, next_instr):
w_newvalue = self.popvalue()
assert w_newvalue is not None
- self.fastlocals_w[varindex] = w_newvalue
+ self.locals_stack_w[varindex] = w_newvalue
def POP_TOP(self, oparg, next_instr):
self.popvalue()
@@ -696,12 +696,12 @@
LOAD_GLOBAL._always_inline_ = True
def DELETE_FAST(self, varindex, next_instr):
- if self.fastlocals_w[varindex] is None:
+ if self.locals_stack_w[varindex] is None:
varname = self.getlocalvarname(varindex)
message = "local variable '%s' referenced before assignment"
raise operationerrfmt(self.space.w_UnboundLocalError, message,
varname)
- self.fastlocals_w[varindex] = None
+ self.locals_stack_w[varindex] = None
def BUILD_TUPLE(self, itemcount, next_instr):
items = self.popvalues(itemcount)
diff --git a/pypy/interpreter/test/test_eval.py b/pypy/interpreter/test/test_eval.py
--- a/pypy/interpreter/test/test_eval.py
+++ b/pypy/interpreter/test/test_eval.py
@@ -15,16 +15,16 @@
self.code = code
Frame.__init__(self, space)
self.numlocals = numlocals
- self.fastlocals_w = [None] * self.numlocals
+ self._fastlocals_w = [None] * self.numlocals
def getcode(self):
return self.code
def setfastscope(self, scope_w):
- self.fastlocals_w = scope_w
+ self._fastlocals_w = scope_w
def getfastscope(self):
- return self.fastlocals_w
+ return self._fastlocals_w
def getfastscopelength(self):
return self.numlocals
@@ -38,11 +38,11 @@
self.f.fast2locals()
assert space.eq_w(self.f.w_locals, self.space.wrap({}))
- self.f.fastlocals_w[0] = w(5)
+ self.f._fastlocals_w[0] = w(5)
self.f.fast2locals()
assert space.eq_w(self.f.w_locals, self.space.wrap({'x': 5}))
- self.f.fastlocals_w[2] = w(7)
+ self.f._fastlocals_w[2] = w(7)
self.f.fast2locals()
assert space.eq_w(self.f.w_locals, self.space.wrap({'x': 5, 'args': 7}))
@@ -57,13 +57,13 @@
w = self.space.wrap
self.f.w_locals = self.space.wrap({})
self.f.locals2fast()
- self.sameList(self.f.fastlocals_w, [None]*5)
+ self.sameList(self.f._fastlocals_w, [None]*5)
self.f.w_locals = self.space.wrap({'x': 5})
self.f.locals2fast()
- self.sameList(self.f.fastlocals_w, [w(5)] + [None]*4)
+ self.sameList(self.f._fastlocals_w, [w(5)] + [None]*4)
self.f.w_locals = self.space.wrap({'x':5, 'args':7})
self.f.locals2fast()
- self.sameList(self.f.fastlocals_w, [w(5), None, w(7),
- None, None])
+ self.sameList(self.f._fastlocals_w, [w(5), None, w(7),
+ None, None])
diff --git a/pypy/module/__builtin__/functional.py b/pypy/module/__builtin__/functional.py
--- a/pypy/module/__builtin__/functional.py
+++ b/pypy/module/__builtin__/functional.py
@@ -294,7 +294,7 @@
break
new_frame = space.createframe(code, w_func.w_func_globals,
w_func.closure)
- new_frame.fastlocals_w[0] = w_item
+ new_frame.locals_stack_w[0] = w_item
w_res = new_frame.run()
result_w.append(w_res)
return result_w
diff --git a/pypy/module/pypyjit/interp_jit.py b/pypy/module/pypyjit/interp_jit.py
--- a/pypy/module/pypyjit/interp_jit.py
+++ b/pypy/module/pypyjit/interp_jit.py
@@ -21,8 +21,7 @@
from pypy.module.pypyjit.interp_resop import W_DebugMergePoint
PyFrame._virtualizable2_ = ['last_instr', 'pycode',
- 'valuestackdepth', 'valuestack_w[*]',
- 'fastlocals_w[*]',
+ 'valuestackdepth', 'locals_stack_w[*]',
'last_exception',
'lastblock',
'is_being_profiled',
diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py
--- a/pypy/objspace/flow/flowcontext.py
+++ b/pypy/objspace/flow/flowcontext.py
@@ -384,8 +384,9 @@
# hack for unrolling iterables, don't use this
def replace_in_stack(self, oldvalue, newvalue):
w_new = Constant(newvalue)
- stack_items_w = self.crnt_frame.valuestack_w
- for i in range(self.crnt_frame.valuestackdepth-1, -1, -1):
+ f = self.crnt_frame
+ stack_items_w = f.locals_stack_w
+ for i in range(f.valuestackdepth-1, f.nlocals-1, -1):
w_v = stack_items_w[i]
if isinstance(w_v, Constant):
if w_v.value is oldvalue:
diff --git a/pypy/objspace/flow/framestate.py b/pypy/objspace/flow/framestate.py
--- a/pypy/objspace/flow/framestate.py
+++ b/pypy/objspace/flow/framestate.py
@@ -10,7 +10,7 @@
def __init__(self, state):
if isinstance(state, PyFrame):
# getfastscope() can return real None, for undefined locals
- data = state.getfastscope() + state.savevaluestack()
+ data = state.save_locals_stack()
if state.last_exception is None:
data.append(Constant(None))
data.append(Constant(None))
@@ -36,11 +36,9 @@
def restoreframe(self, frame):
if isinstance(frame, PyFrame):
- fastlocals = len(frame.fastlocals_w)
data = self.mergeable[:]
recursively_unflatten(frame.space, data)
- frame.setfastscope(data[:fastlocals]) # Nones == undefined locals
- frame.restorevaluestack(data[fastlocals:-2])
+ frame.restore_locals_stack(data[:-2]) # Nones == undefined locals
if data[-2] == Constant(None):
assert data[-1] == Constant(None)
frame.last_exception = None
diff --git a/pypy/objspace/flow/test/test_framestate.py b/pypy/objspace/flow/test/test_framestate.py
--- a/pypy/objspace/flow/test/test_framestate.py
+++ b/pypy/objspace/flow/test/test_framestate.py
@@ -25,7 +25,7 @@
dummy = Constant(None)
#dummy.dummy = True
arg_list = ([Variable() for i in range(formalargcount)] +
- [dummy] * (len(frame.fastlocals_w) - formalargcount))
+ [dummy] * (frame.nlocals - formalargcount))
frame.setfastscope(arg_list)
return frame
@@ -42,7 +42,7 @@
def test_neq_hacked_framestate(self):
frame = self.getframe(self.func_simple)
fs1 = FrameState(frame)
- frame.fastlocals_w[-1] = Variable()
+ frame.locals_stack_w[frame.nlocals-1] = Variable()
fs2 = FrameState(frame)
assert fs1 != fs2
@@ -55,7 +55,7 @@
def test_union_on_hacked_framestates(self):
frame = self.getframe(self.func_simple)
fs1 = FrameState(frame)
- frame.fastlocals_w[-1] = Variable()
+ frame.locals_stack_w[frame.nlocals-1] = Variable()
fs2 = FrameState(frame)
assert fs1.union(fs2) == fs2 # fs2 is more general
assert fs2.union(fs1) == fs2 # fs2 is more general
@@ -63,7 +63,7 @@
def test_restore_frame(self):
frame = self.getframe(self.func_simple)
fs1 = FrameState(frame)
- frame.fastlocals_w[-1] = Variable()
+ frame.locals_stack_w[frame.nlocals-1] = Variable()
fs1.restoreframe(frame)
assert fs1 == FrameState(frame)
@@ -82,25 +82,26 @@
def test_getoutputargs(self):
frame = self.getframe(self.func_simple)
fs1 = FrameState(frame)
- frame.fastlocals_w[-1] = Variable()
+ frame.locals_stack_w[frame.nlocals-1] = Variable()
fs2 = FrameState(frame)
outputargs = fs1.getoutputargs(fs2)
# 'x' -> 'x' is a Variable
- # fastlocals_w[-1] -> fastlocals_w[-1] is Constant(None)
- assert outputargs == [frame.fastlocals_w[0], Constant(None)]
+ # locals_w[n-1] -> locals_w[n-1] is Constant(None)
+ assert outputargs == [frame.locals_stack_w[0], Constant(None)]
def test_union_different_constants(self):
frame = self.getframe(self.func_simple)
fs1 = FrameState(frame)
- frame.fastlocals_w[-1] = Constant(42)
+ frame.locals_stack_w[frame.nlocals-1] = Constant(42)
fs2 = FrameState(frame)
fs3 = fs1.union(fs2)
fs3.restoreframe(frame)
- assert isinstance(frame.fastlocals_w[-1], Variable) # generalized
+ assert isinstance(frame.locals_stack_w[frame.nlocals-1], Variable)
+ # ^^^ generalized
def test_union_spectag(self):
frame = self.getframe(self.func_simple)
fs1 = FrameState(frame)
- frame.fastlocals_w[-1] = Constant(SpecTag())
+ frame.locals_stack_w[frame.nlocals-1] = Constant(SpecTag())
fs2 = FrameState(frame)
assert fs1.union(fs2) is None # UnionError
More information about the pypy-commit
mailing list