Author: Armin Rigo <ar...@tunes.org> Branch: finalizer Changeset: r1468:bc9a0f2e120d Date: 2014-10-07 11:10 +0200 http://bitbucket.org/pypy/stmgc/changeset/bc9a0f2e120d/
Log: in-progress diff --git a/c7/stm/core.h b/c7/stm/core.h --- a/c7/stm/core.h +++ b/c7/stm/core.h @@ -203,6 +203,7 @@ struct list_s *young_objects_with_light_finalizers; struct list_s *old_objects_with_light_finalizers; struct list_s *objects_with_finalizers; + struct list_s *run_finalizers; }; enum /* safe_point */ { diff --git a/c7/stm/finalizer.c b/c7/stm/finalizer.c --- a/c7/stm/finalizer.c +++ b/c7/stm/finalizer.c @@ -123,15 +123,13 @@ return _finalizer_tmpstack; } -static void _recursively_bump_finalization_state(object_t *obj, int from_state) +static void _recursively_bump_finalization_state(object_t *obj, int to_state) { struct list_s *tmpstack = _finalizer_emptystack; assert(list_is_empty(tmpstack)); - assert(_finalization_state(obj) == from_state); - while (1) { - if (_finalization_state(obj) == from_state) { + if (_finalization_state(obj) == to_state - 1) { /* bump to the next state */ write_locks[mark_loc(obj)]++; @@ -151,27 +149,35 @@ { /* for non-light finalizers */ - /* there is one 'objects_with_finalizers' list per segment, but it - doesn't really matter: all objects are considered equal, and if - they survive, they are added again into one list that is attached - at the end to an arbitrary segment. */ - struct list_s *new_with_finalizer = list_create(); - struct list_s *marked = list_create(); - struct list_s *pending = list_create(); + /* there is one 'objects_with_finalizers' list per segment. + Objects that survives remain the their original segment's list. + For objects that existed since a long time, it doesn't change + anything: any thread, through any segment, should see the same + old content. (If the content was different between segments, + the object would be in a 'modified_old_objects' list somewhere, + and so it wouldn't be dead). But it's important if the object + was created by the same transaction: then only that segment + sees valid content. + */ + struct list_s *marked_seg[NB_SEGMENTS]; + struct list_s *pending; LIST_CREATE(_finalizer_emptystack); + LIST_CREATE(pending); long j; for (j = 1; j <= NB_SEGMENTS; j++) { struct stm_priv_segment_info_s *pseg = get_priv_segment(j); + struct list_s *marked = list_create(); struct list_s *lst = pseg->objects_with_finalizers; long i, count = list_count(lst); + lst->count = 0; for (i = 0; i < count; i++) { object_t *x = (object_t *)list_item(lst, i); assert(_finalization_state(x) != 1); if (_finalization_state(x) >= 2) { - LIST_APPEND(new_with_finalizer, x); + list_set_item(lst, lst->count++, (uintptr_t)x); continue; } LIST_APPEND(marked, x); @@ -184,32 +190,39 @@ pending = finalizer_trace(y, pending); } else if (state == 2) { - _recursively_bump_finalization_state(y, 2); + _recursively_bump_finalization_state(y, 3); } } - _recursively_bump_finalization_state(x, 1); + assert(_finalization_state(x) == 1); + _recursively_bump_finalization_state(x, 2); } - list_clear(lst); + + marked_seg[j - 1] = marked; } - long i, count = list_count(marked); - for (i = 0; i < count; i++) { - object_t *x = (object_t *)list_item(marked, i); + LIST_FREE(pending); - int state = _finalization_state(x); - assert(state >= 2); - if (state == 2) { - LIST_APPEND(run_finalizers, x); - _recursively_bump_finalization_state(x, 2); + for (j = 1; j <= NB_SEGMENTS; j++) { + struct stm_priv_segment_info_s *pseg = get_priv_segment(j); + struct list_s *lst = pseg->objects_with_finalizers; + struct list_s *marked = marked_seg[j - 1]; + + long i, count = list_count(marked); + for (i = 0; i < count; i++) { + object_t *x = (object_t *)list_item(marked, i); + + int state = _finalization_state(x); + assert(state >= 2); + if (state == 2) { + LIST_APPEND(pseg->run_finalizers, x); + _recursively_bump_finalization_state(x, 3); + } + else { + list_set_item(lst, lst->count++, (uintptr_t)x); + } } - else { - LIST_APPEND(new_with_finalizer, x); - } + list_free(marked); } LIST_FREE(_finalizer_emptystack); - list_free(pending); - list_free(marked); - list_free(get_priv_segment(1)->objects_with_finalizers); - get_priv_segment(1)->objects_with_finalizers = new_with_finalizer; } diff --git a/c7/stm/finalizer.h b/c7/stm/finalizer.h --- a/c7/stm/finalizer.h +++ b/c7/stm/finalizer.h @@ -2,5 +2,3 @@ static void deal_with_young_objects_with_finalizers(void); static void deal_with_old_objects_with_finalizers(void); static void deal_with_objects_with_finalizers(void); - -static struct list_s *run_finalizers; diff --git a/c7/stm/setup.c b/c7/stm/setup.c --- a/c7/stm/setup.c +++ b/c7/stm/setup.c @@ -131,11 +131,11 @@ pr->young_objects_with_light_finalizers = list_create(); pr->old_objects_with_light_finalizers = list_create(); pr->objects_with_finalizers = list_create(); + pr->run_finalizers = list_create(); pr->overflow_number = GCFLAG_OVERFLOW_NUMBER_bit0 * i; highest_overflow_number = pr->overflow_number; pr->pub.transaction_read_version = 0xff; } - run_finalizers = list_create(); /* The pages are shared lazily, as remap_file_pages() takes a relatively long time for each page. @@ -176,8 +176,8 @@ list_free(pr->young_objects_with_light_finalizers); list_free(pr->old_objects_with_light_finalizers); list_free(pr->objects_with_finalizers); + list_free(pr->run_finalizers); } - list_free(run_finalizers); munmap(stm_object_pages, TOTAL_MEMORY); stm_object_pages = NULL; _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit