[pypy-commit] lang-smalltalk storage: extra exception for SenderManipulation, also don't throw if sender unchanged, also make interp.trace immutable

timfel noreply at buildbot.pypy.org
Fri Jul 11 18:25:20 CEST 2014


Author: Tim Felgentreff <timfelgentreff at gmail.com>
Branch: storage
Changeset: r895:9cb31b513e7d
Date: 2014-07-11 18:25 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/9cb31b513e7d/

Log:	extra exception for SenderManipulation, also don't throw if sender
	unchanged, also make interp.trace immutable

diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -25,7 +25,7 @@
 class Interpreter(object):
     _immutable_fields_ = ["space", "image", "image_name",
                           "interrupt_counter_size",
-                          "startup_time", "evented", "interrupts"]
+                          "startup_time", "trace", "evented", "interrupts"]
 
     jit_driver = jit.JitDriver(
         greens=['pc', 'self', 'method'],
@@ -57,6 +57,7 @@
         self.interrupt_check_counter = self.interrupt_counter_size
         self.next_wakeup_tick = 0
         self.trace = trace
+        self.current_stack_depth = 0
         self.trace_proxy = False
 
     def loop(self, w_active_context):
@@ -69,7 +70,7 @@
                 raise Exception("loop_bytecodes left without raising...")
             except StackOverflow, e:
                 if self.trace:
-                    print "====== StackOverflow, contexts forced to heap at: %s" % e.s_new_context.short_str()
+                    print "====== StackOverflow, contexts forced to heap at: \n%s" % e.s_new_context.print_stack()
                 s_new_context = e.s_new_context
             except Return, nlr:
                 assert nlr.s_target_context or nlr.is_local
@@ -80,6 +81,10 @@
                         s_new_context._activate_unwind_context(self)
                         s_new_context = s_sender
                 s_new_context.push(nlr.value)
+            except SenderManipulation, e:
+                if self.trace:
+                    print "====== SenderManipulation out of process, all contexts forced to heap!!!\n%s" % e.s_new_context.print_stack()
+                s_new_context = e.s_new_context
             except ProcessSwitch, p:
                 assert not self.space.suppress_process_switch[0], "ProcessSwitch should be disabled..."
                 if self.trace:
@@ -223,7 +228,7 @@
         return s_frame
 
     def padding(self, symbol=' '):
-        return symbol
+        return symbol * self.current_stack_depth
 
 class ReturnFromTopLevel(Exception):
     _attrs_ = ["object"]
@@ -244,6 +249,10 @@
     def __init__(self, s_new_context):
         self.s_new_context = s_new_context
 
+class SenderManipulation(ContextSwitchException):
+    """This forces frames to the heap down to where the sender was
+    manipulated."""
+
 class StackOverflow(ContextSwitchException):
     """This causes the current jit-loop to be left.
     This is an experimental mechanism to avoid stack-overflow errors
@@ -570,6 +579,7 @@
 
         # ######################################################################
         if interp.trace:
+            interp.current_stack_depth += 1
             print interp.padding() + s_frame.short_str()
 
         return interp.stack_frame(s_frame, self)
@@ -723,12 +733,18 @@
             try:
                 self.w_receiver().store(self.space, third, self.top())
             except error.SenderChainManipulation, e:
-                raise StackOverflow(self)
+                # TODO: shouldn't need to throw, simply mark the
+                # receiver as dirty and handle it when we return out
+                # of that context
+                raise SenderManipulation(self)
         elif opType == 6:
             try:
                 self.w_receiver().store(self.space, third, self.pop())
             except error.SenderChainManipulation, e:
-                raise StackOverflow(self)
+                # TODO: shouldn't need to throw, simply mark the
+                # receiver as dirty and handle it when we return out
+                # of that context
+                raise SenderManipulation(self)
         elif opType == 7:
             w_association = self.w_method().getliteral(third)
             association = wrapper.AssociationWrapper(self.space, w_association)
diff --git a/spyvm/plugins/vmdebugging.py b/spyvm/plugins/vmdebugging.py
--- a/spyvm/plugins/vmdebugging.py
+++ b/spyvm/plugins/vmdebugging.py
@@ -8,15 +8,15 @@
 def stop_ui_process():
     DebuggingPlugin.userdata['stop_ui'] = True
 
- at DebuggingPlugin.expose_primitive(unwrap_spec=[object])
-def trace(interp, s_frame, w_rcvr):
-    interp.trace = True
-    return w_rcvr
+# @DebuggingPlugin.expose_primitive(unwrap_spec=[object])
+# def trace(interp, s_frame, w_rcvr):
+#     interp.trace = True
+#     return w_rcvr
 
- at DebuggingPlugin.expose_primitive(unwrap_spec=[object])
-def untrace(interp, s_frame, w_rcvr):
-    interp.trace = False
-    return w_rcvr
+# @DebuggingPlugin.expose_primitive(unwrap_spec=[object])
+# def untrace(interp, s_frame, w_rcvr):
+#     interp.trace = False
+#     return w_rcvr
 
 @DebuggingPlugin.expose_primitive(unwrap_spec=[object])
 def trace_proxy(interp, s_frame, w_rcvr):
diff --git a/spyvm/shadow.py b/spyvm/shadow.py
--- a/spyvm/shadow.py
+++ b/spyvm/shadow.py
@@ -693,9 +693,11 @@
     # === Sender ===
 
     def store_s_sender(self, s_sender, raise_error=True):
-        self._s_sender = s_sender
-        if raise_error:
-            raise error.SenderChainManipulation(self)
+        if self._s_sender is not s_sender:
+            # it happens
+            self._s_sender = s_sender
+            if raise_error:
+                raise error.SenderChainManipulation(self)
 
     def w_sender(self):
         sender = self.s_sender()


More information about the pypy-commit mailing list