[pypy-commit] pypy stm-gc: Test and fix.
arigo
noreply at buildbot.pypy.org
Mon Apr 23 13:29:02 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r54672:55e1db872e5a
Date: 2012-04-23 12:12 +0200
http://bitbucket.org/pypy/pypy/changeset/55e1db872e5a/
Log: Test and fix.
diff --git a/pypy/rpython/memory/gc/stmgc.py b/pypy/rpython/memory/gc/stmgc.py
--- a/pypy/rpython/memory/gc/stmgc.py
+++ b/pypy/rpython/memory/gc/stmgc.py
@@ -279,9 +279,13 @@
def _stm_write_barrier_global(obj):
tls = self.get_tls()
if tls is self.main_thread_tls:
- return obj # not in transaction
+ # not in a transaction: the main thread writes to a global obj.
+ # In this case we turn the object local.
+ tls.main_thread_writes_to_global_obj(obj)
+ return obj
#
- # we need to find or make a local copy
+ # else, in a transaction: we find or make a local copy of the
+ # global object
hdr = self.header(obj)
if hdr.tid & GCFLAG_WAS_COPIED == 0:
#
diff --git a/pypy/rpython/memory/gc/stmtls.py b/pypy/rpython/memory/gc/stmtls.py
--- a/pypy/rpython/memory/gc/stmtls.py
+++ b/pypy/rpython/memory/gc/stmtls.py
@@ -113,6 +113,13 @@
if value is not self:
del StmGCTLS.nontranslated_dict[key]
self.start_transaction()
+ # do something special here after we restarted the "transaction"
+ # in the main thread: we have to make sure that the write_barrier
+ # calls done in the main thread before enter/leave_transactional_mode
+ # are still pointing to local objects. Conservatively, we mark as
+ # local all objects directly referenced from the stack.
+ self.gc.root_walker.walk_current_stack_roots(
+ StmGCTLS._remark_object_as_local, self)
def start_transaction(self):
"""Start a transaction: performs any pending cleanups, and set
@@ -256,6 +263,16 @@
def fresh_new_weakref(self, obj):
self.local_weakrefs.append(obj)
+ def _remark_object_as_local(self, root):
+ self.main_thread_writes_to_global_obj(root.address[0])
+
+ def main_thread_writes_to_global_obj(self, obj):
+ hdr = self.gc.header(obj)
+ ll_assert(hdr.tid & GCFLAG_WAS_COPIED == 0,
+ "write in main thread: unexpected GCFLAG_WAS_COPIED")
+ hdr.tid &= ~GCFLAG_GLOBAL
+ self.sharedarea_tls.add_regular(obj)
+
# ------------------------------------------------------------
def _promote_locals_to_globals(self):
diff --git a/pypy/rpython/memory/gc/test/test_stmgc.py b/pypy/rpython/memory/gc/test/test_stmgc.py
--- a/pypy/rpython/memory/gc/test/test_stmgc.py
+++ b/pypy/rpython/memory/gc/test/test_stmgc.py
@@ -336,7 +336,28 @@
self.checkflags(t_adr, True, False)
obj = self.gc.stm_writebarrier(t_adr) # main thread, global:
assert obj == t_adr # doesn't make a copy
- #self.checkflags(obj, False, False) -- LATER check that it becomes local
+ self.checkflags(obj, False, False) # but it becomes local
+
+ def test_relocalize_objects_after_transactional_mode(self):
+ from pypy.rpython.memory.gc.test import test_stmtls
+ self.gc.root_walker = test_stmtls.FakeRootWalker()
+ #
+ tr1, tr1_adr = self.malloc(SR, globl=True)
+ tr2, tr2_adr = self.malloc(SR, globl=True)
+ tr1.sr2 = tr2
+ self.gc.root_walker.current_stack = [tr1]
+ obj = self.gc.stm_writebarrier(tr1_adr)
+ assert obj == tr1_adr
+ obj = self.gc.stm_writebarrier(tr2_adr)
+ assert obj == tr2_adr
+ self.checkflags(tr1_adr, False, False) # tr1 has become local
+ self.checkflags(tr2_adr, False, False) # tr2 has become local
+ #
+ self.gc.enter_transactional_mode()
+ self.gc.leave_transactional_mode()
+ self.checkflags(tr2_adr, True, False) # tr2 has become global again
+ # but tr1 is still local, because it is directly referenced from stack
+ self.checkflags(tr1_adr, False, False)
def test_commit_transaction_empty(self):
self.select_thread(1)
More information about the pypy-commit
mailing list