[pypy-commit] lang-smalltalk vref: virtualize sender only around c_loop

timfel noreply at buildbot.pypy.org
Wed Jul 2 17:52:53 CEST 2014


Author: Tim Felgentreff <timfelgentreff at gmail.com>
Branch: vref
Changeset: r849:2f3aaab262c5
Date: 2014-07-02 17:48 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/2f3aaab262c5/

Log:	virtualize sender only around c_loop

diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -86,7 +86,6 @@
                 s_new_context = self.c_loop(s_new_context)
             except StackOverflow, e:
                 s_new_context = e.s_context
-                s_new_context.unvirtualize_sender()
             except Return, nlr:
                 s_new_context = s_sender
                 while s_new_context is not nlr.s_target_context:
@@ -99,15 +98,28 @@
             except ProcessSwitch, p:
                 if self.trace:
                     print "====== Switch from: %s to: %s ======" % (s_new_context.short_str(), p.s_new_context.short_str())
-                s_new_context.unvirtualize_sender()
                 s_new_context = p.s_new_context
 
     def c_loop(self, s_context, may_context_switch=True):
+        s_sender = s_context.s_sender()
+        s_sender_ref = jit.vref_None
+        if s_sender:
+            s_sender_ref = jit.virtual_ref(s_sender)
+            s_context.store_s_sender(virtual=s_sender_ref, raiseError=False)
+        try:
+            self._c_loop_virtual(s_context, may_context_switch=may_context_switch)
+        finally:
+            if s_sender:
+                jit.virtual_ref_finish(s_sender_ref, s_sender)
+                s_context.restore_s_sender(s_sender)
+
+    def _c_loop_virtual(self, s_context, may_context_switch=True):
         assert isinstance(s_context, ContextPartShadow)
         old_pc = 0
         if not jit.we_are_jitted() and may_context_switch:
             self.quick_check_for_interrupt(s_context)
         method = s_context.s_method()
+
         while True:
             pc = s_context.pc()
             if pc < old_pc:
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -1315,7 +1315,7 @@
     # Set some fields
     s_block_ctx.store_pc(s_block_ctx.initialip())
     try:
-        s_block_ctx.store_s_sender(virtual=jit.virtual_ref(s_frame))
+        s_block_ctx.store_s_sender(direct=s_frame)
     except SenderChainManipulation, e:
         assert e.s_context == s_block_ctx
     return s_block_ctx
diff --git a/spyvm/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -543,12 +543,14 @@
         " Return self of the method, or the method that contains the block "
         return self.s_home().w_receiver()
 
+    def restore_s_sender(self, s_direct):
+        if self._virtual_s_sender is not jit.vref_None:
+            # virtual sender wasn't already cleared by e.g. mark_returned
+            self._virtual_s_sender = jit.vref_None
+            self._direct_s_sender = s_direct
+
     def store_s_sender(self, direct=None, virtual=jit.vref_None, raiseError=True):
         assert direct is None or virtual is jit.vref_None # can only set one or the other
-        if self._virtual_s_sender is not jit.vref_None and virtual is jit.vref_None:
-            # if we have a vref but we're removing it...
-            sender = self._virtual_s_sender()
-            jit.virtual_ref_finish(self._virtual_s_sender, sender)
         self._virtual_s_sender = virtual
         self._direct_s_sender = direct
         if raiseError:
@@ -608,12 +610,6 @@
         except error.SenderChainManipulation, e:
             assert self == e.s_context
 
-    def unvirtualize_sender(self):
-        sender = self.s_sender()
-        self.store_s_sender(direct=sender, raiseError=False)
-        if sender:
-            sender.unvirtualize_sender()
-
     def is_returned(self):
         return self.pc() == -1 and self.w_sender is self.space.w_nil
 
@@ -897,7 +893,7 @@
         s_new_context.store_w_method(s_method.w_self())
         if s_sender:
             try:
-                s_new_context.store_s_sender(virtual=jit.virtual_ref(s_sender))
+                s_new_context.store_s_sender(direct=s_sender)
             except error.SenderChainManipulation, e:
                 assert s_new_context == e.s_context
         s_new_context.store_w_receiver(w_receiver)


More information about the pypy-commit mailing list