Author: Armin Rigo <ar...@tunes.org> Branch: stmgc-c7 Changeset: r71474:e7566140001b Date: 2014-05-12 19:58 +0200 http://bitbucket.org/pypy/pypy/changeset/e7566140001b/
Log: Add an optional "pure" flag to bh_getfield_gc & friends, as well as to raw_load. diff --git a/rpython/jit/backend/llgraph/runner.py b/rpython/jit/backend/llgraph/runner.py --- a/rpython/jit/backend/llgraph/runner.py +++ b/rpython/jit/backend/llgraph/runner.py @@ -456,32 +456,37 @@ bh_call_f = _do_call bh_call_v = _do_call - def bh_getfield_gc(self, p, descr): + def _bh_getfield(self, p, descr, pure=False): p = support.cast_arg(lltype.Ptr(descr.S), p) return support.cast_result(descr.FIELD, getattr(p, descr.fieldname)) - bh_getfield_gc_pure = bh_getfield_gc - bh_getfield_gc_i = bh_getfield_gc - bh_getfield_gc_r = bh_getfield_gc - bh_getfield_gc_f = bh_getfield_gc + direct_getfield_gc = _bh_getfield + direct_getfield_gc_pure = _bh_getfield + direct_getfield_raw = _bh_getfield + direct_getfield_raw_pure = _bh_getfield - bh_getfield_raw = bh_getfield_gc - bh_getfield_raw_pure = bh_getfield_raw - bh_getfield_raw_i = bh_getfield_raw - bh_getfield_raw_r = bh_getfield_raw - bh_getfield_raw_f = bh_getfield_raw + bh_getfield_gc_i = _bh_getfield + bh_getfield_gc_r = _bh_getfield + bh_getfield_gc_f = _bh_getfield - def bh_setfield_gc(self, p, newvalue, descr): + bh_getfield_raw_i = _bh_getfield + bh_getfield_raw_r = _bh_getfield + bh_getfield_raw_f = _bh_getfield + + def _bh_setfield(self, p, newvalue, descr): p = support.cast_arg(lltype.Ptr(descr.S), p) setattr(p, descr.fieldname, support.cast_arg(descr.FIELD, newvalue)) - bh_setfield_gc_i = bh_setfield_gc - bh_setfield_gc_r = bh_setfield_gc - bh_setfield_gc_f = bh_setfield_gc + direct_setfield_gc = _bh_setfield + direct_setfield_raw = _bh_setfield - bh_setfield_raw = bh_setfield_gc - bh_setfield_raw_i = bh_setfield_raw - bh_setfield_raw_f = bh_setfield_raw + bh_setfield_gc_i = _bh_setfield + bh_setfield_gc_r = _bh_setfield + bh_setfield_gc_f = _bh_setfield + + bh_setfield_raw = _bh_setfield + bh_setfield_raw_i = _bh_setfield + bh_setfield_raw_f = _bh_setfield def bh_arraylen_gc(self, a, descr): array = a._obj.container @@ -489,35 +494,39 @@ array = getattr(array, descr.OUTERA._arrayfld) return array.getlength() - def bh_getarrayitem_gc(self, a, index, descr): + def _bh_getarrayitem(self, a, index, descr, pure=False): a = support.cast_arg(lltype.Ptr(descr.A), a) array = a._obj return support.cast_result(descr.A.OF, array.getitem(index)) - bh_getarrayitem_gc_pure = bh_getarrayitem_gc - bh_getarrayitem_gc_i = bh_getarrayitem_gc - bh_getarrayitem_gc_r = bh_getarrayitem_gc - bh_getarrayitem_gc_f = bh_getarrayitem_gc + direct_getarrayitem_gc = _bh_getarrayitem + direct_getarrayitem_gc_pure = _bh_getarrayitem + direct_getarrayitem_raw = _bh_getarrayitem + direct_getarrayitem_raw_pure = _bh_getarrayitem - bh_getarrayitem_raw = bh_getarrayitem_gc - bh_getarrayitem_raw_pure = bh_getarrayitem_raw - bh_getarrayitem_raw_i = bh_getarrayitem_raw - bh_getarrayitem_raw_r = bh_getarrayitem_raw - bh_getarrayitem_raw_f = bh_getarrayitem_raw + bh_getarrayitem_gc_i = _bh_getarrayitem + bh_getarrayitem_gc_r = _bh_getarrayitem + bh_getarrayitem_gc_f = _bh_getarrayitem - def bh_setarrayitem_gc(self, a, index, item, descr): + bh_getarrayitem_raw_i = _bh_getarrayitem + bh_getarrayitem_raw_r = _bh_getarrayitem + bh_getarrayitem_raw_f = _bh_getarrayitem + + def _bh_setarrayitem(self, a, index, item, descr): a = support.cast_arg(lltype.Ptr(descr.A), a) array = a._obj array.setitem(index, support.cast_arg(descr.A.OF, item)) - bh_setarrayitem_gc_i = bh_setarrayitem_gc - bh_setarrayitem_gc_r = bh_setarrayitem_gc - bh_setarrayitem_gc_f = bh_setarrayitem_gc + direct_setarrayitem_gc = _bh_setarrayitem + direct_setarrayitem_raw = _bh_setarrayitem - bh_setarrayitem_raw = bh_setarrayitem_gc - bh_setarrayitem_raw_i = bh_setarrayitem_raw - bh_setarrayitem_raw_r = bh_setarrayitem_raw - bh_setarrayitem_raw_f = bh_setarrayitem_raw + bh_setarrayitem_gc_i = _bh_setarrayitem + bh_setarrayitem_gc_r = _bh_setarrayitem + bh_setarrayitem_gc_f = _bh_setarrayitem + + bh_setarrayitem_raw_i = _bh_setarrayitem + bh_setarrayitem_raw_r = _bh_setarrayitem + bh_setarrayitem_raw_f = _bh_setarrayitem def bh_getinteriorfield_gc(self, a, index, descr): array = a._obj.container @@ -1072,12 +1081,17 @@ return _op_default_implementation def _new_execute(opname): + if hasattr(LLGraphCPU, 'direct_' + opname): + methname = 'direct_' + opname + else: + methname = 'bh_' + opname + # def execute(self, descr, *args): if descr is not None: new_args = args + (descr,) else: new_args = args - return getattr(self.cpu, 'bh_' + opname)(*new_args) + return getattr(self.cpu, methname)(*new_args) execute.func_name = 'execute_' + opname return execute diff --git a/rpython/jit/backend/llsupport/llmodel.py b/rpython/jit/backend/llsupport/llmodel.py --- a/rpython/jit/backend/llsupport/llmodel.py +++ b/rpython/jit/backend/llsupport/llmodel.py @@ -385,14 +385,14 @@ # ____________________ RAW PRIMITIVES ________________________ @specialize.argtype(1) - def read_int_at_mem(self, gcref, ofs, size, sign): + def read_int_at_mem(self, gcref, ofs, size, sign, pure=False): for STYPE, UTYPE, itemsize in unroll_basic_sizes: if size == itemsize: if sign: - val = llop.raw_load(STYPE, gcref, ofs) + val = llop.raw_load(STYPE, gcref, ofs, pure) val = rffi.cast(lltype.Signed, val) else: - val = llop.raw_load(UTYPE, gcref, ofs) + val = llop.raw_load(UTYPE, gcref, ofs, pure) val = rffi.cast(lltype.Signed, val) return val else: @@ -409,8 +409,8 @@ raise NotImplementedError("size = %d" % size) @specialize.argtype(1) - def read_ref_at_mem(self, gcref, ofs): - return llop.raw_load(llmemory.GCREF, gcref, ofs) + def read_ref_at_mem(self, gcref, ofs, pure=False): + return llop.raw_load(llmemory.GCREF, gcref, ofs, pure) # non-@specialized: must only be called with llmemory.GCREF def write_ref_at_mem(self, gcref, ofs, newvalue): @@ -418,8 +418,8 @@ # the write barrier is implied above @specialize.argtype(1) - def read_float_at_mem(self, gcref, ofs): - return llop.raw_load(longlong.FLOATSTORAGE, gcref, ofs) + def read_float_at_mem(self, gcref, ofs, pure=False): + return llop.raw_load(longlong.FLOATSTORAGE, gcref, ofs, pure) @specialize.argtype(1) def write_float_at_mem(self, gcref, ofs, newvalue): @@ -461,23 +461,23 @@ def bh_arraylen_gc(self, array, arraydescr): assert isinstance(arraydescr, ArrayDescr) ofs = arraydescr.lendescr.offset - return self.read_int_at_mem(array, ofs, WORD, 1) + return self.read_int_at_mem(array, ofs, WORD, 1, True) @specialize.argtype(1) - def bh_getarrayitem_gc_i(self, gcref, itemindex, arraydescr): + def bh_getarrayitem_gc_i(self, gcref, itemindex, arraydescr, pure=False): ofs, size, sign = self.unpack_arraydescr_size(arraydescr) return self.read_int_at_mem(gcref, ofs + itemindex * size, size, - sign) + sign, pure) - def bh_getarrayitem_gc_r(self, gcref, itemindex, arraydescr): + def bh_getarrayitem_gc_r(self, gcref, itemindex, arraydescr, pure=False): ofs = self.unpack_arraydescr(arraydescr) - return self.read_ref_at_mem(gcref, itemindex * WORD + ofs) + return self.read_ref_at_mem(gcref, itemindex * WORD + ofs, pure) @specialize.argtype(1) - def bh_getarrayitem_gc_f(self, gcref, itemindex, arraydescr): + def bh_getarrayitem_gc_f(self, gcref, itemindex, arraydescr, pure=False): ofs = self.unpack_arraydescr(arraydescr) fsize = rffi.sizeof(longlong.FLOATSTORAGE) - return self.read_float_at_mem(gcref, itemindex * fsize + ofs) + return self.read_float_at_mem(gcref, itemindex * fsize + ofs, pure) @specialize.argtype(1) def bh_setarrayitem_gc_i(self, gcref, itemindex, newvalue, arraydescr): @@ -557,19 +557,19 @@ return ord(u.chars[index]) @specialize.argtype(1) - def bh_getfield_gc_i(self, struct, fielddescr): + def bh_getfield_gc_i(self, struct, fielddescr, pure=False): ofs, size, sign = self.unpack_fielddescr_size(fielddescr) - return self.read_int_at_mem(struct, ofs, size, sign) + return self.read_int_at_mem(struct, ofs, size, sign, pure) @specialize.argtype(1) - def bh_getfield_gc_r(self, struct, fielddescr): + def bh_getfield_gc_r(self, struct, fielddescr, pure=False): ofs = self.unpack_fielddescr(fielddescr) - return self.read_ref_at_mem(struct, ofs) + return self.read_ref_at_mem(struct, ofs, pure) @specialize.argtype(1) - def bh_getfield_gc_f(self, struct, fielddescr): + def bh_getfield_gc_f(self, struct, fielddescr, pure=False): ofs = self.unpack_fielddescr(fielddescr) - return self.read_float_at_mem(struct, ofs) + return self.read_float_at_mem(struct, ofs, pure) bh_getfield_raw_i = bh_getfield_gc_i bh_getfield_raw_r = bh_getfield_gc_r diff --git a/rpython/jit/backend/model.py b/rpython/jit/backend/model.py --- a/rpython/jit/backend/model.py +++ b/rpython/jit/backend/model.py @@ -199,25 +199,25 @@ # lltype specific operations # -------------------------- - def bh_getarrayitem_gc_i(self, array, index, arraydescr): + def bh_getarrayitem_gc_i(self, array, index, arraydescr, pure=False): raise NotImplementedError - def bh_getarrayitem_gc_r(self, array, index, arraydescr): + def bh_getarrayitem_gc_r(self, array, index, arraydescr, pure=False): raise NotImplementedError - def bh_getarrayitem_gc_f(self, array, index, arraydescr): + def bh_getarrayitem_gc_f(self, array, index, arraydescr, pure=False): raise NotImplementedError - def bh_getfield_gc_i(self, struct, fielddescr): + def bh_getfield_gc_i(self, struct, fielddescr, pure=False): raise NotImplementedError - def bh_getfield_gc_r(self, struct, fielddescr): + def bh_getfield_gc_r(self, struct, fielddescr, pure=False): raise NotImplementedError - def bh_getfield_gc_f(self, struct, fielddescr): + def bh_getfield_gc_f(self, struct, fielddescr, pure=False): raise NotImplementedError - def bh_getfield_raw_i(self, struct, fielddescr): + def bh_getfield_raw_i(self, struct, fielddescr, pure=False): raise NotImplementedError - def bh_getfield_raw_r(self, struct, fielddescr): + def bh_getfield_raw_r(self, struct, fielddescr, pure=False): raise NotImplementedError - def bh_getfield_raw_f(self, struct, fielddescr): + def bh_getfield_raw_f(self, struct, fielddescr, pure=False): raise NotImplementedError def bh_new(self, sizedescr): 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 @@ -2000,7 +2000,7 @@ r = self.cpu.bh_getfield_gc_i(r1.value, descrshort) assert r == 1313 self.cpu.bh_setfield_gc_i(r1.value, 1333, descrshort) - r = self.cpu.bh_getfield_gc_i(r1.value, descrshort) + r = self.cpu.bh_getfield_gc_i(r1.value, descrshort, pure=True) assert r == 1333 r = self.execute_operation(rop.GETFIELD_GC, [r1], 'int', descr=descrshort) @@ -2938,7 +2938,7 @@ b = lltype.malloc(B, 4) b[3] = a x = cpu.bh_getarrayitem_gc_r( - lltype.cast_opaque_ptr(llmemory.GCREF, b), 3, descr_B) + lltype.cast_opaque_ptr(llmemory.GCREF, b), 3, descr_B, pure=True) assert lltype.cast_opaque_ptr(lltype.Ptr(A), x) == a if self.cpu.supports_floats: C = lltype.GcArray(lltype.Float) @@ -2993,6 +2993,11 @@ descrfld_rx) assert x == ord('?') # + x = cpu.bh_getfield_raw_i( + heaptracker.adr2int(llmemory.cast_ptr_to_adr(rs)), + descrfld_rx, pure=True) + assert x == ord('?') + # cpu.bh_setfield_raw_i( heaptracker.adr2int(llmemory.cast_ptr_to_adr(rs)), ord('!'), descrfld_rx) @@ -3473,7 +3478,10 @@ expected = rffi.cast(lltype.Signed, rffi.cast(RESTYPE, value)) a[3] = rffi.cast(RESTYPE, value) a_rawint = heaptracker.adr2int(llmemory.cast_ptr_to_adr(a)) - x = cpu.bh_getarrayitem_raw_i(a_rawint, 3, descrarray) + x = cpu.bh_getarrayitem_raw_i(a_rawint, 3, descrarray, pure=False) + assert x == expected, ( + "%r: got %r, expected %r" % (RESTYPE, x, expected)) + x = cpu.bh_getarrayitem_raw_i(a_rawint, 3, descrarray, pure=True) assert x == expected, ( "%r: got %r, expected %r" % (RESTYPE, x, expected)) lltype.free(a, flavor='raw') diff --git a/rpython/jit/metainterp/executor.py b/rpython/jit/metainterp/executor.py --- a/rpython/jit/metainterp/executor.py +++ b/rpython/jit/metainterp/executor.py @@ -84,24 +84,39 @@ if condbox.getint(): do_call(cpu, metainterp, argboxes[1:], descr) -def do_getarrayitem_gc(cpu, _, arraybox, indexbox, arraydescr): +def _do_getarrayitem_gc(cpu, pure, arraybox, indexbox, arraydescr): array = arraybox.getref_base() index = indexbox.getint() if arraydescr.is_array_of_pointers(): - return BoxPtr(cpu.bh_getarrayitem_gc_r(array, index, arraydescr)) + return BoxPtr(cpu.bh_getarrayitem_gc_r(array, index, arraydescr, pure)) elif arraydescr.is_array_of_floats(): - return BoxFloat(cpu.bh_getarrayitem_gc_f(array, index, arraydescr)) + return BoxFloat(cpu.bh_getarrayitem_gc_f(array, index, arraydescr, + pure)) else: - return BoxInt(cpu.bh_getarrayitem_gc_i(array, index, arraydescr)) + return BoxInt(cpu.bh_getarrayitem_gc_i(array, index, arraydescr, pure)) -def do_getarrayitem_raw(cpu, _, arraybox, indexbox, arraydescr): +def do_getarrayitem_gc(cpu, _, arraybox, indexbox, arraydescr): + return _do_getarrayitem_gc(cpu, False, arraybox, indexbox, arraydescr) + +def do_getarrayitem_gc_pure(cpu, _, arraybox, indexbox, arraydescr): + return _do_getarrayitem_gc(cpu, True, arraybox, indexbox, arraydescr) + +def _do_getarrayitem_raw(cpu, pure, arraybox, indexbox, arraydescr): array = arraybox.getint() index = indexbox.getint() assert not arraydescr.is_array_of_pointers() if arraydescr.is_array_of_floats(): - return BoxFloat(cpu.bh_getarrayitem_raw_f(array, index, arraydescr)) + return BoxFloat(cpu.bh_getarrayitem_raw_f(array, index, arraydescr, + pure)) else: - return BoxInt(cpu.bh_getarrayitem_raw_i(array, index, arraydescr)) + return BoxInt(cpu.bh_getarrayitem_raw_i(array, index, arraydescr, + pure)) + +def do_getarrayitem_raw(cpu, _, arraybox, indexbox, arraydescr): + return _do_getarrayitem_raw(cpu, False, arraybox, indexbox, arraydescr) + +def do_getarrayitem_raw_pure(cpu, _, arraybox, indexbox, arraydescr): + return _do_getarrayitem_raw(cpu, True, arraybox, indexbox, arraydescr) def do_setarrayitem_gc(cpu, _, arraybox, indexbox, itembox, arraydescr): array = arraybox.getref_base() @@ -147,24 +162,36 @@ else: cpu.bh_setinteriorfield_gc_i(array, index, valuebox.getint(), descr) -def do_getfield_gc(cpu, _, structbox, fielddescr): +def _do_getfield_gc(cpu, pure, structbox, fielddescr): struct = structbox.getref_base() if fielddescr.is_pointer_field(): - return BoxPtr(cpu.bh_getfield_gc_r(struct, fielddescr)) + return BoxPtr(cpu.bh_getfield_gc_r(struct, fielddescr, pure)) elif fielddescr.is_float_field(): - return BoxFloat(cpu.bh_getfield_gc_f(struct, fielddescr)) + return BoxFloat(cpu.bh_getfield_gc_f(struct, fielddescr, pure)) else: - return BoxInt(cpu.bh_getfield_gc_i(struct, fielddescr)) + return BoxInt(cpu.bh_getfield_gc_i(struct, fielddescr, pure)) -def do_getfield_raw(cpu, _, structbox, fielddescr): +def do_getfield_gc(cpu, _, structbox, fielddescr): + return _do_getfield_gc(cpu, False, structbox, fielddescr) + +def do_getfield_gc_pure(cpu, _, structbox, fielddescr): + return _do_getfield_gc(cpu, True, structbox, fielddescr) + +def _do_getfield_raw(cpu, pure, structbox, fielddescr): check_descr(fielddescr) struct = structbox.getint() if fielddescr.is_pointer_field(): - return BoxPtr(cpu.bh_getfield_raw_r(struct, fielddescr)) + return BoxPtr(cpu.bh_getfield_raw_r(struct, fielddescr, pure)) elif fielddescr.is_float_field(): - return BoxFloat(cpu.bh_getfield_raw_f(struct, fielddescr)) + return BoxFloat(cpu.bh_getfield_raw_f(struct, fielddescr, pure)) else: - return BoxInt(cpu.bh_getfield_raw_i(struct, fielddescr)) + return BoxInt(cpu.bh_getfield_raw_i(struct, fielddescr, pure)) + +def do_getfield_raw(cpu, _, structbox, fielddescr): + return _do_getfield_raw(cpu, False, structbox, fielddescr) + +def do_getfield_raw_pure(cpu, _, structbox, fielddescr): + return _do_getfield_raw(cpu, True, structbox, fielddescr) def do_setfield_gc(cpu, _, structbox, itembox, fielddescr): struct = structbox.getref_base() @@ -310,14 +337,6 @@ execute[value] = globals()[name] continue # - # Maybe the same without the _PURE suffix? - if key.endswith('_PURE'): - key = key[:-5] - name = 'do_' + key.lower() - if name in globals(): - execute[value] = globals()[name] - continue - # # If missing, fallback to the bhimpl_xxx() method of the # blackhole interpreter. This only works if there is a # method of the exact same name and it accepts simple @@ -338,6 +357,7 @@ rop.DEBUG_MERGE_POINT, rop.JIT_DEBUG, rop.SETARRAYITEM_RAW, + rop.CALL_PURE, rop.CALL_RELEASE_GIL, rop.QUASIIMMUT_FIELD, rop.CALL_MALLOC_GC, diff --git a/rpython/rtyper/lltypesystem/opimpl.py b/rpython/rtyper/lltypesystem/opimpl.py --- a/rpython/rtyper/lltypesystem/opimpl.py +++ b/rpython/rtyper/lltypesystem/opimpl.py @@ -699,7 +699,7 @@ p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs) p[0] = newvalue -def op_raw_load(TVAL, p, ofs): +def op_raw_load(TVAL, p, ofs, pure=False): from rpython.rtyper.lltypesystem import rffi p = rffi.cast(llmemory.Address, p) p = rffi.cast(rffi.CArrayPtr(TVAL), p + ofs) diff --git a/rpython/translator/stm/readbarrier.py b/rpython/translator/stm/readbarrier.py --- a/rpython/translator/stm/readbarrier.py +++ b/rpython/translator/stm/readbarrier.py @@ -1,6 +1,7 @@ from rpython.flowspace.model import SpaceOperation, Constant, Variable from rpython.translator.unsimplify import varoftype from rpython.rtyper.lltypesystem import lltype +from rpython.translator.stm.support import is_immutable READ_OPS = set(['getfield', 'getarrayitem', 'getinteriorfield', 'raw_load']) @@ -18,22 +19,6 @@ else: raise AssertionError(v) -def is_immutable(op): - if op.opname in ('getfield', 'setfield'): - STRUCT = op.args[0].concretetype.TO - return STRUCT._immutable_field(op.args[1].value) - if op.opname in ('getarrayitem', 'setarrayitem'): - ARRAY = op.args[0].concretetype.TO - return ARRAY._immutable_field() - if op.opname == 'getinteriorfield': - OUTER = op.args[0].concretetype.TO - return OUTER._immutable_interiorfield(unwraplist(op.args[1:])) - if op.opname == 'setinteriorfield': - OUTER = op.args[0].concretetype.TO - return OUTER._immutable_interiorfield(unwraplist(op.args[1:-1])) - if op.opname in ('raw_load', 'raw_store'): - return False - def insert_stm_read_barrier(transformer, graph): # We need to put enough 'stm_read' in the graph so that any diff --git a/rpython/translator/stm/support.py b/rpython/translator/stm/support.py --- a/rpython/translator/stm/support.py +++ b/rpython/translator/stm/support.py @@ -12,6 +12,8 @@ if op.opname == 'setinteriorfield': OUTER = op.args[0].concretetype.TO return OUTER._immutable_interiorfield(unwraplist(op.args[1:-1])) - if op.opname in ('raw_load', 'raw_store'): + if op.opname == 'raw_load': + return len(op.args) >= 3 and bool(op.args[2].value) + if op.opname == 'raw_store': return False raise AssertionError(op) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit