Author: Armin Rigo <ar...@tunes.org>
Branch: hashtable
Changeset: r1487:89d9e799e056
Date: 2014-10-31 12:33 +0100
http://bitbucket.org/pypy/stmgc/changeset/89d9e799e056/

Log:    More fixes: on abort, call the light finalizer before cleaning up
        the nursery, and in the correct segment.

diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -973,6 +973,8 @@
                        (int)pseg->transaction_state);
     }
 
+    abort_finalizers(pseg);
+
     /* throw away the content of the nursery */
     long bytes_in_nursery = throw_away_nursery(pseg);
 
@@ -1061,8 +1063,6 @@
     /* invoke the callbacks */
     invoke_and_clear_user_callbacks(1);   /* for abort */
 
-    abort_finalizers();
-
     if (is_abort(STM_SEGMENT->nursery_end)) {
         /* done aborting */
         STM_SEGMENT->nursery_end = pause_signalled ? NSE_SIGPAUSE
diff --git a/c7/stm/finalizer.c b/c7/stm/finalizer.c
--- a/c7/stm/finalizer.c
+++ b/c7/stm/finalizer.c
@@ -58,30 +58,37 @@
     STM_PSEGMENT->finalizers = NULL;
 }
 
-static void abort_finalizers(void)
+static void abort_finalizers(struct stm_priv_segment_info_s *pseg)
 {
     /* like _commit_finalizers(), but forget everything from the
        current transaction */
-    if (STM_PSEGMENT->finalizers != NULL) {
-        if (STM_PSEGMENT->finalizers->run_finalizers != NULL) {
-            if (STM_PSEGMENT->finalizers->running_next != NULL) {
-                *STM_PSEGMENT->finalizers->running_next = (uintptr_t)-1;
+    if (pseg->finalizers != NULL) {
+        if (pseg->finalizers->run_finalizers != NULL) {
+            if (pseg->finalizers->running_next != NULL) {
+                *pseg->finalizers->running_next = (uintptr_t)-1;
             }
-            list_free(STM_PSEGMENT->finalizers->run_finalizers);
+            list_free(pseg->finalizers->run_finalizers);
         }
-        list_free(STM_PSEGMENT->finalizers->objects_with_finalizers);
-        free(STM_PSEGMENT->finalizers);
-        STM_PSEGMENT->finalizers = NULL;
+        list_free(pseg->finalizers->objects_with_finalizers);
+        free(pseg->finalizers);
+        pseg->finalizers = NULL;
     }
 
-    /* also call the light finalizers for objects that are about to
+    /* call the light finalizers for objects that are about to
        be forgotten from the current transaction */
-    struct list_s *lst = STM_PSEGMENT->young_objects_with_light_finalizers;
+    char *old_gs_register = STM_SEGMENT->segment_base;
+    bool must_fix_gs = old_gs_register != pseg->pub.segment_base;
+
+    struct list_s *lst = pseg->young_objects_with_light_finalizers;
     long i, count = list_count(lst);
     if (lst > 0) {
         for (i = 0; i < count; i++) {
             object_t *obj = (object_t *)list_item(lst, i);
             assert(_is_young(obj));
+            if (must_fix_gs) {
+                set_gs_register(pseg->pub.segment_base);
+                must_fix_gs = false;
+            }
             stmcb_light_finalizer(obj);
         }
         list_clear(lst);
@@ -90,15 +97,22 @@
     /* also deals with overflow objects: they are at the tail of
        old_objects_with_light_finalizers (this list is kept in order
        and we cannot add any already-committed object) */
-    lst = STM_PSEGMENT->old_objects_with_light_finalizers;
+    lst = pseg->old_objects_with_light_finalizers;
     count = list_count(lst);
     while (count > 0) {
         object_t *obj = (object_t *)list_item(lst, --count);
-        if (!IS_OVERFLOW_OBJ(STM_PSEGMENT, obj))
+        if (!IS_OVERFLOW_OBJ(pseg, obj))
             break;
         lst->count = count;
+        if (must_fix_gs) {
+            set_gs_register(pseg->pub.segment_base);
+            must_fix_gs = false;
+        }
         stmcb_light_finalizer(obj);
     }
+
+    if (STM_SEGMENT->segment_base != old_gs_register)
+        set_gs_register(old_gs_register);
 }
 
 
diff --git a/c7/stm/finalizer.h b/c7/stm/finalizer.h
--- a/c7/stm/finalizer.h
+++ b/c7/stm/finalizer.h
@@ -14,7 +14,7 @@
 static void teardown_finalizer(void);
 
 static void _commit_finalizers(void);
-static void abort_finalizers(void);
+static void abort_finalizers(struct stm_priv_segment_info_s *);
 
 #define commit_finalizers()   do {              \
     if (STM_PSEGMENT->finalizers != NULL)       \
diff --git a/c7/test/test_finalizer.py b/c7/test/test_finalizer.py
--- a/c7/test/test_finalizer.py
+++ b/c7/test/test_finalizer.py
@@ -9,6 +9,7 @@
         #
         @ffi.callback("void(object_t *)")
         def light_finalizer(obj):
+            assert stm_get_obj_size(obj) == 48
             segnum = lib.current_segment_num()
             tlnum = '?'
             for n, tl in enumerate(self.tls):
@@ -20,6 +21,10 @@
         lib.stmcb_light_finalizer = light_finalizer
         self._light_finalizer_keepalive = light_finalizer
 
+    def teardown_method(self, meth):
+        lib.stmcb_light_finalizer = ffi.NULL
+        BaseTest.teardown_method(self, meth)
+
     def expect_finalized(self, objs, from_tlnum=None):
         assert [obj for (obj, tlnum) in self.light_finalizers_called] == objs
         if from_tlnum is not None:
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to