[pypy-commit] lang-smalltalk vref: commit first translating version where all senders are vrefs

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


Author: Tim Felgentreff <timfelgentreff at gmail.com>
Branch: vref
Changeset: r848:a0a057d2e444
Date: 2014-07-02 13:05 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/a0a057d2e444/

Log:	commit first translating version where all senders are vrefs

diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -86,6 +86,7 @@
                 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:
@@ -98,9 +99,11 @@
             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):
+        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)
diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -203,7 +203,7 @@
         return r_uint(val)
 
 
-    @jit.elidable
+    # @jit.elidable
     def as_repr_string(self):
         return "W_SmallInteger(%d)" % self.value
 
@@ -457,7 +457,7 @@
                 name = self.s_class.name
             return "a %s" % (name or '?',)
 
-    @jit.elidable
+    # @jit.elidable
     def as_repr_string(self):
         return self.as_embellished_string("W_O /w Class", "")
 
@@ -491,7 +491,7 @@
 class W_AbstractPointersObject(W_AbstractObjectWithClassReference):
     """Common object."""
     _attrs_ = ['shadow']
-    
+
     def changed(self):
         # This is invoked when an instance-variable is changed.
         # Kept here in case it might be usefull in the future.
@@ -550,7 +550,7 @@
 
     def _get_shadow(self):
         return self.shadow
-    
+
     @objectmodel.specialize.arg(2)
     def attach_shadow_of_class(self, space, TheClass):
         shadow = TheClass(space, self)
@@ -632,7 +632,7 @@
         w_other.changed()
         return True
 
-    @jit.elidable
+    # @jit.elidable
     def as_repr_string(self):
         return W_AbstractObjectWithClassReference.as_embellished_string(self,
                                 className='W_PointersObject',
@@ -651,11 +651,11 @@
         self.fieldtypes = fieldtypes_of_length(self.s_class, size)
         for i in range(size): # do it by hand for the JIT's sake
             vars[i] = w_nil
-    
+
     def set_vars(self, new_vars):
         self._vars = new_vars
         make_sure_not_resized(self._vars)
-    
+
     def fillin(self, space, g_self):
         W_AbstractPointersObject.fillin(self, space, g_self)
         from spyvm.fieldtypes import fieldtypes_of
@@ -1013,7 +1013,7 @@
     _immutable_fields_ = ['_realsize', 'display', '_depth', '_real_depth_buffer']
 
     pixelbuffer = None
-    
+
     @staticmethod
     def create(space, w_class, size, depth, display):
         if depth < 8:
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(s_frame)
+        s_block_ctx.store_s_sender(virtual=jit.virtual_ref(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
@@ -34,7 +34,7 @@
     import_from_mixin(version.VersionMixin)
 
     version = None
-    
+
     def __init__(self, space, w_self):
         AbstractShadow.__init__(self, space, w_self)
         self.changed()
@@ -78,7 +78,7 @@
 
     _attrs_ = ["name", "_instance_size", "instance_varsized", "instance_kind",
                 "_s_methoddict", "_s_superclass", "subclass_s"]
-    
+
     def __init__(self, space, w_self):
         # fields added here should also be in objspace.py:56ff, 300ff
         self.name = ''
@@ -449,17 +449,19 @@
 class ContextPartShadow(AbstractRedirectingShadow):
 
     __metaclass__ = extendabletype
-    _attrs_ = ['_s_sender', '_pc', '_temps_and_stack',
+    _attrs_ = ['_direct_s_sender', '_virtual_s_sender', '_pc', '_temps_and_stack',
             '_stack_ptr', 'instances_w']
 
     _virtualizable_ = [
-        "_s_sender", "_pc",
+        "_virtual_s_sender", "_direct_s_sender",
+        "_pc",
         "_temps_and_stack[*]", "_stack_ptr",
         "_w_self", "_w_self_size"
     ]
 
     def __init__(self, space, w_self):
-        self._s_sender = None
+        self._virtual_s_sender = jit.vref_None
+        self._direct_s_sender = None
         AbstractRedirectingShadow.__init__(self, space, w_self)
         self.instances_w = {}
 
@@ -541,25 +543,35 @@
         " Return self of the method, or the method that contains the block "
         return self.s_home().w_receiver()
 
-    def store_s_sender(self, s_sender):
-        assert s_sender is None or isinstance(s_sender, ContextPartShadow)
-        self._s_sender = s_sender
-        raise error.SenderChainManipulation(self)
+    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:
+            raise error.SenderChainManipulation(self)
 
     def store_w_sender(self, w_sender):
         assert isinstance(w_sender, model.W_PointersObject)
         if w_sender.is_same_object(self.space.w_nil):
-            self._s_sender = None
+            self.store_s_sender(raiseError=False)
         else:
-            self.store_s_sender(w_sender.as_context_get_shadow(self.space))
+            self.store_s_sender(direct=w_sender.as_context_get_shadow(self.space))
 
     def w_sender(self):
-        if self._s_sender is None:
+        sender = self.s_sender()
+        if sender is None:
             return self.space.w_nil
-        return self._s_sender.w_self()
+        return sender.w_self()
 
     def s_sender(self):
-        return self._s_sender
+        if self._direct_s_sender:
+            return self._direct_s_sender
+        else:
+            return self._virtual_s_sender()
 
     def store_unwrap_pc(self, w_pc):
         if w_pc.is_same_object(self.space.w_nil):
@@ -592,10 +604,16 @@
     def mark_returned(self):
         self.store_pc(-1)
         try:
-            self.store_s_sender(None)
+            self.store_s_sender()
         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
 
@@ -879,7 +897,7 @@
         s_new_context.store_w_method(s_method.w_self())
         if s_sender:
             try:
-                s_new_context.store_s_sender(s_sender)
+                s_new_context.store_s_sender(virtual=jit.virtual_ref(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