[pypy-commit] lang-smalltalk default: added may_context_switch to stack frame to enable primitives 221, 222: valueNoContextSwitch(:)

lwassermann noreply at buildbot.pypy.org
Fri May 3 21:59:01 CEST 2013


Author: Lars Wassermann <lars.wassermann at gmail.com>
Branch: 
Changeset: r372:854e627f1b25
Date: 2013-05-03 20:09 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/854e627f1b25/

Log:	added may_context_switch to stack frame to enable primitives 221,
	222: valueNoContextSwitch(:)

diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -83,9 +83,9 @@
                     print "====== Switch from: %s to: %s ======" % (s_new_context.short_str(0), p.s_new_context.short_str(0))
                 s_new_context = p.s_new_context
 
-    def c_loop(self, s_context):
+    def c_loop(self, s_context, may_context_switch=True):
         old_pc = 0
-        if not jit.we_are_jitted():
+        if not jit.we_are_jitted() and may_context_switch:
             self.quick_check_for_interrupt(s_context)
         while True:
             pc = s_context.pc()
@@ -118,7 +118,7 @@
         decr_by = int(trace_length // 100)
         return max(decr_by, 1)
 
-    def stack_frame(self, s_new_frame):
+    def stack_frame(self, s_new_frame, may_context_switch=True):
         if not self._loop:
             return s_new_frame # this test is done to not loop in test,
                                # but rather step just once where wanted
@@ -127,7 +127,7 @@
 
         self.remaining_stack_depth -= 1
         try:
-            retval = self.c_loop(s_new_frame)
+            retval = self.c_loop(s_new_frame, may_context_switch)
         finally:
             self.remaining_stack_depth += 1
         return retval
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -51,7 +51,8 @@
 pos_32bit_int = object()
 
 def expose_primitive(code, unwrap_spec=None, no_result=False,
-                    result_is_new_frame=False, clean_stack=True, compiled_method=False):
+                    result_is_new_frame=False, may_context_switch=True,
+                    clean_stack=True, compiled_method=False):
     # heuristics to give it a nice name
     name = None
     for key, value in globals().iteritems():
@@ -68,7 +69,7 @@
 
         wrapped = wrap_primitive(
             unwrap_spec=unwrap_spec, no_result=no_result,
-            result_is_new_frame=result_is_new_frame,
+            result_is_new_frame=result_is_new_frame, may_context_switch=may_context_switch,
             clean_stack=clean_stack, compiled_method=compiled_method
         )(func)
         wrapped.func_name = "wrap_prim_" + name
@@ -79,12 +80,14 @@
 
 
 def wrap_primitive(unwrap_spec=None, no_result=False,
-                   result_is_new_frame=False, clean_stack=True,
-                   compiled_method=False):
+                   result_is_new_frame=False, may_context_switch=True,
+                   clean_stack=True, compiled_method=False):
     # some serious magic, don't look
     from rpython.rlib.unroll import unrolling_iterable
 
     assert not (no_result and result_is_new_frame)
+    assert may_context_switch or result_is_new_frame
+
     # Because methods always have a receiver, an unwrap_spec of [] is a bug
     assert unwrap_spec is None or unwrap_spec
 
@@ -96,7 +99,7 @@
                 else:
                     w_result = func(interp, s_frame, argument_count_m1)
                 if result_is_new_frame:
-                    return interp.stack_frame(w_result)
+                    return interp.stack_frame(w_result, may_context_switch)
                 if not no_result:
                     assert w_result is not None
                     s_frame.push(w_result)
@@ -144,7 +147,7 @@
                     if clean_stack:
                         # happens only if no exception occurs!
                         s_frame.pop_n(len_unwrap_spec)
-                    return interp.stack_frame(s_new_frame)
+                    return interp.stack_frame(s_new_frame, may_context_switch)
                 else:
                     w_result = func(interp, s_frame, *args)
                     # After calling primitive, reload context-shadow in case it
@@ -1278,8 +1281,7 @@
     return w_context
 
 
-def activateClosure(interp, s_frame, w_block, args_w, mayContextSwitch=True):
-    # XXX mayContextSwitch is ignored
+def activateClosure(interp, s_frame, w_block, args_w):
     space = interp.space
     if not w_block.getclass(space).is_same_object(
             space.w_BlockClosure):
@@ -1327,13 +1329,13 @@
 def func(interp, s_frame, w_block_closure, args_w):
     return activateClosure(interp, s_frame, w_block_closure, args_w)
 
- at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH, unwrap_spec=[object], result_is_new_frame=True)
+ at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH, unwrap_spec=[object], result_is_new_frame=True, may_context_switch=False)
 def func(interp, s_frame, w_block_closure):
-    return activateClosure(interp, s_frame, w_block_closure, [], mayContextSwitch=False)
+    return activateClosure(interp, s_frame, w_block_closure, [])
 
- at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH_, unwrap_spec=[object, object], result_is_new_frame=True)
+ at expose_primitive(CLOSURE_VALUE_NO_CONTEXT_SWITCH_, unwrap_spec=[object, object], result_is_new_frame=True, may_context_switch=False)
 def func(interp, s_frame, w_block_closure, w_a0):
-    return activateClosure(interp, s_frame, w_block_closure, [w_a0], mayContextSwitch=False)
+    return activateClosure(interp, s_frame, w_block_closure, [w_a0])
 
 # ___________________________________________________________________________
 # Override the default primitive to give latitude to the VM in context management.
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
@@ -1003,7 +1003,7 @@
         assert False
 
 class StackTestInterpreter(interpreter.Interpreter):
-    def stack_frame(self, w_frame):
+    def stack_frame(self, w_frame, may_interrupt=True):
         import sys
         stack_depth = self.max_stack_depth - self.remaining_stack_depth
         for i in range(stack_depth + 1):
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
@@ -261,7 +261,7 @@
 
         with py.test.raises(interpreter.ProcessSwitch):
             semaphore.wait(currentcontext)
-            
+
         assert wrapper.scheduler(space).active_process() is process._w_self
         semaphore.signal(currentcontext)
         assert wrapper.scheduler(space).active_process() is process._w_self


More information about the pypy-commit mailing list