Author: Richard Plangger <planri...@gmail.com> Branch: gcstress-hypothesis Changeset: r82770:4dbf54a3736b Date: 2016-03-04 15:58 +0100 http://bitbucket.org/pypy/pypy/changeset/4dbf54a3736b/
Log: block of bytecodes is now supported, it seems that some cases are generated that trash the constraint max_size of the initial stack is 0 diff --git a/rpython/jit/backend/llsupport/tl/code.py b/rpython/jit/backend/llsupport/tl/code.py --- a/rpython/jit/backend/llsupport/tl/code.py +++ b/rpython/jit/backend/llsupport/tl/code.py @@ -165,7 +165,8 @@ def filter_bytecode(self, stack): w_idx = stack.peek(1) w_list = stack.peek(2) - if w_idx.value >= len(w_list.items): + if w_idx.value >= len(w_list.items) or \ + w_idx.value < 0: return True return False @@ -178,7 +179,8 @@ def filter_bytecode(self, stack): w_idx = stack.peek(0) w_list = stack.peek(1) - if w_idx.value >= len(w_list.items): + if w_idx.value >= len(w_list.items) or \ + w_idx.value < 0: return True return False diff --git a/rpython/jit/backend/llsupport/tl/interp.py b/rpython/jit/backend/llsupport/tl/interp.py --- a/rpython/jit/backend/llsupport/tl/interp.py +++ b/rpython/jit/backend/llsupport/tl/interp.py @@ -17,6 +17,15 @@ assert isinstance(w_lst, W_ListObject) return space.wrap(self.items + w_lst.items) + def copy(self): + newlist = [] + for item in self.items: + if item is None: + newlist.append(None) + else: + newlist.append(item.copy()) + return W_ListObject(newlist) + def is_of_type(self, type): """ NOT_RPYTHON """ return type in (code.LIST_TYP,) @@ -31,6 +40,9 @@ assert isinstance(w_int, W_IntObject) return space.wrap(self.value - w_int.value) + def copy(self): + return W_IntObject(self.value) + def concat(self, space, w_obj): raise NotImplementedError("cannot concat int with object") @@ -50,6 +62,9 @@ assert isinstance(w_str, W_StrObject) return space.wrap(self.value + w_str.value) + def copy(self): + return W_StrObject(self.value) + def is_of_type(self, type): """ NOT_RPYTHON """ return type in (code.STR_TYP,) diff --git a/rpython/jit/backend/llsupport/tl/stack.py b/rpython/jit/backend/llsupport/tl/stack.py --- a/rpython/jit/backend/llsupport/tl/stack.py +++ b/rpython/jit/backend/llsupport/tl/stack.py @@ -7,6 +7,8 @@ def from_items(space, elems): s = Stack(len(elems)) for elem in elems: + if isinstance(elem, list): + elem = [space.wrap(e) for e in elem] s.append(space.wrap(elem)) return s @@ -19,11 +21,14 @@ def size(self): return self.stackpos - def copy(self): + def copy(self, values=False): """ NOT_RPYTHON """ copy = Stack(self.size()) for item in self.stack: - copy.append(item) + if values: + copy.append(item.copy()) + else: + copy.append(item) return copy def append(self, elem): @@ -80,6 +85,10 @@ assert n >= 0 self.stack[n] = elem + def reset(self): + self.stack = [None] * self.size() + self.stackpos = 0 + def __repr__(self): """ NOT_RPYTHON """ entry_types = [e.TYPE for e in self.stack] diff --git a/rpython/jit/backend/llsupport/tl/test/code_strategies.py b/rpython/jit/backend/llsupport/tl/test/code_strategies.py --- a/rpython/jit/backend/llsupport/tl/test/code_strategies.py +++ b/rpython/jit/backend/llsupport/tl/test/code_strategies.py @@ -20,9 +20,11 @@ elif typ == COND_TYP: return st.integers(min_value=0, max_value=4) elif typ == STR_TYP: - return st.text() + return st.text().filter(lambda x: x is not None) elif typ == LIST_TYP: - return st.lists(elements=st.one_of(st.integers())) # TODO must be recursive + # TODO recursive + result = st.lists(elements=st.one_of(get_strategy_for('i'))) + return result.filter(lambda x: x is not None) else: raise NotImplementedError("type: " + str(typ)) @@ -35,10 +37,11 @@ @defines_strategy def runtime_stack(min_size=0, average_size=5, max_size=4096, types=all_types): - if max_size < average_size: - average_size = max_size // 2 - stack_entries = st.lists(stack_entry(all_types), min_size, - average_size, max_size) + if max_size == 0: + return st.just(stack.Stack(0)) + stack_entries = st.lists(stack_entry(all_types), min_size=min_size, + average_size=average_size, + max_size=max_size) return stack_entries.map(lambda elems: \ stack.Stack.from_items(STD_SPACE, elems)) @@ -89,6 +92,9 @@ # get a stack that is the same for one test run stack_strat = runtime_stack(max_size=max_stack_size) run_stack = draw(st.shared(stack_strat, 'stack')) + # propagate the changes to the stack + orig_stack = run_stack.copy(values=True) + assert orig_stack is not run_stack # get a byte code class clazz = draw(bytecode_class(run_stack)) @@ -96,7 +102,5 @@ assume(not inst.filter_bytecode(run_stack)) bytecode, consts = code.Context().transform([inst]) - # propagate the changes to the stack - orig_stack = run_stack.copy() interp.dispatch_once(STD_SPACE, 0, bytecode, consts, run_stack) return inst, orig_stack diff --git a/rpython/jit/backend/llsupport/tl/test/test_tl_interp.py b/rpython/jit/backend/llsupport/tl/test/test_tl_interp.py --- a/rpython/jit/backend/llsupport/tl/test/test_tl_interp.py +++ b/rpython/jit/backend/llsupport/tl/test/test_tl_interp.py @@ -105,7 +105,6 @@ _, stack = codes[0] bytecode, consts = code.Context().transform(bc_obj_list) space = interp.Space() - stack = Stack(16) pc = 0 end = len(bytecode) while pc < end: diff --git a/rpython/jit/backend/llsupport/tl/test/zrpy_gc_hypo_test.py b/rpython/jit/backend/llsupport/tl/test/zrpy_gc_hypo_test.py --- a/rpython/jit/backend/llsupport/tl/test/zrpy_gc_hypo_test.py +++ b/rpython/jit/backend/llsupport/tl/test/zrpy_gc_hypo_test.py @@ -1,35 +1,33 @@ import py from hypothesis import given +from hypothesis.strategies import lists from rpython.tool.udir import udir from rpython.jit.metainterp.optimize import SpeculativeError from rpython.annotator.listdef import s_list_of_strings from rpython.translator.translator import TranslationContext from rpython.translator.c import genc -from rpython.jit.backend.llsupport.tl import interp +from rpython.jit.backend.llsupport.tl import interp, code from rpython.jit.backend.llsupport.tl.test import code_strategies as st def persist(type, contents): dir = udir.ensure(type) - print "written", type, "to", dir with open(dir.strpath, 'wb') as fd: fd.write(contents) return dir.strpath def persist_constants(consts): contents = "" - for string in consts: + for key, string in sorted(consts.items()): contents += string.replace("\n", "\\n") + "\n" - return persist('constants', contents) + return persist('constants', contents.encode('utf-8')) def persist_bytecode(bc): return persist('bytecode', bc) + class GCHypothesis(object): - builder = None - def setup_method(self, name): - if self.builder: - return + def setup_class(cls): t = TranslationContext() t.config.translation.gc = "incminimark" t.config.translation.gcremovetypeptr = True @@ -42,7 +40,7 @@ cbuilder.generate_source(defines=cbuilder.DEBUG_DEFINES) cbuilder.compile() # prevent from rebuilding the c object! - self.builder = cbuilder + cls.builder = cbuilder def execute(self, bytecode, consts): exe = self.builder.executable_name @@ -53,10 +51,25 @@ res = self.builder.translator.platform.execute(exe, args, env=env) return res.returncode, res.out, res.err - @given(st.bytecode_block()) + # cannot have a non empty stack, cannot pass stack to executable! + @given(st.bytecode(max_stack_size=0)) def test_execute_single_bytecode(self, program): - bytecode, consts = program + bc_obj, stack = program + assert stack.size() == 0 + bytecode, consts = code.Context().transform([bc_obj]) result, out, err = self.execute(bytecode, consts) if result != 0: raise Exception(("could not run program. returned %d" " stderr:\n%s\nstdout:\n%s\n") % (result, err, out)) + + # cannot have a non empty stack, cannot pass stack to executable! + @given(lists(st.bytecode(max_stack_size=0), min_size=1, average_size=24)) + def test_execute_bytecodes(self, args): + _, stack = args[0] + assert stack.size() == 0 + bc_objs = [bc for bc, _ in args] + bytecode, consts = code.Context().transform(bc_objs) + result, out, err = self.execute(bytecode, consts) + if result != 0: + raise Exception(("could not run program. returned %d" + " stderr:\n%s\nstdout:\n%s\n") % (result, err, out)) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit