Author: Tim Felgentreff <timfelgentr...@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): _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit