[pypy-commit] pypy stmgc-c4: WIP: make stm_transaction_break a guard
Raemi
noreply at buildbot.pypy.org
Sun Jan 12 14:11:15 CET 2014
Author: Remi Meier <remi.meier at gmail.com>
Branch: stmgc-c4
Changeset: r68604:55c2df34eca5
Date: 2014-01-12 12:16 +0100
http://bitbucket.org/pypy/pypy/changeset/55c2df34eca5/
Log: WIP: make stm_transaction_break a guard
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -67,7 +67,8 @@
self=self, co_code=co_code,
next_instr=next_instr, ec=ec)
# nothing inbetween!
- rstm.jit_stm_transaction_break_point(False)
+ if rstm.jit_should_break_transaction(False):
+ rstm.jit_stm_transaction_break_point()
self = self._hints_for_stm()
next_instr = self.handle_bytecode(co_code, next_instr, ec)
except ExitFrame:
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
@@ -70,7 +70,8 @@
frame=self, next_instr=next_instr, pycode=pycode,
is_being_profiled=is_being_profiled)
# nothing inbetween!
- rstm.jit_stm_transaction_break_point(False)
+ if rstm.jit_should_break_transaction(False):
+ rstm.jit_stm_transaction_break_point()
co_code = pycode.co_code
self.valuestackdepth = hint(self.valuestackdepth, promote=True)
next_instr = self.handle_bytecode(co_code, next_instr, ec)
@@ -96,7 +97,8 @@
self.last_instr = intmask(jumpto)
ec.bytecode_trace(self, decr_by)
jumpto = r_uint(self.last_instr)
- rstm.jit_stm_transaction_break_point(True)
+ if rstm.jit_should_break_transaction(True):
+ rstm.jit_stm_transaction_break_point()
#
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
@@ -1341,15 +1341,17 @@
[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)
+
+ return SpaceOperation('stm_should_break_transaction',
+ [c_arg], op.result)
+
def rewrite_op_jit_stm_transaction_break_point(self, op):
- if isinstance(op.args[0], Constant):
- arg = int(op.args[0].value)
- c_arg = Constant(arg, lltype.Signed)
- else:
- log.WARNING("stm_transaction_break_point without const argument, assuming False in %r" % (self.graph,))
- c_arg = Constant(0, lltype.Signed)
-
- return SpaceOperation('stm_transaction_break', [c_arg], op.result)
+ return SpaceOperation('stm_transaction_break', [], op.result)
def rewrite_op_jit_marker(self, op):
key = op.args[0].value
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
@@ -893,8 +893,14 @@
def bhimpl_ref_isvirtual(x):
return False
- @arguments("i")
- def bhimpl_stm_transaction_break(if_there_is_no_other):
+
+ @arguments("i", returns="i")
+ def bhimpl_stm_should_break_transaction(if_there_is_no_other):
+ return False
+
+
+ @arguments()
+ def bhimpl_stm_transaction_break():
pass
# ----------
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
@@ -18,8 +18,7 @@
from rpython.rlib.jit import Counters
from rpython.rlib.objectmodel import we_are_translated, specialize
from rpython.rlib.unroll import unrolling_iterable
-from rpython.rtyper.lltypesystem import lltype, rclass, rffi
-
+from rpython.rtyper.lltypesystem import lltype, rclass, rffi, llmemory
# ____________________________________________________________
@@ -189,13 +188,26 @@
# ------------------------------
@arguments("int")
- def opimpl_stm_transaction_break(self, if_there_is_no_other):
+ def opimpl_stm_should_break_transaction(self, if_there_is_no_other):
val = bool(if_there_is_no_other)
mi = self.metainterp
if (mi.stm_break_wanted or (val and not mi.stm_break_done)):
mi.stm_break_done = True
mi.stm_break_wanted = False
- self.execute(rop.STM_TRANSACTION_BREAK, ConstInt(val))
+ # insert a CALL
+ resbox = history.BoxInt(0)
+ funcptr = mi.staticdata.stm_should_break_transaction
+ funcdescr = mi.staticdata.stm_should_break_transaction_descr
+ funcaddr = llmemory.cast_ptr_to_adr(funcptr)
+ mi._record_helper_nonpure_varargs(
+ rop.CALL, resbox, funcdescr,
+ [ConstInt(mi.cpu.cast_adr_to_int(funcaddr)),])
+ return resbox
+ else:
+ return ConstInt(0)
+
+ def opimpl_stm_transaction_break(self):
+ self.execute(rop.STM_TRANSACTION_BREAK)
for _opimpl in ['int_add', 'int_sub', 'int_mul', 'int_floordiv', 'int_mod',
'int_lt', 'int_le', 'int_eq',
@@ -1507,6 +1519,22 @@
d = self.exit_frame_with_exception_descr_ref
self.cpu.exit_frame_with_exception_descr_ref = d
+ if self.config.translation.stm:
+ self.stm_should_break_transaction = rffi.llexternal(
+ 'stm_should_break_transaction',
+ [], lltype.Bool,
+ sandboxsafe=True, _nowrapper=True, transactionsafe=True)
+ FUNC = lltype.typeOf(self.stm_should_break_transaction).TO
+
+ ei = EffectInfo([], [], [], [],
+ EffectInfo.EF_CANNOT_RAISE,
+ can_invalidate=False)
+
+ self.stm_should_break_transaction_descr = (
+ self.cpu.calldescrof(FUNC, FUNC.ARGS,
+ FUNC.RESULT, ei))
+
+
def _freeze_(self):
return True
@@ -2695,7 +2723,6 @@
# if the codewriter didn't produce any OS_LIBFFI_CALL at all.
assert self.staticdata.has_libffi_call
#
- from rpython.rtyper.lltypesystem import llmemory
from rpython.rlib.jit_libffi import CIF_DESCRIPTION_P
from rpython.jit.backend.llsupport.ffisupport import get_arg_descr
#
diff --git a/rpython/jit/metainterp/test/test_stm.py b/rpython/jit/metainterp/test/test_stm.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/metainterp/test/test_stm.py
@@ -0,0 +1,19 @@
+import py, sys
+from rpython.jit.metainterp.test.support import LLJitMixin
+from rpython.rlib.jit import JitDriver, dont_look_inside
+from rpython.rlib.rarithmetic import ovfcheck, LONG_BIT, intmask
+from rpython.jit.codewriter.policy import StopAtXPolicy
+from rpython.rlib import rstm
+
+
+
+
+class STMTests:
+ def test_simple(self):
+ def g():
+ return rstm.jit_stm_should_break_transaction(False)
+ res = self.interp_operations(g, [])
+ assert res == False
+
+class TestLLtype(STMTests, LLJitMixin):
+ pass
diff --git a/rpython/jit/tl/tlc.py b/rpython/jit/tl/tlc.py
--- a/rpython/jit/tl/tlc.py
+++ b/rpython/jit/tl/tlc.py
@@ -250,7 +250,8 @@
myjitdriver.jit_merge_point(frame=frame,
code=code, pc=pc, pool=pool)
# nothing inbetween!
- rstm.jit_stm_transaction_break_point(False)
+ if rstm.jit_should_break_transaction(False):
+ rstm.jit_stm_transaction_break_point()
opcode = ord(code[pc])
pc += 1
stack = frame.stack
@@ -351,7 +352,8 @@
pc += char2int(code[pc])
pc += 1
if jitted and old_pc > pc:
- rstm.jit_stm_transaction_break_point(True)
+ if rstm.jit_should_break_transaction(True):
+ rstm.jit_stm_transaction_break_point()
myjitdriver.can_enter_jit(code=code, pc=pc, frame=frame,
pool=pool)
@@ -361,7 +363,8 @@
old_pc = pc
pc += char2int(code[pc]) + 1
if jitted and old_pc > pc:
- rstm.jit_stm_transaction_break_point(True)
+ if rstm.jit_should_break_transaction(True):
+ rstm.jit_stm_transaction_break_point()
myjitdriver.can_enter_jit(code=code, pc=pc, frame=frame,
pool=pool)
else:
@@ -373,7 +376,8 @@
old_pc = pc
pc += offset
if jitted and old_pc > pc:
- rstm.jit_stm_transaction_break_point(True)
+ if rstm.jit_should_break_transaction(True):
+ rstm.jit_stm_transaction_break_point()
myjitdriver.can_enter_jit(code=code, pc=pc, frame=frame,
pool=pool)
diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py
--- a/rpython/rlib/rstm.py
+++ b/rpython/rlib/rstm.py
@@ -29,26 +29,20 @@
addr = llop.stm_get_adr_of_read_barrier_cache(llmemory.Address)
return rffi.cast(lltype.Signed, addr)
-def jit_stm_transaction_break_point(if_there_is_no_other):
+def jit_stm_transaction_break_point():
+ if we_are_translated():
+ llop.jit_stm_transaction_break_point(lltype.Void)
+
+
+def jit_stm_should_break_transaction(if_there_is_no_other):
# 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
# a CALL_RELEASE_GIL
- pass # specialized below
- # llop.jit_stm_transaction_break_point(lltype.Void,
- # if_there_is_no_other)
+ return llop.jit_stm_should_break_transaction(lltype.Bool,
+ if_there_is_no_other)
-class JitSTMTransactionBreakPoint(ExtRegistryEntry):
- _about_ = jit_stm_transaction_break_point
- def compute_result_annotation(self, arg):
- from rpython.annotator import model as annmodel
- return annmodel.s_None
- def specialize_call(self, hop):
- [v_arg] = hop.inputargs(lltype.Bool)
- hop.exception_cannot_occur()
- return hop.genop('jit_stm_transaction_break_point', [v_arg],
- resulttype=lltype.Void)
-
+
@dont_look_inside
def become_inevitable():
llop.stm_become_inevitable(lltype.Void)
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
@@ -525,6 +525,7 @@
canraise=(Exception,),
canmallocgc=True),
'jit_stm_transaction_break_point' : LLOp(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
@@ -701,6 +701,9 @@
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 get_op_impl(opname):
diff --git a/rpython/translator/stm/jitdriver.py b/rpython/translator/stm/jitdriver.py
--- a/rpython/translator/stm/jitdriver.py
+++ b/rpython/translator/stm/jitdriver.py
@@ -18,12 +18,13 @@
and op.args[0].value == 'jit_merge_point'):
jitdriver = op.args[1].value
if not jitdriver.autoreds:
- if (relaxed
- or (i + 1 < len(block.operations)
- and block.operations[i+1].opname == 'jit_stm_transaction_break_point')):
- found.append((block, i))
- else:
- log.WARNING("ignoring jitdriver without a transaction break point in %r" % (graph,))
+ # XXX: BUG, redo the below code in order to ensure atomicity of bytecode instrs
+ # if (relaxed
+ # or (i + 1 < len(block.operations)
+ # and block.operations[i+1].opname == 'jit_stm_transaction_break_point')):
+ found.append((block, i))
+ # else:
+ # log.WARNING("ignoring jitdriver without a transaction break point in %r" % (graph,))
else:
log.WARNING("ignoring jitdriver with autoreds in %r" % (
graph,)) # XXX XXX!
More information about the pypy-commit
mailing list