Author: Armin Rigo <[email protected]>
Branch: stmgc-c7
Changeset: r69892:0fc7602e53d3
Date: 2014-03-12 10:46 +0100
http://bitbucket.org/pypy/pypy/changeset/0fc7602e53d3/
Log: Reimplement stm_ignored
diff --git a/rpython/memory/gctransform/stmframework.py
b/rpython/memory/gctransform/stmframework.py
--- a/rpython/memory/gctransform/stmframework.py
+++ b/rpython/memory/gctransform/stmframework.py
@@ -5,6 +5,7 @@
BaseFrameworkGCTransformer, BaseRootWalker, sizeofaddr)
from rpython.memory.gctypelayout import WEAKREF, WEAKREFPTR
from rpython.rtyper import rmodel, llannotation
+from rpython.translator.backendopt.support import var_needsgc
class StmFrameworkGCTransformer(BaseFrameworkGCTransformer):
@@ -52,6 +53,25 @@
for var in reversed(livevars):
hop.genop("stm_pop_root_into", [var])
+ def transform_block(self, *args, **kwds):
+ self.in_stm_ignored = False
+ BaseFrameworkGCTransformer.transform_block(self, *args, **kwds)
+ assert not self.in_stm_ignored, (
+ "unbalanced stm_ignore_start/stm_ignore_stop in block")
+
+ def gct_stm_ignored_start(self, hop):
+ assert not self.in_stm_ignored
+ self.in_stm_ignored = True
+ self.default(hop)
+
+ def gct_stm_ignored_stop(self, hop):
+ assert self.in_stm_ignored
+ self.in_stm_ignored = False
+ self.default(hop)
+
+ def var_needs_set_transform(self, var):
+ return True
+
def transform_generic_set(self, hop):
# XXX detect if we're inside a 'stm_ignored' block and... do what?
assert self.write_barrier_ptr == "stm"
@@ -61,8 +81,13 @@
'raw_store')
if (v_struct.concretetype.TO._gckind == "gc"
and hop.spaceop not in self.clean_sets):
- self.write_barrier_calls += 1
- hop.genop("stm_write", [v_struct])
+ if self.in_stm_ignored:
+ if var_needsgc(hop.spaceop.args[-1]):
+ raise Exception("in stm_ignored block: write of a gc "
+ "pointer")
+ else:
+ self.write_barrier_calls += 1
+ hop.genop("stm_write", [v_struct])
hop.rename('bare_' + opname)
def gc_header_for(self, obj, needs_hash=False):
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
@@ -450,6 +450,9 @@
'stm_abort_info_pop': LLOp(),
'stm_inspect_abort_info': LLOp(sideeffects=False, canmallocgc=True),
+ 'stm_ignored_start': LLOp(canrun=True),
+ 'stm_ignored_stop': LLOp(canrun=True),
+
## 'stm_allocate_nonmovable_int_adr': LLOp(sideeffects=False,
canmallocgc=True),
## 'stm_become_inevitable': LLOp(canmallocgc=True),
## 'stm_stop_all_other_threads': LLOp(canmallocgc=True),
@@ -467,9 +470,6 @@
## 'stm_get_adr_of_nursery_nextlimit': LLOp(),
## 'stm_get_adr_of_active': LLOp(),
-## 'stm_ignored_start': LLOp(canrun=True),
-## 'stm_ignored_stop': LLOp(canrun=True),
-
# __________ address operations __________
'boehm_malloc': LLOp(),
diff --git a/rpython/translator/stm/funcgen.py
b/rpython/translator/stm/funcgen.py
--- a/rpython/translator/stm/funcgen.py
+++ b/rpython/translator/stm/funcgen.py
@@ -197,6 +197,12 @@
result = funcgen.expr(op.result)
return '%s = NULL; //XXX stm_inspect_abort_info();' % (result,)
+def stm_ignored_start(funcgen, op):
+ return '/* stm_ignored_start */'
+
+def stm_ignored_stop(funcgen, op):
+ return '/* stm_ignored_stop */'
+
##def stm_initialize(funcgen, op):
## return '''stm_initialize();
diff --git a/rpython/translator/stm/readbarrier.py
b/rpython/translator/stm/readbarrier.py
--- a/rpython/translator/stm/readbarrier.py
+++ b/rpython/translator/stm/readbarrier.py
@@ -23,10 +23,20 @@
if not block.operations:
continue
newops = []
+ stm_ignored = False
for op in block.operations:
if op.opname in READ_OPS and is_gc_ptr(op.args[0].concretetype):
- v_none = varoftype(lltype.Void)
- newops.append(SpaceOperation('stm_read', [op.args[0]], v_none))
- transformer.read_barrier_counts += 1
+ if not stm_ignored:
+ v_none = varoftype(lltype.Void)
+ newops.append(SpaceOperation('stm_read',
+ [op.args[0]], v_none))
+ transformer.read_barrier_counts += 1
+ elif op.opname == 'stm_ignored_start':
+ assert stm_ignored == False
+ stm_ignored = True
+ elif op.opname == 'stm_ignored_stop':
+ assert stm_ignored == True
+ stm_ignored = False
newops.append(op)
+ assert stm_ignored == False
block.operations = newops
diff --git a/rpython/translator/stm/test/test_readbarrier.py
b/rpython/translator/stm/test/test_readbarrier.py
--- a/rpython/translator/stm/test/test_readbarrier.py
+++ b/rpython/translator/stm/test/test_readbarrier.py
@@ -1,3 +1,4 @@
+from rpython.rlib.objectmodel import stm_ignored
from rpython.translator.stm.test.transform_support import BaseTestTransform
from rpython.rtyper.lltypesystem import lltype
@@ -24,3 +25,14 @@
res = self.interpret(f1, [-5])
assert res == 42
assert self.read_barriers == [x1]
+
+ def test_stm_ignored_read(self):
+ X = lltype.GcStruct('X', ('foo', lltype.Signed))
+ x1 = lltype.malloc(X, immortal=True)
+ x1.foo = 42
+ def f1():
+ with stm_ignored:
+ return x1.foo
+ res = self.interpret(f1, [])
+ assert res == 42
+ assert self.read_barriers == []
diff --git a/rpython/translator/stm/test/test_ztranslated.py
b/rpython/translator/stm/test/test_ztranslated.py
--- a/rpython/translator/stm/test/test_ztranslated.py
+++ b/rpython/translator/stm/test/test_ztranslated.py
@@ -395,3 +395,27 @@
lines = dataerr.split('\n')
assert lines[0] == ' 0.400000'
assert lines[1] == ' 1.200000'
+
+ def test_stm_ignored(self):
+ class X:
+ foo = 84
+ prebuilt = X()
+ prebuilt2 = X()
+ def main(argv):
+ with objectmodel.stm_ignored:
+ prebuilt.foo = 42
+ with objectmodel.stm_ignored:
+ x = prebuilt2.foo
+ print 'did not crash', x
+ return 0
+
+ t, cbuilder = self.compile(main)
+ opnames = [op.opname for op in t.graphs[0].startblock.operations]
+ assert opnames[:6] == ['stm_ignored_start',
+ 'bare_setfield', # with no stm_write
+ 'stm_ignored_stop',
+ 'stm_ignored_start',
+ 'getfield', # with no stm_read
+ 'stm_ignored_stop']
+ data = cbuilder.cmdexec('')
+ assert 'did not crash 84\n' in data
diff --git a/rpython/translator/stm/test/transform_support.py
b/rpython/translator/stm/test/transform_support.py
--- a/rpython/translator/stm/test/transform_support.py
+++ b/rpython/translator/stm/test/transform_support.py
@@ -87,19 +87,18 @@
self.op_stm_read(obj) # implicitly counts as a read barrier too
def op_stm_ignored_start(self):
- xxx
assert self.stm_ignored == False
self.stm_ignored = True
def op_stm_ignored_stop(self):
- xxx
assert self.stm_ignored == True
self.stm_ignored = False
def op_getfield(self, obj, field):
if obj._TYPE.TO._gckind == 'gc':
if obj._TYPE.TO._immutable_field(field):
- self.gcptrs_actually_read.append(obj)
+ if not self.stm_ignored:
+ self.gcptrs_actually_read.append(obj)
return LLFrame.op_getfield(self, obj, field)
def op_setfield(self, obj, fieldname, fieldvalue):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit