[pypy-commit] pypy inline-dict-ops: implement {get/set}interiorfield for the llgraph backend
fijal
noreply at buildbot.pypy.org
Thu Jun 23 14:35:05 CEST 2011
Author: Maciej Fijalkowski <fijall at 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',
More information about the pypy-commit
mailing list