[pypy-commit] stmgc c7: fix and add a failing test

Raemi noreply at buildbot.pypy.org
Fri Jan 17 10:36:16 CET 2014


Author: Remi Meier <remi.meier at gmail.com>
Branch: c7
Changeset: r617:e9166bf77a19
Date: 2014-01-17 10:35 +0100
http://bitbucket.org/pypy/stmgc/changeset/e9166bf77a19/

Log:	fix and add a failing test

diff --git a/c7/core.c b/c7/core.c
--- a/c7/core.c
+++ b/c7/core.c
@@ -379,16 +379,21 @@
     uintptr_t pagenum = ((uintptr_t)obj) / 4096;
     assert(pagenum < NB_PAGES);
 
-    /* old objects from the same transaction */
-    if (flag_page_private[pagenum] == UNCOMMITTED_SHARED_PAGE
-        || obj->stm_flags & GCFLAG_NOT_COMMITTED) {
-        _STM_TL2->old_objects_to_trace = stm_list_append
-            (_STM_TL2->old_objects_to_trace, obj);
+    _STM_TL2->old_objects_to_trace = stm_list_append
+        (_STM_TL2->old_objects_to_trace, obj);
+    obj->stm_flags &= ~GCFLAG_WRITE_BARRIER;
 
+    /* for old objects from the same transaction we don't need
+       to privatize the page */
+    if ((flag_page_private[pagenum] == UNCOMMITTED_SHARED_PAGE)
+        || (obj->stm_flags & GCFLAG_NOT_COMMITTED)) {
         return;
     }
+
+    /* privatize if SHARED_PAGE */
     _stm_privatize(pagenum);
 
+    /* lock the object for writing in thread 0's page */
     uintptr_t t0_offset = (uintptr_t)obj;
     char* t0_addr = get_thread_base(0) + t0_offset;
     struct object_s *t0_obj = (struct object_s *)t0_addr;
@@ -397,12 +402,10 @@
     if (previous)
         abort();                /* XXX */
 
-    obj->stm_flags &= ~GCFLAG_WRITE_BARRIER;
-    
     stm_read(obj);
 
-    _STM_TL2->modified_objects = stm_list_append(
-        _STM_TL2->modified_objects, obj);
+    _STM_TL2->modified_objects = stm_list_append
+        (_STM_TL2->modified_objects, obj);
 }
 
 
@@ -541,11 +544,16 @@
     struct stm_list_s *old_objs = _STM_TL2->old_objects_to_trace;
     while (!stm_list_is_empty(old_objs)) {
         object_t *item = stm_list_pop_item(old_objs);
-        stmcb_trace(real_address(item),
-                    trace_if_young);
+
+        assert(!_is_young(item));
+        assert(!(item->stm_flags & GCFLAG_WRITE_BARRIER));
+        
+        /* re-add write-barrier */
+        item->stm_flags |= GCFLAG_WRITE_BARRIER;
+        
+        stmcb_trace(real_address(item), trace_if_young);
     }
 
-    /* XXX fix modified_objects? */
     
     // also move objects to PRIVATE_PAGE pages, but then
     // also add the GCFLAG_NOT_COMMITTED to these objects.
diff --git a/c7/test/test_basic.py b/c7/test/test_basic.py
--- a/c7/test/test_basic.py
+++ b/c7/test/test_basic.py
@@ -117,6 +117,48 @@
         assert p_[8] == 'u'
         stm_stop_transaction()
 
+        
+    def test_commit_fresh_objects2(self):
+        self.switch(1)
+        stm_start_transaction()
+        lp, p = stm_allocate(16)
+        p[8] = 'u'
+        lp2, p2 = stm_allocate(16)
+        p2[8] = 'v'
+        assert p2 - p == 16
+        stm_write(lp) # test not crash
+        stm_write(lp2) # test not crash
+        stm_read(lp) # test not crash
+        stm_read(lp2) # test not crash
+        stm_push_root(lp)
+        stm_push_root(lp2)
+        stm_stop_transaction()
+        lp2 = stm_pop_root()
+        lp = stm_pop_root()
+        
+        self.switch(0)
+        
+        stm_start_transaction()
+        stm_write(lp) # privatize page
+        p_ = stm_get_real_address(lp)
+        assert p_[8] == 'u'
+        p_[8] = 'x'
+        stm_write(lp2)
+        p2_ = stm_get_real_address(lp2)
+        assert p2_[8] == 'v'
+        p2_[8] = 'y'
+        stm_stop_transaction()
+
+        self.switch(1)
+
+        stm_start_transaction()
+        stm_write(lp)
+        p_ = stm_get_real_address(lp)
+        assert p_[8] == 'x'
+        stm_read(lp2)
+        p2_ = stm_get_real_address(lp2)
+        assert p2_[8] == 'y'
+        stm_stop_transaction()
 
 
         


More information about the pypy-commit mailing list