[pypy-commit] lang-smalltalk storage: use StackOverflow protection from rlib
timfel
noreply at buildbot.pypy.org
Thu Jul 10 15:29:29 CEST 2014
Author: Tim Felgentreff <timfelgentreff at gmail.com>
Branch: storage
Changeset: r888:afd77668220d
Date: 2014-07-10 12:00 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/afd77668220d/
Log: use StackOverflow protection from rlib
diff --git a/spyvm/constants.py b/spyvm/constants.py
--- a/spyvm/constants.py
+++ b/spyvm/constants.py
@@ -190,6 +190,5 @@
# Interpreter constants
#
-MAX_LOOP_DEPTH = 100
INTERRUPT_COUNTER_SIZE = 10000
CompileTime = time.time()
diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -4,7 +4,7 @@
from spyvm import model, constants, primitives, conftest, wrapper
from spyvm.tool.bitmanipulation import splitter
-from rpython.rlib import jit
+from rpython.rlib import jit, rstackovf
from rpython.rlib import objectmodel, unroll
class MissingBytecode(Exception):
@@ -24,7 +24,7 @@
class Interpreter(object):
_immutable_fields_ = ["space", "image", "image_name",
- "max_stack_depth", "interrupt_counter_size",
+ "interrupt_counter_size",
"startup_time", "evented", "interrupts"]
jit_driver = jit.JitDriver(
@@ -35,8 +35,7 @@
)
def __init__(self, space, image=None, image_name="",
- trace=False, evented=True, interrupts=True,
- max_stack_depth=constants.MAX_LOOP_DEPTH):
+ trace=False, evented=True, interrupts=True):
import time
# === Initialize immutable variables
@@ -47,7 +46,6 @@
self.startup_time = image.startup_time
else:
self.startup_time = constants.CompileTime
- self.max_stack_depth = max_stack_depth
self.evented = evented
self.interrupts = interrupts
try:
@@ -57,7 +55,6 @@
# === Initialize mutable variables
self.interrupt_check_counter = self.interrupt_counter_size
- self.current_stack_depth = 0
self.next_wakeup_tick = 0
self.trace = trace
self.trace_proxy = False
@@ -66,7 +63,6 @@
# 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.current_stack_depth == 0
s_sender = s_new_context.s_sender()
try:
self.loop_bytecodes(s_new_context)
@@ -122,16 +118,11 @@
try:
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
+ except rstackovf.StackOverflow:
+ rstackovf.check_stack_overflow()
+ raise StackOverflow(s_frame)
def step(self, context):
bytecode = context.fetch_next_bytecode()
@@ -205,7 +196,7 @@
s_frame = self.create_toplevel_context(w_receiver, selector, w_selector, w_arguments)
self.interrupt_check_counter = self.interrupt_counter_size
return self.interpret_toplevel(s_frame.w_self())
-
+
def create_toplevel_context(self, w_receiver, selector="", w_selector=None, w_arguments=[]):
if w_selector is None:
assert selector, "Need either string or W_Object selector"
@@ -213,7 +204,7 @@
w_selector = self.image.w_asSymbol
else:
w_selector = self.perform(self.space.wrap_string(selector), "asSymbol")
-
+
w_method = model.W_CompiledMethod(self.space, header=512)
w_method.literalatput0(self.space, 1, w_selector)
assert len(w_arguments) <= 7
@@ -225,7 +216,7 @@
return s_frame
def padding(self, symbol=' '):
- return symbol * self.current_stack_depth
+ return symbol
class ReturnFromTopLevel(Exception):
_attrs_ = ["object"]
@@ -964,11 +955,9 @@
# in order to enable tracing/jumping for message sends etc.
def debugging():
def stepping_debugger_init(original):
- def meth(self, space, image=None, image_name="", trace=False,
- max_stack_depth=constants.MAX_LOOP_DEPTH):
+ def meth(self, space, image=None, image_name="", trace=False):
return_value = original(self, space, image=image,
- image_name=image_name, trace=trace,
- max_stack_depth=max_stack_depth)
+ image_name=image_name, trace=trace)
# ##############################################################
self.message_stepping = False
diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py
--- a/targetimageloadingsmalltalk.py
+++ b/targetimageloadingsmalltalk.py
@@ -14,13 +14,13 @@
print """
Usage: %s <path> [-r|-m] [-naHu] [-jpis] [-tlLE]
<path> - image path (default: Squeak.image)
-
+
Execution mode:
(no flags) - Image will be normally opened.
-r|--run <code> - Code will be compiled and executed, result printed.
-m|--method <selector> - Selector will be sent to a SmallInteger, result printed.
-h|--help - Output this and exit.
-
+
Execution parameters:
-n|--num <int> - Only with -m or -r, SmallInteger to be used as receiver (default: nil).
-a|--arg <arg> - Only with -m, will be used as single String argument.
@@ -30,28 +30,25 @@
in the image and execute the context directly. The image window will
probably not open. Good for benchmarking.
-u - Only with -m or -r, try to stop UI-process at startup. Can help benchmarking.
-
+
Other parameters:
-j|--jit <jitargs> - jitargs will be passed to the jit configuration.
-p|--poll - Actively poll for events. Try this if the image is not responding well.
-i|--no-interrupts - Disable timer interrupt. Disables non-cooperative scheduling.
- -s <num> - After num stack frames, the entire stack will be dumped to the heap.
- This breaks performance, but protects agains stack overflow.
- num <= 0 disables stack protection (default: %d)
-
+
Logging parameters:
-t|--trace - Output a trace of each message, primitive, return value and process switch.
-l|--storage-log - Output a log of storage operations.
-L|--storage-log-aggregate - Output an aggregated storage log at the end of execution.
-E|--storage-log-elements - Include classnames of elements into the storage log.
-
- """ % (argv[0], constants.MAX_LOOP_DEPTH)
+
+ """ % argv[0]
def get_parameter(argv, idx, arg):
if len(argv) < idx + 1:
raise RuntimeError("Error: missing argument after %s" % arg)
return argv[idx], idx + 1
-
+
prebuilt_space = objspace.ObjSpace()
def entry_point(argv):
@@ -65,12 +62,11 @@
# == Other parameters
poll = False
interrupts = True
- max_stack_depth = constants.MAX_LOOP_DEPTH
trace = False
-
+
path = argv[1] if len(argv) > 1 else "Squeak.image"
idx = 2
-
+
while idx < len(argv):
arg = argv[idx]
idx += 1
@@ -96,9 +92,6 @@
code, idx = get_parameter(argv, idx, arg)
elif arg in ["-i", "--no-interrupts"]:
interrupts = False
- elif arg in ["-s"]:
- arg, idx = get_parameter(argv, idx, arg)
- max_stack_depth = int(arg)
elif arg in ["-P", "--process"]:
headless = False
elif arg in ["-u"]:
@@ -113,10 +106,10 @@
else:
_usage(argv)
return -1
-
+
if code and selector:
raise RuntimeError("Cannot handle both -r and -m.")
-
+
path = rpath.rabspath(path)
try:
f = open_file_as_stream(path, mode="rb", buffering=0)
@@ -127,16 +120,16 @@
except OSError as e:
os.write(2, "%s -- %s (LoadError)\n" % (os.strerror(e.errno), path))
return 1
-
+
# Load & prepare image and environment
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=not poll,
- interrupts=interrupts, max_stack_depth=max_stack_depth)
+ interrupts=interrupts)
space.runtime_setup(argv[0])
-
+
# Create context to be executed
if code or selector:
if not have_number:
@@ -155,7 +148,7 @@
context = active_context(interp.space)
else:
context = active_context(interp.space)
-
+
w_result = execute_context(interp, context)
print result_string(w_result)
storage_logger.print_aggregated_log()
@@ -198,13 +191,13 @@
return None
w_receiver_class.as_class_get_shadow(space).s_methoddict().sync_method_cache()
return selector
-
+
def create_context(interp, w_receiver, selector, stringarg):
args = []
if stringarg:
args.append(interp.space.wrap_string(stringarg))
return interp.create_toplevel_context(w_receiver, selector, w_arguments = args)
-
+
def create_process(interp, s_frame):
space = interp.space
w_active_process = wrapper.scheduler(space).active_process()
@@ -221,10 +214,10 @@
priority = 7
w_benchmark_proc.store(space, 1, s_frame.w_self())
w_benchmark_proc.store(space, 2, space.wrap_int(priority))
-
+
# Make process eligible for scheduling
wrapper.ProcessWrapper(space, w_benchmark_proc).put_to_sleep()
-
+
def active_context(space):
w_active_process = wrapper.scheduler(space).active_process()
active_process = wrapper.ProcessWrapper(space, w_active_process)
@@ -240,7 +233,7 @@
except error.Exit, e:
print "Exited: %s" % e.msg
return None
-
+
# _____ Target and Main _____
def target(driver, *args):
More information about the pypy-commit
mailing list