[pypy-commit] lang-smalltalk storage-refactoring-virtual-pc: Merged storage branch.
anton_gulenko
noreply at buildbot.pypy.org
Thu May 15 12:40:35 CEST 2014
Author: Anton Gulenko <anton.gulenko at googlemail.com>
Branch: storage-refactoring-virtual-pc
Changeset: r830:a8514605c0c4
Date: 2014-05-15 12:40 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/a8514605c0c4/
Log: Merged storage branch.
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",
"max_stack_depth", "interrupt_counter_size",
- "startup_time", "evented"]
+ "startup_time", "evented", "interrupts"]
jit_driver = jit.JitDriver(
greens=['pc', 'self', 'method'],
@@ -34,9 +34,9 @@
get_printable_location=get_printable_location
)
- def __init__(self, space, image=None, image_name="", trace=False,
- evented=True,
- max_stack_depth=constants.MAX_LOOP_DEPTH):
+ def __init__(self, space, image=None, image_name="",
+ trace=False, evented=True, interrupts=True,
+ max_stack_depth=constants.MAX_LOOP_DEPTH):
import time
# === Initialize immutable variables
@@ -49,6 +49,7 @@
self.startup_time = constants.CompileTime
self.max_stack_depth = max_stack_depth
self.evented = evented
+ self.interrupts = interrupts
try:
self.interrupt_counter_size = int(os.environ["SPY_ICS"])
except KeyError:
@@ -56,7 +57,7 @@
# === Initialize mutable variables
self.interrupt_check_counter = self.interrupt_counter_size
- self.remaining_stack_depth = max_stack_depth
+ self.current_stack_depth = 0
self.next_wakeup_tick = 0
self.trace = trace
self.trace_proxy = False
@@ -65,13 +66,15 @@
# This is the top-level loop and is not invoked recursively.
s_new_context = w_active_context.as_context_get_shadow(self.space)
while True:
- assert self.remaining_stack_depth == self.max_stack_depth
+ assert self.current_stack_depth == 0
# Need to save s_sender, loop_bytecodes will nil this on return
s_sender = s_new_context.s_sender()
try:
self.loop_bytecodes(s_new_context)
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()
s_new_context = e.s_new_context
except Return, nlr:
s_new_context = s_sender
@@ -106,16 +109,26 @@
self.jitted_check_for_interrupt(s_context)
self.jit_driver.can_enter_jit(pc=pc, self=self, method=method, s_context=s_context)
- # This is just a wrapper around loop_bytecodes that handles the remaining_stack_depth mechanism
+ try:
+ self.step(s_context)
+ except Return, nlr:
+ if nlr.s_target_context is not s_context:
+ s_context._activate_unwind_context(self)
+ raise nlr
+ else:
+ s_context.push(nlr.value)
+
+ # This is just a wrapper around loop_bytecodes that handles the stack overflow protection mechanism
def stack_frame(self, s_new_frame, may_context_switch=True, fresh_context=False):
- if self.remaining_stack_depth <= 1:
- raise StackOverflow(s_new_frame)
-
- self.remaining_stack_depth -= 1
+ if self.max_stack_depth > 0:
+ if self.current_stack_depth >= self.max_stack_depth:
+ raise StackOverflow(s_new_frame)
+
+ self.current_stack_depth += 1
try:
self.loop_bytecodes(s_new_frame, may_context_switch=may_context_switch, fresh_context=fresh_context)
finally:
- self.remaining_stack_depth += 1
+ self.current_stack_depth -= 1
def step(self, context, pc):
bytecode = context.fetch_bytecode(pc)
@@ -134,6 +147,8 @@
# ============== Methods for handling user interrupts ==============
def jitted_check_for_interrupt(self, s_frame):
+ if not self.interrupts:
+ return
# Normally, the tick counter is decremented by 1 for every message send.
# Since we don't know how many messages are called during this trace, we
# just decrement by 100th of the trace length (num of bytecodes).
@@ -143,6 +158,8 @@
self.quick_check_for_interrupt(s_frame, decr_by)
def quick_check_for_interrupt(self, s_frame, dec=1):
+ if not self.interrupts:
+ return
self.interrupt_check_counter -= dec
if self.interrupt_check_counter <= 0:
self.interrupt_check_counter = self.interrupt_counter_size
@@ -205,7 +222,7 @@
return self.interpret_toplevel(s_frame.w_self())
def padding(self, symbol=' '):
- return symbol * (self.max_stack_depth - self.remaining_stack_depth)
+ return symbol * self.current_stack_depth
class ReturnFromTopLevel(Exception):
_attrs_ = ["object"]
diff --git a/spyvm/test/test_interpreter.py b/spyvm/test/test_interpreter.py
--- a/spyvm/test/test_interpreter.py
+++ b/spyvm/test/test_interpreter.py
@@ -1014,7 +1014,7 @@
class StackTestInterpreter(TestInterpreter):
def stack_frame(self, w_frame, may_interrupt=True, fresh_context=False):
- stack_depth = self.max_stack_depth - self.remaining_stack_depth
+ stack_depth = self.current_stack_depth
for i in range(stack_depth + 1):
assert sys._getframe(5 + i * 7).f_code.co_name == 'loop_bytecodes'
assert sys._getframe(6 + stack_depth * 7).f_code.co_name == 'loop'
diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py
--- a/targetimageloadingsmalltalk.py
+++ b/targetimageloadingsmalltalk.py
@@ -6,7 +6,7 @@
from rpython.rlib import jit, rpath
from spyvm import model, interpreter, squeakimage, objspace, wrapper,\
- error, shadow, storage_statistics
+ error, shadow, storage_statistics, constants
from spyvm.tool.analyseimage import create_image
from spyvm.interpreter_proxy import VirtualMachine
@@ -128,13 +128,14 @@
-r|--run [code string]
-b|--benchmark [code string]
-p|--poll_events
+ -ni|--no-interrupts
+ -d|--max-stack-depth [number, default %d, <= 0 disables stack protection]
--strategy-log
--strategy-stats
- --strategy-stats-dot
+ --strategy-stats-dot
--strategy-stats-details
[image path, default: Squeak.image]
- """ % argv[0]
-
+ """ % (argv[0], constants.MAX_LOOP_DEPTH)
def _arg_missing(argv, idx, arg):
if len(argv) == idx + 1:
@@ -152,6 +153,8 @@
stringarg = ""
code = None
as_benchmark = False
+ max_stack_depth = constants.MAX_LOOP_DEPTH
+ interrupts = True
while idx < len(argv):
arg = argv[idx]
@@ -189,6 +192,12 @@
code = argv[idx + 1]
as_benchmark = True
idx += 1
+ elif arg in ["-ni", "--no-interrupts"]:
+ interrupts = False
+ elif arg in ["-d", "--max-stack-depth"]:
+ _arg_missing(argv, idx, arg)
+ max_stack_depth = int(argv[idx + 1])
+ idx += 1
elif arg == "--strategy-log":
storage_statistics.activate_statistics(log=True)
elif arg == "--strategy-stats":
@@ -221,7 +230,9 @@
space = prebuilt_space
image_reader = squeakimage.reader_for_image(space, squeakimage.Stream(data=imagedata))
image = create_image(space, image_reader)
- interp = interpreter.Interpreter(space, image, image_name=path, trace=trace, evented=evented)
+ interp = interpreter.Interpreter(space, image, image_name=path,
+ trace=trace, evented=evented,
+ interrupts=interrupts, max_stack_depth=max_stack_depth)
space.runtime_setup(argv[0])
result = 0
if benchmark is not None:
More information about the pypy-commit
mailing list