[pypy-commit] pypy stmgc-c7: make stm_hint_commit_soon visible to the JIT in order to not remove transaction
Raemi
noreply at buildbot.pypy.org
Mon May 12 09:18:23 CEST 2014
Author: Remi Meier <remi.meier at 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)
- at 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
+
# ____________________________________________________________
More information about the pypy-commit
mailing list