Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit