[pypy-svn] pypy out-of-line-guards-2: Start a module containing all support code for the front-end

arigo commits-noreply at bitbucket.org
Sat Apr 2 20:17:24 CEST 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: out-of-line-guards-2
Changeset: r43112:b5bf46d6ee96
Date: 2011-04-02 17:17 +0200
http://bitbucket.org/pypy/pypy/changeset/b5bf46d6ee96/

Log:	Start a module containing all support code for the front-end for
	quasi-immutable fields.

diff --git a/pypy/jit/metainterp/quasiimmut.py b/pypy/jit/metainterp/quasiimmut.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/metainterp/quasiimmut.py
@@ -0,0 +1,42 @@
+from pypy.rpython.rclass import IR_QUASI_IMMUTABLE
+from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
+
+
+def is_quasi_immutable(STRUCT, fieldname):
+    imm_fields = STRUCT._hints.get('immutable_fields')
+    return (imm_fields is not None and
+            imm_fields.fields.get(fieldname) is IR_QUASI_IMMUTABLE)
+
+def get_mutate_field_name(fieldname):
+    if fieldname.startswith('inst_'):    # lltype
+        return 'mutate_' + fieldname[5:]
+    elif fieldname.startswith('o'):      # ootype
+        return 'mutate_' + fieldname[1:]
+    else:
+        raise AssertionError(fieldname)
+
+def get_current_mutate_instance(cpu, gcref, mutatefielddescr):
+    """Returns the current SlowMutate instance in the field,
+    possibly creating one.
+    """
+    mutate_gcref = cpu.bh_getfield_gc_r(gcref, mutatefielddescr)
+    if mutate_gcref:
+        mutate = SlowMutate.show(cpu, mutate_gcref)
+    else:
+        mutate = SlowMutate()
+        cpu.bh_setfield_gc_r(gcref, mutatefielddescr, mutate.hide(cpu))
+    return mutate
+
+
+class SlowMutate(object):
+    def __init__(self):
+        pass
+
+    def hide(self, cpu):
+        mutate_ptr = cpu.ts.cast_instance_to_base_ref(self)
+        return cpu.ts.cast_to_ref(mutate_ptr)
+
+    @staticmethod
+    def show(cpu, mutate_gcref):
+        mutate_ptr = cpu.ts.cast_to_baseclass(mutate_gcref)
+        return cast_base_ptr_to_instance(SlowMutate, mutate_ptr)

diff --git a/pypy/jit/metainterp/test/test_quasiimmut.py b/pypy/jit/metainterp/test/test_quasiimmut.py
new file mode 100644
--- /dev/null
+++ b/pypy/jit/metainterp/test/test_quasiimmut.py
@@ -0,0 +1,40 @@
+from pypy.rpython.lltypesystem import lltype, llmemory, rclass
+from pypy.rpython.rclass import FieldListAccessor, IR_QUASI_IMMUTABLE
+from pypy.jit.metainterp import typesystem
+from pypy.jit.metainterp.quasiimmut import SlowMutate
+from pypy.jit.metainterp.quasiimmut import get_current_mutate_instance
+
+
+def test_get_current_mutate_instance():
+    accessor = FieldListAccessor()
+    accessor.initialize(None, {'inst_x': IR_QUASI_IMMUTABLE})
+    STRUCT = lltype.GcStruct('Foo', ('inst_x', lltype.Signed),
+                             ('mutate_x', rclass.OBJECTPTR),
+                             hints={'immutable_fields': accessor})
+    foo = lltype.malloc(STRUCT, zero=True)
+    foo.inst_x = 42
+    assert not foo.mutate_x
+
+    class FakeCPU:
+        ts = typesystem.llhelper
+
+        def bh_getfield_gc_r(self, gcref, fielddescr):
+            assert fielddescr == mutatefielddescr
+            foo = lltype.cast_opaque_ptr(lltype.Ptr(STRUCT), gcref)
+            result = foo.mutate_x
+            return lltype.cast_opaque_ptr(llmemory.GCREF, result)
+
+        def bh_setfield_gc_r(self, gcref, fielddescr, newvalue_gcref):
+            assert fielddescr == mutatefielddescr
+            foo = lltype.cast_opaque_ptr(lltype.Ptr(STRUCT), gcref)
+            newvalue = lltype.cast_opaque_ptr(rclass.OBJECTPTR, newvalue_gcref)
+            foo.mutate_x = newvalue
+
+    cpu = FakeCPU()
+    mutatefielddescr = ('fielddescr', STRUCT, 'mutate_x')
+
+    foo_gcref = lltype.cast_opaque_ptr(llmemory.GCREF, foo)
+    sm1 = get_current_mutate_instance(cpu, foo_gcref, mutatefielddescr)
+    assert isinstance(sm1, SlowMutate)
+    sm2 = get_current_mutate_instance(cpu, foo_gcref, mutatefielddescr)
+    assert sm1 is sm2


More information about the Pypy-commit mailing list