[pypy-svn] pypy default: Backed out changeset 124ebb7828dd, merge of out-of-line-guards-2. It seems

fijal commits-noreply at bitbucket.org
Sun Apr 17 10:28:03 CEST 2011


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: 
Changeset: r43419:671bbe385458
Date: 2011-04-17 10:13 +0200
http://bitbucket.org/pypy/pypy/changeset/671bbe385458/

Log:	Backed out changeset 124ebb7828dd, merge of out-of-line-guards-2. It
	seems to have broken benchmarks, investigation needed

diff --git a/pypy/rpython/ootypesystem/rclass.py b/pypy/rpython/ootypesystem/rclass.py
--- a/pypy/rpython/ootypesystem/rclass.py
+++ b/pypy/rpython/ootypesystem/rclass.py
@@ -262,10 +262,6 @@
         self.rbase = getinstancerepr(self.rtyper, self.classdef.basedef)
         self.rbase.setup()
 
-        for name, attrdef in selfattrs.iteritems():
-            if not attrdef.readonly and self.is_quasi_immutable(name):
-                ootype.addFields(self.lowleveltype, {'mutable_'+name: OBJECT})
-
         classattributes = {}
         baseInstance = self.lowleveltype._superclass
         classrepr = getclassrepr(self.rtyper, self.classdef)
@@ -480,9 +476,11 @@
         mangled_name = mangle(attr, self.rtyper.getconfig())
         cname = inputconst(ootype.Void, mangled_name)
         self.hook_access_field(vinst, cname, llops, flags)
-        self.hook_setfield(vinst, attr, llops)
         llops.genop('oosetfield', [vinst, cname, vvalue])
 
+    def hook_access_field(self, vinst, cname, llops, flags):
+        pass        # for virtualizables; see rvirtualizable2.py
+
     def rtype_is_true(self, hop):
         vinst, = hop.inputargs(self)
         return hop.genop('oononnull', [vinst], resulttype=ootype.Bool)

diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py
--- a/pypy/jit/backend/model.py
+++ b/pypy/jit/backend/model.py
@@ -291,7 +291,6 @@
         # that belong to this loop or to a bridge attached to it.
         # Filled by the frontend calling record_faildescr_index().
         self.faildescr_indices = []
-        self.invalidate_positions = []
         debug_start("jit-mem-looptoken-alloc")
         debug_print("allocating Loop #", self.number)
         debug_stop("jit-mem-looptoken-alloc")

diff --git a/pypy/jit/metainterp/history.py b/pypy/jit/metainterp/history.py
--- a/pypy/jit/metainterp/history.py
+++ b/pypy/jit/metainterp/history.py
@@ -791,7 +791,6 @@
     operations = None
     token = None
     call_pure_results = None
-    quasi_immutable_deps = None
 
     def __init__(self, name):
         self.name = name

diff --git a/pypy/rpython/lltypesystem/lltype.py b/pypy/rpython/lltypesystem/lltype.py
--- a/pypy/rpython/lltypesystem/lltype.py
+++ b/pypy/rpython/lltypesystem/lltype.py
@@ -341,14 +341,13 @@
         return _struct(self, n, initialization='example')
 
     def _immutable_field(self, field):
-        if self._hints.get('immutable'):
-            return True
         if 'immutable_fields' in self._hints:
             try:
-                return self._hints['immutable_fields'].fields[field]
+                s = self._hints['immutable_fields'].fields[field]
+                return s or True
             except KeyError:
                 pass
-        return False
+        return self._hints.get('immutable', False)
 
 class RttiStruct(Struct):
     _runtime_type_info = None
@@ -1030,8 +1029,6 @@
         return None   # null pointer
     if type(p._obj0) is int:
         return p      # a pointer obtained by cast_int_to_ptr
-    if getattr(p._obj0, '_carry_around_for_tests', False):
-        return p      # a pointer obtained by cast_instance_to_base_ptr
     container = obj._normalizedcontainer()
     if type(container) is int:
         # this must be an opaque ptr originating from an integer
@@ -1884,8 +1881,8 @@
         if self.__class__ is not other.__class__:
             return NotImplemented
         if hasattr(self, 'container') and hasattr(other, 'container'):
-            obj1 = self._normalizedcontainer()
-            obj2 = other._normalizedcontainer()
+            obj1 = self.container._normalizedcontainer()
+            obj2 = other.container._normalizedcontainer()
             return obj1 == obj2
         else:
             return self is other
@@ -1909,8 +1906,6 @@
             # an integer, cast to a ptr, cast to an opaque    
             if type(self.container) is int:
                 return self.container
-            if getattr(self.container, '_carry_around_for_tests', False):
-                return self.container
             return self.container._normalizedcontainer()
         else:
             return _parentable._normalizedcontainer(self)

diff --git a/pypy/rpython/lltypesystem/ll2ctypes.py b/pypy/rpython/lltypesystem/ll2ctypes.py
--- a/pypy/rpython/lltypesystem/ll2ctypes.py
+++ b/pypy/rpython/lltypesystem/ll2ctypes.py
@@ -578,7 +578,6 @@
 _all_callbacks_results = []
 _int2obj = {}
 _callback_exc_info = None
-_opaque_objs = [None]
 
 def get_rtyper():
     llinterp = LLInterpreter.current_interpreter
@@ -617,10 +616,6 @@
             T = lltype.Ptr(lltype.typeOf(container))
             # otherwise it came from integer and we want a c_void_p with
             # the same valu
-            if getattr(container, 'llopaque', None):
-                no = len(_opaque_objs)
-                _opaque_objs.append(container)
-                return no * 2 + 1
         else:
             container = llobj._obj
         if isinstance(T.TO, lltype.FuncType):
@@ -769,14 +764,10 @@
     if isinstance(T, lltype.Typedef):
         T = T.OF
     if isinstance(T, lltype.Ptr):
-        ptrval = ctypes.cast(cobj, ctypes.c_void_p).value
-        if not cobj or not ptrval:   # NULL pointer
+        if not cobj or not ctypes.cast(cobj, ctypes.c_void_p).value:   # NULL pointer
             # CFunctionType.__nonzero__ is broken before Python 2.6
             return lltype.nullptr(T.TO)
         if isinstance(T.TO, lltype.Struct):
-            if ptrval & 1: # a tagged pointer
-                gcref = _opaque_objs[ptrval // 2].hide()
-                return lltype.cast_opaque_ptr(T, gcref)
             REAL_TYPE = T.TO
             if T.TO._arrayfld is not None:
                 carray = getattr(cobj.contents, T.TO._arrayfld)
@@ -1237,9 +1228,7 @@
         return not self == other
 
     def _cast_to_ptr(self, PTRTYPE):
-        if self.intval & 1:
-            return _opaque_objs[self.intval // 2]
-        return force_cast(PTRTYPE, self.intval)
+         return force_cast(PTRTYPE, self.intval)
 
 ##     def _cast_to_int(self):
 ##         return self.intval

diff --git a/pypy/jit/metainterp/test/test_quasiimmut.py b/pypy/jit/metainterp/test/test_quasiimmut.py
deleted file mode 100644
--- a/pypy/jit/metainterp/test/test_quasiimmut.py
+++ /dev/null
@@ -1,266 +0,0 @@
-
-import py
-
-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 QuasiImmut
-from pypy.jit.metainterp.quasiimmut import get_current_qmut_instance
-from pypy.jit.metainterp.test.test_basic import LLJitMixin
-from pypy.jit.codewriter.policy import StopAtXPolicy
-from pypy.rlib.jit import JitDriver, dont_look_inside
-
-
-def test_get_current_qmut_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)
-    qmut1 = get_current_qmut_instance(cpu, foo_gcref, mutatefielddescr)
-    assert isinstance(qmut1, QuasiImmut)
-    qmut2 = get_current_qmut_instance(cpu, foo_gcref, mutatefielddescr)
-    assert qmut1 is qmut2
-
-
-class QuasiImmutTests(object):
-
-    def test_simple_1(self):
-        myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
-        class Foo:
-            _immutable_fields_ = ['a?']
-            def __init__(self, a):
-                self.a = a
-        def f(a, x):
-            foo = Foo(a)
-            total = 0
-            while x > 0:
-                myjitdriver.jit_merge_point(foo=foo, x=x, total=total)
-                # read a quasi-immutable field out of a Constant
-                total += foo.a
-                x -= 1
-            return total
-        #
-        res = self.meta_interp(f, [100, 7])
-        assert res == 700
-        self.check_loops(getfield_gc=0, everywhere=True)
-        #
-        from pypy.jit.metainterp.warmspot import get_stats
-        loops = get_stats().loops
-        for loop in loops:
-            assert len(loop.quasi_immutable_deps) == 1
-            assert isinstance(loop.quasi_immutable_deps.keys()[0], QuasiImmut)
-
-    def test_nonopt_1(self):
-        myjitdriver = JitDriver(greens=[], reds=['x', 'total', 'lst'])
-        class Foo:
-            _immutable_fields_ = ['a?']
-            def __init__(self, a):
-                self.a = a
-        def setup(x):
-            return [Foo(100 + i) for i in range(x)]
-        def f(a, x):
-            lst = setup(x)
-            total = 0
-            while x > 0:
-                myjitdriver.jit_merge_point(lst=lst, x=x, total=total)
-                # read a quasi-immutable field out of a variable
-                x -= 1
-                total += lst[x].a
-            return total
-        #
-        assert f(100, 7) == 721
-        res = self.meta_interp(f, [100, 7])
-        assert res == 721
-        self.check_loops(getfield_gc=1)
-        #
-        from pypy.jit.metainterp.warmspot import get_stats
-        loops = get_stats().loops
-        for loop in loops:
-            assert loop.quasi_immutable_deps is None
-
-    def test_change_during_tracing_1(self):
-        myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
-        class Foo:
-            _immutable_fields_ = ['a?']
-            def __init__(self, a):
-                self.a = a
-        @dont_look_inside
-        def residual_call(foo):
-            foo.a += 1
-        def f(a, x):
-            foo = Foo(a)
-            total = 0
-            while x > 0:
-                myjitdriver.jit_merge_point(foo=foo, x=x, total=total)
-                # read a quasi-immutable field out of a Constant
-                total += foo.a
-                residual_call(foo)
-                x -= 1
-            return total
-        #
-        assert f(100, 7) == 721
-        res = self.meta_interp(f, [100, 7])
-        assert res == 721
-        self.check_loops(getfield_gc=1)
-
-    def test_change_during_tracing_2(self):
-        myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
-        class Foo:
-            _immutable_fields_ = ['a?']
-            def __init__(self, a):
-                self.a = a
-        @dont_look_inside
-        def residual_call(foo, difference):
-            foo.a += difference
-        def f(a, x):
-            foo = Foo(a)
-            total = 0
-            while x > 0:
-                myjitdriver.jit_merge_point(foo=foo, x=x, total=total)
-                # read a quasi-immutable field out of a Constant
-                total += foo.a
-                residual_call(foo, +1)
-                residual_call(foo, -1)
-                x -= 1
-            return total
-        #
-        assert f(100, 7) == 700
-        res = self.meta_interp(f, [100, 7])
-        assert res == 700
-        self.check_loops(getfield_gc=1)
-
-    def test_change_invalidate_reentering(self):
-        myjitdriver = JitDriver(greens=['foo'], reds=['x', 'total'])
-        class Foo:
-            _immutable_fields_ = ['a?']
-            def __init__(self, a):
-                self.a = a
-        def f(foo, x):
-            total = 0
-            while x > 0:
-                myjitdriver.jit_merge_point(foo=foo, x=x, total=total)
-                # read a quasi-immutable field out of a Constant
-                total += foo.a
-                x -= 1
-            return total
-        def g(a, x):
-            foo = Foo(a)
-            res1 = f(foo, x)
-            foo.a += 1          # invalidation, while the jit is not running
-            res2 = f(foo, x)    # should still mark the loop as invalid
-            return res1 * 1000 + res2
-        #
-        assert g(100, 7) == 700707
-        res = self.meta_interp(g, [100, 7])
-        assert res == 700707
-        self.check_loops(getfield_gc=0)
-
-    def test_invalidate_while_running(self):
-        jitdriver = JitDriver(greens=['foo'], reds=['i', 'total'])
-
-        class Foo(object):
-            _immutable_fields_ = ['a?']
-            def __init__(self, a):
-                self.a = a
-
-        def external(foo, v):
-            if v:
-                foo.a = 2
-
-        def f(foo):
-            i = 0
-            total = 0
-            while i < 10:
-                jitdriver.jit_merge_point(i=i, foo=foo, total=total)
-                external(foo, i > 7)
-                i += 1
-                total += foo.a
-            return total
-
-        def g():
-            return f(Foo(1))
-
-        assert self.meta_interp(g, [], policy=StopAtXPolicy(external)) == g()
-
-    def test_invalidate_by_setfield(self):
-        py.test.skip("Not implemented")
-        jitdriver = JitDriver(greens=['bc', 'foo'], reds=['i', 'total'])
-
-        class Foo(object):
-            _immutable_fields_ = ['a?']
-            def __init__(self, a):
-                self.a = a
-
-        def f(foo, bc):
-            i = 0
-            total = 0
-            while i < 10:
-                jitdriver.jit_merge_point(bc=bc, i=i, foo=foo, total=total)
-                if bc == 0:
-                    f(foo, 1)
-                if bc == 1:
-                    foo.a = int(i > 5)
-                i += 1
-                total += foo.a
-            return total
-
-        def g():
-            return f(Foo(1), 0)
-
-        assert self.meta_interp(g, []) == g()
-
-    def test_invalidate_bridge(self):
-        jitdriver = JitDriver(greens=['foo'], reds=['i', 'total'])
-
-        class Foo(object):
-            _immutable_fields_ = ['a?']
-
-        def f(foo):
-            i = 0
-            total = 0
-            while i < 10:
-                jitdriver.jit_merge_point(i=i, total=total, foo=foo)
-                if i > 5:
-                    total += foo.a
-                else:
-                    total += 2*foo.a
-                i += 1
-            return total
-
-        def main():
-            foo = Foo()
-            foo.a = 1
-            total = f(foo)
-            foo.a = 2
-            total += f(foo)
-            return total
-
-        res = self.meta_interp(main, [])
-        assert res == main()
-
-class TestLLtypeGreenFieldsTests(QuasiImmutTests, LLJitMixin):
-    pass

diff --git a/pypy/jit/metainterp/quasiimmut.py b/pypy/jit/metainterp/quasiimmut.py
deleted file mode 100644
--- a/pypy/jit/metainterp/quasiimmut.py
+++ /dev/null
@@ -1,116 +0,0 @@
-import weakref
-from pypy.rpython.rclass import IR_QUASI_IMMUTABLE
-from pypy.rpython.lltypesystem import lltype, rclass
-from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
-from pypy.jit.metainterp.history import AbstractDescr
-
-
-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_qmut_instance(cpu, gcref, mutatefielddescr):
-    """Returns the current QuasiImmut instance in the field,
-    possibly creating one.
-    """
-    # XXX this is broken on x86
-    qmut_gcref = cpu.bh_getfield_gc_r(gcref, mutatefielddescr)
-    if qmut_gcref:
-        qmut = QuasiImmut.show(cpu, qmut_gcref)
-    else:
-        qmut = QuasiImmut(cpu)
-        cpu.bh_setfield_gc_r(gcref, mutatefielddescr, qmut.hide())
-    return qmut
-
-def make_invalidation_function(STRUCT, mutatefieldname):
-    #
-    def _invalidate_now(p):
-        qmut_ptr = getattr(p, mutatefieldname)
-        setattr(p, mutatefieldname, lltype.nullptr(rclass.OBJECT))
-        qmut = cast_base_ptr_to_instance(QuasiImmut, qmut_ptr)
-        qmut.invalidate()
-    _invalidate_now._dont_inline_ = True
-    #
-    def invalidation(p):
-        if getattr(p, mutatefieldname):
-            _invalidate_now(p)
-    #
-    return invalidation
-
-
-class QuasiImmut(object):
-    llopaque = True
-    
-    def __init__(self, cpu):
-        self.cpu = cpu
-        # list of weakrefs to the LoopTokens that must be invalidated if
-        # this value ever changes
-        self.looptokens_wrefs = []
-        self.compress_limit = 30
-
-    def hide(self):
-        qmut_ptr = self.cpu.ts.cast_instance_to_base_ref(self)
-        return self.cpu.ts.cast_to_ref(qmut_ptr)
-
-    @staticmethod
-    def show(cpu, qmut_gcref):
-        qmut_ptr = cpu.ts.cast_to_baseclass(qmut_gcref)
-        return cast_base_ptr_to_instance(QuasiImmut, qmut_ptr)
-
-    def register_loop_token(self, wref_looptoken):
-        if len(self.looptokens_wrefs) > self.compress_limit:
-            self.compress_looptokens_list()
-        self.looptokens_wrefs.append(wref_looptoken)
-
-    def compress_looptokens_list(self):
-        self.looptokens_wrefs = [wref for wref in self.looptokens_wrefs
-                                      if wref() is not None]
-        self.compress_limit = (len(self.looptokens_wrefs) + 15) * 2
-
-    def invalidate(self):
-        # When this is called, all the loops that we record become
-        # invalid and must not be called again, nor returned to.
-        wrefs = self.looptokens_wrefs
-        self.looptokens_wrefs = []
-        for wref in wrefs:
-            looptoken = wref()
-            if looptoken is not None:
-                self.cpu.invalidate_loop(looptoken)
-
-
-class QuasiImmutDescr(AbstractDescr):
-    def __init__(self, cpu, structbox, fielddescr, mutatefielddescr):
-        self.cpu = cpu
-        self.structbox = structbox
-        self.fielddescr = fielddescr
-        self.mutatefielddescr = mutatefielddescr
-        gcref = structbox.getref_base()
-        self.qmut = get_current_qmut_instance(cpu, gcref, mutatefielddescr)
-        self.constantfieldbox = self.get_current_constant_fieldvalue()
-
-    def get_current_constant_fieldvalue(self):
-        from pypy.jit.metainterp import executor
-        from pypy.jit.metainterp.resoperation import rop
-        fieldbox = executor.execute(self.cpu, None, rop.GETFIELD_GC,
-                                    self.fielddescr, self.structbox)
-        return fieldbox.constbox()
-
-    def is_still_valid(self):
-        cpu = self.cpu
-        gcref = self.structbox.getref_base()
-        qmut = get_current_qmut_instance(cpu, gcref, self.mutatefielddescr)
-        if qmut is not self.qmut:
-            return False
-        else:
-            currentbox = self.get_current_constant_fieldvalue()
-            assert self.constantfieldbox.same_constant(currentbox)
-            return True

diff --git a/pypy/jit/metainterp/test/test_virtualizable.py b/pypy/jit/metainterp/test/test_virtualizable.py
--- a/pypy/jit/metainterp/test/test_virtualizable.py
+++ b/pypy/jit/metainterp/test/test_virtualizable.py
@@ -2,7 +2,6 @@
 from pypy.rpython.extregistry import ExtRegistryEntry
 from pypy.rpython.lltypesystem import lltype, lloperation, rclass, llmemory
 from pypy.rpython.annlowlevel import llhelper
-from pypy.rpython.rclass import IR_IMMUTABLE, IR_ARRAY_IMMUTABLE
 from pypy.jit.codewriter.policy import StopAtXPolicy
 from pypy.jit.codewriter import heaptracker
 from pypy.rlib.jit import JitDriver, hint, dont_look_inside
@@ -46,7 +45,7 @@
         ('inst_node', lltype.Ptr(LLtypeMixin.NODE)),
         hints = {'virtualizable2_accessor': FieldListAccessor()})
     XY._hints['virtualizable2_accessor'].initialize(
-        XY, {'inst_x' : IR_IMMUTABLE, 'inst_node' : IR_IMMUTABLE})
+        XY, {'inst_x' : "", 'inst_node' : ""})
 
     xy_vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True)
     heaptracker.set_testing_vtable_for_gcstruct(XY, xy_vtable, 'XY')
@@ -211,8 +210,7 @@
         ('inst_l2', lltype.Ptr(lltype.GcArray(lltype.Signed))),
         hints = {'virtualizable2_accessor': FieldListAccessor()})
     XY2._hints['virtualizable2_accessor'].initialize(
-        XY2, {'inst_x' : IR_IMMUTABLE,
-              'inst_l1' : IR_ARRAY_IMMUTABLE, 'inst_l2' : IR_ARRAY_IMMUTABLE})
+        XY2, {'inst_x' : "", 'inst_l1' : "[*]", 'inst_l2' : "[*]"})
 
     xy2_vtable = lltype.malloc(rclass.OBJECT_VTABLE, immortal=True)
     heaptracker.set_testing_vtable_for_gcstruct(XY2, xy2_vtable, 'XY2')

diff --git a/pypy/jit/metainterp/test/test_optimizeopt.py b/pypy/jit/metainterp/test/test_optimizeopt.py
--- a/pypy/jit/metainterp/test/test_optimizeopt.py
+++ b/pypy/jit/metainterp/test/test_optimizeopt.py
@@ -5717,35 +5717,8 @@
         # not obvious, because of the exception UnicodeDecodeError that
         # can be raised by ll_str2unicode()
 
-    def test_quasi_immut(self):
-        ops = """
-        [p0, p1, i0]
-        quasiimmut_field(p0, descr=quasiimmutdescr)
-        guard_not_invalidated() []
-        i1 = getfield_gc(p0, descr=quasifielddescr)
-        jump(p1, p0, i1)
-        """
-        expected = """
-        [p0, p1, i0]
-        i1 = getfield_gc(p0, descr=quasifielddescr)
-        jump(p1, p0, i1)
-        """
-        self.optimize_loop(ops, expected)
-
-    def test_quasi_immut_2(self):
-        ops = """
-        []
-        quasiimmut_field(ConstPtr(myptr), descr=quasiimmutdescr)
-        guard_not_invalidated() []
-        i1 = getfield_gc(ConstPtr(myptr), descr=quasifielddescr)
-        jump()
-        """
-        expected = """
-        []
-        guard_not_invalidated() []        
-        jump()
-        """
-        self.optimize_loop(ops, expected, expected)
+
+
 
 ##class TestOOtype(OptimizeOptTest, OOtypeMixin):
 

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,9 +7,8 @@
 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, check_skip_operation
+from pypy.jit.codewriter.policy import log
 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
@@ -562,8 +561,7 @@
                                                 arraydescr)
             return []
         # check for _immutable_fields_ hints
-        immut = v_inst.concretetype.TO._immutable_field(c_fieldname.value)
-        if immut:
+        if v_inst.concretetype.TO._immutable_field(c_fieldname.value):
             if (self.callcontrol is not None and
                 self.callcontrol.could_be_green_field(v_inst.concretetype.TO,
                                                       c_fieldname.value)):
@@ -576,21 +574,10 @@
         descr = self.cpu.fielddescrof(v_inst.concretetype.TO,
                                       c_fieldname.value)
         kind = getkind(RESULT)[0]
-        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('-live-', [], None),
-                   SpaceOperation('record_quasiimmut_field',
-                                  [v_inst, descr, descr1], None),
-                   op1]
-        return op1
+        return SpaceOperation('getfield_%s_%s%s' % (argname, kind, pure),
+                              [v_inst, descr], op.result)
 
     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/metainterp/optimizeopt/optimizer.py b/pypy/jit/metainterp/optimizeopt/optimizer.py
--- a/pypy/jit/metainterp/optimizeopt/optimizer.py
+++ b/pypy/jit/metainterp/optimizeopt/optimizer.py
@@ -257,7 +257,6 @@
         self.pendingfields = []
         self.posponedop = None
         self.exception_might_have_happened = False
-        self.quasi_immutable_deps = None
         self.newoperations = []
         if loop is not None:
             self.call_pure_results = loop.call_pure_results
@@ -310,7 +309,6 @@
         new.pure_operations = self.pure_operations
         new.producer = self.producer
         assert self.posponedop is None
-        new.quasi_immutable_deps = self.quasi_immutable_deps
 
         return new
 
@@ -412,7 +410,6 @@
             self.first_optimization.propagate_forward(op)
             self.i += 1
         self.loop.operations = self.newoperations
-        self.loop.quasi_immutable_deps = self.quasi_immutable_deps
         # accumulate counters
         self.resumedata_memo.update_counters(self.metainterp_sd.profiler)
 

diff --git a/pypy/jit/metainterp/optimizeopt/__init__.py b/pypy/jit/metainterp/optimizeopt/__init__.py
--- a/pypy/jit/metainterp/optimizeopt/__init__.py
+++ b/pypy/jit/metainterp/optimizeopt/__init__.py
@@ -41,8 +41,7 @@
                 # during preamble but to keep it during the loop
                 optimizations.append(o)
 
-    if ('rewrite' not in enable_opts or 'virtualize' not in enable_opts
-        or 'heap' not in enable_opts):
+    if 'rewrite' not in enable_opts or 'virtualize' not in enable_opts:
         optimizations.append(OptSimplify())
 
     if inline_short_preamble:

diff --git a/pypy/rpython/test/test_annlowlevel.py b/pypy/rpython/test/test_annlowlevel.py
--- a/pypy/rpython/test/test_annlowlevel.py
+++ b/pypy/rpython/test/test_annlowlevel.py
@@ -4,12 +4,9 @@
 
 from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
 from pypy.rpython.lltypesystem.rstr import mallocstr, mallocunicode
-from pypy.rpython.lltypesystem import lltype
 from pypy.rpython.ootypesystem import ootype
 from pypy.rpython.annlowlevel import hlstr, llstr, oostr
 from pypy.rpython.annlowlevel import hlunicode, llunicode
-from pypy.rpython import annlowlevel
-
 
 class TestLLType(BaseRtypingTest, LLRtypeMixin):
     def test_hlstr(self):
@@ -56,15 +53,6 @@
         res = self.interpret(f, [self.unicode_to_ll(u"abc")])
         assert res == 3
 
-    def test_cast_instance_to_base_ptr(self):
-        class X(object):
-            pass
-        x = X()
-        ptr = annlowlevel.cast_instance_to_base_ptr(x)
-        assert lltype.typeOf(ptr) == annlowlevel.base_ptr_lltype()
-        y = annlowlevel.cast_base_ptr_to_instance(X, ptr)
-        assert y is x
-
 
 class TestOOType(BaseRtypingTest, OORtypeMixin):
     def test_hlstr(self):
@@ -83,12 +71,3 @@
 
         res = self.interpret(f, [self.string_to_ll("abc")])
         assert res == 3
-
-    def test_cast_instance_to_base_obj(self):
-        class X(object):
-            pass
-        x = X()
-        obj = annlowlevel.cast_instance_to_base_obj(x)
-        assert lltype.typeOf(obj) == annlowlevel.base_obj_ootype()
-        y = annlowlevel.cast_base_ptr_to_instance(X, obj)
-        assert y is x

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
@@ -286,10 +286,6 @@
             raise ValueError("CALL_ASSEMBLER not supported")
         llimpl.redirect_call_assembler(self, oldlooptoken, newlooptoken)
 
-    def invalidate_loop(self, looptoken):
-        for loop in looptoken.compiled_loop_token.loop_and_bridges:
-            loop._obj.externalobj.invalid = True
-
     # ----------
 
     def sizeof(self, S):

diff --git a/pypy/jit/metainterp/test/test_optimizeutil.py b/pypy/jit/metainterp/test/test_optimizeutil.py
--- a/pypy/jit/metainterp/test/test_optimizeutil.py
+++ b/pypy/jit/metainterp/test/test_optimizeutil.py
@@ -3,7 +3,6 @@
 from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rstr
 from pypy.rpython.ootypesystem import ootype
 from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
-from pypy.rpython.rclass import FieldListAccessor, IR_QUASI_IMMUTABLE
 
 from pypy.jit.backend.llgraph import runner
 from pypy.jit.metainterp.history import (BoxInt, BoxPtr, ConstInt, ConstPtr,
@@ -13,7 +12,6 @@
 from pypy.jit.codewriter.effectinfo import EffectInfo
 from pypy.jit.codewriter.heaptracker import register_known_gctype, adr2int
 from pypy.jit.tool.oparser import parse
-from pypy.jit.metainterp.quasiimmut import QuasiImmutDescr
 
 def test_sort_descrs():
     class PseudoDescr(AbstractDescr):
@@ -64,18 +62,6 @@
     nextdescr = cpu.fielddescrof(NODE, 'next')
     otherdescr = cpu.fielddescrof(NODE2, 'other')
 
-    accessor = FieldListAccessor()
-    accessor.initialize(None, {'inst_field': IR_QUASI_IMMUTABLE})
-    QUASI = lltype.GcStruct('QUASIIMMUT', ('inst_field', lltype.Signed),
-                            ('mutate_field', rclass.OBJECTPTR),
-                            hints={'immutable_fields': accessor})
-    quasi = lltype.malloc(QUASI, immortal=True)
-    quasifielddescr = cpu.fielddescrof(QUASI, 'inst_field')
-    quasibox = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, quasi))
-    quasiimmutdescr = QuasiImmutDescr(cpu, quasibox,
-                                      quasifielddescr,
-                                      cpu.fielddescrof(QUASI, 'mutate_field'))
-
     NODEOBJ = lltype.GcStruct('NODEOBJ', ('parent', OBJECT),
                                          ('ref', lltype.Ptr(OBJECT)))
     nodeobj = lltype.malloc(NODEOBJ)

diff --git a/pypy/jit/metainterp/virtualizable.py b/pypy/jit/metainterp/virtualizable.py
--- a/pypy/jit/metainterp/virtualizable.py
+++ b/pypy/jit/metainterp/virtualizable.py
@@ -1,7 +1,6 @@
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython.ootypesystem import ootype
 from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
-from pypy.rpython.rclass import IR_ARRAY_IMMUTABLE, IR_IMMUTABLE
 from pypy.rpython import rvirtualizable2
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.rlib.unroll import unrolling_iterable
@@ -11,7 +10,7 @@
 from pypy.jit.metainterp.warmstate import wrap, unwrap
 from pypy.rlib.objectmodel import specialize
 
-class VirtualizableInfo(object):
+class VirtualizableInfo:
     TOKEN_NONE            = 0      # must be 0 -- see also x86.call_assembler
     TOKEN_TRACING_RESCALL = -1
 
@@ -34,13 +33,11 @@
         all_fields = accessor.fields
         static_fields = []
         array_fields = []
-        for name, tp in all_fields.iteritems():
-            if tp == IR_ARRAY_IMMUTABLE:
+        for name, suffix in all_fields.iteritems():
+            if suffix == '[*]':
                 array_fields.append(name)
-            elif tp == IR_IMMUTABLE:
+            else:
                 static_fields.append(name)
-            else:
-                raise Exception("unknown type: %s" % tp)
         self.static_fields = static_fields
         self.array_fields = array_fields
         #

diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -492,8 +492,6 @@
     def consider_guard_no_exception(self, op):
         self.perform_guard(op, [], None)
 
-    consider_guard_not_invalidated = consider_guard_no_exception
-
     def consider_guard_exception(self, op):
         loc = self.rm.make_sure_var_in_reg(op.getarg(0))
         box = TempBox()

diff --git a/pypy/rpython/lltypesystem/test/test_ll2ctypes.py b/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
--- a/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
+++ b/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
@@ -1293,28 +1293,6 @@
         rffi.cast(SP, p).x = 0
         lltype.free(chunk, flavor='raw')
 
-    def test_opaque_tagged_pointers(self):
-        from pypy.rpython.annlowlevel import cast_base_ptr_to_instance
-        from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
-        from pypy.rpython.lltypesystem import rclass
-        
-        class Opaque(object):
-            llopaque = True
-
-            def hide(self):
-                ptr = cast_instance_to_base_ptr(self)
-                return lltype.cast_opaque_ptr(llmemory.GCREF, ptr)
-
-            @staticmethod
-            def show(gcref):
-                ptr = lltype.cast_opaque_ptr(lltype.Ptr(rclass.OBJECT), gcref)
-                return cast_base_ptr_to_instance(Opaque, ptr)
-
-        opaque = Opaque()
-        round = ctypes2lltype(llmemory.GCREF, lltype2ctypes(opaque.hide()))
-        assert Opaque.show(round) is opaque
-
-
 class TestPlatform(object):
     def test_lib_on_libpaths(self):
         from pypy.translator.platform import platform

diff --git a/pypy/jit/metainterp/optimizeopt/heap.py b/pypy/jit/metainterp/optimizeopt/heap.py
--- a/pypy/jit/metainterp/optimizeopt/heap.py
+++ b/pypy/jit/metainterp/optimizeopt/heap.py
@@ -119,7 +119,6 @@
         self._lazy_setfields = []
         # cached array items:  {descr: CachedArrayItems}
         self.cached_arrayitems = {}
-        self._remove_guard_not_invalidated = False
 
     def reconstruct_for_next_iteration(self, optimizer, valuemap):
         new = OptHeap()
@@ -379,43 +378,6 @@
         self.cache_arrayitem_value(op.getdescr(), value, indexvalue, fieldvalue,
                                    write=True)
 
-    def optimize_QUASIIMMUT_FIELD(self, op):
-        # Pattern: QUASIIMMUT_FIELD(s, descr=QuasiImmutDescr)
-        #          x = GETFIELD_GC(s, descr='inst_x')
-        # If 's' is a constant (after optimizations), then we make 's.inst_x'
-        # a constant too, and we rely on the rest of the optimizations to
-        # constant-fold the following getfield_gc.
-        structvalue = self.getvalue(op.getarg(0))
-        if not structvalue.is_constant():
-            self._remove_guard_not_invalidated = True
-            return    # not a constant at all; ignore QUASIIMMUT_FIELD
-        #
-        from pypy.jit.metainterp.quasiimmut import QuasiImmutDescr
-        qmutdescr = op.getdescr()
-        assert isinstance(qmutdescr, QuasiImmutDescr)
-        # check that the value is still correct; it could have changed
-        # already between the tracing and now.  In this case, we are
-        # simply ignoring the QUASIIMMUT_FIELD hint and compiling it
-        # as a regular getfield.
-        if not qmutdescr.is_still_valid():
-            self._remove_guard_not_invalidated = True
-            return
-        # record as an out-of-line guard
-        if self.optimizer.quasi_immutable_deps is None:
-            self.optimizer.quasi_immutable_deps = {}
-        self.optimizer.quasi_immutable_deps[qmutdescr.qmut] = None
-        # perform the replacement in the list of operations
-        fieldvalue = self.getvalue(qmutdescr.constantfieldbox)
-        cf = self.field_cache(qmutdescr.fielddescr)
-        cf.remember_field_value(structvalue, fieldvalue)
-        self._remove_guard_not_invalidated = False
-
-    def optimize_GUARD_NOT_INVALIDATED(self, op):
-        if self._remove_guard_not_invalidated:
-            return
-        self._remove_guard_not_invalidated = False
-        self.emit_operation(op)
-
     def propagate_forward(self, op):
         opnum = op.getopnum()
         for value, func in optimize_ops:

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
@@ -312,7 +312,6 @@
                          rop.DEBUG_MERGE_POINT,
                          rop.JIT_DEBUG,
                          rop.SETARRAYITEM_RAW,
-                         rop.QUASIIMMUT_FIELD,
                          ):      # list of opcodes never executed by pyjitpl
                 continue
             raise AssertionError("missing %r" % (key,))

diff --git a/pypy/rpython/rclass.py b/pypy/rpython/rclass.py
--- a/pypy/rpython/rclass.py
+++ b/pypy/rpython/rclass.py
@@ -3,8 +3,7 @@
 #from pypy.annotation.classdef import isclassdef
 from pypy.annotation import description
 from pypy.rpython.error import TyperError
-from pypy.rpython.rmodel import Repr, getgcflavor, inputconst
-from pypy.rpython.lltypesystem.lltype import Void
+from pypy.rpython.rmodel import Repr, getgcflavor
 
 
 class FieldListAccessor(object):
@@ -13,8 +12,6 @@
         assert type(fields) is dict
         self.TYPE = TYPE
         self.fields = fields
-        for x in fields.itervalues():
-            assert isinstance(x, ImmutableRanking)
 
     def __repr__(self):
         return '<FieldListAccessor for %s>' % getattr(self, 'TYPE', '?')
@@ -22,20 +19,6 @@
     def _freeze_(self):
         return True
 
-class ImmutableRanking(object):
-    def __init__(self, name, is_immutable):
-        self.name = name
-        self.is_immutable = is_immutable
-    def __nonzero__(self):
-        return self.is_immutable
-    def __repr__(self):
-        return '<%s>' % self.name
-
-IR_MUTABLE         = ImmutableRanking('mutable', False)
-IR_IMMUTABLE       = ImmutableRanking('immutable', True)
-IR_ARRAY_IMMUTABLE = ImmutableRanking('array_immutable', True)
-IR_QUASI_IMMUTABLE = ImmutableRanking('quasi_immutable', False)
-
 class ImmutableConflictError(Exception):
     """Raised when the _immutable_ or _immutable_fields_ hints are
     not consistent across a class hierarchy."""
@@ -172,8 +155,7 @@
         self.classdef = classdef
 
     def _setup_repr(self):
-        if self.classdef is None:
-            self.immutable_field_set = set()
+        pass
 
     def _check_for_immutable_hints(self, hints):
         loc = self.classdef.classdesc.lookup('_immutable_')
@@ -185,13 +167,13 @@
                     self.classdef,))
             hints = hints.copy()
             hints['immutable'] = True
-        self.immutable_field_set = set()  # unless overwritten below
+        self.immutable_field_list = []  # unless overwritten below
         if self.classdef.classdesc.lookup('_immutable_fields_') is not None:
             hints = hints.copy()
             immutable_fields = self.classdef.classdesc.classdict.get(
                 '_immutable_fields_')
             if immutable_fields is not None:
-                self.immutable_field_set = set(immutable_fields.value)
+                self.immutable_field_list = immutable_fields.value
             accessor = FieldListAccessor()
             hints['immutable_fields'] = accessor
         return hints
@@ -219,35 +201,33 @@
         if "immutable_fields" in hints:
             accessor = hints["immutable_fields"]
             if not hasattr(accessor, 'fields'):
-                immutable_fields = set()
+                immutable_fields = []
                 rbase = self
                 while rbase.classdef is not None:
-                    immutable_fields.update(rbase.immutable_field_set)
+                    immutable_fields += rbase.immutable_field_list
                     rbase = rbase.rbase
                 self._parse_field_list(immutable_fields, accessor)
 
     def _parse_field_list(self, fields, accessor):
-        ranking = {}
+        with_suffix = {}
         for name in fields:
-            if name.endswith('[*]'):    # for virtualizables' lists
+            if name.endswith('[*]'):
                 name = name[:-3]
-                rank = IR_ARRAY_IMMUTABLE
-            elif name.endswith('?'):    # a quasi-immutable field
-                name = name[:-1]
-                rank = IR_QUASI_IMMUTABLE
-            else:                       # a regular immutable/green field
-                rank = IR_IMMUTABLE
+                suffix = '[*]'
+            else:
+                suffix = ''
             try:
                 mangled_name, r = self._get_field(name)
             except KeyError:
                 continue
-            ranking[mangled_name] = rank
-        accessor.initialize(self.object_type, ranking)
-        return ranking
+            with_suffix[mangled_name] = suffix
+        accessor.initialize(self.object_type, with_suffix)
+        return with_suffix
 
     def _check_for_immutable_conflicts(self):
         # check for conflicts, i.e. a field that is defined normally as
         # mutable in some parent class but that is now declared immutable
+        from pypy.rpython.lltypesystem.lltype import Void
         is_self_immutable = "immutable" in self.object_type._hints
         base = self
         while base.classdef is not None:
@@ -268,30 +248,12 @@
                         "class %r has _immutable_=True, but parent class %r "
                         "defines (at least) the mutable field %r" % (
                         self, base, fieldname))
-                if (fieldname in self.immutable_field_set or
-                    (fieldname + '?') in self.immutable_field_set):
+                if fieldname in self.immutable_field_list:
                     raise ImmutableConflictError(
                         "field %r is defined mutable in class %r, but "
                         "listed in _immutable_fields_ in subclass %r" % (
                         fieldname, base, self))
 
-    def hook_access_field(self, vinst, cname, llops, flags):
-        pass        # for virtualizables; see rvirtualizable2.py
-
-    def hook_setfield(self, vinst, fieldname, llops):
-        if self.is_quasi_immutable(fieldname):
-            c_fieldname = inputconst(Void, 'mutate_' + fieldname)
-            llops.genop('jit_force_quasi_immutable', [vinst, c_fieldname])
-
-    def is_quasi_immutable(self, fieldname):
-        search = fieldname + '?'
-        rbase = self
-        while rbase.classdef is not None:
-            if search in rbase.immutable_field_set:
-                return True
-            rbase = rbase.rbase
-        return False
-
     def new_instance(self, llops, classcallhop=None):
         raise NotImplementedError
 

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, quasiimmut
+from pypy.jit.metainterp import history
 from pypy.rpython.lltypesystem import lltype, rclass
 from pypy.tool.udir import udir
 
@@ -85,20 +85,12 @@
                     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/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
@@ -167,7 +167,6 @@
 
 class CompiledLoop(object):
     has_been_freed = False
-    invalid = False
 
     def __init__(self):
         self.inputargs = []
@@ -934,9 +933,6 @@
         if forced:
             raise GuardFailed
 
-    def op_guard_not_invalidated(self, descr):
-        if self.loop.invalid:
-            raise GuardFailed
 
 class OOFrame(Frame):
 

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,43 +947,3 @@
     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) == 3
-        assert op1.args[0] == v_x
-        assert op1.args[1] == ('fielddescr', STRUCT, 'inst_x')
-        assert op1.args[2] == ('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)

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,8 +171,7 @@
 class VirtualizableAnalyzer(BoolGraphAnalyzer):
     def analyze_simple_operation(self, op, graphinfo):
         return op.opname in ('jit_force_virtualizable',
-                             'jit_force_virtual',
-                             'jit_force_quasi_immutable')
+                             'jit_force_virtual')
 
 # ____________________________________________________________
 

diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -555,16 +555,6 @@
     opimpl_setfield_raw_r = _opimpl_setfield_raw_any
     opimpl_setfield_raw_f = _opimpl_setfield_raw_any
 
-    @arguments("box", "descr", "descr", "orgpc")
-    def opimpl_record_quasiimmut_field(self, box, fielddescr,
-                                       mutatefielddescr, orgpc):
-        from pypy.jit.metainterp.quasiimmut import QuasiImmutDescr
-        cpu = self.metainterp.cpu
-        descr = QuasiImmutDescr(cpu, box, fielddescr, mutatefielddescr)
-        self.metainterp.history.record(rop.QUASIIMMUT_FIELD, [box],
-                                       None, descr=descr)
-        self.generate_guard(rop.GUARD_NOT_INVALIDATED, resumepc=orgpc)
-
     def _nonstandard_virtualizable(self, pc, box):
         # returns True if 'box' is actually not the "standard" virtualizable
         # that is stored in metainterp.virtualizable_boxes[-1]
@@ -1086,8 +1076,6 @@
         if opnum == rop.GUARD_NOT_FORCED:
             resumedescr = compile.ResumeGuardForcedDescr(metainterp_sd,
                                                    metainterp.jitdriver_sd)
-        elif opnum == rop.GUARD_NOT_INVALIDATED:
-            resumedescr = compile.ResumeGuardNotInvalidated()
         else:
             resumedescr = compile.ResumeGuardDescr()
         guard_op = metainterp.history.record(opnum, moreargs, None,
@@ -1860,9 +1848,6 @@
                 self.handle_possible_exception()
             except ChangeFrame:
                 pass
-        elif opnum == rop.GUARD_NOT_INVALIDATED:
-            pass # XXX we want to do something special in resume descr,
-                 # but not now
         elif opnum == rop.GUARD_NO_OVERFLOW:   # an overflow now detected
             self.execute_raised(OverflowError(), constant=True)
             try:

diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py
--- a/pypy/jit/metainterp/compile.py
+++ b/pypy/jit/metainterp/compile.py
@@ -76,11 +76,6 @@
             op.setdescr(None)    # clear reference, mostly for tests
             if not we_are_translated():
                 op._jumptarget_number = descr.number
-    # record this looptoken on the QuasiImmut used in the code
-    if loop.quasi_immutable_deps is not None:
-        for qmut in loop.quasi_immutable_deps:
-            qmut.register_loop_token(wref)
-        # XXX maybe we should clear the dictionary here
     # mostly for tests: make sure we don't keep a reference to the LoopToken
     loop.token = None
     if not we_are_translated():
@@ -401,12 +396,6 @@
         self.copy_all_attributes_into(res)
         return res
 
-class ResumeGuardNotInvalidated(ResumeGuardDescr):
-    def _clone_if_mutable(self):
-        res = ResumeGuardNotInvalidated()
-        self.copy_all_attributes_into(res)
-        return res
-
 class ResumeAtPositionDescr(ResumeGuardDescr):
     def _clone_if_mutable(self):
         res = ResumeAtPositionDescr()

diff --git a/pypy/rpython/lltypesystem/test/test_lloperation.py b/pypy/rpython/lltypesystem/test/test_lloperation.py
--- a/pypy/rpython/lltypesystem/test/test_lloperation.py
+++ b/pypy/rpython/lltypesystem/test/test_lloperation.py
@@ -54,7 +54,6 @@
 
 def test_is_pure():
     from pypy.objspace.flow.model import Variable, Constant
-    from pypy.rpython import rclass
     assert llop.bool_not.is_pure([Variable()])
     assert llop.debug_assert.is_pure([Variable()])
     assert not llop.int_add_ovf.is_pure([Variable(), Variable()])
@@ -86,50 +85,38 @@
     assert llop.getarrayitem.is_pure([v_a2, Variable()])
     assert llop.getarraysize.is_pure([v_a2])
     #
-    for kind in [rclass.IR_MUTABLE, rclass.IR_IMMUTABLE,
-                 rclass.IR_ARRAY_IMMUTABLE, rclass.IR_QUASI_IMMUTABLE]:
-        accessor = rclass.FieldListAccessor()
-        S3 = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed),
-                             hints={'immutable_fields': accessor})
-        accessor.initialize(S3, {'x': kind})
-        v_s3 = Variable()
-        v_s3.concretetype = lltype.Ptr(S3)
-        assert not llop.setfield.is_pure([v_s3, Constant('x'), Variable()])
-        assert not llop.setfield.is_pure([v_s3, Constant('y'), Variable()])
-        assert llop.getfield.is_pure([v_s3, Constant('x')]) is kind
-        assert not llop.getfield.is_pure([v_s3, Constant('y')])
+    accessor = rclass.FieldListAccessor()
+    S3 = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed),
+                         hints={'immutable_fields': accessor})
+    accessor.initialize(S3, {'x': ''})
+    v_s3 = Variable()
+    v_s3.concretetype = lltype.Ptr(S3)
+    assert not llop.setfield.is_pure([v_s3, Constant('x'), Variable()])
+    assert not llop.setfield.is_pure([v_s3, Constant('y'), Variable()])
+    assert llop.getfield.is_pure([v_s3, Constant('x')])
+    assert not llop.getfield.is_pure([v_s3, Constant('y')])
 
 def test_getfield_pure():
     S1 = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed))
     S2 = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed),
                          hints={'immutable': True})
     accessor = rclass.FieldListAccessor()
+    S3 = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed),
+                         hints={'immutable_fields': accessor})
+    accessor.initialize(S3, {'x': ''})
     #
     s1 = lltype.malloc(S1); s1.x = 45
     py.test.raises(TypeError, llop.getfield, lltype.Signed, s1, 'x')
     s2 = lltype.malloc(S2); s2.x = 45
     assert llop.getfield(lltype.Signed, s2, 'x') == 45
+    s3 = lltype.malloc(S3); s3.x = 46; s3.y = 47
+    assert llop.getfield(lltype.Signed, s3, 'x') == 46
+    py.test.raises(TypeError, llop.getfield, lltype.Signed, s3, 'y')
     #
     py.test.raises(TypeError, llop.getinteriorfield, lltype.Signed, s1, 'x')
     assert llop.getinteriorfield(lltype.Signed, s2, 'x') == 45
-    #
-    for kind in [rclass.IR_MUTABLE, rclass.IR_IMMUTABLE,
-                 rclass.IR_ARRAY_IMMUTABLE, rclass.IR_QUASI_IMMUTABLE]:
-        #
-        S3 = lltype.GcStruct('S', ('x', lltype.Signed), ('y', lltype.Signed),
-                             hints={'immutable_fields': accessor})
-        accessor.initialize(S3, {'x': kind})
-        s3 = lltype.malloc(S3); s3.x = 46; s3.y = 47
-        if kind in [rclass.IR_IMMUTABLE, rclass.IR_ARRAY_IMMUTABLE]:
-            assert llop.getfield(lltype.Signed, s3, 'x') == 46
-            assert llop.getinteriorfield(lltype.Signed, s3, 'x') == 46
-        else:
-            py.test.raises(TypeError, llop.getfield, lltype.Signed, s3, 'x')
-            py.test.raises(TypeError, llop.getinteriorfield,
-                           lltype.Signed, s3, 'x')
-        py.test.raises(TypeError, llop.getfield, lltype.Signed, s3, 'y')
-        py.test.raises(TypeError, llop.getinteriorfield,
-                       lltype.Signed, s3, 'y')
+    assert llop.getinteriorfield(lltype.Signed, s3, 'x') == 46
+    py.test.raises(TypeError, llop.getinteriorfield, lltype.Signed, s3, 'y')
 
 # ___________________________________________________________________________
 # This tests that the LLInterpreter and the LL_OPERATIONS tables are in sync.

diff --git a/pypy/jit/backend/x86/runner.py b/pypy/jit/backend/x86/runner.py
--- a/pypy/jit/backend/x86/runner.py
+++ b/pypy/jit/backend/x86/runner.py
@@ -145,14 +145,6 @@
     def redirect_call_assembler(self, oldlooptoken, newlooptoken):
         self.assembler.redirect_call_assembler(oldlooptoken, newlooptoken)
 
-    def invalidate_loop(self, looptoken):
-        from pypy.jit.backend.x86 import codebuf
-        
-        for addr, tgt in looptoken.compiled_loop_token.invalidate_positions:
-            mc = codebuf.MachineCodeBlockWrapper()
-            mc.JMP_l(tgt)
-            mc.copy_to_raw_memory(addr - 1)
-
 class CPU386(AbstractX86CPU):
     WORD = 4
     NUM_REGS = 8

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
@@ -525,9 +525,6 @@
 def op_jit_force_virtual(x):
     return x
 
-def op_jit_force_quasi_immutable(*args):
-    pass
-
 def op_get_group_member(TYPE, grpptr, memberoffset):
     from pypy.rpython.lltypesystem import llgroup
     assert isinstance(memberoffset, llgroup.GroupMemberOffset)

diff --git a/pypy/rpython/test/test_rvirtualizable2.py b/pypy/rpython/test/test_rvirtualizable2.py
--- a/pypy/rpython/test/test_rvirtualizable2.py
+++ b/pypy/rpython/test/test_rvirtualizable2.py
@@ -5,7 +5,6 @@
 from pypy.rlib.jit import hint
 from pypy.objspace.flow.model import summary
 from pypy.rpython.llinterp import LLInterpreter
-from pypy.rpython.rclass import IR_IMMUTABLE, IR_ARRAY_IMMUTABLE
 from pypy import conftest
 
 
@@ -117,8 +116,8 @@
         TYPE = self.gettype(v_inst)
         accessor = TYPE._hints['virtualizable2_accessor']
         assert accessor.TYPE == TYPE
-        assert accessor.fields == {self.prefix + 'v1': IR_IMMUTABLE,
-                                   self.prefix + 'v2': IR_ARRAY_IMMUTABLE}
+        assert accessor.fields == {self.prefix + 'v1' : "",
+                                   self.prefix + 'v2': "[*]"}
         #
         def fn2(n):
             Base().base1 = 42

diff --git a/pypy/jit/metainterp/blackhole.py b/pypy/jit/metainterp/blackhole.py
--- a/pypy/jit/metainterp/blackhole.py
+++ b/pypy/jit/metainterp/blackhole.py
@@ -1166,11 +1166,6 @@
     def bhimpl_setfield_raw_f(cpu, struct, fielddescr, newvalue):
         cpu.bh_setfield_raw_f(struct, fielddescr, newvalue)
 
-    @arguments("cpu", "r", "d", "d")
-    def bhimpl_record_quasiimmut_field(self, struct, fielddescr,
-                                       mutatefielddescr):
-        pass
-
     @arguments("cpu", "d", returns="r")
     def bhimpl_new(cpu, descr):
         return cpu.bh_new(descr)
@@ -1292,8 +1287,6 @@
             # We get here because it used to overflow, but now it no longer
             # does.
             pass
-        elif opnum == rop.GUARD_NOT_INVALIDATED:
-            pass
         else:
             from pypy.jit.metainterp.resoperation import opname
             raise NotImplementedError(opname[opnum])

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
@@ -433,7 +433,6 @@
     'jit_marker':           LLOp(),
     'jit_force_virtualizable':LLOp(canrun=True),
     'jit_force_virtual':    LLOp(canrun=True),
-    'jit_force_quasi_immutable': LLOp(canrun=True),
     'get_exception_addr':   LLOp(),
     'get_exc_value_addr':   LLOp(),
     'do_malloc_fixedsize_clear':LLOp(canraise=(MemoryError,),canunwindgc=True),

diff --git a/pypy/jit/backend/x86/test/test_quasiimmut.py b/pypy/jit/backend/x86/test/test_quasiimmut.py
deleted file mode 100644
--- a/pypy/jit/backend/x86/test/test_quasiimmut.py
+++ /dev/null
@@ -1,9 +0,0 @@
-
-import py
-from pypy.jit.backend.x86.test.test_basic import Jit386Mixin
-from pypy.jit.metainterp.test import test_quasiimmut
-
-class TestLoopSpec(Jit386Mixin, test_quasiimmut.QuasiImmutTests):
-    # for the individual tests see
-    # ====> ../../../metainterp/test/test_loop.py
-    pass

diff --git a/pypy/rpython/rvirtualizable2.py b/pypy/rpython/rvirtualizable2.py
--- a/pypy/rpython/rvirtualizable2.py
+++ b/pypy/rpython/rvirtualizable2.py
@@ -50,7 +50,7 @@
 
     def hook_access_field(self, vinst, cname, llops, flags):
         #if not flags.get('access_directly'):
-        if self.my_redirected_fields.get(cname.value):
+        if cname.value in self.my_redirected_fields:
             cflags = inputconst(lltype.Void, flags)
             llops.genop('jit_force_virtualizable', [vinst, cname, cflags])
 

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
@@ -380,7 +380,6 @@
     'GUARD_NO_OVERFLOW/0d',
     'GUARD_OVERFLOW/0d',
     'GUARD_NOT_FORCED/0d',
-    'GUARD_NOT_INVALIDATED/0d',
     '_GUARD_LAST', # ----- end of guard operations -----
 
     '_NOSIDEEFFECT_FIRST', # ----- start of no_side_effect operations -----
@@ -476,7 +475,6 @@
     'VIRTUAL_REF_FINISH/2',   # removed before it's passed to the backend
     'COPYSTRCONTENT/5',       # src, dst, srcstart, dststart, length
     'COPYUNICODECONTENT/5',
-    'QUASIIMMUT_FIELD/1d',    # [objptr], descr=SlowMutateDescr
 
     '_CANRAISE_FIRST', # ----- start of can_raise operations -----
     '_CALL_FIRST',

diff --git a/pypy/rpython/lltypesystem/test/test_lltype.py b/pypy/rpython/lltypesystem/test/test_lltype.py
--- a/pypy/rpython/lltypesystem/test/test_lltype.py
+++ b/pypy/rpython/lltypesystem/test/test_lltype.py
@@ -794,8 +794,15 @@
         def __init__(self, fields):
             self.fields = fields
     S = GcStruct('S', ('x', lltype.Signed),
-                 hints={'immutable_fields': FieldListAccessor({'x': 1234})})
-    assert S._immutable_field('x') == 1234
+                 hints={'immutable_fields': FieldListAccessor({'x':''})})
+    assert S._immutable_field('x') == True
+    #
+    class FieldListAccessor(object):
+        def __init__(self, fields):
+            self.fields = fields
+    S = GcStruct('S', ('x', lltype.Signed),
+                 hints={'immutable_fields': FieldListAccessor({'x':'[*]'})})
+    assert S._immutable_field('x') == '[*]'
 
 def test_typedef():
     T = Typedef(Signed, 'T')

diff --git a/pypy/jit/metainterp/optimizeopt/unroll.py b/pypy/jit/metainterp/optimizeopt/unroll.py
--- a/pypy/jit/metainterp/optimizeopt/unroll.py
+++ b/pypy/jit/metainterp/optimizeopt/unroll.py
@@ -267,8 +267,6 @@
             virtual_state = modifier.get_virtual_state(jump_args)
 
             loop.preamble.operations = self.optimizer.newoperations
-            loop.preamble.quasi_immutable_deps = (
-                self.optimizer.quasi_immutable_deps)
             self.optimizer = self.optimizer.reconstruct_for_next_iteration()
             inputargs = self.inline(self.cloned_operations,
                                     loop.inputargs, jump_args)
@@ -278,7 +276,6 @@
             loop.preamble.operations.append(jmp)
 
             loop.operations = self.optimizer.newoperations
-            loop.quasi_immutable_deps = self.optimizer.quasi_immutable_deps
 
             start_resumedescr = loop.preamble.start_resumedescr.clone_if_mutable()
             assert isinstance(start_resumedescr, ResumeGuardDescr)

diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -85,7 +85,6 @@
                           'nslots',
                           'instancetypedef',
                           'terminator',
-                          '_version_tag?',
                           ]
 
     # for config.objspace.std.getattributeshortcut

diff --git a/pypy/jit/metainterp/warmspot.py b/pypy/jit/metainterp/warmspot.py
--- a/pypy/jit/metainterp/warmspot.py
+++ b/pypy/jit/metainterp/warmspot.py
@@ -131,16 +131,6 @@
 def find_set_param(graphs):
     return _find_jit_marker(graphs, 'set_param')
 
-def find_force_quasi_immutable(graphs):
-    results = []
-    for graph in graphs:
-        for block in graph.iterblocks():
-            for i in range(len(block.operations)):
-                op = block.operations[i]
-                if op.opname == 'jit_force_quasi_immutable':
-                    results.append((graph, block, i))
-    return results
-
 def get_stats():
     return pyjitpl._warmrunnerdesc.stats
 
@@ -197,7 +187,6 @@
         self.rewrite_can_enter_jits()
         self.rewrite_set_param()
         self.rewrite_force_virtual(vrefinfo)
-        self.rewrite_force_quasi_immutable()
         self.add_finish()
         self.metainterp_sd.finish_setup(self.codewriter)
 
@@ -853,28 +842,6 @@
         all_graphs = self.translator.graphs
         vrefinfo.replace_force_virtual_with_call(all_graphs)
 
-    def replace_force_quasiimmut_with_direct_call(self, op):
-        ARG = op.args[0].concretetype
-        mutatefieldname = op.args[1].value
-        key = (ARG, mutatefieldname)
-        if key in self._cache_force_quasiimmed_funcs:
-            cptr = self._cache_force_quasiimmed_funcs[key]
-        else:
-            from pypy.jit.metainterp import quasiimmut
-            func = quasiimmut.make_invalidation_function(ARG, mutatefieldname)
-            FUNC = lltype.Ptr(lltype.FuncType([ARG], lltype.Void))
-            llptr = self.helper_func(FUNC, func)
-            cptr = Constant(llptr, FUNC)
-            self._cache_force_quasiimmed_funcs[key] = cptr
-        op.opname = 'direct_call'
-        op.args = [cptr, op.args[0]]
-
-    def rewrite_force_quasi_immutable(self):
-        self._cache_force_quasiimmed_funcs = {}
-        graphs = self.translator.graphs
-        for graph, block, i in find_force_quasi_immutable(graphs):
-            self.replace_force_quasiimmut_with_direct_call(block.operations[i])
-
     # ____________________________________________________________
 
     def execute_token(self, loop_token):

diff --git a/pypy/rpython/lltypesystem/rclass.py b/pypy/rpython/lltypesystem/rclass.py
--- a/pypy/rpython/lltypesystem/rclass.py
+++ b/pypy/rpython/lltypesystem/rclass.py
@@ -322,7 +322,6 @@
         #       before they are fully built, to avoid strange bugs in case
         #       of recursion where other code would uses these
         #       partially-initialized dicts.
-        AbstractInstanceRepr._setup_repr(self)
         self.rclass = getclassrepr(self.rtyper, self.classdef)
         fields = {}
         allinstancefields = {}
@@ -371,11 +370,6 @@
             kwds = {}
             if self.gcflavor == 'gc':
                 kwds['rtti'] = True
-
-            for name, attrdef in attrs:
-                if not attrdef.readonly and self.is_quasi_immutable(name):
-                    llfields.append(('mutate_' + name, OBJECTPTR))
-
             object_type = MkStruct(self.classdef.name,
                                    ('super', self.rbase.object_type),
                                    hints=hints,
@@ -494,7 +488,6 @@
             if force_cast:
                 vinst = llops.genop('cast_pointer', [vinst], resulttype=self)
             self.hook_access_field(vinst, cname, llops, flags)
-            self.hook_setfield(vinst, attr, llops)
             llops.genop('setfield', [vinst, cname, vvalue])
         else:
             if self.classdef is None:
@@ -502,6 +495,9 @@
             self.rbase.setfield(vinst, attr, vvalue, llops, force_cast=True,
                                 flags=flags)
 
+    def hook_access_field(self, vinst, cname, llops, flags):
+        pass        # for virtualizables; see rvirtualizable2.py
+
     def new_instance(self, llops, classcallhop=None):
         """Build a new instance, without calling __init__."""
         flavor = self.gcflavor

diff --git a/pypy/rpython/annlowlevel.py b/pypy/rpython/annlowlevel.py
--- a/pypy/rpython/annlowlevel.py
+++ b/pypy/rpython/annlowlevel.py
@@ -480,26 +480,7 @@
 # ____________________________________________________________
 
 def cast_object_to_ptr(PTR, object):
-    """NOT_RPYTHON: hack. The object may be disguised as a PTR now.
-    Limited to casting a given object to a single type.
-    """
-    if isinstance(PTR, lltype.Ptr):
-        TO = PTR.TO
-    else:
-        TO = PTR
-    if not hasattr(object, '_carry_around_for_tests'):
-        assert not hasattr(object, '_TYPE')
-        object._carry_around_for_tests = True
-        object._TYPE = TO
-    else:
-        assert object._TYPE == TO
-    #
-    if isinstance(PTR, lltype.Ptr):
-        return lltype._ptr(PTR, object, True)
-    elif isinstance(PTR, ootype.Instance):
-        return object
-    else:
-        raise NotImplementedError("cast_object_to_ptr(%r, ...)" % PTR)
+    raise NotImplementedError("cast_object_to_ptr")
 
 def cast_instance_to_base_ptr(instance):
     return cast_object_to_ptr(base_ptr_lltype(), instance)
@@ -554,13 +535,7 @@
 # ____________________________________________________________
 
 def cast_base_ptr_to_instance(Class, ptr):
-    """NOT_RPYTHON: hack. Reverse the hacking done in cast_object_to_ptr()."""
-    if isinstance(lltype.typeOf(ptr), lltype.Ptr):
-        ptr = ptr._as_obj()
-    if not isinstance(ptr, Class):
-        raise NotImplementedError("cast_base_ptr_to_instance: casting %r to %r"
-                                  % (ptr, Class))
-    return ptr
+    raise NotImplementedError("cast_base_ptr_to_instance")
 
 class CastBasePtrToInstanceEntry(extregistry.ExtRegistryEntry):
     _about_ = cast_base_ptr_to_instance

diff --git a/pypy/jit/metainterp/optimizeopt/simplify.py b/pypy/jit/metainterp/optimizeopt/simplify.py
--- a/pypy/jit/metainterp/optimizeopt/simplify.py
+++ b/pypy/jit/metainterp/optimizeopt/simplify.py
@@ -20,9 +20,6 @@
         op = ResOperation(rop.SAME_AS, [op.getarg(0)], op.result)
         self.emit_operation(op)
 
-    def optimize_QUASIIMMUT_FIELD(self, op):
-        pass
-
     def propagate_forward(self, op):
         opnum = op.getopnum()
         for value, func in optimize_ops:

diff --git a/pypy/rpython/ootypesystem/ootype.py b/pypy/rpython/ootypesystem/ootype.py
--- a/pypy/rpython/ootypesystem/ootype.py
+++ b/pypy/rpython/ootypesystem/ootype.py
@@ -268,14 +268,13 @@
         return self._superclass._get_fields_with_default() + self._fields_with_default
 
     def _immutable_field(self, field):
-        if self._hints.get('immutable'):
-            return True
         if 'immutable_fields' in self._hints:
             try:
-                return self._hints['immutable_fields'].fields[field]
+                s = self._hints['immutable_fields'].fields[field]
+                return s or True
             except KeyError:
                 pass
-        return False
+        return self._hints.get('immutable', False)
 
 
 class SpecializableType(OOType):

diff --git a/pypy/rpython/test/test_rclass.py b/pypy/rpython/test/test_rclass.py
--- a/pypy/rpython/test/test_rclass.py
+++ b/pypy/rpython/test/test_rclass.py
@@ -5,8 +5,6 @@
 from pypy.rpython.ootypesystem import ootype
 from pypy.rlib.rarithmetic import intmask, r_longlong
 from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin, OORtypeMixin
-from pypy.rpython.rclass import IR_IMMUTABLE, IR_ARRAY_IMMUTABLE
-from pypy.rpython.rclass import IR_QUASI_IMMUTABLE
 from pypy.objspace.flow.model import summary
 
 class EmptyBase(object):
@@ -748,10 +746,8 @@
         t, typer, graph = self.gengraph(f, [])
         A_TYPE = deref(graph.getreturnvar().concretetype)
         accessor = A_TYPE._hints["immutable_fields"]
-        assert accessor.fields == {"inst_x": IR_IMMUTABLE,
-                                   "inst_y": IR_ARRAY_IMMUTABLE} or \
-               accessor.fields == {"ox": IR_IMMUTABLE,
-                                   "oy": IR_ARRAY_IMMUTABLE} # for ootype
+        assert accessor.fields == {"inst_x" : "", "inst_y" : "[*]"} or \
+               accessor.fields == {"ox" : "", "oy" : "[*]"} # for ootype
 
     def test_immutable_fields_subclass_1(self):
         from pypy.jit.metainterp.typesystem import deref
@@ -769,8 +765,8 @@
         t, typer, graph = self.gengraph(f, [])
         B_TYPE = deref(graph.getreturnvar().concretetype)
         accessor = B_TYPE._hints["immutable_fields"]
-        assert accessor.fields == {"inst_x": IR_IMMUTABLE} or \
-               accessor.fields == {"ox": IR_IMMUTABLE} # for ootype
+        assert accessor.fields == {"inst_x" : ""} or \
+               accessor.fields == {"ox" : ""} # for ootype
 
     def test_immutable_fields_subclass_2(self):
         from pypy.jit.metainterp.typesystem import deref
@@ -789,10 +785,8 @@
         t, typer, graph = self.gengraph(f, [])
         B_TYPE = deref(graph.getreturnvar().concretetype)
         accessor = B_TYPE._hints["immutable_fields"]
-        assert accessor.fields == {"inst_x": IR_IMMUTABLE,
-                                   "inst_y": IR_IMMUTABLE} or \
-               accessor.fields == {"ox": IR_IMMUTABLE,
-                                   "oy": IR_IMMUTABLE} # for ootype
+        assert accessor.fields == {"inst_x" : "", "inst_y" : ""} or \
+               accessor.fields == {"ox" : "", "oy" : ""} # for ootype
 
     def test_immutable_fields_only_in_subclass(self):
         from pypy.jit.metainterp.typesystem import deref
@@ -810,8 +804,8 @@
         t, typer, graph = self.gengraph(f, [])
         B_TYPE = deref(graph.getreturnvar().concretetype)
         accessor = B_TYPE._hints["immutable_fields"]
-        assert accessor.fields == {"inst_y": IR_IMMUTABLE} or \
-               accessor.fields == {"oy": IR_IMMUTABLE} # for ootype
+        assert accessor.fields == {"inst_y" : ""} or \
+               accessor.fields == {"oy" : ""} # for ootype
 
     def test_immutable_forbidden_inheritance_1(self):
         from pypy.rpython.rclass import ImmutableConflictError
@@ -855,8 +849,8 @@
         except AttributeError:
             A_TYPE = B_TYPE._superclass  # for ootype
         accessor = A_TYPE._hints["immutable_fields"]
-        assert accessor.fields == {"inst_v": IR_IMMUTABLE} or \
-               accessor.fields == {"ov": IR_IMMUTABLE} # for ootype
+        assert accessor.fields == {"inst_v" : ""} or \
+               accessor.fields == {"ov" : ""} # for ootype
 
     def test_immutable_subclass_1(self):
         from pypy.rpython.rclass import ImmutableConflictError
@@ -901,37 +895,6 @@
         B_TYPE = deref(graph.getreturnvar().concretetype)
         assert B_TYPE._hints["immutable"]
 
-    def test_quasi_immutable(self):
-        from pypy.jit.metainterp.typesystem import deref
-        class A(object):
-            _immutable_fields_ = ['x', 'y', 'a?', 'b?']
-        class B(A):
-            pass
-        def f():
-            a = A()
-            a.x = 42
-            a.a = 142
-            b = B()
-            b.x = 43
-            b.y = 41
-            b.a = 44
-            b.b = 45
-            return B()
-        t, typer, graph = self.gengraph(f, [])
-        B_TYPE = deref(graph.getreturnvar().concretetype)
-        accessor = B_TYPE._hints["immutable_fields"]
-        assert accessor.fields == {"inst_y": IR_IMMUTABLE,
-                                   "inst_b": IR_QUASI_IMMUTABLE} or \
-               accessor.fields == {"ox": IR_IMMUTABLE,
-                                   "oy": IR_IMMUTABLE,
-                                   "oa": IR_QUASI_IMMUTABLE,
-                                   "ob": IR_QUASI_IMMUTABLE} # for ootype
-        found = []
-        for op in graph.startblock.operations:
-            if op.opname == 'jit_force_quasi_immutable':
-                found.append(op.args[1].value)
-        assert found == ['mutate_a', 'mutate_a', 'mutate_b']
-
 
 class TestLLtype(BaseTestRclass, LLRtypeMixin):
 

diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -48,12 +48,11 @@
 
 
 class GuardToken(object):
-    def __init__(self, faildescr, failargs, fail_locs, exc, has_jump):
+    def __init__(self, faildescr, failargs, fail_locs, exc):
         self.faildescr = faildescr
         self.failargs = failargs
         self.fail_locs = fail_locs
         self.exc = exc
-        self.has_jump = has_jump
 
 DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', ('i', lltype.Signed))
 
@@ -134,7 +133,6 @@
     def setup(self, looptoken):
         assert self.memcpy_addr != 0, "setup_once() not called?"
         self.current_clt = looptoken.compiled_loop_token
-        self.invalidate_positions = []
         self.pending_guard_tokens = []
         self.mc = codebuf.MachineCodeBlockWrapper()
         if self.datablockwrapper is None:
@@ -143,7 +141,6 @@
                                                             allblocks)
 
     def teardown(self):
-        self.invalidate_positions = None
         self.pending_guard_tokens = None
         self.mc = None
         self.looppos = -1
@@ -438,24 +435,15 @@
         # tok.faildescr._x86_adr_jump_offset to contain the raw address of
         # the 4-byte target field in the JMP/Jcond instruction, and patch
         # the field in question to point (initially) to the recovery stub
-        inv_counter = 0
-        clt = self.current_clt
         for tok in self.pending_guard_tokens:
             addr = rawstart + tok.pos_jump_offset
             tok.faildescr._x86_adr_jump_offset = addr
             relative_target = tok.pos_recovery_stub - (tok.pos_jump_offset + 4)
             assert rx86.fits_in_32bits(relative_target)
             #
-            if tok.has_jump:
-                mc = codebuf.MachineCodeBlockWrapper()
-                mc.writeimm32(relative_target)
-                mc.copy_to_raw_memory(addr)
-            else:
-                # guard not invalidate, patch where it jumps
-                pos, _ = self.invalidate_positions[inv_counter]
-                clt.invalidate_positions.append((pos + rawstart,
-                                                 relative_target))
-                inv_counter += 1
+            mc = codebuf.MachineCodeBlockWrapper()
+            mc.writeimm32(relative_target)
+            mc.copy_to_raw_memory(addr)
 
     def get_asmmemmgr_blocks(self, looptoken):
         clt = looptoken.compiled_loop_token
@@ -1459,13 +1447,6 @@
         self.mc.CMP(heap(self.cpu.pos_exception()), imm0)
         self.implement_guard(guard_token, 'NZ')
 
-    def genop_guard_guard_not_invalidated(self, ign_1, guard_op, guard_token,
-                                     locs, ign_2):
-        pos = self.mc.get_relative_pos() + 1 # after potential jmp
-        guard_token.pos_jump_offset = pos
-        self.invalidate_positions.append((pos, 0))
-        self.pending_guard_tokens.append(guard_token)
-
     def genop_guard_guard_exception(self, ign_1, guard_op, guard_token,
                                     locs, resloc):
         loc = locs[0]
@@ -1564,8 +1545,7 @@
         exc = (guard_opnum == rop.GUARD_EXCEPTION or
                guard_opnum == rop.GUARD_NO_EXCEPTION or
                guard_opnum == rop.GUARD_NOT_FORCED)
-        return GuardToken(faildescr, failargs, fail_locs, exc, has_jump=
-                          guard_opnum != rop.GUARD_NOT_INVALIDATED)
+        return GuardToken(faildescr, failargs, fail_locs, exc)
 
     def generate_quick_failure(self, guardtok):
         """Generate the initial code for handling a failure.  We try to


More information about the Pypy-commit mailing list