[pypy-svn] pypy out-of-line-guards-2: On getfields of quasi-immutable fields, write in the jitcodes a
arigo
commits-noreply at bitbucket.org
Sat Apr 2 20:17:23 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: out-of-line-guards-2
Changeset: r43111:cdc159d28520
Date: 2011-04-02 17:14 +0200
http://bitbucket.org/pypy/pypy/changeset/cdc159d28520/
Log: On getfields of quasi-immutable fields, write in the jitcodes a
'record_quasiimmut_field' operation in addition to the
getfield_gc_*. As for setfields of quasi-immutable fields, they are
hidden from the JIT; for now this is done by making the whole
function containing them as don't-look-inside.
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
@@ -7,8 +7,9 @@
from pypy.jit.codewriter.flatten import ListOfKind, IndirectCallTargets
from pypy.jit.codewriter import support, heaptracker, longlong
from pypy.jit.codewriter.effectinfo import EffectInfo
-from pypy.jit.codewriter.policy import log
+from pypy.jit.codewriter.policy import log, check_skip_operation
from pypy.jit.metainterp.typesystem import deref, arrayItem
+from pypy.jit.metainterp import quasiimmut
from pypy.rlib import objectmodel
from pypy.rlib.jit import _we_are_jitted
from pypy.translator.simplify import get_funcobj
@@ -561,7 +562,8 @@
arraydescr)
return []
# check for _immutable_fields_ hints
- if v_inst.concretetype.TO._immutable_field(c_fieldname.value):
+ immut = v_inst.concretetype.TO._immutable_field(c_fieldname.value)
+ if immut:
if (self.callcontrol is not None and
self.callcontrol.could_be_green_field(v_inst.concretetype.TO,
c_fieldname.value)):
@@ -574,10 +576,20 @@
descr = self.cpu.fielddescrof(v_inst.concretetype.TO,
c_fieldname.value)
kind = getkind(RESULT)[0]
- return SpaceOperation('getfield_%s_%s%s' % (argname, kind, pure),
- [v_inst, descr], op.result)
+ op1 = SpaceOperation('getfield_%s_%s%s' % (argname, kind, pure),
+ [v_inst, descr], op.result)
+ #
+ if immut is quasiimmut.IR_QUASI_IMMUTABLE:
+ descr1 = self.cpu.fielddescrof(
+ v_inst.concretetype.TO,
+ quasiimmut.get_mutate_field_name(c_fieldname.value))
+ op1 = [SpaceOperation('record_quasiimmut_field',
+ [v_inst, descr1], None),
+ op1]
+ return op1
def rewrite_op_setfield(self, op):
+ check_skip_operation(op) # just to check it doesn't raise
if self.is_typeptr_getset(op):
# ignore the operation completely -- instead, it's done by 'new'
return
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
@@ -171,7 +171,8 @@
class VirtualizableAnalyzer(BoolGraphAnalyzer):
def analyze_simple_operation(self, op, graphinfo):
return op.opname in ('jit_force_virtualizable',
- 'jit_force_virtual')
+ 'jit_force_virtual',
+ 'jit_force_quasi_immutable')
# ____________________________________________________________
diff --git a/pypy/jit/codewriter/policy.py b/pypy/jit/codewriter/policy.py
--- a/pypy/jit/codewriter/policy.py
+++ b/pypy/jit/codewriter/policy.py
@@ -1,5 +1,5 @@
from pypy.translator.simplify import get_funcobj
-from pypy.jit.metainterp import history
+from pypy.jit.metainterp import history, quasiimmut
from pypy.rpython.lltypesystem import lltype, rclass
from pypy.tool.udir import udir
@@ -85,12 +85,20 @@
getkind(v.concretetype, supports_floats, supports_longlong)
v = op.result
getkind(v.concretetype, supports_floats, supports_longlong)
+ check_skip_operation(op)
except NotImplementedError, e:
log.WARNING('%s, ignoring graph' % (e,))
log.WARNING(' %s' % (graph,))
return True
return False
+def check_skip_operation(op):
+ if op.opname == 'setfield':
+ if quasiimmut.is_quasi_immutable(op.args[0].concretetype.TO,
+ op.args[1].value):
+ raise NotImplementedError("write to quasi-immutable field %r"
+ % (op.args[1].value,))
+
# ____________________________________________________________
class StopAtXPolicy(JitPolicy):
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
@@ -947,3 +947,42 @@
assert op1.args[1] == 'calldescr-%d' % effectinfo.EffectInfo.OS_ARRAYCOPY
assert op1.args[2] == ListOfKind('int', [v3, v4, v5])
assert op1.args[3] == ListOfKind('ref', [v1, v2])
+
+def test_quasi_immutable():
+ from pypy.rpython.rclass import FieldListAccessor, IR_QUASI_IMMUTABLE
+ accessor = FieldListAccessor()
+ accessor.initialize(None, {'inst_x': IR_QUASI_IMMUTABLE})
+ v2 = varoftype(lltype.Signed)
+ STRUCT = lltype.GcStruct('struct', ('inst_x', lltype.Signed),
+ ('mutate_x', rclass.OBJECTPTR),
+ hints={'immutable_fields': accessor})
+ for v_x in [const(lltype.malloc(STRUCT)), varoftype(lltype.Ptr(STRUCT))]:
+ op = SpaceOperation('getfield', [v_x, Constant('inst_x', lltype.Void)],
+ v2)
+ tr = Transformer(FakeCPU())
+ [op1, op2] = tr.rewrite_operation(op)
+ assert op1.opname == 'record_quasiimmut_field'
+ assert len(op1.args) == 2
+ assert op1.args[0] == v_x
+ assert op1.args[1] == ('fielddescr', STRUCT, 'mutate_x')
+ assert op1.result is None
+ assert op2.opname == 'getfield_gc_i'
+ assert len(op2.args) == 2
+ assert op2.args[0] == v_x
+ assert op2.args[1] == ('fielddescr', STRUCT, 'inst_x')
+ assert op2.result is op.result
+
+def test_quasi_immutable_setfield():
+ from pypy.rpython.rclass import FieldListAccessor, IR_QUASI_IMMUTABLE
+ accessor = FieldListAccessor()
+ accessor.initialize(None, {'inst_x': IR_QUASI_IMMUTABLE})
+ v1 = varoftype(lltype.Signed)
+ STRUCT = lltype.GcStruct('struct', ('inst_x', lltype.Signed),
+ ('mutate_x', rclass.OBJECTPTR),
+ hints={'immutable_fields': accessor})
+ for v_x in [const(lltype.malloc(STRUCT)), varoftype(lltype.Ptr(STRUCT))]:
+ op = SpaceOperation('setfield',
+ [v_x, Constant('inst_x', lltype.Void), v1],
+ varoftype(lltype.Void))
+ tr = Transformer(FakeCPU())
+ raises(NotImplementedError, tr.rewrite_operation, op)
More information about the Pypy-commit
mailing list