[pypy-commit] pypy vref-copy: start hacking on vref-getfield
fijal
noreply at buildbot.pypy.org
Tue Aug 21 17:31:16 CEST 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: vref-copy
Changeset: r56775:0235d65362bf
Date: 2012-08-21 17:30 +0200
http://bitbucket.org/pypy/pypy/changeset/0235d65362bf/
Log: start hacking on vref-getfield
diff --git a/pypy/jit/metainterp/test/test_virtualref.py b/pypy/jit/metainterp/test/test_virtualref.py
--- a/pypy/jit/metainterp/test/test_virtualref.py
+++ b/pypy/jit/metainterp/test/test_virtualref.py
@@ -654,6 +654,30 @@
res = self.meta_interp(f, [10])
assert res == 0
+ def test_vref_getfield(self):
+ driver = JitDriver(greens = [], reds = ['n', 's'])
+
+ class X(object):
+ def __init__(self, x):
+ self.x = x
+
+ @dont_look_inside
+ def residual(vref):
+ return vref.getfield('x')
+
+ def f(n):
+ s = 0
+ while n > 0:
+ driver.jit_merge_point(n=n, s=s)
+ x = X(1)
+ v = virtual_ref(x)
+ s += residual(v)
+ virtual_ref_finish(v, x)
+ n -= 1
+ return s
+
+ res = self.meta_interp(f, [10])
+ assert res == 10
class TestLLtype(VRefTests, LLJitMixin):
pass
diff --git a/pypy/jit/metainterp/virtualref.py b/pypy/jit/metainterp/virtualref.py
--- a/pypy/jit/metainterp/virtualref.py
+++ b/pypy/jit/metainterp/virtualref.py
@@ -36,11 +36,19 @@
def _freeze_(self):
return True
+ def _find_type_of_virtualref(self):
+ # XXX limitation is that we can only have one type
+ for graph in graphs:
+ for block in graph.iterblocks():
+ for op in block.operations:
+
def replace_force_virtual_with_call(self, graphs):
# similar to rvirtualizable2.replace_force_virtualizable_with_call().
c_force_virtual_ptr = None
c_is_virtual_ptr = None
+ c_getfield_ptrs = {} # fieldname -> function
force_virtual_count = 0
+ self._find_type_of_virtualref()
for graph in graphs:
for block in graph.iterblocks():
for op in block.operations:
@@ -60,6 +68,16 @@
#
op.opname = 'direct_call'
op.args = [c_is_virtual_ptr, op.args[0]]
+ if op.opname == 'jit_vref_getfield':
+ # get a function for each field
+ key = op.args[1].value
+ c_func = c_getfield_ptrs.get(key, None)
+ if c_func is None:
+ c_func = self.get_vref_getfield_fnptr(key,
+ op.result.concretetype)
+ c_getfield_ptrs[key] = c_func
+ op.opname = 'direct_call'
+ op.args = [c_func, op.args[0]]
#
if c_force_virtual_ptr is not None:
log("replaced %d 'jit_force_virtual' with %r" % (force_virtual_count,
@@ -137,6 +155,18 @@
force_virtual_if_necessary)
return inputconst(lltype.typeOf(funcptr), funcptr)
+ def get_vref_getfield_fnptr(self, name, RES_TP):
+ def read_virtual_field(inst):
+ if inst.typeptr != self.jit_virtual_ref_vtable:
+ lltype.cast_ptr(
+ xxx
+ xxx
+ FUNC = lltype.FuncType([rclass.OBJECTPTR], RES_TP)
+ funcptr = self.warmrunnerdesc.helper_func(
+ lltype.Ptr(FUNC),
+ read_virtual_field)
+ return inputconst(lltype.typeOf(funcptr), funcptr)
+
def get_is_virtual_fnptr(self):
#
def is_virtual(inst):
diff --git a/pypy/rlib/_jit_vref.py b/pypy/rlib/_jit_vref.py
--- a/pypy/rlib/_jit_vref.py
+++ b/pypy/rlib/_jit_vref.py
@@ -53,6 +53,7 @@
def specialize_call(self, hop):
r_generic_object = getinstancerepr(hop.rtyper, None)
+ hop.genop('jit_record_vref', [hop.args_v[0]], resulttype=lltype.Void)
[v] = hop.inputargs(r_generic_object) # might generate a cast_pointer
hop.exception_cannot_occur()
return v
@@ -82,9 +83,7 @@
hop.exception_cannot_occur()
v = hop.inputarg(self, arg=0)
c_name = hop.inputconst(lltype.Void, attr)
- r_arg = hop.rtyper.getrepr(hop.args_s[0].s_instance)
- v2 = hop.genop('cast_pointer', [v], resulttype=r_arg)
- return hop.genop('jit_vref_getfield', [v2, c_name],
+ return hop.genop('jit_vref_getfield', [v, c_name],
resulttype = hop.r_result)
from pypy.rpython.ootypesystem.rclass import OBJECT
diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -435,6 +435,7 @@
'jit_force_quasi_immutable': LLOp(canrun=True),
'jit_record_known_class' : LLOp(canrun=True),
'jit_vref_getfield' : LLOp(canrun=True),
+ 'jit_record_vref': LLOp(canrun=True),
'get_exception_addr': LLOp(),
'get_exc_value_addr': LLOp(),
'do_malloc_fixedsize_clear':LLOp(canmallocgc=True),
diff --git a/pypy/rpython/lltypesystem/opimpl.py b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -558,7 +558,8 @@
return x
def op_jit_vref_getfield(x, field):
- return getattr(x, 'inst_' + field)
+ # XXX is this even a correct hack?
+ return getattr(x._obj._parentstructure(), 'inst_' + field)
def op_jit_is_virtual(x):
return False
More information about the pypy-commit
mailing list