Author: Maciej Fijalkowski <fij...@gmail.com> Branch: ffi-backend Changeset: r55803:fd15b25e46da Date: 2012-06-24 17:42 +0200 http://bitbucket.org/pypy/pypy/changeset/fd15b25e46da/
Log: (arigo, fijal) a half broken implementation of raw_store in the jit diff --git a/pypy/jit/codewriter/effectinfo.py b/pypy/jit/codewriter/effectinfo.py --- a/pypy/jit/codewriter/effectinfo.py +++ b/pypy/jit/codewriter/effectinfo.py @@ -81,9 +81,13 @@ OS_LLONG_U_TO_FLOAT = 94 # OS_MATH_SQRT = 100 + # + OS_RAW_MALLOC_VARSIZE = 110 + OS_RAW_FREE = 111 # for debugging: - _OS_CANRAISE = set([OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL]) + _OS_CANRAISE = set([OS_NONE, OS_STR2UNICODE, OS_LIBFFI_CALL, + OS_RAW_MALLOC_VARSIZE]) def __new__(cls, readonly_descrs_fields, readonly_descrs_arrays, write_descrs_fields, write_descrs_arrays, diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py --- a/pypy/jit/codewriter/jtransform.py +++ b/pypy/jit/codewriter/jtransform.py @@ -11,6 +11,7 @@ from pypy.objspace.flow.model import SpaceOperation, Variable, Constant, c_last_exception from pypy.rlib import objectmodel from pypy.rlib.jit import _we_are_jitted +from pypy.rlib.rgc import lltype_is_gc from pypy.rpython.lltypesystem import lltype, llmemory, rstr, rclass, rffi from pypy.rpython.rclass import IR_QUASIIMMUTABLE, IR_QUASIIMMUTABLE_ARRAY from pypy.translator.simplify import get_funcobj @@ -208,6 +209,10 @@ if op.args[0] in self.vable_array_vars: self.vable_array_vars[op.result]= self.vable_array_vars[op.args[0]] + def rewrite_op_cast_ptr_to_adr(self, op): + if lltype_is_gc(op.args[0].concretetype): + raise Exception("cast_ptr_to_adr for GC types unsupported") + def rewrite_op_cast_pointer(self, op): newop = self.rewrite_op_same_as(op) assert newop is None @@ -520,9 +525,12 @@ name += '_add_memory_pressure' if not track_allocation: name += '_no_track_allocation' - return self._do_builtin_call(op, name, args, - extra = (TYPE,), - extrakey = TYPE) + op1 = self.prepare_builtin_call(op, name, args, (TYPE,), TYPE) + if name == 'raw_malloc_varsize': + return self._handle_oopspec_call(op1, args, + EffectInfo.OS_RAW_MALLOC_VARSIZE, + EffectInfo.EF_CAN_RAISE) + return self.rewrite_op_direct_call(op1) def rewrite_op_malloc_varsize(self, op): if op.args[1].value['flavor'] == 'raw': @@ -550,8 +558,13 @@ name = 'raw_free' if not track_allocation: name += '_no_track_allocation' - return self._do_builtin_call(op, name, [op.args[0]], - extra = (STRUCT,), extrakey = STRUCT) + op1 = self.prepare_builtin_call(op, name, [op.args[0]], (STRUCT,), + STRUCT) + if name == 'raw_free': + return self._handle_oopspec_call(op1, [op.args[0]], + EffectInfo.OS_RAW_FREE, + EffectInfo.EF_CANNOT_RAISE) + return self.rewrite_op_direct_call(op1) def rewrite_op_getarrayitem(self, op): ARRAY = op.args[0].concretetype.TO @@ -840,6 +853,12 @@ return SpaceOperation('setinteriorfield_gc_%s' % kind, args, op.result) + def rewrite_op_raw_store(self, op): + kind = getkind(op.args[3].concretetype)[0] + return SpaceOperation('raw_store_%s' % kind, + [op.args[0], op.args[2], op.args[3]], + None) + def _rewrite_equality(self, op, opname): arg0, arg1 = op.args if isinstance(arg0, Constant) and not arg0.value: @@ -850,7 +869,7 @@ return self._rewrite_symmetric(op) def _is_gc(self, v): - return getattr(getattr(v.concretetype, "TO", None), "_gckind", "?") == 'gc' + return lltype_is_gc(v.concretetype) def _is_rclass_instance(self, v): return lltype._castdepth(v.concretetype.TO, rclass.OBJECT) >= 0 diff --git a/pypy/jit/codewriter/test/test_jtransform.py b/pypy/jit/codewriter/test/test_jtransform.py --- a/pypy/jit/codewriter/test/test_jtransform.py +++ b/pypy/jit/codewriter/test/test_jtransform.py @@ -123,6 +123,7 @@ INT = lltype.Signed UNICHAR = lltype.UniChar FLOAT = lltype.Float + ARRAYPTR = rffi.CArrayPtr(lltype.Signed) argtypes = { EI.OS_MATH_SQRT: ([FLOAT], FLOAT), EI.OS_STR2UNICODE:([PSTR], PUNICODE), @@ -139,16 +140,26 @@ EI.OS_UNIEQ_NONNULL_CHAR: ([PUNICODE, UNICHAR], INT), EI.OS_UNIEQ_CHECKNULL_CHAR: ([PUNICODE, UNICHAR], INT), EI.OS_UNIEQ_LENGTHOK: ([PUNICODE, PUNICODE], INT), + EI.OS_RAW_MALLOC_VARSIZE: ([INT], ARRAYPTR), + EI.OS_RAW_FREE: ([ARRAYPTR], lltype.Void), } argtypes = argtypes[oopspecindex] assert argtypes[0] == [v.concretetype for v in op.args[1:]] assert argtypes[1] == op.result.concretetype if oopspecindex == EI.OS_STR2UNICODE: assert extraeffect == EI.EF_ELIDABLE_CAN_RAISE + elif oopspecindex == EI.OS_RAW_MALLOC_VARSIZE: + assert extraeffect == EI.EF_CAN_RAISE + elif oopspecindex == EI.OS_RAW_FREE: + assert extraeffect == EI.EF_CANNOT_RAISE else: assert extraeffect == EI.EF_ELIDABLE_CANNOT_RAISE return 'calldescr-%d' % oopspecindex + def calldescr_canraise(self, calldescr): + EI = effectinfo.EffectInfo + if calldescr == 'calldescr-%d' % EI.OS_RAW_MALLOC_VARSIZE: + return True return False @@ -547,10 +558,13 @@ flags = Constant({'flavor': 'raw'}, lltype.Void) op = SpaceOperation('malloc_varsize', [Constant(S, lltype.Void), flags, v1], v) - tr = Transformer(FakeCPU(), FakeResidualCallControl()) + tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) op0, op1 = tr.rewrite_operation(op) assert op0.opname == 'residual_call_ir_i' assert op0.args[0].value == 'raw_malloc_varsize' # pseudo-function as a str + assert (op0.args[1] == 'calldescr-%d' % + effectinfo.EffectInfo.OS_RAW_MALLOC_VARSIZE) + assert op1.opname == '-live-' assert op1.args == [] @@ -591,21 +605,28 @@ assert op1.args == [] def test_raw_free(): - S = lltype.Struct('dummy', ('x', lltype.Signed)) - for flag in [True, False]: - flags = Constant({'flavor': 'raw', 'track_allocation': flag}, - lltype.Void) - op = SpaceOperation('free', [varoftype(lltype.Ptr(S)), flags], - varoftype(lltype.Void)) - tr = Transformer(FakeCPU(), FakeResidualCallControl()) - op0, op1 = tr.rewrite_operation(op) - assert op0.opname == 'residual_call_ir_v' - if flag: - pseudo_op_name = 'raw_free' - else: - pseudo_op_name = 'raw_free_no_track_allocation' - assert op0.args[0].value == pseudo_op_name # pseudo-function as a str - assert op1.opname == '-live-' + S = rffi.CArray(lltype.Signed) + flags = Constant({'flavor': 'raw', 'track_allocation': True}, + lltype.Void) + op = SpaceOperation('free', [varoftype(lltype.Ptr(S)), flags], + varoftype(lltype.Void)) + tr = Transformer(FakeCPU(), FakeBuiltinCallControl()) + op0 = tr.rewrite_operation(op) + assert op0.opname == 'residual_call_ir_v' + assert op0.args[0].value == 'raw_free' + assert op0.args[1] == 'calldescr-%d' % effectinfo.EffectInfo.OS_RAW_FREE + +def test_raw_free_no_track_allocation(): + S = rffi.CArray(lltype.Signed) + flags = Constant({'flavor': 'raw', 'track_allocation': False}, + lltype.Void) + op = SpaceOperation('free', [varoftype(lltype.Ptr(S)), flags], + varoftype(lltype.Void)) + tr = Transformer(FakeCPU(), FakeResidualCallControl()) + op0, op1 = tr.rewrite_operation(op) + assert op0.opname == 'residual_call_ir_v' + assert op0.args[0].value == 'raw_free_no_track_allocation' + assert op1.opname == '-live-' def test_rename_on_links(): v1 = Variable() @@ -621,6 +642,13 @@ assert block.exits[0].target is block2 assert block.exits[0].args == [v1] +def test_cast_ptr_to_adr(): + t = Transformer(FakeCPU(), None) + v = varoftype(lltype.Ptr(lltype.Array())) + v2 = varoftype(llmemory.Address) + op1 = t.rewrite_operation(SpaceOperation('cast_ptr_to_adr', [v], v2)) + assert op1 is None + def test_int_eq(): v1 = varoftype(lltype.Signed) v2 = varoftype(lltype.Signed) @@ -830,6 +858,15 @@ op1 = Transformer(FakeCPU()).rewrite_operation(op) assert not op1 +def test_raw_store(): + v_storage = varoftype(llmemory.Address) + v_typ = varoftype(lltype.Void) + v_index = varoftype(lltype.Signed) + v_item = varoftype(lltype.Signed) # for example + op = SpaceOperation('raw_store', [v_storage, v_typ, v_index, v_item]) + op1 = Transformer(FakeCPU()).rewrite_operation(op) + assert op1.opname == 'raw_store' + def test_promote_1(): v1 = varoftype(lltype.Signed) v2 = varoftype(lltype.Signed) diff --git a/pypy/jit/metainterp/test/test_rawmem.py b/pypy/jit/metainterp/test/test_rawmem.py --- a/pypy/jit/metainterp/test/test_rawmem.py +++ b/pypy/jit/metainterp/test/test_rawmem.py @@ -1,6 +1,7 @@ from pypy.jit.metainterp.test.support import LLJitMixin from pypy.rpython.lltypesystem import lltype, rffi - +from pypy.rlib.rawstorage import (alloc_raw_storage, raw_storage_setitem, + free_raw_storage) class TestJITRawMem(LLJitMixin): def test_cast_void_ptr(self): @@ -18,7 +19,7 @@ s += rffi.cast(lltype.Ptr(TP), a.storage)[0] lltype.free(x, flavor="raw") return s - res = self.interp_operations(f, [10]) + self.interp_operations(f, [10]) def test_fixed_size_malloc(self): TIMEVAL = lltype.Struct('dummy', ('tv_sec', rffi.LONG), ('tv_usec', rffi.LONG)) @@ -30,3 +31,14 @@ assert res == 42 self.check_operations_history({'call': 2, 'guard_no_exception': 1, 'finish': 1}) + + def test_raw_storage(self): + def f(): + p = alloc_raw_storage(15) + raw_storage_setitem(p, 3, 24) + free_raw_storage(p) + return 42 + res = self.interp_operations(f, []) + assert res == 42 + self.check_operations_history({'call': 2, 'guard_no_exception': 1, + 'finish': 1}) diff --git a/pypy/rlib/rgc.py b/pypy/rlib/rgc.py --- a/pypy/rlib/rgc.py +++ b/pypy/rlib/rgc.py @@ -475,3 +475,6 @@ def specialize_call(self, hop): hop.exception_is_here() return hop.genop('gc_typeids_z', [], resulttype = hop.r_result) + +def lltype_is_gc(TP): + return getattr(getattr(TP, "TO", None), "_gckind", "?") == 'gc' diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py --- a/pypy/rpython/llinterp.py +++ b/pypy/rpython/llinterp.py @@ -1011,8 +1011,14 @@ def op_raw_store(self, addr, typ, offset, value): checkadr(addr) assert lltype.typeOf(value) == typ - assert offset.TYPE == typ - getattr(addr, str(typ).lower())[offset.repeat] = value + if isinstance(offset, int): + from pypy.rpython.lltypesystem import rffi + ll_p = rffi.cast(rffi.CCHARP, addr) + ll_p = rffi.cast(rffi.CArrayPtr(typ), rffi.ptradd(ll_p, offset)) + ll_p[0] = value + else: + assert offset.TYPE == typ + getattr(addr, str(typ).lower())[offset.repeat] = value def op_stack_malloc(self, size): # mmh raise NotImplementedError("backend only") _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit