Author: Maciej Fijalkowski <fij...@gmail.com> Branch: share-guard-info Changeset: r79662:afcfd65aebea Date: 2015-09-17 11:28 +0200 http://bitbucket.org/pypy/pypy/changeset/afcfd65aebea/
Log: merge default diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py --- a/pypy/module/itertools/interp_itertools.py +++ b/pypy/module/itertools/interp_itertools.py @@ -2,6 +2,7 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.typedef import TypeDef, make_weakref_descr from pypy.interpreter.gateway import interp2app, unwrap_spec, WrappedDefault +from rpython.rlib import jit class W_Count(W_Root): @@ -322,6 +323,11 @@ """) +islice_ignore_items_driver = jit.JitDriver(name='islice_ignore_items', + greens=['tp'], + reds=['num', 'w_islice', + 'w_iterator']) + class W_ISlice(W_Root): def __init__(self, space, w_iterable, w_startstop, args_w): self.iterable = space.iter(w_iterable) @@ -407,11 +413,18 @@ raise def _ignore_items(self, num): - if self.iterable is None: + w_iterator = self.iterable + if w_iterator is None: raise OperationError(self.space.w_StopIteration, self.space.w_None) + + tp = self.space.type(w_iterator) while True: + islice_ignore_items_driver.jit_merge_point(tp=tp, + num=num, + w_islice=self, + w_iterator=w_iterator) try: - self.space.next(self.iterable) + self.space.next(w_iterator) except OperationError as e: if e.match(self.space, self.space.w_StopIteration): self.iterable = None diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py --- a/pypy/module/itertools/test/test_itertools.py +++ b/pypy/module/itertools/test/test_itertools.py @@ -1085,3 +1085,18 @@ assert list(itertools.islice(c2, 3)) == expected c3 = pickle.loads(pickle.dumps(c)) assert list(itertools.islice(c3, 3)) == expected + + def test_islice_attack(self): + import itertools + class Iterator(object): + first = True + def __iter__(self): + return self + def next(self): + if self.first: + self.first = False + list(islice) + return 52 + myiter = Iterator() + islice = itertools.islice(myiter, 5, 8) + raises(StopIteration, islice.next) diff --git a/pypy/module/pypyjit/test_pypy_c/test_containers.py b/pypy/module/pypyjit/test_pypy_c/test_containers.py --- a/pypy/module/pypyjit/test_pypy_c/test_containers.py +++ b/pypy/module/pypyjit/test_pypy_c/test_containers.py @@ -81,7 +81,7 @@ setfield_gc(p13, 32, descr=<FieldS dicttable.resize_counter .+>) }}} guard_no_exception(descr=...) - p20 = new_with_vtable(ConstClass(W_IntObject)) + p20 = new_with_vtable(descr=...) call_n(ConstClass(_ll_dict_setitem_lookup_done_trampoline), p13, p10, p20, i12, i17, descr=<Callv 0 rrrii EF=5>) setfield_gc(p20, i5, descr=<FieldS .*W_IntObject.inst_intval .*>) guard_no_exception(descr=...) diff --git a/pypy/module/pypyjit/test_pypy_c/test_cprofile.py b/pypy/module/pypyjit/test_pypy_c/test_cprofile.py --- a/pypy/module/pypyjit/test_pypy_c/test_cprofile.py +++ b/pypy/module/pypyjit/test_pypy_c/test_cprofile.py @@ -31,7 +31,7 @@ # but all calls can be special-cased by the backend if # supported. On 64-bit there is only the two calls to # read_timestamp. - r = re.compile(r" call[(]ConstClass[(](.+?)[)]") + r = re.compile(r" call_\w[(]ConstClass[(](.+?)[)]") calls = r.findall(repr(loop.ops_by_id(method))) if sys.maxint == 2147483647: assert len(calls) == 6 diff --git a/pypy/module/pypyjit/test_pypy_c/test_instance.py b/pypy/module/pypyjit/test_pypy_c/test_instance.py --- a/pypy/module/pypyjit/test_pypy_c/test_instance.py +++ b/pypy/module/pypyjit/test_pypy_c/test_instance.py @@ -124,7 +124,7 @@ setfield_gc(ConstPtr(ptr39), i59, descr=...) i62 = int_lt(i61, 0) guard_false(i62, descr=...) - jump(p0, p1, p3, p6, p7, p12, i59, p18, i31, i59, descr=...) + jump(p0, p1, p3, p6, p7, p12, i59, p18, i31, i59, p100, descr=...) """) def test_mutate_class(self): @@ -167,7 +167,7 @@ i70 = int_lt(i58, i33) guard_true(i70, descr=...) guard_not_invalidated(descr=...) - p71 = getfield_gc(p64, descr=...) + p71 = getfield_gc_r(p64, descr=...) guard_value(p71, ConstPtr(ptr42), descr=...) p72 = force_token() p73 = force_token() @@ -175,7 +175,7 @@ i75 = getfield_raw_i(..., descr=...) i76 = int_lt(i75, 0) guard_false(i76, descr=...) - p77 = new_with_vtable(...) + p77 = new_with_vtable(descr=...) setfield_gc(p77, p64, descr=...) setfield_gc(p77, ConstPtr(null), descr=...) setfield_gc(p77, ConstPtr(null), descr=...) @@ -183,7 +183,7 @@ setfield_gc(p77, ConstPtr(null), descr=...) setfield_gc(p77, ConstPtr(ptr42), descr=...) setfield_gc(ConstPtr(ptr69), p77, descr=...) - jump(p0, p1, p3, p6, p7, p12, i74, p20, p26, i33, p77, descr=...) + jump(p0, p1, p3, p6, p7, p12, i74, p20, p26, i33, p77, p100, descr=...) """) diff --git a/pypy/module/pypyjit/test_pypy_c/test_min_max.py b/pypy/module/pypyjit/test_pypy_c/test_min_max.py --- a/pypy/module/pypyjit/test_pypy_c/test_min_max.py +++ b/pypy/module/pypyjit/test_pypy_c/test_min_max.py @@ -38,7 +38,7 @@ loop, = log.loops_by_filename(self.filepath) assert loop.match(""" ... - p76 = call_assembler(_, _, _, _, descr=...) + p76 = call_assembler_r(_, _, _, _, descr=...) ... """) loop2 = log.loops[0] @@ -50,11 +50,11 @@ guard_not_invalidated? i17 = int_ge(i11, i7) guard_false(i17, descr=...) - p18 = getarrayitem_gc(p5, i11, descr=...) + p18 = getarrayitem_gc_r(p5, i11, descr=...) i19 = int_add(i11, 1) setfield_gc(p2, i19, descr=...) guard_nonnull_class(p18, ConstClass(W_IntObject), descr=...) - i20 = getfield_gc_pure(p18, descr=...) + i20 = getfield_gc_pure_i(p18, descr=...) i21 = int_gt(i20, i14) guard_true(i21, descr=...) jump(..., descr=...) @@ -79,6 +79,6 @@ assert len(guards) < 20 assert loop.match(""" ... - p76 = call_assembler(_, _, _, _, descr=...) + p76 = call_assembler_r(_, _, _, _, descr=...) ... """) diff --git a/pypy/module/pypyjit/test_pypy_c/test_misc.py b/pypy/module/pypyjit/test_pypy_c/test_misc.py --- a/pypy/module/pypyjit/test_pypy_c/test_misc.py +++ b/pypy/module/pypyjit/test_pypy_c/test_misc.py @@ -65,7 +65,7 @@ assert loop.match(""" i7 = int_gt(i4, 1) guard_true(i7, descr=...) - p11 = call(ConstClass(rbigint.int_mul), p5, i4, descr=...) + p11 = call_r(ConstClass(rbigint.int_mul), p5, i4, descr=...) guard_no_exception(descr=...) i13 = int_sub(i4, 1) --TICK-- @@ -113,14 +113,14 @@ i12 = int_is_true(i4) guard_true(i12, descr=...) guard_not_invalidated(descr=...) - i13 = int_add_ovf(i8, i9) - guard_no_overflow(descr=...) - i10p = getfield_gc_pure(p10, descr=...) + i10p = getfield_gc_pure_i(p10, descr=...) i10 = int_mul_ovf(2, i10p) guard_no_overflow(descr=...) i14 = int_add_ovf(i13, i10) guard_no_overflow(descr=...) - setfield_gc(p7, p11, descr=...) + i13 = int_add_ovf(i14, i9) + guard_no_overflow(descr=...) + setfield_gc(p17, p10, descr=...) i17 = int_sub_ovf(i4, 1) guard_no_overflow(descr=...) --TICK-- @@ -277,6 +277,7 @@ i28 = int_add_ovf(i10, i25) guard_no_overflow(descr=...) --TICK-- + if00 = arraylen_gc(p16, descr=...) jump(..., descr=...) """) diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py --- a/rpython/jit/backend/llsupport/gc.py +++ b/rpython/jit/backend/llsupport/gc.py @@ -131,7 +131,7 @@ def _record_constptrs(self, op, gcrefs_output_list, ops_with_movable_const_ptr, changeable_const_pointers): - ops_with_movable_const_ptr[op] = [] + l = None for i in range(op.numargs()): v = op.getarg(i) if isinstance(v, ConstPtr) and bool(v.value): @@ -139,7 +139,10 @@ if rgc._make_sure_does_not_move(p): gcrefs_output_list.append(p) else: - ops_with_movable_const_ptr[op].append(i) + if l is None: + l = [i] + else: + l.append(i) if v not in changeable_const_pointers: changeable_const_pointers.append(v) # @@ -148,8 +151,8 @@ assert rgc._make_sure_does_not_move(llref) gcrefs_output_list.append(llref) # - if len(ops_with_movable_const_ptr[op]) == 0: - del ops_with_movable_const_ptr[op] + if l: + ops_with_movable_const_ptr[op] = l def _rewrite_changeable_constptrs(self, op, ops_with_movable_const_ptr, moving_obj_tracker): newops = [] diff --git a/rpython/jit/backend/test/runner_test.py b/rpython/jit/backend/test/runner_test.py --- a/rpython/jit/backend/test/runner_test.py +++ b/rpython/jit/backend/test/runner_test.py @@ -2601,16 +2601,16 @@ # call: 8 bytes too much. If we repeat the call often enough, crash. ops = [] for i in range(50): - i3 = InputArgInt() ops += [ - ResOperation(rop.CALL_RELEASE_GIL, - [ConstInt(0), funcbox, i1, i2], i3, + ResOperation(rop.CALL_RELEASE_GIL_I, + [ConstInt(0), funcbox, i1, i2], descr=calldescr), - ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), + ResOperation(rop.GUARD_NOT_FORCED, [], descr=faildescr), ] + i3 = ops[-2] ops[-1].setfailargs([]) ops += [ - ResOperation(rop.FINISH, [i3], None, descr=BasicFinalDescr(0)) + ResOperation(rop.FINISH, [i3], descr=BasicFinalDescr(0)) ] looptoken = JitCellToken() self.cpu.compile_loop([i1, i2], ops, looptoken) @@ -3072,16 +3072,16 @@ rffi.RFFI_SAVE_LASTERROR | rffi.RFFI_ALT_ERRNO, ]: faildescr = BasicFailDescr(1) - inputargs = [BoxInt() for i in range(7)] - i1 = BoxInt() + inputargs = [InputArgInt() for i in range(7)] ops = [ - ResOperation(rop.CALL_RELEASE_GIL, + ResOperation(rop.CALL_RELEASE_GIL_I, [ConstInt(saveerr), ConstInt(func1_adr)] - + inputargs, i1, + + inputargs, descr=calldescr), - ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), - ResOperation(rop.FINISH, [i1], None, descr=BasicFinalDescr(0)) + ResOperation(rop.GUARD_NOT_FORCED, [], descr=faildescr), ] + i1 = ops[0] + ops += [ResOperation(rop.FINISH, [i1], descr=BasicFinalDescr(0))] ops[-2].setfailargs([]) looptoken = JitCellToken() self.cpu.compile_loop(inputargs, ops, looptoken) @@ -3142,16 +3142,16 @@ rffi.RFFI_READSAVED_LASTERROR | rffi.RFFI_ALT_ERRNO, ]: faildescr = BasicFailDescr(1) - inputargs = [BoxInt() for i in range(7)] - i1 = BoxInt() + inputargs = [InputArgInt() for i in range(7)] ops = [ - ResOperation(rop.CALL_RELEASE_GIL, + ResOperation(rop.CALL_RELEASE_GIL_I, [ConstInt(saveerr), ConstInt(func1_adr)] - + inputargs, i1, + + inputargs, descr=calldescr), - ResOperation(rop.GUARD_NOT_FORCED, [], None, descr=faildescr), - ResOperation(rop.FINISH, [i1], None, descr=BasicFinalDescr(0)) + ResOperation(rop.GUARD_NOT_FORCED, [], descr=faildescr), ] + i1 = ops[-2] + ops += [ResOperation(rop.FINISH, [i1], descr=BasicFinalDescr(0))] ops[-2].setfailargs([]) looptoken = JitCellToken() self.cpu.compile_loop(inputargs, ops, looptoken) diff --git a/rpython/jit/backend/test/test_ll_random.py b/rpython/jit/backend/test/test_ll_random.py --- a/rpython/jit/backend/test/test_ll_random.py +++ b/rpython/jit/backend/test/test_ll_random.py @@ -2,9 +2,8 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, rstr from rpython.rtyper import rclass from rpython.jit.backend.test import test_random -from rpython.jit.metainterp.resoperation import ResOperation, rop -from rpython.jit.metainterp.history import ConstInt, ConstPtr -from rpython.jit.metainterp.history import BoxPtr +from rpython.jit.metainterp.resoperation import ResOperation, rop, optypes +from rpython.jit.metainterp.history import ConstInt, ConstPtr, getkind from rpython.jit.codewriter import heaptracker from rpython.jit.codewriter.effectinfo import EffectInfo from rpython.rtyper.annlowlevel import llhelper @@ -101,10 +100,12 @@ kwds['hints'] = {'vtable': with_vtable._obj} for i in range(r.randrange(1, 5)): if r.random() < 0.1: + kind = 'r' TYPE = llmemory.GCREF else: + kind = 'i' TYPE = self.get_random_primitive_type(r) - fields.append(('f%d' % i, TYPE)) + fields.append(('%s%d' % (kind, i), TYPE)) S = type('S%d' % self.counter, *fields, **kwds) self.counter += 1 if cache: @@ -120,7 +121,7 @@ self.vtable_counter += 1 S = self.get_random_structure_type(r, with_vtable=vtable, cache=False) name = S._name - vtable.name = rclass.alloc_array_name(name) + heaptracker.set_testing_vtable_for_gcstruct(S, vtable, name) self.structure_types_and_vtables.append((S, vtable)) # return S, vtable @@ -168,7 +169,7 @@ if length == 0: raise test_random.CannotProduceOperation v_index = r.choice(self.intvars) - if not (0 <= v_index.value < length): + if not (0 <= v_index.getint() < length): v_index = ConstInt(r.random_integer() % length) return v_index @@ -242,14 +243,14 @@ if r.random() < 0.5: return GuardClassOperation.gen_guard(self, builder, r) else: - v = BoxPtr(lltype.nullptr(llmemory.GCREF.TO)) - op = ResOperation(rop.SAME_AS, [ConstPtr(v.value)], v) + NULL = lltype.nullptr(llmemory.GCREF.TO) + op = ResOperation(rop.SAME_AS_R, [ConstPtr(NULL)]) builder.loop.operations.append(op) v2, S2 = builder.get_structptr_var(r, must_have_vtable=True) vtable2 = S2._hints['vtable']._as_ptr() c_vtable2 = ConstAddr(llmemory.cast_ptr_to_adr(vtable2), builder.cpu) - op = ResOperation(self.opnum, [v, c_vtable2], None) + op = ResOperation(self.opnum, [op, c_vtable2], None) return op, False class ZeroPtrFieldOperation(test_random.AbstractOperation): @@ -263,7 +264,7 @@ choice = [] for name in names: FIELD = getattr(S, name) - if isinstance(FIELD, lltype.Ptr) and FIELD._needsgc(): + if FIELD is lltype.Signed: # xxx should be a gc ptr, but works too choice.append(name) if not choice: raise test_random.CannotProduceOperation @@ -282,10 +283,12 @@ if names[0] == 'parent': names = names[1:] choice = [] + kind = optypes[self.opnum] for name in names: FIELD = getattr(S, name) if not isinstance(FIELD, lltype.Ptr): - choice.append(name) + if kind == 'n' or getkind(FIELD)[0] == kind: + choice.append(name) if not choice: raise test_random.CannotProduceOperation name = r.choice(choice) @@ -341,7 +344,8 @@ w = ConstInt(r.random_integer()) else: w = r.choice(builder.intvars) - if rffi.cast(lltype.Signed, rffi.cast(TYPE, w.value)) == w.value: + value = w.getint() + if rffi.cast(lltype.Signed, rffi.cast(TYPE, value)) == value: break builder.do(self.opnum, [v, w], descr) @@ -353,13 +357,14 @@ w = ConstInt(r.random_integer()) else: w = r.choice(builder.intvars) - if rffi.cast(lltype.Signed, rffi.cast(TYPE, w.value)) == w.value: + value = w.getint() + if rffi.cast(lltype.Signed, rffi.cast(TYPE, value)) == value: break builder.do(self.opnum, [v, v_index, w], descr) class NewOperation(test_random.AbstractOperation): - def size_descr(self, builder, S): - descr = builder.cpu.sizeof(S) + def size_descr(self, builder, S, *vtable): + descr = builder.cpu.sizeof(S, *vtable) descr._random_info = 'cpu.sizeof(...)' descr._random_type = S return descr @@ -367,13 +372,11 @@ def produce_into(self, builder, r): if self.opnum == rop.NEW_WITH_VTABLE: S, vtable = builder.get_random_structure_type_and_vtable(r) - args = [ConstAddr(llmemory.cast_ptr_to_adr(vtable), builder.cpu)] - descr = None + descr = self.size_descr(builder, S, vtable) else: S = builder.get_random_structure_type(r) - args = [] descr = self.size_descr(builder, S) - v_ptr = builder.do(self.opnum, args, descr) + v_ptr = builder.do(self.opnum, [], descr) builder.ptrvars.append((v_ptr, S)) class ArrayOperation(test_random.AbstractOperation): @@ -408,7 +411,8 @@ w = ConstInt(r.random_integer()) else: w = r.choice(builder.intvars) - if rffi.cast(lltype.Signed, rffi.cast(A.OF, w.value)) == w.value: + value = w.getint() + if rffi.cast(lltype.Signed, rffi.cast(A.OF, value)) == value: break builder.do(self.opnum, [v, v_index, w], descr) @@ -486,7 +490,7 @@ class AbstractSetItemOperation(AbstractStringOperation): def produce_into(self, builder, r): v_string = self.get_string(builder, r) - if not isinstance(v_string, BoxPtr): + if isinstance(v_string, ConstPtr): raise test_random.CannotProduceOperation # setitem(Const, ...) v_index = builder.get_index(len(v_string.getref(self.ptr).chars), r) v_target = ConstInt(r.random_integer() % self.max) @@ -501,13 +505,15 @@ def produce_into(self, builder, r): v_srcstring = self.get_string(builder, r) v_dststring = self.get_string(builder, r) - if v_srcstring.value == v_dststring.value: # because it's not a + src = v_srcstring.getref(self.ptr) + dst = v_dststring.getref(self.ptr) + if src == dst: # because it's not a raise test_random.CannotProduceOperation # memmove(), but memcpy() - srclen = len(v_srcstring.getref(self.ptr).chars) - dstlen = len(v_dststring.getref(self.ptr).chars) + srclen = len(src.chars) + dstlen = len(dst.chars) v_length = builder.get_index(min(srclen, dstlen), r) - v_srcstart = builder.get_index(srclen - v_length.value + 1, r) - v_dststart = builder.get_index(dstlen - v_length.value + 1, r) + v_srcstart = builder.get_index(srclen - v_length.getint() + 1, r) + v_dststart = builder.get_index(dstlen - v_length.getint() + 1, r) builder.do(self.opnum, [v_srcstring, v_dststring, v_srcstart, v_dststart, v_length]) @@ -548,16 +554,22 @@ class BaseCallOperation(test_random.AbstractOperation): def non_raising_func_code(self, builder, r): subset = builder.subset_of_intvars(r) - if len(subset) == 0: - sum = "" - funcargs = "" + funcargs = ", ".join(['arg_%d' % i for i in range(len(subset))]) + sum = "intmask(%s)" % " + ".join( + ['arg_%d' % i for i in range(len(subset))] + ['42']) + if self.opnum == rop.CALL_I: + result = 'sum' + elif self.opnum == rop.CALL_F: + result = 'float(sum)' + elif self.opnum == rop.CALL_N: + result = '' else: - funcargs = ", ".join(['arg_%d' % i for i in range(len(subset))]) - sum = "intmask(%s)" % " + ".join(['arg_%d' % i for i in range(len(subset))]) + raise AssertionError(self.opnum) code = py.code.Source(""" def f(%s): - return %s - """ % (funcargs, sum)).compile() + sum = %s + return %s + """ % (funcargs, sum, result)).compile() d = {'intmask' : intmask} exec code in d return subset, d['f'] @@ -573,14 +585,25 @@ """ % funcargs).compile() vtableptr = v._hints['vtable']._as_ptr() d = { - 'ptr': S.value, + 'ptr': S.getref_base(), 'vtable' : vtableptr, 'LLException' : LLException, } exec code in d return subset, d['f'], vtableptr + def getresulttype(self): + if self.opnum == rop.CALL_I: + return lltype.Signed + elif self.opnum == rop.CALL_F: + return lltype.Float + elif self.opnum == rop.CALL_N or self.opnum == rop.COND_CALL: + return lltype.Void + else: + raise AssertionError(self.opnum) + def getcalldescr(self, builder, TP): + assert TP.RESULT == self.getresulttype() ef = EffectInfo.MOST_GENERAL return builder.cpu.calldescrof(TP, TP.ARGS, TP.RESULT, ef) @@ -589,17 +612,14 @@ def produce_into(self, builder, r): fail_subset = builder.subset_of_intvars(r) subset, f = self.non_raising_func_code(builder, r) - if len(subset) == 0: - RES = lltype.Void - else: - RES = lltype.Signed + RES = self.getresulttype() TP = lltype.FuncType([lltype.Signed] * len(subset), RES) ptr = llhelper(lltype.Ptr(TP), f) c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) - op = ResOperation(rop.GUARD_NO_EXCEPTION, [], None, + op = ResOperation(rop.GUARD_NO_EXCEPTION, [], descr=builder.getfaildescr()) op.setfailargs(fail_subset) builder.loop.operations.append(op) @@ -609,10 +629,7 @@ class CallOperationException(BaseCallOperation): def produce_into(self, builder, r): subset, f = self.non_raising_func_code(builder, r) - if len(subset) == 0: - RES = lltype.Void - else: - RES = lltype.Signed + RES = self.getresulttype() TP = lltype.FuncType([lltype.Signed] * len(subset), RES) ptr = llhelper(lltype.Ptr(TP), f) c_addr = ConstAddr(llmemory.cast_ptr_to_adr(ptr), builder.cpu) @@ -621,7 +638,7 @@ self.put(builder, args, descr) _, vtableptr = builder.get_random_structure_type_and_vtable(r) exc_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu) - op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], BoxPtr(), + op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], descr=builder.getfaildescr()) op.setfailargs(builder.subset_of_intvars(r)) op._exc_box = None @@ -642,7 +659,7 @@ descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu) - op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], BoxPtr(), + op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], descr=builder.getfaildescr()) op.setfailargs(fail_subset) builder.loop.operations.append(op) @@ -658,7 +675,7 @@ args = [c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) - op = ResOperation(rop.GUARD_NO_EXCEPTION, [], BoxPtr(), + op = ResOperation(rop.GUARD_NO_EXCEPTION, [], descr=builder.getfaildescr()) op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu) op.setfailargs(builder.subset_of_intvars(r)) @@ -682,7 +699,7 @@ if vtableptr != exc: break other_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu) - op = ResOperation(rop.GUARD_EXCEPTION, [other_box], BoxPtr(), + op = ResOperation(rop.GUARD_EXCEPTION, [other_box], descr=builder.getfaildescr()) op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu) op.setfailargs(builder.subset_of_intvars(r)) @@ -713,7 +730,7 @@ args = [v_cond, c_addr] + subset descr = self.getcalldescr(builder, TP) self.put(builder, args, descr) - op = ResOperation(rop.GUARD_NO_EXCEPTION, [], None, + op = ResOperation(rop.GUARD_NO_EXCEPTION, [], descr=builder.getfaildescr()) op.setfailargs(fail_subset) builder.loop.operations.append(op) @@ -723,17 +740,18 @@ OPERATIONS = test_random.OPERATIONS[:] for i in range(4): # make more common - OPERATIONS.append(GetFieldOperation(rop.GETFIELD_GC)) - OPERATIONS.append(GetFieldOperation(rop.GETFIELD_GC)) - OPERATIONS.append(GetInteriorFieldOperation(rop.GETINTERIORFIELD_GC)) + OPERATIONS.append(GetFieldOperation(rop.GETFIELD_GC_I)) + OPERATIONS.append(GetFieldOperation(rop.GETFIELD_GC_I)) + OPERATIONS.append(GetInteriorFieldOperation(rop.GETINTERIORFIELD_GC_I)) + OPERATIONS.append(GetInteriorFieldOperation(rop.GETINTERIORFIELD_GC_I)) OPERATIONS.append(SetFieldOperation(rop.SETFIELD_GC)) OPERATIONS.append(ZeroPtrFieldOperation(rop.ZERO_PTR_FIELD)) OPERATIONS.append(SetInteriorFieldOperation(rop.SETINTERIORFIELD_GC)) OPERATIONS.append(NewOperation(rop.NEW)) OPERATIONS.append(NewOperation(rop.NEW_WITH_VTABLE)) - OPERATIONS.append(GetArrayItemOperation(rop.GETARRAYITEM_GC)) - OPERATIONS.append(GetArrayItemOperation(rop.GETARRAYITEM_GC)) + OPERATIONS.append(GetArrayItemOperation(rop.GETARRAYITEM_GC_I)) + OPERATIONS.append(GetArrayItemOperation(rop.GETARRAYITEM_GC_I)) OPERATIONS.append(SetArrayItemOperation(rop.SETARRAYITEM_GC)) OPERATIONS.append(NewArrayOperation(rop.NEW_ARRAY_CLEAR)) OPERATIONS.append(ArrayLenOperation(rop.ARRAYLEN_GC)) @@ -750,14 +768,16 @@ for i in range(2): OPERATIONS.append(GuardClassOperation(rop.GUARD_CLASS)) - OPERATIONS.append(CallOperation(rop.CALL)) - OPERATIONS.append(RaisingCallOperation(rop.CALL)) - OPERATIONS.append(RaisingCallOperationGuardNoException(rop.CALL)) - OPERATIONS.append(RaisingCallOperationWrongGuardException(rop.CALL)) - OPERATIONS.append(CallOperationException(rop.CALL)) OPERATIONS.append(CondCallOperation(rop.COND_CALL)) + OPERATIONS.append(RaisingCallOperation(rop.CALL_N)) + OPERATIONS.append(RaisingCallOperationGuardNoException(rop.CALL_N)) + OPERATIONS.append(RaisingCallOperationWrongGuardException(rop.CALL_N)) OPERATIONS.append(GuardNonNullClassOperation(rop.GUARD_NONNULL_CLASS)) +for _opnum in [rop.CALL_I, rop.CALL_F, rop.CALL_N]: + OPERATIONS.append(CallOperation(_opnum)) + OPERATIONS.append(CallOperationException(_opnum)) + LLtypeOperationBuilder.OPERATIONS = OPERATIONS # ____________________________________________________________ diff --git a/rpython/jit/backend/test/test_random.py b/rpython/jit/backend/test/test_random.py --- a/rpython/jit/backend/test/test_random.py +++ b/rpython/jit/backend/test/test_random.py @@ -8,7 +8,7 @@ from rpython.jit.metainterp.resoperation import ResOperation, rop from rpython.jit.metainterp.resoperation import InputArgInt, InputArgRef from rpython.jit.metainterp.resoperation import InputArgFloat -from rpython.jit.metainterp.executor import execute_nonspec_const +from rpython.jit.metainterp.executor import _execute_arglist, wrap_constant from rpython.jit.metainterp.resoperation import opname from rpython.jit.codewriter import longlong from rpython.rtyper.lltypesystem import lltype, rstr @@ -56,11 +56,18 @@ self.fakemetainterp._got_exc = None op = ResOperation(opnum, argboxes, descr) if opnum != rop.ZERO_PTR_FIELD: - assert op.type != VOID, op - c_result = execute_nonspec_const(self.cpu, self.fakemetainterp, - opnum, argboxes, descr, - type=op.type) - op.copy_value_from(c_result) + result = _execute_arglist(self.cpu, self.fakemetainterp, + opnum, argboxes, descr) + if result is not None: + c_result = wrap_constant(result) + op.copy_value_from(c_result) + else: + import ctypes + addr = self.cpu.cast_gcref_to_int(argboxes[0].getref_base()) + offset = argboxes[1].getint() + assert (offset % ctypes.sizeof(ctypes.c_long)) == 0 + ptr = ctypes.cast(addr, ctypes.POINTER(ctypes.c_long)) + ptr[offset / ctypes.sizeof(ctypes.c_long)] = 0 self.loop.operations.append(op) return op @@ -300,6 +307,8 @@ elif v_result.type == FLOAT: builder.floatvars.append(v_result) assert self.boolres != True + elif v_result.type == VOID: + assert self.boolres != True else: raise NotImplementedError(v_result) @@ -828,6 +837,8 @@ op = self.should_fail_by if not op.getfailargs(): return False + for _fail_box in fail_args: + _fail_box.set_forwarded(None) # generate the branch: a sequence of operations that ends in a FINISH subloop = DummyLoop([]) self.subloops.append(subloop) # keep around for debugging diff --git a/rpython/jit/backend/x86/assembler.py b/rpython/jit/backend/x86/assembler.py --- a/rpython/jit/backend/x86/assembler.py +++ b/rpython/jit/backend/x86/assembler.py @@ -175,12 +175,12 @@ for i in range(4): mc.MOV_sr(i * WORD, cond_call_register_arguments[i].value) mc.CALL(eax) + self._reload_frame_if_necessary(mc) if IS_X86_64: mc.ADD(esp, imm(WORD)) else: mc.ADD(esp, imm(WORD * 7)) self.set_extra_stack_depth(mc, 0) - self._reload_frame_if_necessary(mc, align_stack=True) self.pop_gcmap(mc) # cancel the push_gcmap(store=True) in the caller self._pop_all_regs_from_frame(mc, [], supports_floats, callee_only) mc.RET() @@ -244,14 +244,15 @@ mc.MOV_rs(edi.value, WORD * 3) # load the itemsize self.set_extra_stack_depth(mc, 16) mc.CALL(imm(follow_jump(addr))) + self._reload_frame_if_necessary(mc) mc.ADD_ri(esp.value, 16 - WORD) + self.set_extra_stack_depth(mc, 0) + # mc.TEST_rr(eax.value, eax.value) mc.J_il(rx86.Conditions['Z'], 0xfffff) # patched later jz_location = mc.get_relative_pos() # nursery_free_adr = self.cpu.gc_ll_descr.get_nursery_free_addr() - self._reload_frame_if_necessary(mc, align_stack=True) - self.set_extra_stack_depth(mc, 0) self._pop_all_regs_from_frame(mc, [eax, edi], self.cpu.supports_floats) mc.MOV(edi, heap(nursery_free_adr)) # load this in EDI self.pop_gcmap(mc) # push_gcmap(store=True) done by the caller @@ -1050,8 +1051,7 @@ cb = callbuilder.CallBuilder(self, fnloc, arglocs) cb.emit_no_collect() - def _reload_frame_if_necessary(self, mc, align_stack=False, - shadowstack_reg=None): + def _reload_frame_if_necessary(self, mc, shadowstack_reg=None): gcrootmap = self.cpu.gc_ll_descr.gcrootmap if gcrootmap: if gcrootmap.is_shadow_stack: @@ -1065,7 +1065,7 @@ # frame never uses card marking, so we enforce this is not # an array self._write_barrier_fastpath(mc, wbdescr, [ebp], array=False, - is_frame=True, align_stack=align_stack) + is_frame=True) genop_int_neg = _unaryop("NEG") genop_int_invert = _unaryop("NOT") @@ -2083,7 +2083,7 @@ # ------------------- END CALL ASSEMBLER ----------------------- def _write_barrier_fastpath(self, mc, descr, arglocs, array=False, - is_frame=False, align_stack=False): + is_frame=False): # Write code equivalent to write_barrier() in the GC: it checks # a flag in the object at arglocs[0], and if set, it calls a # helper piece of assembler. The latter saves registers as needed @@ -2139,13 +2139,9 @@ # if not is_frame: mc.PUSH(loc_base) - if is_frame and align_stack: - mc.SUB_ri(esp.value, 16 - WORD) # erase the return address mc.CALL(imm(self.wb_slowpath[helper_num])) if not is_frame: mc.stack_frame_size_delta(-WORD) - if is_frame and align_stack: - mc.ADD_ri(esp.value, 16 - WORD) # erase the return address if card_marking: # The helper ends again with a check of the flag in the object. diff --git a/rpython/jit/backend/x86/regalloc.py b/rpython/jit/backend/x86/regalloc.py --- a/rpython/jit/backend/x86/regalloc.py +++ b/rpython/jit/backend/x86/regalloc.py @@ -134,6 +134,8 @@ self.final_jump_op = None def _prepare(self, inputargs, operations, allgcrefs): + for box in inputargs: + assert box.get_forwarded() is None cpu = self.assembler.cpu self.fm = X86FrameManager(cpu.get_baseofs_of_frame_field()) operations = cpu.gc_ll_descr.rewrite_assembler(cpu, operations, diff --git a/rpython/jit/metainterp/compile.py b/rpython/jit/metainterp/compile.py --- a/rpython/jit/metainterp/compile.py +++ b/rpython/jit/metainterp/compile.py @@ -2,7 +2,7 @@ from rpython.rtyper.lltypesystem import lltype, llmemory from rpython.rtyper.annlowlevel import cast_instance_to_gcref from rpython.rlib.objectmodel import we_are_translated -from rpython.rlib.debug import debug_start, debug_stop, debug_print +from rpython.rlib.debug import debug_start, debug_stop, debug_print, have_debug_prints from rpython.rlib.rarithmetic import r_uint, intmask from rpython.rlib import rstack from rpython.rlib.jit import JitDebugInfo, Counters, dont_look_inside @@ -531,6 +531,7 @@ loop.inputargs, operations, original_jitcell_token, name=loopname, + log=have_debug_prints(), memo=memo) finally: debug_stop("jit-backend") @@ -577,7 +578,8 @@ try: asminfo = do_compile_bridge(metainterp_sd, faildescr, inputargs, operations, - original_loop_token, memo) + original_loop_token, have_debug_prints(), + memo) finally: debug_stop("jit-backend") metainterp_sd.profiler.end_backend() diff --git a/rpython/jit/metainterp/optimizeopt/optimizer.py b/rpython/jit/metainterp/optimizeopt/optimizer.py --- a/rpython/jit/metainterp/optimizeopt/optimizer.py +++ b/rpython/jit/metainterp/optimizeopt/optimizer.py @@ -256,7 +256,6 @@ self.optearlyforce = None self.optunroll = None - self._emitting = True self._last_guard_op = None self.set_optimizations(optimizations) @@ -586,6 +585,7 @@ self.force_box(farg) elif op.can_raise(): self.exception_might_have_happened = True +<<<<<<< local if self._emitting: if op.has_no_side_effect() or op.is_guard() or op.is_jit_debug(): pass @@ -593,6 +593,10 @@ self._last_guard_op = None self._really_emitted_operation = op self._newoperations.append(op) +======= + self._really_emitted_operation = op + self._newoperations.append(op) +>>>>>>> other def _copy_resume_data_from(self, guard_op, last_guard_op): descr = compile.invent_fail_descr_for_op(guard_op.getopnum(), self) diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py b/rpython/jit/metainterp/optimizeopt/unroll.py --- a/rpython/jit/metainterp/optimizeopt/unroll.py +++ b/rpython/jit/metainterp/optimizeopt/unroll.py @@ -434,18 +434,6 @@ return label_args - def is_call_pure_with_exception(self, op): - if op.is_call_pure(): - effectinfo = op.getdescr().get_extra_info() - # Assert that only EF_ELIDABLE_CANNOT_RAISE or - # EF_ELIDABLE_OR_MEMORYERROR end up here, not - # for example EF_ELIDABLE_CAN_RAISE. - assert effectinfo.extraeffect in ( - effectinfo.EF_ELIDABLE_CANNOT_RAISE, - effectinfo.EF_ELIDABLE_OR_MEMORYERROR) - return effectinfo.extraeffect != effectinfo.EF_ELIDABLE_CANNOT_RAISE - return False - class UnrollInfo(LoopInfo): """ A state after optimizing the peeled loop, contains the following: _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit