[pypy-commit] lang-smalltalk default: (tfel, tpape) store the last context when suspending, and raise to the trampoline when switching contexts
timfel
noreply at buildbot.pypy.org
Fri Mar 8 13:43:42 CET 2013
Author: Tim Felgentreff <timfelgentreff at gmail.com>
Branch:
Changeset: r143:683631ae4a75
Date: 2013-03-08 13:11 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/683631ae4a75/
Log: (tfel, tpape) store the last context when suspending, and raise to
the trampoline when switching contexts
diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -70,6 +70,9 @@
s_new_context.mark_returned()
s_new_context = s_sender
s_new_context.push(nlr.value)
+ except ProcessSwitch, p:
+ self.remaining_stack_depth = self.max_stack_depth
+ s_new_context = p.s_new_context
def c_loop(self, s_context):
# padding = ' ' * (self.max_stack_depth - self.remaining_stack_depth)
@@ -146,11 +149,17 @@
class StackOverflow(Exception):
def __init__(self, s_top_context):
self.s_context = s_top_context
+
class Return(Exception):
def __init__(self, object, s_context):
self.value = object
self.s_target_context = s_context
+class ProcessSwitch(Exception):
+ def __init__(self, s_context):
+ self.s_new_context = s_context
+
+
def make_call_primitive_bytecode(primitive, selector, argcount):
def callPrimitive(self, interp, current_bytecode):
# WARNING: this is used for bytecodes for which it is safe to
diff --git a/spyvm/test/test_wrapper.py b/spyvm/test/test_wrapper.py
--- a/spyvm/test/test_wrapper.py
+++ b/spyvm/test/test_wrapper.py
@@ -144,11 +144,13 @@
def test_suspend_active(self):
process, old_process = self.make_processes(4, 2, space.w_false)
- old_process.suspend(space.w_true)
+ w_fake_context = model.W_Object()
+ old_process.suspend(w_fake_context)
process_list = wrapper.scheduler(space).get_process_list(old_process.priority())
assert process_list.first_link() is process_list.last_link()
assert process_list.first_link() is space.w_nil
assert old_process.my_list() is space.w_nil
+ assert old_process.suspended_context() is w_fake_context
assert wrapper.scheduler(space).active_process() is process._w_self
def new_process_consistency(self, process, old_process, w_active_context,
@@ -181,7 +183,7 @@
def test_activate(self):
process, old_process = self.make_processes(4, 2, space.w_false)
- w_frame = process.activate(space.w_true)
+ w_frame = process.activate()
self.new_process_consistency(process, old_process, w_frame,
space.w_true, space.w_false)
diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py
--- a/spyvm/wrapper.py
+++ b/spyvm/wrapper.py
@@ -71,13 +71,15 @@
process_list = sched.get_process_list(priority)
process_list.add_process(self._w_self)
- def activate(self, w_current_frame):
+ def activate(self):
+ from spyvm.interpreter import ProcessSwitch
+ assert not self.is_active_process()
sched = scheduler(self.space)
sched.store_active_process(self._w_self)
w_frame = self.suspended_context()
self.store_suspended_context(self.space.w_nil)
self.store_my_list(self.space.w_nil)
- return w_frame
+ raise ProcessSwitch(w_frame.as_context_get_shadow(self.space))
def deactivate(self, w_current_frame):
self.put_to_sleep()
@@ -90,7 +92,7 @@
priority = self.priority()
if priority > active_priority:
active_process.deactivate(w_current_frame)
- return self.activate(w_current_frame)
+ return self.activate()
else:
self.put_to_sleep()
return w_current_frame
@@ -102,7 +104,8 @@
if self.is_active_process():
assert self.my_list().is_same_object(self.space.w_nil)
w_process = scheduler(self.space).highest_priority_process()
- return ProcessWrapper(self.space, w_process).activate(w_current_frame)
+ self.store_suspended_context(w_current_frame)
+ return ProcessWrapper(self.space, w_process).activate()
else:
process_list = ProcessListWrapper(self.space, self.my_list())
process_list.remove(self._w_self)
More information about the pypy-commit
mailing list