Author: Remi Meier <remi.me...@inf.ethz.ch> Branch: stmgc-c7 Changeset: r71468:a43485667edf Date: 2014-05-12 09:16 +0200 http://bitbucket.org/pypy/pypy/changeset/a43485667edf/
Log: make stm_hint_commit_soon visible to the JIT in order to not remove transaction breaks right after it diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py --- a/rpython/jit/backend/llsupport/gc.py +++ b/rpython/jit/backend/llsupport/gc.py @@ -237,7 +237,7 @@ return self.malloc_array(arraydescr.basesize, num_elem, arraydescr.itemsize, arraydescr.lendescr.offset) - + def get_malloc_slowpath_addr(self): return None @@ -257,7 +257,7 @@ class GcRootMap_shadowstack(object): is_shadow_stack = True is_stm = False - + def __init__(self, gcdescr): pass @@ -271,7 +271,7 @@ class GcRootMap_stm(object): is_shadow_stack = True is_stm = True - + def __init__(self, gcdescr): pass @@ -490,7 +490,7 @@ unicode_itemsize = self.unicode_descr.itemsize unicode_ofs_length = self.unicode_descr.lendescr.offset - + def malloc_str(length): type_id = llop.extract_ushort(llgroup.HALFWORD, str_type_id) return llop1.do_malloc_varsize_clear( @@ -499,7 +499,7 @@ str_ofs_length) self.generate_function('malloc_str', malloc_str, [lltype.Signed]) - + def malloc_unicode(length): type_id = llop.extract_ushort(llgroup.HALFWORD, unicode_type_id) return llop1.do_malloc_varsize_clear( @@ -529,6 +529,9 @@ self.generate_function('stm_try_inevitable', rstm.become_inevitable, [], RESULT=lltype.Void) + self.generate_function('stm_hint_commit_soon', + rstm.hint_commit_soon, [], + RESULT=lltype.Void) def _bh_malloc(self, sizedescr): from rpython.memory.gctypelayout import check_typeid @@ -603,7 +606,7 @@ def can_use_nursery_malloc(self, size): return size < self.max_size_of_young_obj - + def has_write_barrier_class(self): return WriteBarrierDescr @@ -612,7 +615,7 @@ def get_malloc_slowpath_array_addr(self): return self.get_malloc_fn_addr('malloc_array') - + # ____________________________________________________________ def get_ll_description(gcdescr, translator=None, rtyper=None): diff --git a/rpython/jit/backend/llsupport/stmrewrite.py b/rpython/jit/backend/llsupport/stmrewrite.py --- a/rpython/jit/backend/llsupport/stmrewrite.py +++ b/rpython/jit/backend/llsupport/stmrewrite.py @@ -31,6 +31,10 @@ self.next_op_may_be_in_new_transaction() self.newops.append(op) return + if opnum == rop.STM_HINT_COMMIT_SOON: + self._do_stm_call('stm_hint_commit_soon', [], None, + op.stm_location) + return # ---------- pure operations, guards ---------- if op.is_always_pure() or op.is_guard() or op.is_ovf(): self.newops.append(op) 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 @@ -912,7 +912,12 @@ @arguments() def bhimpl_stm_transaction_break(): pass - + + @arguments() + def bhimpl_stm_hint_commit_soon(): + pass + + # ---------- # the main hints and recursive calls 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 @@ -127,7 +127,8 @@ opnum == rop.COPYSTRCONTENT or opnum == rop.COPYUNICODECONTENT): return - if opnum in (rop.GUARD_NOT_FORCED, rop.GUARD_NOT_FORCED_2): + if opnum in (rop.GUARD_NOT_FORCED, rop.GUARD_NOT_FORCED_2, + rop.STM_HINT_COMMIT_SOON): self.stm_break_wanted = True return if (rop._OVF_FIRST <= opnum <= rop._OVF_LAST or diff --git a/rpython/jit/metainterp/optimizeopt/stm.py b/rpython/jit/metainterp/optimizeopt/stm.py --- a/rpython/jit/metainterp/optimizeopt/stm.py +++ b/rpython/jit/metainterp/optimizeopt/stm.py @@ -31,7 +31,7 @@ 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) @@ -39,7 +39,7 @@ 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 @@ -84,6 +84,11 @@ 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 --- a/rpython/jit/metainterp/optimizeopt/test/test_stm.py +++ b/rpython/jit/metainterp/optimizeopt/test/test_stm.py @@ -70,7 +70,7 @@ i0 = stm_should_break_transaction() guard_false(i0) [] - + jump() """ expected = """ @@ -93,7 +93,7 @@ preamble = """ [p1] i1 = getfield_gc(p1, descr=adescr) - + i0 = stm_should_break_transaction() guard_false(i0) [] jump(p1) @@ -102,7 +102,7 @@ [p1] i0 = stm_should_break_transaction() guard_false(i0) [] - + jump(p1) """ self.optimize_loop(ops, expected, expected_preamble=preamble) @@ -142,10 +142,10 @@ [] 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) @@ -164,7 +164,7 @@ stm_transaction_break(0) guard_not_forced() [] - + i0 = stm_should_break_transaction() guard_false(i0) [] jump() @@ -209,7 +209,7 @@ guard_not_forced() [] p6 = force_token() # not removed! - + i0 = stm_should_break_transaction() guard_false(i0) [] jump(p0) @@ -224,7 +224,7 @@ escape() p6 = force_token() # not removed! - + i0 = stm_should_break_transaction() guard_false(i0) [] jump(p0) @@ -234,7 +234,7 @@ escape() p6 = force_token() # not removed! - + i0 = stm_should_break_transaction() guard_false(i0) [] jump(p0) @@ -246,7 +246,7 @@ [p0, p1] setfield_gc(p0, p1, descr=adescr) stm_transaction_break(0) - + p2 = force_token() p3 = force_token() jump(p0, p1) @@ -264,9 +264,9 @@ [p0, p1] p2 = force_token() p3 = force_token() - + setfield_gc(p0, p1, descr=adescr) # moved here by other stuff... - jump(p0, p1) + jump(p0, p1) """ self.optimize_loop(ops, expected, expected_preamble=preamble) @@ -286,3 +286,46 @@ 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/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -224,6 +224,13 @@ # because of that self._record_stm_transaction_break(True) + @arguments() + def opimpl_stm_hint_commit_soon(self): + mi = self.metainterp + mi.history.record(rop.STM_HINT_COMMIT_SOON, [], None) + self.metainterp.heapcache.invalidate_caches(rop.STM_HINT_COMMIT_SOON, + None, []) + for _opimpl in ['int_add', 'int_sub', 'int_mul', 'int_floordiv', 'int_mod', 'int_lt', 'int_le', 'int_eq', 'int_ne', 'int_gt', 'int_ge', 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 @@ -495,6 +495,7 @@ 'VIRTUAL_REF/2', # removed before it's passed to the backend 'READ_TIMESTAMP/0', 'STM_SHOULD_BREAK_TRANSACTION/0', + 'STM_HINT_COMMIT_SOON/0', 'MARK_OPAQUE_PTR/1b', # this one has no *visible* side effect, since the virtualizable # must be forced, however we need to execute it anyway 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 @@ -55,13 +55,17 @@ 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':1, + 'stm_transaction_break':2, + 'stm_hint_commit_soon':1, 'stm_should_break_transaction':3, - 'guard_not_forced':2, + 'guard_not_forced':3, 'guard_no_exception':1, 'call_may_force':1}) diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py --- a/rpython/rlib/rstm.py +++ b/rpython/rlib/rstm.py @@ -49,7 +49,6 @@ return llop.jit_stm_should_break_transaction(lltype.Bool, if_there_is_no_other) -@dont_look_inside def hint_commit_soon(): """As the name says, just a hint. Maybe calling it several times in a row is more persuasive""" 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 @@ -438,7 +438,7 @@ 'stm_should_break_transaction': LLOp(sideeffects=False), 'stm_set_transaction_length': LLOp(), - 'stm_hint_commit_soon': LLOp(), + 'stm_hint_commit_soon': LLOp(canrun=True), 'stm_threadlocalref_get': LLOp(sideeffects=False), 'stm_threadlocalref_set': LLOp(canmallocgc=True), # may allocate new array, 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,6 +715,9 @@ def op_jit_stm_transaction_break_point(): pass +def op_stm_hint_commit_soon(): + pass + # ____________________________________________________________ _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit