Author: Armin Rigo <ar...@tunes.org>
Branch: stmgc-c7-rewindjmp
Changeset: r72846:02f43fae7c8c
Date: 2014-08-17 18:17 +0200
http://bitbucket.org/pypy/pypy/changeset/02f43fae7c8c/

Log:    In-progress: kill stuff from the JIT

diff --git a/pypy/module/pypyjit/interp_jit.py 
b/pypy/module/pypyjit/interp_jit.py
--- a/pypy/module/pypyjit/interp_jit.py
+++ b/pypy/module/pypyjit/interp_jit.py
@@ -56,9 +56,6 @@
             pypyjitdriver.jit_merge_point(ec=ec,
                 frame=self, next_instr=next_instr, pycode=pycode,
                 is_being_profiled=self.is_being_profiled)
-            if self.space.threadlocals.threads_running: # quasi-immutable field
-                if rstm.jit_stm_should_break_transaction(False):
-                    rstm.jit_stm_transaction_break_point()
 
             co_code = pycode.co_code
             self.valuestackdepth = hint(self.valuestackdepth, promote=True)
@@ -89,8 +86,7 @@
             ec.bytecode_trace(self, decr_by)
             jumpto = r_uint(self.last_instr)
             if self.space.threadlocals.threads_running: # quasi-immutable field
-                if rstm.jit_stm_should_break_transaction(True):
-                    rstm.jit_stm_transaction_break_point()
+                rstm.possible_transaction_break()
         #
         pypyjitdriver.can_enter_jit(frame=self, ec=ec, next_instr=jumpto,
                                     pycode=self.getcode(),
diff --git a/rpython/jit/codewriter/jtransform.py 
b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -1418,20 +1418,9 @@
                                           [v], None))
         return ops
 
-    def rewrite_op_jit_stm_should_break_transaction(self, op):
-        assert isinstance(op.args[0], Constant)
-        
-        arg = int(op.args[0].value)
-        c_arg = Constant(arg, lltype.Signed)
+    def rewrite_op_stm_rewind_jmp_frame(self, op):
+        return []
 
-        return [SpaceOperation('stm_should_break_transaction',
-                               [c_arg], op.result),
-                SpaceOperation('-live-', [], None),]
-
-    def rewrite_op_jit_stm_transaction_break_point(self, op):
-        return [SpaceOperation('stm_transaction_break', [], op.result),
-                SpaceOperation('-live-', [], None),]
-    
     def rewrite_op_jit_marker(self, op):
         key = op.args[0].value
         jitdriver = op.args[1].value
diff --git a/rpython/jit/codewriter/test/test_jtransform.py 
b/rpython/jit/codewriter/test/test_jtransform.py
--- a/rpython/jit/codewriter/test/test_jtransform.py
+++ b/rpython/jit/codewriter/test/test_jtransform.py
@@ -929,15 +929,18 @@
     assert block.operations[1].result is None
     assert block.exits[0].args == [v1]
 
-def test_jit_stm_transaction_break_point():
-    py.test.skip("XXX?")
-    op = SpaceOperation('jit_stm_transaction_break_point',
-                        [Constant(1, lltype.Signed)], lltype.Void)
+def test_stm_should_break_transaction():
+    op = SpaceOperation('stm_should_break_transaction', [], lltype.Bool)
     tr = Transformer()
     op2 = tr.rewrite_operation(op)
-    assert op2.opname == 'stm_transaction_break'
-    assert op2.args[0].value == 1
-    
+    assert op2.opname == 'stm_should_break_transaction'
+
+def test_stm_rewind_jmp_frame():
+    op = SpaceOperation('stm_rewind_jmp_frame', [], lltype.Void)
+    tr = Transformer()
+    op2 = tr.rewrite_operation(op)
+    assert op2 == []
+
 def test_jit_merge_point_1():
     class FakeJitDriverSD:
         index = 42
diff --git a/rpython/jit/metainterp/blackhole.py 
b/rpython/jit/metainterp/blackhole.py
--- a/rpython/jit/metainterp/blackhole.py
+++ b/rpython/jit/metainterp/blackhole.py
@@ -908,18 +908,15 @@
         return False
 
 
-    @arguments("i", returns="i")
-    def bhimpl_stm_should_break_transaction(if_there_is_no_other):
-        return False
-
-
-    @arguments()
-    def bhimpl_stm_transaction_break():
-        pass
+    @arguments(returns="i")
+    def bhimpl_stm_should_break_transaction():
+        from rpython.rlib import rstm
+        return rstm.should_break_transaction()
 
     @arguments()
     def bhimpl_stm_hint_commit_soon():
-        pass
+        from rpython.rlib import rstm
+        rstm.hint_commit_soon()
 
 
     # ----------
diff --git a/rpython/jit/metainterp/heapcache.py 
b/rpython/jit/metainterp/heapcache.py
--- a/rpython/jit/metainterp/heapcache.py
+++ b/rpython/jit/metainterp/heapcache.py
@@ -51,13 +51,6 @@
         self.input_indirections = {}
         self.output_indirections = {}
 
-
-        # to do some of the work of optimizeopt/stm.py, we have a similar
-        # logic here:
-        self.stm_break_wanted = True
-
-
-
     def _input_indirection(self, box):
         return self.input_indirections.get(box, box)
 
@@ -137,11 +130,8 @@
             opnum == rop.SETFIELD_RAW or
             opnum == rop.SETARRAYITEM_RAW or
             opnum == rop.SETINTERIORFIELD_RAW or
-            opnum == rop.RAW_STORE):
-            return
-        if opnum in (rop.GUARD_NOT_FORCED, rop.GUARD_NOT_FORCED_2,
-                     rop.STM_HINT_COMMIT_SOON):
-            self.stm_break_wanted = True
+            opnum == rop.RAW_STORE or
+            opnum == rop.STM_HINT_COMMIT_SOON):
             return
         if (rop._OVF_FIRST <= opnum <= rop._OVF_LAST or
             rop._NOSIDEEFFECT_FIRST <= opnum <= rop._NOSIDEEFFECT_LAST or
@@ -207,7 +197,6 @@
                                     del cache[frombox]
                     return
             else:
-                self.stm_break_wanted = True
                 # Only invalidate things that are either escaped or arguments
                 for descr, boxes in self.heap_cache.iteritems():
                     for box in boxes.keys():
@@ -226,8 +215,6 @@
         # above, but hit an assertion in "pypy test_multiprocessing.py".
         self.reset(reset_virtuals=False, trace_branch=False)
 
-        self.stm_break_wanted = True
-
     def is_class_known(self, box):
         return box in self.known_class_boxes
 
@@ -338,6 +325,3 @@
     def replace_box(self, oldbox, newbox):
         self.input_indirections[self._output_indirection(newbox)] = 
self._input_indirection(oldbox)
         self.output_indirections[self._input_indirection(oldbox)] = 
self._output_indirection(newbox)
-
-    def stm_break_done(self):
-        self.stm_break_wanted = False
diff --git a/rpython/jit/metainterp/history.py 
b/rpython/jit/metainterp/history.py
--- a/rpython/jit/metainterp/history.py
+++ b/rpython/jit/metainterp/history.py
@@ -627,7 +627,6 @@
     operations = None
     call_pure_results = None
     stm_info = None
-    is_really_loop = False
     logops = None
     quasi_immutable_deps = None
 
diff --git a/rpython/jit/metainterp/optimizeopt/__init__.py 
b/rpython/jit/metainterp/optimizeopt/__init__.py
--- a/rpython/jit/metainterp/optimizeopt/__init__.py
+++ b/rpython/jit/metainterp/optimizeopt/__init__.py
@@ -8,7 +8,6 @@
 from rpython.jit.metainterp.optimizeopt.simplify import OptSimplify
 from rpython.jit.metainterp.optimizeopt.pure import OptPure
 from rpython.jit.metainterp.optimizeopt.earlyforce import OptEarlyForce
-from rpython.jit.metainterp.optimizeopt.stm import OptSTM
 from rpython.rlib.jit import PARAMETERS, ENABLE_ALL_OPTS
 from rpython.rlib.unroll import unrolling_iterable
 from rpython.rlib.debug import debug_start, debug_stop, debug_print
@@ -35,9 +34,6 @@
 def build_opt_chain(metainterp_sd, enable_opts):
     optimizations = []
     unroll = 'unroll' in enable_opts    # 'enable_opts' is normally a dict
-    if metainterp_sd.config.translation.stm:
-        optimizations.append(OptSTM())
-        
     for name, opt in unroll_all_opts:
         if name in enable_opts:
             if opt is not None:
diff --git a/rpython/jit/metainterp/optimizeopt/heap.py 
b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -275,14 +275,12 @@
             opnum == rop.COPYSTRCONTENT or       # no effect on GC struct/array
             opnum == rop.COPYUNICODECONTENT):    # no effect on GC struct/array
             return
-        if (opnum == rop.STM_TRANSACTION_BREAK or
-            opnum == rop.CALL_ASSEMBLER):
-            self._seen_guard_not_invalidated = False
         if (opnum == rop.CALL or
             opnum == rop.CALL_PURE or
             opnum == rop.COND_CALL or
             opnum == rop.CALL_MAY_FORCE or
-            opnum == rop.CALL_RELEASE_GIL):
+            opnum == rop.CALL_RELEASE_GIL or
+            opnum == rop.CALL_ASSEMBLER):
             if opnum == rop.CALL_ASSEMBLER:
                 self._seen_guard_not_invalidated = False
             else:
diff --git a/rpython/jit/metainterp/optimizeopt/stm.py 
b/rpython/jit/metainterp/optimizeopt/stm.py
deleted file mode 100644
--- a/rpython/jit/metainterp/optimizeopt/stm.py
+++ /dev/null
@@ -1,94 +0,0 @@
-from rpython.jit.metainterp.optimizeopt.optimizer import (Optimization, )
-from rpython.jit.metainterp.optimizeopt.util import make_dispatcher_method
-from rpython.jit.codewriter.effectinfo import EffectInfo
-from rpython.jit.metainterp.resoperation import rop, ResOperation
-
-class OptSTM(Optimization):
-    """
-    This step removes a lot of uncecessary transaction_breaks (TBs)
-    emitted by pyjitpl from traces. We only want to keep these
-    unconditional TBs after external calls (identified by GUARD_NOT_FORCED)
-    because they are likely to return as inevitable transactions which
-    we want to break ASAP.
-    Guarded TBs are left in place, as they represent app-level loops
-    and are likely points to break between atomic transactions.
-
-    The cached_ops is here to remove the virtualizable-forcing added
-    by pyjitpl before unconditional TBs. See tests.
-    """
-    def __init__(self):
-        self.remove_next_gnf = False # guard_not_forced
-        self.keep_but_ignore_gnf = False
-        self.cached_ops = []
-
-    def propagate_forward(self, op):
-        dispatch_opt(self, op)
-
-    def flush_cached(self):
-        while self.cached_ops:
-            self.emit_operation(self.cached_ops.pop(0))
-
-    def flush(self):
-        # just in case. it shouldn't be necessary
-        self.flush_cached()
-
-    def default_emit(self, op):
-        self.flush_cached()
-        self.emit_operation(op)
-
-    def _break_wanted(self):
-        is_loop = self.optimizer.loop.is_really_loop
-        return self.optimizer.stm_info.get('break_wanted', is_loop)
-
-    def _set_break_wanted(self, val):
-        self.optimizer.stm_info['break_wanted'] = val
-
-    def optimize_FORCE_TOKEN(self, op):
-        # if we have cached stuff, flush it. Not our case
-        self.flush_cached()
-        self.cached_ops.append(op)
-
-    def optimize_SETFIELD_GC(self, op):
-        if not self.cached_ops:
-            # setfield not for force_token
-            self.emit_operation(op)
-        else:
-            assert len(self.cached_ops) == 1
-            assert self.cached_ops[0].getopnum() == rop.FORCE_TOKEN
-            self.cached_ops.append(op)
-
-    def optimize_STM_SHOULD_BREAK_TRANSACTION(self, op):
-        self.flush_cached()
-        self._set_break_wanted(False)
-        self.emit_operation(op)
-
-    def optimize_STM_TRANSACTION_BREAK(self, op):
-        assert not self.remove_next_gnf
-        really_wanted = op.getarg(0).getint()
-        if really_wanted or self._break_wanted():
-            self.flush_cached()
-            self._set_break_wanted(False)
-            self.emit_operation(op)
-            self.keep_but_ignore_gnf = True
-        else:
-            self.cached_ops = []
-            self.remove_next_gnf = True
-
-    def optimize_GUARD_NOT_FORCED(self, op):
-        self.flush_cached()
-        if self.remove_next_gnf:
-            self.remove_next_gnf = False
-        else:
-            if not self.keep_but_ignore_gnf:
-                self._set_break_wanted(True)
-            self.keep_but_ignore_gnf = False
-            self.emit_operation(op)
-
-    def optimize_STM_HINT_COMMIT_SOON(self, op):
-        self.flush_cached()
-        self._set_break_wanted(True)
-        self.emit_operation(op)
-
-
-dispatch_opt = make_dispatcher_method(OptSTM, 'optimize_',
-                                      default=OptSTM.default_emit)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_stm.py 
b/rpython/jit/metainterp/optimizeopt/test/test_stm.py
deleted file mode 100644
--- a/rpython/jit/metainterp/optimizeopt/test/test_stm.py
+++ /dev/null
@@ -1,331 +0,0 @@
-from rpython.jit.metainterp.optimizeopt.test.test_optimizeopt import (
-    BaseTestWithUnroll,)
-from rpython.jit.metainterp.optimizeopt.test.test_util import LLtypeMixin
-from rpython.jit.codewriter.effectinfo import EffectInfo
-from rpython.rtyper.lltypesystem import lltype, rclass, rffi, llmemory
-
-
-class TestSTM(BaseTestWithUnroll, LLtypeMixin):
-    stm = True
-
-    namespace = LLtypeMixin.namespace.copy()
-    namespace.update(locals())
-
-
-    def test_unrolled_loop(self):
-        ops = """
-        []
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-        jump()
-        """
-        self.optimize_loop(ops, ops, expected_preamble=ops)
-
-    def test_really_wanted_tb(self):
-        ops = """
-        []
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        stm_transaction_break(1)
-        guard_not_forced() []
-
-        jump()
-        """
-        preamble = """
-        []
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        stm_transaction_break(1)
-        guard_not_forced() []
-
-        jump()
-        """
-        expected = """
-        []
-        stm_transaction_break(1)
-        guard_not_forced() []
-
-        jump()
-        """
-        self.optimize_loop(ops, expected, expected_preamble=preamble)
-
-
-    def test_unrolled_loop2(self):
-        ops = """
-        []
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-
-        jump()
-        """
-        preamble = """
-        []
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-
-        jump()
-        """
-        expected = """
-        []
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-        jump()
-        """
-        self.optimize_loop(ops, expected, expected_preamble=preamble)
-
-    def test_not_disable_opt(self):
-        ops = """
-        [p1]
-        i1 = getfield_gc(p1, descr=adescr)
-
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-        jump(p1)
-        """
-        preamble = """
-        [p1]
-        i1 = getfield_gc(p1, descr=adescr)
-
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-        jump(p1)
-        """
-        expected = """
-        [p1]
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-
-        jump(p1)
-        """
-        self.optimize_loop(ops, expected, expected_preamble=preamble)
-
-    def test_dont_remove_first_tb(self):
-        ops = """
-        []
-        stm_transaction_break(0)
-        guard_not_forced() []
-        stm_transaction_break(0)
-        guard_not_forced() []
-        stm_transaction_break(0)
-        guard_not_forced() []
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-        jump()
-        """
-        preamble = """
-        []
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-        jump()
-        """
-        expected = """
-        []
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-        jump()
-        """
-        self.optimize_loop(ops, expected, expected_preamble=preamble)
-
-    def test_add_tb_after_guard_not_forced(self):
-        ops = """
-        []
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        escape() # e.g. like a call_release_gil
-        guard_not_forced() []
-
-        stm_transaction_break(0)
-        guard_not_forced() []
-        stm_transaction_break(0)
-        guard_not_forced() []
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-        jump()
-        """
-        preamble = """
-        []
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        escape()
-        guard_not_forced() []
-
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-        jump()
-        """
-        expected = """
-        []
-        escape()
-        guard_not_forced() []
-
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-        jump()
-        """
-        self.optimize_loop(ops, expected, expected_preamble=preamble)
-
-    def test_remove_force_token(self):
-        ops = """
-        [p0]
-        p1 = force_token()
-        setfield_gc(p0, p1, descr=adescr)
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        p2 = force_token()
-        setfield_gc(p0, p2, descr=adescr)
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        p3 = force_token()
-        setfield_gc(p0, p3, descr=adescr)
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        escape()
-
-        p4 = force_token()
-        setfield_gc(p0, p4, descr=adescr)
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        p6 = force_token() # not removed!
-
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-        jump(p0)
-        """
-        preamble = """
-        [p0]
-        p1 = force_token()
-        setfield_gc(p0, p1, descr=adescr)
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        escape()
-
-        p6 = force_token() # not removed!
-
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-        jump(p0)
-        """
-        expected = """
-        [p0]
-        escape()
-
-        p6 = force_token() # not removed!
-
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-        jump(p0)
-        """
-        self.optimize_loop(ops, expected, expected_preamble=preamble)
-
-    def test_not_remove_setfield(self):
-        ops = """
-        [p0, p1]
-        setfield_gc(p0, p1, descr=adescr)
-        stm_transaction_break(0)
-
-        p2 = force_token()
-        p3 = force_token()
-        jump(p0, p1)
-        """
-        preamble = """
-        [p0, p1]
-        setfield_gc(p0, p1, descr=adescr)
-        stm_transaction_break(0)
-
-        p2 = force_token()
-        p3 = force_token()
-        jump(p0, p1)
-        """
-        expected = """
-        [p0, p1]
-        p2 = force_token()
-        p3 = force_token()
-
-        setfield_gc(p0, p1, descr=adescr) # moved here by other stuff...
-        jump(p0, p1)
-        """
-        self.optimize_loop(ops, expected, expected_preamble=preamble)
-
-    def test_stm_location_1(self):
-        # This tests setfield_gc on a non-virtual.  On a virtual, it doesn't
-        # really matter, because STM conflicts are impossible anyway
-        ops = """
-        [i1, p1]
-        setfield_gc(p1, i1, descr=adescr) {81}
-        call(i1, descr=nonwritedescr) {90}
-        jump(i1, p1)
-        """
-        expected = """
-        [i1, p1]
-        call(i1, descr=nonwritedescr) {90}
-        setfield_gc(p1, i1, descr=adescr) {81}
-        jump(i1, p1)
-        """
-        self.optimize_loop(ops, expected)
-
-    def test_add_tb_after_commit_soon(self):
-        ops = """
-        []
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        stm_hint_commit_soon()
-
-        stm_transaction_break(0)
-        guard_not_forced() []
-        stm_transaction_break(0)
-        guard_not_forced() []
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-        jump()
-        """
-        preamble = """
-        []
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        stm_hint_commit_soon()
-
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-        jump()
-        """
-        expected = """
-        []
-        stm_hint_commit_soon()
-
-        stm_transaction_break(0)
-        guard_not_forced() []
-
-        i0 = stm_should_break_transaction()
-        guard_false(i0) []
-        jump()
-        """
-        self.optimize_loop(ops, expected, expected_preamble=preamble)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_util.py 
b/rpython/jit/metainterp/optimizeopt/test/test_util.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_util.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_util.py
@@ -1,6 +1,6 @@
 import py, random
 
-from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rstr, rffi
+from rpython.rtyper.lltypesystem import lltype, llmemory, rclass, rffi
 from rpython.rtyper.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
 from rpython.rtyper.rclass import FieldListAccessor, IR_QUASIIMMUTABLE
 
@@ -331,7 +331,7 @@
     def get_name_from_address(self, addr):
         # hack
         try:
-            return "".join(addr.ptr.name)[:-1] # remove \x00
+            return "".join(addr.ptr.name.chars)
         except AttributeError:
             return ""
 
diff --git a/rpython/jit/metainterp/optimizeopt/unroll.py 
b/rpython/jit/metainterp/optimizeopt/unroll.py
--- a/rpython/jit/metainterp/optimizeopt/unroll.py
+++ b/rpython/jit/metainterp/optimizeopt/unroll.py
@@ -75,7 +75,6 @@
 
         start_label = loop.operations[0]
         if start_label.getopnum() == rop.LABEL:
-            loop.is_really_loop = True
             loop.operations = loop.operations[1:]
             # We need to emit the label op before import_state() as emitting it
             # will clear heap caches
diff --git a/rpython/jit/metainterp/pyjitpl.py 
b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -186,52 +186,16 @@
             raise AssertionError("bad result box type")
 
     # ------------------------------
-    def _record_stm_transaction_break(self, really_wanted):
-        # records an unconditional stm_transaction_break
-        mi = self.metainterp
-        mi.vable_and_vrefs_before_residual_call()
-        mi._record_helper_nonpure_varargs(
-            rop.STM_TRANSACTION_BREAK, None, None,
-            [history.ConstInt(really_wanted)])
-        mi.vrefs_after_residual_call()
-        mi.vable_after_residual_call()
-        #
-        if not really_wanted:
-            # we're about the return ConstInt(0), which will go into the
-            # jitcode's %iN variable.  But it will be captured by the
-            # GUARD_NOT_FORCED's resume data too.  It is essential that we
-            # don't capture the old, stale value!  Also, store ConstInt(1)
-            # to make sure that upon resuming we'll see a result of 1 (XXX
-            # unsure if it's needed, but it shouldn't hurt).
-            self.make_result_of_lastop(ConstInt(1))
-        #
-        mi.generate_guard(rop.GUARD_NOT_FORCED, None)
-        self.metainterp.heapcache.stm_break_done()
-
-
-    @arguments("int")
-    def opimpl_stm_should_break_transaction(self, if_there_is_no_other):
-        val = bool(if_there_is_no_other)
-        mi = self.metainterp
-        if val:
-            # app-level loop: only one of these per loop is really needed
-            resbox = history.BoxInt(0)
-            mi.history.record(rop.STM_SHOULD_BREAK_TRANSACTION, [], resbox)
-            self.metainterp.heapcache.stm_break_done()
-            return resbox
-        else:
-            # between byte-code instructions: only keep if it is
-            # likely that we are inevitable here
-            if self.metainterp.heapcache.stm_break_wanted:
-                self._record_stm_transaction_break(False)
-            return ConstInt(0)
 
     @arguments()
-    def opimpl_stm_transaction_break(self):
-        # always wanted: inserted after we compile a bridge because there
-        # were just too many breaks and we failed the should_break&guard
-        # because of that
-        self._record_stm_transaction_break(True)
+    def opimpl_stm_should_break_transaction(self):
+        # XXX make it return BoxInt(1) instead of BoxInt(0) if there
+        # is an inevitable transaction, because it's likely that there
+        # will always be an inevitable transaction here
+        resbox = history.BoxInt(0)
+        mi = self.metainterp
+        mi.history.record(rop.STM_SHOULD_BREAK_TRANSACTION, [], resbox)
+        return resbox
 
     @arguments()
     def opimpl_stm_hint_commit_soon(self):
@@ -1855,8 +1819,6 @@
         if opnum == rop.GUARD_NOT_FORCED or opnum == rop.GUARD_NOT_FORCED_2:
             resumedescr = compile.ResumeGuardForcedDescr(self.staticdata,
                                                          self.jitdriver_sd)
-            # for detecting stm breaks that are needed
-            self.heapcache.invalidate_caches(opnum, resumedescr, moreargs)
         elif opnum == rop.GUARD_NOT_INVALIDATED:
             resumedescr = compile.ResumeGuardNotInvalidated()
         elif opnum == rop.GUARD_FUTURE_CONDITION:
diff --git a/rpython/jit/metainterp/resoperation.py 
b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -521,7 +521,6 @@
     'QUASIIMMUT_FIELD/1d',    # [objptr], descr=SlowMutateDescr
     'RECORD_KNOWN_CLASS/2',   # [objptr, clsptr]
     'KEEPALIVE/1',
-    'STM_TRANSACTION_BREAK/1',
     'STM_READ/1',
 
     '_CANRAISE_FIRST', # ----- start of can_raise operations -----
diff --git a/rpython/jit/metainterp/test/test_stm.py 
b/rpython/jit/metainterp/test/test_stm.py
--- a/rpython/jit/metainterp/test/test_stm.py
+++ b/rpython/jit/metainterp/test/test_stm.py
@@ -11,63 +11,10 @@
 class STMTests:
     def test_simple(self):
         def g():
-            return rstm.jit_stm_should_break_transaction(False)
+            return rstm.should_break_transaction()
         res = self.interp_operations(g, [], translationoptions={"stm":True})
         assert res == False
-        self.check_operations_history(stm_transaction_break=1,
-                                      stm_should_break_transaction=0)
-
-    def test_not_removed(self):
-        import time
-        def g():
-            time.sleep(0)
-            return rstm.jit_stm_should_break_transaction(False)
-        res = self.interp_operations(g, [], translationoptions={"stm":True})
-        assert res == False
-        self.check_operations_history(stm_transaction_break=1,
-                                      call_may_force=1,
-                                      stm_should_break_transaction=0)
-
-    def test_not_removed2(self):
-        def g():
-            return rstm.jit_stm_should_break_transaction(True)
-        res = self.interp_operations(g, [], translationoptions={"stm":True})
-        assert res == False
-        self.check_operations_history(stm_transaction_break=0,
-                                      stm_should_break_transaction=1)
-
-    def test_transaction_break(self):
-        def g():
-            rstm.jit_stm_transaction_break_point()
-            return 42
-        self.interp_operations(g, [], translationoptions={"stm":True})
-        self.check_operations_history({'stm_transaction_break':1,
-                                       'guard_not_forced':1})
-
-    def test_heapcache(self):
-        import time
-        def g():
-            rstm.jit_stm_should_break_transaction(True) # keep (start of loop)
-            rstm.jit_stm_should_break_transaction(False)
-            time.sleep(0)
-            rstm.jit_stm_should_break_transaction(False) # keep (after 
guard_not_forced)
-            rstm.jit_stm_should_break_transaction(False)
-            rstm.jit_stm_should_break_transaction(True) # keep (True)
-            rstm.jit_stm_should_break_transaction(True) # keep (True)
-            rstm.jit_stm_should_break_transaction(False)
-            rstm.hint_commit_soon()
-            rstm.jit_stm_should_break_transaction(False) # keep
-            rstm.jit_stm_should_break_transaction(False)
-            return 42
-        res = self.interp_operations(g, [], translationoptions={"stm":True})
-        assert res == 42
-        self.check_operations_history({
-            'stm_transaction_break':2,
-            'stm_hint_commit_soon':1,
-            'stm_should_break_transaction':3,
-            'guard_not_forced':3,
-            'guard_no_exception':1,
-            'call_may_force':1})
+        self.check_operations_history(stm_should_break_transaction=1)
 
     def test_debug_merge_points(self):
         myjitdriver = JitDriver(greens = ['a'], reds = ['x', 'res'])
diff --git a/rpython/rlib/jit.py b/rpython/rlib/jit.py
--- a/rpython/rlib/jit.py
+++ b/rpython/rlib/jit.py
@@ -483,12 +483,14 @@
     name = 'jitdriver'
     inline_jit_merge_point = False
     _store_last_enter_jit = None
+    stm_report_location = None
 
     def __init__(self, greens=None, reds=None, virtualizables=None,
                  get_jitcell_at=None, set_jitcell_at=None,
                  get_printable_location=None, confirm_enter_jit=None,
                  can_never_inline=None, should_unroll_one_iteration=None,
-                 name='jitdriver', check_untranslated=True):
+                 name='jitdriver', check_untranslated=True,
+                 stm_report_location=None):
         if greens is not None:
             self.greens = greens
         self.name = name
@@ -524,6 +526,8 @@
         self.can_never_inline = can_never_inline
         self.should_unroll_one_iteration = should_unroll_one_iteration
         self.check_untranslated = check_untranslated
+        if stm_report_location is not None:
+            self.stm_report_location = stm_report_location
 
     def _freeze_(self):
         return True
diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py
--- a/rpython/rlib/rstm.py
+++ b/rpython/rlib/rstm.py
@@ -46,47 +46,13 @@
     function with the interpreter's dispatch loop, this must be called
     (it turns into a marker in the caller's function).  There is one
     automatically in any jit.jit_merge_point()."""
-    # special-cased below
+    # special-cased below: the emitted operation must be placed
+    # directly in the caller's graph
 
 def possible_transaction_break():
     if stm_is_enabled():
         if llop.stm_should_break_transaction(lltype.Bool):
-            llop.stm_transaction_break(lltype.Void)
-
-# Typical usage of the following two functions:
-#
-# just after jit_merge_point:
-#         if rstm.jit_stm_should_break_transaction(False):
-#             rstm.jit_stm_transaction_break_point()
-#
-# just before can_enter_jit:
-#         if rstm.jit_stm_should_break_transaction(True):
-#             rstm.jit_stm_transaction_break_point()
-#
-# resulting JIT trace (common case):
-#      ...
-#      call_release_gil(...)
-#      stm_transaction_break(0)     # in-line, because we expect "inevitable"
-#      guard_not_forced()
-#      ...
-#      i1 = stm_should_break_transaction()
-#      guard_false(i1)              # out-of-line, because rarely needed
-#      jump()
-#
-def jit_stm_transaction_break_point():
-    # XXX REFACTOR AWAY
-    if we_are_translated():
-        llop.jit_stm_transaction_break_point(lltype.Void)
-
-@specialize.arg(0)
-def jit_stm_should_break_transaction(if_there_is_no_other):
-    # XXX REFACTOR AWAY
-    # if_there_is_no_other means that we use this point only
-    # if there is no other break point in the trace.
-    # If it is False, the point may be used if it comes right
-    # after a CALL_RELEASE_GIL
-    return llop.jit_stm_should_break_transaction(lltype.Bool,
-                                                 if_there_is_no_other)
+            break_transaction()
 
 def hint_commit_soon():
     """As the name says, just a hint. Maybe calling it
@@ -104,7 +70,6 @@
 def partial_commit_and_resume_other_threads():
     pass    # for now
 
-@dont_look_inside
 def should_break_transaction():
     return we_are_translated() and (
         llop.stm_should_break_transaction(lltype.Bool))
diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py
--- a/rpython/rtyper/llinterp.py
+++ b/rpython/rtyper/llinterp.py
@@ -943,7 +943,6 @@
     op_stm_initialize = _stm_not_implemented
     op_stm_finalize = _stm_not_implemented
     op_stm_perform_transaction = _stm_not_implemented
-    op_stm_should_break_transaction = _stm_not_implemented
     op_stm_commit_transaction = _stm_not_implemented
     op_stm_begin_inevitable_transaction = _stm_not_implemented
     op_stm_barrier = _stm_not_implemented
@@ -971,6 +970,9 @@
     op_stm_stop_all_other_threads = _stm_not_implemented
     op_stm_partial_commit_and_resume_other_threads = _stm_not_implemented
 
+    def op_stm_should_break_transaction(self):
+        return False
+
     def op_threadlocalref_set(self, key, value):
         try:
             d = self.llinterpreter.tlrefsdict
diff --git a/rpython/rtyper/lltypesystem/lloperation.py 
b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -436,7 +436,7 @@
     'stm_leave_callback_call':            LLOp(),
     'stm_transaction_break':              LLOp(canmallocgc=True),
     'stm_should_break_transaction':       LLOp(sideeffects=False),
-    'stm_rewind_jmp_frame':               LLOp(),
+    'stm_rewind_jmp_frame':               LLOp(canrun=True),
     'stm_set_transaction_length':         LLOp(),
 
     'stm_hint_commit_soon':   LLOp(canrun=True),
@@ -521,8 +521,6 @@
     'jit_assembler_call': LLOp(canrun=True,   # similar to an 'indirect_call'
                                canraise=(Exception,),
                                canmallocgc=True),
-    'jit_stm_transaction_break_point' : LLOp(canrun=True,canmallocgc=True),
-    'jit_stm_should_break_transaction' : LLOp(canrun=True),
 
     # __________ GC operations __________
 
diff --git a/rpython/rtyper/lltypesystem/opimpl.py 
b/rpython/rtyper/lltypesystem/opimpl.py
--- a/rpython/rtyper/lltypesystem/opimpl.py
+++ b/rpython/rtyper/lltypesystem/opimpl.py
@@ -715,10 +715,7 @@
 def op_jit_assembler_call(funcptr, *args):
     return funcptr(*args)
 
-def op_jit_stm_should_break_transaction(if_there_is_no_other):
-    return False
-
-def op_jit_stm_transaction_break_point():
+def op_stm_rewind_jmp_frame():
     pass
 
 def op_stm_hint_commit_soon():
diff --git a/rpython/translator/stm/breakfinder.py 
b/rpython/translator/stm/breakfinder.py
--- a/rpython/translator/stm/breakfinder.py
+++ b/rpython/translator/stm/breakfinder.py
@@ -7,7 +7,6 @@
     'stm_start_if_not_atomic',
     #'stm_partial_commit_and_resume_other_threads', # new priv_revision
     #'jit_assembler_call',
-    #'jit_stm_transaction_break_point',
     'stm_enter_callback_call',
     'stm_leave_callback_call',
     ])
diff --git a/rpython/translator/stm/inevitable.py 
b/rpython/translator/stm/inevitable.py
--- a/rpython/translator/stm/inevitable.py
+++ b/rpython/translator/stm/inevitable.py
@@ -18,8 +18,7 @@
     'gc_adr_of_root_stack_top', 'gc_add_memory_pressure',
     'weakref_create', 'weakref_deref',
     'jit_assembler_call', 'gc_writebarrier',
-    'shrink_array', 'jit_stm_transaction_break_point',
-    'jit_stm_should_break_transaction',
+    'shrink_array',
     'threadlocalref_get', 'threadlocalref_set',
     ])
 ALWAYS_ALLOW_OPERATIONS |= set(lloperation.enum_tryfold_ops())
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to