Author: Anton Gulenko <anton.gule...@googlemail.com> Branch: storage Changeset: r880:4934d77ae183 Date: 2014-07-10 12:38 +0200 http://bitbucket.org/pypy/lang-smalltalk/changeset/4934d77ae183/
Log: Removed virtual reference of sender. Was causing performance problems. Going to add this refactoring to the vref branch. diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py --- a/spyvm/interpreter.py +++ b/spyvm/interpreter.py @@ -67,10 +67,7 @@ s_new_context = w_active_context.as_context_get_shadow(self.space) while True: assert self.current_stack_depth == 0 - # Need to save s_sender, loop_bytecodes will nil this on return - # Virtual references are not allowed here, and neither are "fresh" contexts (except for the toplevel one). - assert s_new_context.virtual_sender is jit.vref_None - s_sender = s_new_context.direct_sender + s_sender = s_new_context.s_sender() try: self.loop_bytecodes(s_new_context) raise Exception("loop_bytecodes left without raising...") @@ -81,7 +78,7 @@ except Return, nlr: s_new_context = s_sender while s_new_context is not nlr.s_target_context: - s_sender = s_new_context.direct_sender + s_sender = s_new_context.s_sender() s_new_context._activate_unwind_context(self) s_new_context = s_sender s_new_context.push(nlr.value) @@ -122,27 +119,19 @@ # This is a wrapper around loop_bytecodes that cleanly enters/leaves the frame # and handles the stack overflow protection mechanism. def stack_frame(self, s_frame, s_sender, may_context_switch=True): - assert s_frame.virtual_sender is jit.vref_None try: - # Enter the context - store a virtual reference back to the sender - # Non-fresh contexts can happen, e.g. when activating a stored BlockContext. - # The same frame object must not pass through here recursively! - if s_frame.is_fresh() and s_sender is not None: - s_frame.virtual_sender = jit.virtual_ref(s_sender) - + if s_frame._s_sender is None and s_sender is not None: + s_frame.store_s_sender(s_sender, raise_error=False) + self.current_stack_depth += 1 if self.max_stack_depth > 0: if self.current_stack_depth >= self.max_stack_depth: raise StackOverflow(s_frame) - + # Now (continue to) execute the context bytecodes self.loop_bytecodes(s_frame, may_context_switch) finally: self.current_stack_depth -= 1 - # Cleanly leave the context. This will finish the virtual sender-reference, if - # it is still there, which can happen in case of ProcessSwitch or StackOverflow; - # in case of a Return, this will already be handled while unwinding the stack. - s_frame.finish_virtual_sender(s_sender) def step(self, context): bytecode = context.fetch_next_bytecode() diff --git a/spyvm/shadow.py b/spyvm/shadow.py --- a/spyvm/shadow.py +++ b/spyvm/shadow.py @@ -607,13 +607,13 @@ class ContextPartShadow(AbstractRedirectingShadow): __metaclass__ = extendabletype - _attrs_ = ['direct_sender', 'virtual_sender', + _attrs_ = ['_s_sender', '_pc', '_temps_and_stack', '_stack_ptr', 'instances_w'] repr_classname = "ContextPartShadow" _virtualizable_ = [ - 'direct_sender', 'virtual_sender', + '_s_sender', "_pc", "_temps_and_stack[*]", "_stack_ptr", "_w_self", "_w_self_size" ] @@ -622,8 +622,7 @@ # Initialization def __init__(self, space, w_self): - self.direct_sender = None - self.virtual_sender = jit.vref_None + self._s_sender = None AbstractRedirectingShadow.__init__(self, space, w_self) self.instances_w = {} @@ -692,27 +691,9 @@ raise error.WrapperException("Index in context out of bounds") # === Sender === - # There are two fields for the sender (virtual and direct). Only one of them is can be set at a time. - # As long as the frame object is virtualized, using the virtual reference should increase performance. - # As soon as a frame object is forced to the heap, the direct reference must be used. - - def is_fresh(self): - return self.direct_sender is None and self.virtual_sender is jit.vref_None - - def finish_virtual_sender(self, s_sender): - if self.virtual_sender is not jit.vref_None: - if self.pc() != -1: - # stack is unrolling, but this frame was not - # marked_returned: it is an escaped frame - sender = self.virtual_sender() - self.direct_sender = sender - jit.virtual_ref_finish(self.virtual_sender, s_sender) - self.virtual_sender = jit.vref_None def store_s_sender(self, s_sender, raise_error=True): - # If we have a virtual back reference, we must finish it before storing the direct reference. - # self.finish_virtual_sender(save_direct_sender=False) - self.direct_sender = s_sender + self._s_sender = s_sender if raise_error: raise error.SenderChainManipulation(self) @@ -723,11 +704,7 @@ return sender.w_self() def s_sender(self): - if self.direct_sender: - return self.direct_sender - else: - result = self.virtual_sender() - return result + return self._s_sender # === Stack Pointer === _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit