[pypy-commit] lang-smalltalk storage: Refactored creation of context objects.
anton_gulenko
noreply at buildbot.pypy.org
Tue Aug 5 18:06:40 CEST 2014
Author: Anton Gulenko <anton.gulenko at googlemail.com>
Branch: storage
Changeset: r1010:d007ca0a7137
Date: 2014-08-05 17:54 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/d007ca0a7137/
Log: Refactored creation of context objects. Created build() methods,
clean up default constructor. This ensures that certain fields are
only initialized once.
diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -278,7 +278,7 @@
assert len(w_arguments) <= 7
w_method.setbytes([chr(131), chr(len(w_arguments) << 5 + 0), chr(124)]) #returnTopFromMethodBytecode
w_method.set_lookup_class_and_name(w_receiver.getclass(self.space), "Interpreter.perform")
- s_frame = MethodContextShadow(self.space, w_method=w_method, w_receiver=w_receiver)
+ s_frame = MethodContextShadow.build(self.space, w_method, w_receiver)
s_frame.push(w_receiver)
s_frame.push_all(list(w_arguments))
return s_frame
diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -1269,7 +1269,7 @@
def create_frame(self, space, receiver, arguments=[]):
from spyvm.storage_contexts import MethodContextShadow
assert len(arguments) == self.argsize
- return MethodContextShadow(space, w_method=self, w_receiver=receiver, arguments=arguments)
+ return MethodContextShadow.build(space, self, receiver, arguments)
# === Printing ===
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -1287,12 +1287,12 @@
# context of the receiver is used for the new BlockContext.
# Note that in our impl, MethodContext.w_home == self
w_context = assert_pointers(w_context)
- w_method_context = w_context.as_context_get_shadow(interp.space).s_home().w_self()
+ s_method_context = w_context.as_context_get_shadow(interp.space).s_home()
# The block bytecodes are stored inline: so we skip past the
- # byteodes to invoke this primitive to find them (hence +2)
+ # bytecodes to invoke this primitive to get to them.
initialip = s_frame.pc() + 2
- s_new_context = storage_contexts.BlockContextShadow(interp.space, None, 0, w_method_context, argcnt, initialip)
+ s_new_context = storage_contexts.BlockContextShadow.build(interp.space, s_method_context, argcnt, initialip)
return s_new_context.w_self()
@expose_primitive(VALUE, result_is_new_frame=True)
diff --git a/spyvm/storage_contexts.py b/spyvm/storage_contexts.py
--- a/spyvm/storage_contexts.py
+++ b/spyvm/storage_contexts.py
@@ -2,8 +2,11 @@
from spyvm import model, constants, error, wrapper
from spyvm.storage import AbstractRedirectingShadow
from rpython.tool.pairtype import extendabletype
-from rpython.rlib import rarithmetic, jit
-from rpython.rlib.debug import make_sure_not_resized
+from rpython.rlib import rarithmetic, jit, objectmodel
+
+ at objectmodel.specialize.call_location()
+def fresh_virtualizable(x):
+ return jit.hint(x, access_directly=True, fresh_virtualizable=True)
class ContextState(object):
def __init__(self, name):
@@ -33,11 +36,12 @@
# ______________________________________________________________________
# Initialization
- def __init__(self, space, w_self, size=0):
+ def __init__(self, space, w_self, size):
self._s_sender = None
AbstractRedirectingShadow.__init__(self, space, w_self, size)
self.instances_w = {}
self.state = InactiveContext
+ self.store_pc(0)
def copy_from(self, other_shadow):
# Some fields have to be initialized before the rest, to ensure correct initialization.
@@ -237,15 +241,15 @@
@jit.unroll_safe
def init_stack_and_temps(self):
+ self = fresh_virtualizable(self)
stacksize = self.stackend() - self.stackstart()
tempsize = self.tempsize()
temps_and_stack = [None] * (stacksize + tempsize)
self._temps_and_stack = temps_and_stack
- make_sure_not_resized(temps_and_stack)
for i in range(tempsize):
temps_and_stack[i] = self.space.w_nil
self._stack_ptr = rarithmetic.r_uint(tempsize) # we point after the last element
-
+
def stack_get(self, index0):
return self._temps_and_stack[index0]
@@ -369,24 +373,29 @@
repr_classname = "BlockContextShadow"
# === Initialization ===
-
- def __init__(self, space, w_self=None, size=0, w_home=None, argcnt=0, initialip=0):
- self = jit.hint(self, access_directly=True, fresh_virtualizable=True)
- creating_w_self = w_self is None
- if creating_w_self:
- s_home = w_home.as_methodcontext_get_shadow(space)
- contextsize = s_home.size() - s_home.tempsize()
- w_self = model.W_PointersObject(space, space.w_BlockContext, contextsize)
+
+ @staticmethod
+ def build(space, s_home, argcnt, pc):
+ size = s_home.size() - s_home.tempsize()
+ w_self = model.W_PointersObject(space, space.w_BlockContext, size)
+
+ ctx = BlockContextShadow(space, w_self, size)
+ ctx.store_expected_argument_count(argcnt)
+ ctx.store_w_home(s_home.w_self())
+ ctx.store_initialip(pc)
+ ctx.store_pc(pc)
+
+ w_self.store_shadow(ctx)
+ ctx.init_stack_and_temps()
+ return ctx
+
+ def __init__(self, space, w_self, size):
+ self = fresh_virtualizable(self)
ContextPartShadow.__init__(self, space, w_self, size)
- if creating_w_self:
- w_self.store_shadow(self)
- self.store_expected_argument_count(argcnt)
- self.store_initialip(initialip)
- if w_home:
- self.store_w_home(w_home)
- self.store_pc(initialip)
- self.init_stack_and_temps()
-
+ self._w_home = None
+ self._initialip = 0
+ self._eargc = 0
+
def fields_to_copy_first(self):
return [ constants.BLKCTX_HOME_INDEX ]
@@ -502,37 +511,43 @@
repr_classname = "MethodContextShadow"
# === Initialization ===
-
+
+ @staticmethod
+ def build(space, w_method, w_receiver, arguments=[], closure=None):
+ s_MethodContext = space.w_MethodContext.as_class_get_shadow(space)
+ size = w_method.compute_frame_size() + s_MethodContext.instsize()
+
+ ctx = MethodContextShadow(space, None, size)
+ ctx.store_w_receiver(w_receiver)
+ ctx.store_w_method(w_method)
+ ctx.closure = closure
+ ctx.init_stack_and_temps()
+ ctx.initialize_temps(arguments)
+ return ctx
+
+ def __init__(self, space, w_self, size):
+ self = fresh_virtualizable(self)
+ ContextPartShadow.__init__(self, space, w_self, size)
+ self.closure = None
+ self._w_method = None
+ self._w_receiver = None
+ self._is_BlockClosure_ensure = False
+
+ def fields_to_copy_first(self):
+ return [ constants.MTHDCTX_METHOD, constants.MTHDCTX_CLOSURE_OR_NIL ]
+
@jit.unroll_safe
- def __init__(self, space, w_self=None, size=0, w_method=None, w_receiver=None,
- arguments=[], closure=None, pc=0):
- self = jit.hint(self, access_directly=True, fresh_virtualizable=True)
- ContextPartShadow.__init__(self, space, w_self, size)
- self.store_w_receiver(w_receiver)
- self.store_pc(pc)
- self.closure = closure
-
- if w_method:
- self.store_w_method(w_method)
- # The summand is needed, because we calculate i.a. our stackdepth relative of the size of w_self.
- size = w_method.compute_frame_size() + self.space.w_MethodContext.as_class_get_shadow(self.space).instsize()
- self._w_self_size = size
- self.init_stack_and_temps()
- else:
- self._w_method = None
- self._is_BlockClosure_ensure = False
-
+ def initialize_temps(self, arguments):
argc = len(arguments)
for i0 in range(argc):
self.settemp(i0, arguments[i0])
-
+ closure = self.closure
if closure:
+ pc = closure.startpc() - self.w_method().bytecodeoffset() - 1
+ self.store_pc(pc)
for i0 in range(closure.size()):
self.settemp(i0+argc, closure.at0(i0))
-
- def fields_to_copy_first(self):
- return [ constants.MTHDCTX_METHOD, constants.MTHDCTX_CLOSURE_OR_NIL ]
-
+
# === Accessing object fields ===
def fetch(self, n0):
@@ -593,9 +608,8 @@
def store_w_method(self, w_method):
assert isinstance(w_method, model.W_CompiledMethod)
self._w_method = w_method
- if w_method:
- # Primitive 198 is used in BlockClosure >> ensure:
- self._is_BlockClosure_ensure = (w_method.primitive() == 198)
+ # Primitive 198 is a marker used in BlockClosure >> ensure:
+ self._is_BlockClosure_ensure = (w_method.primitive() == 198)
def w_receiver(self):
return self._w_receiver
@@ -627,14 +641,10 @@
if self._w_self is not None:
return self._w_self
else:
- s_MethodContext = self.space.w_MethodContext.as_class_get_shadow(self.space)
- size = self.size() - s_MethodContext.instsize()
space = self.space
- w_self = s_MethodContext.new(size)
- assert isinstance(w_self, model.W_PointersObject)
+ w_self = model.W_PointersObject(space, space.w_MethodContext, self.size())
w_self.store_shadow(self)
self._w_self = w_self
- self._w_self_size = w_self.size()
return w_self
# === Temporary variables ===
diff --git a/spyvm/test/jit.py b/spyvm/test/jit.py
--- a/spyvm/test/jit.py
+++ b/spyvm/test/jit.py
@@ -49,7 +49,7 @@
w_method.literals = literals
w_method.setbytes(bytes)
w_receiver = stack[0]
- s_frame = storage_contexts.MethodContextShadow(space, w_method=w_method, w_receiver=w_receiver)
+ s_frame = storage_contexts.MethodContextShadow.build(space, w_method, w_receiver)
w_frame = s_frame.w_self()
def interp_execute_frame():
return interp.interpret_toplevel(w_frame)
diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py
--- a/spyvm/test/test_primitives.py
+++ b/spyvm/test/test_primitives.py
@@ -31,7 +31,7 @@
def as_blockcontext_get_shadow(self, space):
if not isinstance(self.shadow, storage_contexts.BlockContextShadow):
- self.shadow = storage_contexts.BlockContextShadow(space, self)
+ self.shadow = storage_contexts.BlockContextShadow(space, self, self.size())
return self.shadow
IMAGENAME = "anImage.image"
diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py
--- a/spyvm/wrapper.py
+++ b/spyvm/wrapper.py
@@ -248,9 +248,7 @@
s_outerContext = w_outerContext.as_context_get_shadow(self.space)
w_method = s_outerContext.w_method()
w_receiver = s_outerContext.w_receiver()
- pc = self.startpc() - w_method.bytecodeoffset() - 1
- return storage_contexts.MethodContextShadow(self.space, w_method=w_method, w_receiver=w_receiver,
- arguments=arguments, closure=self, pc=pc)
+ return storage_contexts.MethodContextShadow.build(self.space, w_method, w_receiver, arguments, self)
def tempsize(self):
# We ignore the number of temps a block has, because the first
More information about the pypy-commit
mailing list