Author: Anton Gulenko <anton.gule...@googlemail.com> Branch: storage-context-state Changeset: r921:76c81645836d Date: 2014-07-18 15:29 +0200 http://bitbucket.org/pypy/lang-smalltalk/changeset/76c81645836d/
Log: Delaying SenderChainManipulation as much as possible. Added a 'state' field to Context objects, can be Inactive, Active or Dirty. Setting the sender of an Active context makes it Dirty. When a Dirty context is left, SenderChainManipulation will be raised, forcing all remaining contexts from the stack to the heap. diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -1,6 +1,6 @@ import py import os -from spyvm.shadow import ContextPartShadow, MethodContextShadow, BlockContextShadow, MethodNotFound +from spyvm.shadow import ContextPartShadow, MethodContextShadow, BlockContextShadow, MethodNotFound, ActiveContext, InactiveContext, DirtyContext from spyvm import model, constants, primitives, conftest, wrapper, objspace from spyvm.tool.bitmanipulation import splitter @@ -118,8 +118,10 @@ if self.is_tracing(): self.stack_depth += 1 if s_frame._s_sender is None and s_sender is not None: - s_frame.store_s_sender(s_sender, raise_error=False) + s_frame.store_s_sender(s_sender) # Now (continue to) execute the context bytecodes + assert s_frame.state is InactiveContext + s_frame.state = ActiveContext self.loop_bytecodes(s_frame, may_context_switch) except rstackovf.StackOverflow: rstackovf.check_stack_overflow() @@ -127,7 +129,11 @@ finally: if self.is_tracing(): self.stack_depth -= 1 - + dirty_frame = s_frame.state is DirtyContext + s_frame.state = InactiveContext + if dirty_frame: + raise SenderChainManipulation(s_frame) + def step(self, context): bytecode = context.fetch_next_bytecode() for entry in UNROLLING_BYTECODE_RANGES: @@ -755,16 +761,9 @@ association = wrapper.AssociationWrapper(self.space, w_association) self.push(association.value()) elif opType == 5: - # TODO - the following two special cases should not be necessary - try: - self.w_receiver().store(self.space, third, self.top()) - except SenderChainManipulation, e: - raise SenderChainManipulation(self) + self.w_receiver().store(self.space, third, self.top()) elif opType == 6: - try: - self.w_receiver().store(self.space, third, self.pop()) - except SenderChainManipulation, e: - raise SenderChainManipulation(self) + self.w_receiver().store(self.space, third, self.pop()) elif opType == 7: w_association = self.w_method().getliteral(third) association = wrapper.AssociationWrapper(self.space, w_association) diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -636,18 +636,29 @@ def size(self): return self._w_self_size +class ContextState(object): + def __init__(self, name): + self.name = name + def __str__(self): + return self.name + def __repr__(self): + return self.name +InactiveContext = ContextState("InactiveContext") +ActiveContext = ContextState("ActiveContext") +DirtyContext = ContextState("DirtyContext") + class ContextPartShadow(AbstractRedirectingShadow): __metaclass__ = extendabletype _attrs_ = ['_s_sender', '_pc', '_temps_and_stack', - '_stack_ptr', 'instances_w'] + '_stack_ptr', 'instances_w', 'state'] repr_classname = "ContextPartShadow" _virtualizable_ = [ '_s_sender', "_pc", "_temps_and_stack[*]", "_stack_ptr", - "_w_self", "_w_self_size" + "_w_self", "_w_self_size", 'state' ] # ______________________________________________________________________ @@ -657,13 +668,7 @@ self._s_sender = None AbstractRedirectingShadow.__init__(self, space, w_self, size) self.instances_w = {} - - def copy_field_from(self, n0, other_shadow): - from spyvm.interpreter import SenderChainManipulation - try: - AbstractRedirectingShadow.copy_field_from(self, n0, other_shadow) - except SenderChainManipulation, e: - assert e.s_new_context == self + self.state = InactiveContext def copy_from(self, other_shadow): # Some fields have to be initialized before the rest, to ensure correct initialization. @@ -705,7 +710,7 @@ if n0 == constants.CTXPART_SENDER_INDEX: assert isinstance(w_value, model.W_PointersObject) if w_value.is_nil(self.space): - self.store_s_sender(None, raise_error=False) + self.store_s_sender(None) else: self.store_s_sender(w_value.as_context_get_shadow(self.space)) return @@ -725,12 +730,12 @@ # === Sender === - def store_s_sender(self, s_sender, raise_error=True): + def store_s_sender(self, s_sender): if s_sender is not self._s_sender: self._s_sender = s_sender - if raise_error: - from spyvm.interpreter import SenderChainManipulation - raise SenderChainManipulation(self) + # If new sender is None, we are just being marked as returned. + if s_sender is not None and self.state is ActiveContext: + self.state = DirtyContext def w_sender(self): sender = self.s_sender() @@ -822,7 +827,7 @@ def mark_returned(self): self.store_pc(-1) - self.store_s_sender(None, raise_error=False) + self.store_s_sender(None) def is_returned(self): return self.pc() == -1 and self.w_sender().is_nil(self.space) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit