[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