Author: Maciej Fijalkowski <fij...@gmail.com> Branch: inline-dict-ops Changeset: r45076:a04961b00aeb Date: 2011-06-23 14:39 +0200 http://bitbucket.org/pypy/pypy/changeset/a04961b00aeb/
Log: implement {get/set}interiorfield for the llgraph backend diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py --- a/pypy/jit/backend/llgraph/llimpl.py +++ b/pypy/jit/backend/llgraph/llimpl.py @@ -7,9 +7,7 @@ import weakref from pypy.objspace.flow.model import Variable, Constant from pypy.annotation import model as annmodel -from pypy.jit.metainterp.history import (ConstInt, ConstPtr, - BoxInt, BoxPtr, BoxObj, BoxFloat, - REF, INT, FLOAT) +from pypy.jit.metainterp.history import REF, INT, FLOAT from pypy.jit.codewriter import heaptracker from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr, rffi from pypy.rpython.ootypesystem import ootype @@ -17,7 +15,7 @@ from pypy.rpython.llinterp import LLException from pypy.rpython.extregistry import ExtRegistryEntry -from pypy.jit.metainterp import resoperation, executor +from pypy.jit.metainterp import resoperation from pypy.jit.metainterp.resoperation import rop from pypy.jit.backend.llgraph import symbolic from pypy.jit.codewriter import longlong @@ -327,6 +325,13 @@ assert isinstance(type, str) and len(type) == 1 op.descr = Descr(ofs, type, arg_types=arg_types) +def compile_add_descr_arg(loop, ofs, type, arg_types): + from pypy.jit.backend.llgraph.runner import Descr + loop = _from_opaque(loop) + op = loop.operations[-1] + assert isinstance(type, str) and len(type) == 1 + op.args.append(Descr(ofs, type, arg_types=arg_types)) + def compile_add_loop_token(loop, descr): if we_are_translated(): raise ValueError("CALL_ASSEMBLER not supported") @@ -431,8 +436,11 @@ self._may_force = -1 def getenv(self, v): + from pypy.jit.backend.llgraph.runner import Descr if isinstance(v, Constant): return v.value + elif isinstance(v, Descr): + return v else: return self.env[v] @@ -800,6 +808,30 @@ else: raise NotImplementedError + def op_getinteriorfield_gc(self, fielddescr, array, index, arraydescr): + if fielddescr.typeinfo == REF: + return do_getinteriorfield_gc_ptr(array, index, fielddescr.ofs) + elif fielddescr.typeinfo == INT: + return do_getinteriorfield_gc_int(array, index, fielddescr.ofs) + elif fielddescr.typeinfo == FLOAT: + return do_getinteriorfield_gc_float(array, index, fielddescr.ofs) + else: + raise NotImplementedError + + def op_setinteriorfield_gc(self, fielddescr, array, index, newvalue, + arraydescr): + if fielddescr.typeinfo == REF: + return do_setinteriorfield_gc_ptr(array, index, fielddescr.ofs, + newvalue) + elif fielddescr.typeinfo == INT: + return do_setinteriorfield_gc_int(array, index, fielddescr.ofs, + newvalue) + elif fielddescr.typeinfo == FLOAT: + return do_setinteriorfield_gc_float(array, index, fielddescr.ofs, + newvalue) + else: + raise NotImplementedError + def op_setfield_gc(self, fielddescr, struct, newvalue): if fielddescr.typeinfo == REF: do_setfield_gc_ptr(struct, fielddescr.ofs, newvalue) @@ -1344,6 +1376,22 @@ def do_getfield_gc_ptr(struct, fieldnum): return cast_to_ptr(_getfield_gc(struct, fieldnum)) +def _getinteriorfield_gc(struct, fieldnum): + STRUCT, fieldname = symbolic.TokenToField[fieldnum] + return getattr(struct, fieldname) + +def do_getinteriorfield_gc_int(array, index, fieldnum): + struct = array._obj.container.getitem(index) + return cast_to_int(_getinteriorfield_gc(struct, fieldnum)) + +def do_getinteriorfield_gc_float(array, index, fieldnum): + struct = array._obj.container.getitem(index) + return cast_to_floatstorage(_getinteriorfield_gc(struct, fieldnum)) + +def do_getinteriorfield_gc_ptr(array, index, fieldnum): + struct = array._obj.container.getitem(index) + return cast_to_ptr(_getinteriorfield_gc(struct, fieldnum)) + def _getfield_raw(struct, fieldnum): STRUCT, fieldname = symbolic.TokenToField[fieldnum] ptr = cast_from_int(lltype.Ptr(STRUCT), struct) @@ -1398,26 +1446,28 @@ newvalue = cast_from_ptr(ITEMTYPE, newvalue) array.setitem(index, newvalue) -def do_setfield_gc_int(struct, fieldnum, newvalue): - STRUCT, fieldname = symbolic.TokenToField[fieldnum] - ptr = lltype.cast_opaque_ptr(lltype.Ptr(STRUCT), struct) - FIELDTYPE = getattr(STRUCT, fieldname) - newvalue = cast_from_int(FIELDTYPE, newvalue) - setattr(ptr, fieldname, newvalue) +def new_setfield_gc(cast_func): + def do_setfield_gc(struct, fieldnum, newvalue): + STRUCT, fieldname = symbolic.TokenToField[fieldnum] + ptr = lltype.cast_opaque_ptr(lltype.Ptr(STRUCT), struct) + FIELDTYPE = getattr(STRUCT, fieldname) + newvalue = cast_func(FIELDTYPE, newvalue) + setattr(ptr, fieldname, newvalue) + return do_setfield_gc +do_setfield_gc_int = new_setfield_gc(cast_from_int) +do_setfield_gc_float = new_setfield_gc(cast_from_floatstorage) +do_setfield_gc_ptr = new_setfield_gc(cast_from_ptr) -def do_setfield_gc_float(struct, fieldnum, newvalue): - STRUCT, fieldname = symbolic.TokenToField[fieldnum] - ptr = lltype.cast_opaque_ptr(lltype.Ptr(STRUCT), struct) - FIELDTYPE = getattr(STRUCT, fieldname) - newvalue = cast_from_floatstorage(FIELDTYPE, newvalue) - setattr(ptr, fieldname, newvalue) - -def do_setfield_gc_ptr(struct, fieldnum, newvalue): - STRUCT, fieldname = symbolic.TokenToField[fieldnum] - ptr = lltype.cast_opaque_ptr(lltype.Ptr(STRUCT), struct) - FIELDTYPE = getattr(STRUCT, fieldname) - newvalue = cast_from_ptr(FIELDTYPE, newvalue) - setattr(ptr, fieldname, newvalue) +def new_setinteriorfield_gc(cast_func): + def do_setinteriorfield_gc(array, index, fieldnum, newvalue): + STRUCT, fieldname = symbolic.TokenToField[fieldnum] + struct = array._obj.container.getitem(index) + FIELDTYPE = getattr(STRUCT, fieldname) + setattr(struct, fieldname, cast_func(FIELDTYPE, newvalue)) + return do_setinteriorfield_gc +do_setinteriorfield_gc_int = new_setinteriorfield_gc(cast_from_int) +do_setinteriorfield_gc_float = new_setinteriorfield_gc(cast_from_floatstorage) +do_setinteriorfield_gc_ptr = new_setinteriorfield_gc(cast_from_ptr) def do_setfield_raw_int(struct, fieldnum, newvalue): STRUCT, fieldname = symbolic.TokenToField[fieldnum] @@ -1682,6 +1732,7 @@ setannotation(compile_start_float_var, annmodel.SomeInteger()) setannotation(compile_add, annmodel.s_None) setannotation(compile_add_descr, annmodel.s_None) +setannotation(compile_add_descr_arg, annmodel.s_None) setannotation(compile_add_var, annmodel.s_None) setannotation(compile_add_int_const, annmodel.s_None) setannotation(compile_add_ref_const, annmodel.s_None) diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py --- a/pypy/jit/backend/llgraph/runner.py +++ b/pypy/jit/backend/llgraph/runner.py @@ -2,7 +2,6 @@ Minimal-API wrapper around the llinterpreter to run operations. """ -import sys from pypy.rlib.unroll import unrolling_iterable from pypy.rlib.objectmodel import we_are_translated from pypy.rpython.lltypesystem import lltype, llmemory, rclass @@ -11,12 +10,11 @@ from pypy.jit.metainterp import history from pypy.jit.metainterp.history import REF, INT, FLOAT from pypy.jit.metainterp.warmstate import unwrap -from pypy.jit.metainterp.resoperation import ResOperation, rop +from pypy.jit.metainterp.resoperation import rop from pypy.jit.backend import model from pypy.jit.backend.llgraph import llimpl, symbolic from pypy.jit.metainterp.typesystem import llhelper, oohelper from pypy.jit.codewriter import heaptracker, longlong -from pypy.rlib import rgc class MiniStats: pass @@ -172,8 +170,10 @@ llimpl.compile_add(c, op.getopnum()) descr = op.getdescr() if isinstance(descr, Descr): - llimpl.compile_add_descr(c, descr.ofs, descr.typeinfo, descr.arg_types) - if isinstance(descr, history.LoopToken) and op.getopnum() != rop.JUMP: + llimpl.compile_add_descr(c, descr.ofs, descr.typeinfo, + descr.arg_types) + if (isinstance(descr, history.LoopToken) and + op.getopnum() != rop.JUMP): llimpl.compile_add_loop_token(c, descr) if self.is_oo and isinstance(descr, (OODescr, MethDescr)): # hack hack, not rpython @@ -188,6 +188,9 @@ llimpl.compile_add_ref_const(c, x.value, self.ts.BASETYPE) elif isinstance(x, history.ConstFloat): llimpl.compile_add_float_const(c, x.value) + elif isinstance(x, Descr): + llimpl.compile_add_descr_arg(c, x.ofs, x.typeinfo, + x.arg_types) else: raise Exception("'%s' args contain: %r" % (op.getopname(), x)) @@ -343,8 +346,11 @@ def arraydescrof(self, A): assert A.OF != lltype.Void size = symbolic.get_size(A) - token = history.getkind(A.OF) - return self.getdescr(size, token[0]) + if isinstance(A.OF, lltype.Ptr) or isinstance(A.OF, lltype.Primitive): + token = history.getkind(A.OF)[0] + else: + token = '?' + return self.getdescr(size, token) # ---------- the backend-dependent operations ---------- @@ -408,7 +414,6 @@ def bh_classof(self, struct): struct = lltype.cast_opaque_ptr(rclass.OBJECTPTR, struct) - result = struct.typeptr result_adr = llmemory.cast_ptr_to_adr(struct.typeptr) return heaptracker.adr2int(result_adr) diff --git a/pypy/jit/backend/test/runner_test.py b/pypy/jit/backend/test/runner_test.py --- a/pypy/jit/backend/test/runner_test.py +++ b/pypy/jit/backend/test/runner_test.py @@ -5,7 +5,7 @@ BoxInt, Box, BoxPtr, LoopToken, ConstInt, ConstPtr, - BoxObj, Const, + BoxObj, ConstObj, BoxFloat, ConstFloat) from pypy.jit.metainterp.resoperation import ResOperation, rop from pypy.jit.metainterp.typesystem import deref @@ -870,6 +870,39 @@ 'int', descr=arraydescr) assert r.value == 7441 + def test_array_of_structs(self): + TP = lltype.GcStruct('x') + ITEM = lltype.Struct('x', ('v', lltype.Signed), + ('k', lltype.Float), + ('p', lltype.Ptr(TP))) + a_box, A = self.alloc_array_of(ITEM, 15) + s_box, S = self.alloc_instance(TP) + adescr = self.cpu.arraydescrof(A) + kdescr = self.cpu.fielddescrof(ITEM, 'k') + vdescr = self.cpu.fielddescrof(ITEM, 'v') + pdescr = self.cpu.fielddescrof(ITEM, 'p') + self.execute_operation(rop.SETINTERIORFIELD_GC, [a_box, BoxInt(3), + BoxFloat(1.5), adescr], + 'void', descr=kdescr) + r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3), + adescr], 'float', + descr=kdescr) + assert r.getfloat() == 1.5 + self.execute_operation(rop.SETINTERIORFIELD_GC, [a_box, BoxInt(3), + BoxInt(15), adescr], + 'void', descr=vdescr) + r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3), + adescr], 'int', + descr=vdescr) + assert r.getint() == 15 + self.execute_operation(rop.SETINTERIORFIELD_GC, [a_box, BoxInt(3), + s_box, adescr], + 'void', descr=pdescr) + r = self.execute_operation(rop.GETINTERIORFIELD_GC, [a_box, BoxInt(3), + adescr], 'ref', + descr=pdescr) + assert r.getref_base() == s_box.getref_base() + def test_string_basic(self): s_box = self.alloc_string("hello\xfe") r = self.execute_operation(rop.STRLEN, [s_box], 'int') @@ -1429,7 +1462,6 @@ return BoxPtr(lltype.nullptr(llmemory.GCREF.TO)) def alloc_array_of(self, ITEM, length): - cpu = self.cpu A = lltype.GcArray(ITEM) a = lltype.malloc(A, length) a_box = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, a)) diff --git a/pypy/jit/metainterp/executor.py b/pypy/jit/metainterp/executor.py --- a/pypy/jit/metainterp/executor.py +++ b/pypy/jit/metainterp/executor.py @@ -1,11 +1,8 @@ """This implements pyjitpl's execution of operations. """ -import py -from pypy.rpython.lltypesystem import lltype, llmemory, rstr -from pypy.rpython.ootypesystem import ootype -from pypy.rpython.lltypesystem.lloperation import llop -from pypy.rlib.rarithmetic import ovfcheck, r_uint, intmask, r_longlong +from pypy.rpython.lltypesystem import lltype, rstr +from pypy.rlib.rarithmetic import ovfcheck, r_longlong from pypy.rlib.rtimer import read_timestamp from pypy.rlib.unroll import unrolling_iterable from pypy.jit.metainterp.history import BoxInt, BoxPtr, BoxFloat, check_descr @@ -123,6 +120,13 @@ else: cpu.bh_setarrayitem_raw_i(arraydescr, array, index, itembox.getint()) +def do_getinteriorfield_gc(cpu, _, arraybox, indexbox, arraydescr, fielddescr): + xxx + +def do_setinteriorfield_gc(cpu, _, arraybox, indexbox, valuebox, arraydescr, + fielddecr): + xxx + def do_getfield_gc(cpu, _, structbox, fielddescr): struct = structbox.getref_base() if fielddescr.is_pointer_field(): diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py --- a/pypy/jit/metainterp/resoperation.py +++ b/pypy/jit/metainterp/resoperation.py @@ -1,5 +1,4 @@ from pypy.rlib.objectmodel import we_are_translated -from pypy.rlib.debug import make_sure_not_resized def ResOperation(opnum, args, result, descr=None): cls = opclasses[opnum] @@ -456,6 +455,7 @@ 'GETARRAYITEM_GC/2d', 'GETARRAYITEM_RAW/2d', + 'GETINTERIORFIELD_GC/3d', 'GETFIELD_GC/1d', 'GETFIELD_RAW/1d', '_MALLOC_FIRST', @@ -472,6 +472,7 @@ 'SETARRAYITEM_GC/3d', 'SETARRAYITEM_RAW/3d', + 'SETINTERIORFIELD_GC/4d', 'SETFIELD_GC/2d', 'SETFIELD_RAW/2d', 'STRSETITEM/3', _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit