[pypy-commit] lang-smalltalk storage: Moved SenderChainManipulation exception to interpreter.py, as subclass of ContextSwitchException.
anton_gulenko
noreply at buildbot.pypy.org
Fri Jul 18 14:09:00 CEST 2014
Author: Anton Gulenko <anton.gulenko at googlemail.com>
Branch: storage
Changeset: r917:25b23527e013
Date: 2014-07-18 13:34 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/25b23527e013/
Log: Moved SenderChainManipulation exception to interpreter.py, as
subclass of ContextSwitchException. Catching SenderChainManipulation
explicitely in toplevel loop. Added "sender is not new_sender"
condition to raising SenderChainManipulation. Fixed test.
diff --git a/spyvm/error.py b/spyvm/error.py
--- a/spyvm/error.py
+++ b/spyvm/error.py
@@ -30,7 +30,3 @@
_attrs_ = ["msg"]
def __init__(self, msg):
self.msg = msg
-
-class SenderChainManipulation(Exception):
- def __init__(self, manipulated_context):
- self.s_context = manipulated_context
diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -70,6 +70,10 @@
if self.is_tracing():
print "====== StackOverflow, contexts forced to heap at: %s" % e.s_new_context.short_str()
s_new_context = e.s_new_context
+ except SenderChainManipulation, e:
+ if self.is_tracing():
+ print "====== SenderChainManipulation, contexts forced to heap at: %s" % e.s_new_context.short_str()
+ s_new_context = e.s_new_context
except Return, nlr:
assert nlr.s_target_context or nlr.is_local
s_new_context = s_sender
@@ -198,13 +202,13 @@
def interpret_toplevel(self, w_frame):
try:
+ self.interrupt_check_counter = self.interrupt_counter_size
self.loop(w_frame)
except ReturnFromTopLevel, e:
return e.object
def perform(self, w_receiver, selector="", w_selector=None, w_arguments=[]):
s_frame = self.create_toplevel_context(w_receiver, selector, w_selector, w_arguments)
- self.interrupt_check_counter = self.interrupt_counter_size
return self.interpret_toplevel(s_frame.w_self())
def create_toplevel_context(self, w_receiver, selector="", w_selector=None, w_arguments=[]):
@@ -276,13 +280,18 @@
self.s_new_context = s_new_context
class StackOverflow(ContextSwitchException):
- """This causes the current jit-loop to be left, thus avoiding stack overflows.
+ """This causes the current jit-loop to be left, dumping all virtualized objects to the heap.
This breaks performance, so it should rarely happen.
In case of severe performance problems, execute with -t and check if this occurrs."""
class ProcessSwitch(ContextSwitchException):
- """This causes the interpreter to switch the executed context."""
+ """This causes the interpreter to switch the executed context.
+ Triggered when switching the process."""
+class SenderChainManipulation(ContextSwitchException):
+ """Manipulation of the sender chain can invalidate the jitted C stack.
+ We have to dump all virtual objects and rebuild the stack.
+ We try to raise this as rarely as possible and as late as possible."""
import rpython.rlib.unroll
if hasattr(unroll, "unrolling_zero"):
@@ -753,15 +762,16 @@
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 error.SenderChainManipulation, e:
- raise StackOverflow(self)
+ except SenderChainManipulation, e:
+ raise SenderChainManipulation(self)
elif opType == 6:
try:
self.w_receiver().store(self.space, third, self.pop())
- except error.SenderChainManipulation, e:
- raise StackOverflow(self)
+ except SenderChainManipulation, e:
+ raise SenderChainManipulation(self)
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
@@ -659,10 +659,11 @@
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 error.SenderChainManipulation, e:
- assert e.s_context == self
+ except SenderChainManipulation, e:
+ assert e.s_new_context == self
def copy_from(self, other_shadow):
# Some fields have to be initialized before the rest, to ensure correct initialization.
@@ -725,9 +726,11 @@
# === Sender ===
def store_s_sender(self, s_sender, raise_error=True):
- self._s_sender = s_sender
- if raise_error:
- raise error.SenderChainManipulation(self)
+ if s_sender is not self._s_sender:
+ self._s_sender = s_sender
+ if raise_error:
+ from spyvm.interpreter import SenderChainManipulation
+ raise SenderChainManipulation(self)
def w_sender(self):
sender = self.s_sender()
diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py
--- a/spyvm/test/test_interpreter.py
+++ b/spyvm/test/test_interpreter.py
@@ -983,4 +983,4 @@
w_frame, s_frame = new_frame(bytes)
s_frame.store_w_receiver(w_frame)
s_frame.push(w_frame)
- py.test.raises(interpreter.StackOverflow, step_in_interp, s_frame)
+ py.test.raises(interpreter.SenderChainManipulation, step_in_interp, s_frame)
More information about the pypy-commit
mailing list