[pypy-commit] lang-smalltalk storage: Removed virtual reference of sender. Was causing performance problems.
anton_gulenko
noreply at buildbot.pypy.org
Thu Jul 10 12:56:58 CEST 2014
Author: Anton Gulenko <anton.gulenko at 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 ===
More information about the pypy-commit
mailing list