Author: Anton Gulenko <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit