Author: Armin Rigo <ar...@tunes.org> Branch: Changeset: r913:e7ae3f43dde8 Date: 2014-03-01 20:03 +0100 http://bitbucket.org/pypy/stmgc/changeset/e7ae3f43dde8/
Log: in-progress. still a bug left diff --git a/c7/stm/core.c b/c7/stm/core.c --- a/c7/stm/core.c +++ b/c7/stm/core.c @@ -236,6 +236,7 @@ char *realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj); ssize_t obj_size = stmcb_size_rounded_up((struct object_s *)realobj); + assert(obj_size >= 16); uintptr_t start = (uintptr_t)obj; uintptr_t end = start + obj_size; uintptr_t first_page = start / 4096UL; diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c --- a/c7/stm/gcpage.c +++ b/c7/stm/gcpage.c @@ -95,6 +95,8 @@ return addr; } +static struct list_s *testing_prebuilt_objs = NULL; + object_t *_stm_allocate_old(ssize_t size_rounded_up) { /* only for tests */ @@ -103,6 +105,11 @@ object_t *o = (object_t *)(p - stm_object_pages); o->stm_flags = STM_FLAGS_PREBUILT; + + if (testing_prebuilt_objs == NULL) + testing_prebuilt_objs = list_create(); + LIST_APPEND(testing_prebuilt_objs, o); + return o; } @@ -147,6 +154,13 @@ return lock_idx; } +static inline bool mark_visited_test(object_t *obj) +{ + uintptr_t lock_idx = mark_loc(obj); + assert(write_locks[lock_idx] == 0 || write_locks[lock_idx] == WL_VISITED); + return write_locks[lock_idx] != 0; +} + static inline bool mark_visited_test_and_set(object_t *obj) { uintptr_t lock_idx = mark_loc(obj); @@ -228,6 +242,7 @@ object_t * /*item*/, ({ uintptr_t lock_idx = mark_loc(item); + assert(write_locks[lock_idx] == 0); write_locks[lock_idx] = pseg->write_lock_num; })); } @@ -261,6 +276,9 @@ tl = tl->next; } while (tl != stm_all_thread_locals); + + LIST_FOREACH_R(testing_prebuilt_objs, object_t * /*item*/, + mark_record_trace(&item)); } static void mark_visit_all_objects(void) @@ -283,6 +301,43 @@ _stm_largemalloc_sweep(); } +static void clean_up_segment_lists(void) +{ + long i; + for (i = 0; i < NB_SEGMENTS; i++) { + struct stm_priv_segment_info_s *pseg = get_priv_segment(i); + struct list_s *lst; + + /* 'objects_pointing_to_nursery' should be empty, but isn't + necessarily because it also lists objects that have been + written to but don't actually point to the nursery. Clear + it up and set GCFLAG_WRITE_BARRIER again on the objects. */ + lst = pseg->objects_pointing_to_nursery; + if (lst != NULL) { + LIST_FOREACH_R(lst, uintptr_t /*item*/, + ({ + struct object_s *realobj = (struct object_s *) + REAL_ADDRESS(pseg->pub.segment_base, item); + assert(!(realobj->stm_flags & GCFLAG_WRITE_BARRIER)); + realobj->stm_flags |= GCFLAG_WRITE_BARRIER; + })); + list_clear(lst); + } + + /* Remove from 'large_overflow_objects' all objects that die */ + lst = pseg->large_overflow_objects; + if (lst != NULL) { + uintptr_t n = list_count(lst); + while (n > 0) { + object_t *obj = (object_t *)list_item(lst, --n); + if (!mark_visited_test(obj)) { + list_set_item(lst, n, list_pop_item(lst)); + } + } + } + } +} + static void major_collection_now_at_safe_point(void) { dprintf(("\n")); @@ -303,6 +358,9 @@ list_free(mark_objects_to_trace); mark_objects_to_trace = NULL; + /* cleanup */ + clean_up_segment_lists(); + /* sweeping */ mutex_pages_lock(); sweep_large_objects(); diff --git a/c7/stm/largemalloc.c b/c7/stm/largemalloc.c --- a/c7/stm/largemalloc.c +++ b/c7/stm/largemalloc.c @@ -251,6 +251,12 @@ assert((chunk->size & (sizeof(char *) - 1)) == 0); assert(chunk->prev_size != THIS_CHUNK_FREE); +#ifndef NDEBUG + assert(chunk->size >= sizeof(dlist_t)); + assert(chunk->size <= (((char *)last_chunk) - (char *)data)); + memset(data, 0xDD, chunk->size); +#endif + /* try to merge with the following chunk in memory */ size_t msize = chunk->size + CHUNK_HEADER_SIZE; mchunk_t *mscan = chunk_at_offset(chunk, msize); diff --git a/c7/stm/list.h b/c7/stm/list.h --- a/c7/stm/list.h +++ b/c7/stm/list.h @@ -58,6 +58,12 @@ return lst->items[index]; } +static inline void list_set_item(struct list_s *lst, uintptr_t index, + uintptr_t newitem) +{ + lst->items[index] = newitem; +} + #define LIST_FOREACH_R(lst, TYPE, CODE) \ do { \ struct list_s *_lst = (lst); \ diff --git a/c7/test/support.py b/c7/test/support.py --- a/c7/test/support.py +++ b/c7/test/support.py @@ -217,7 +217,7 @@ return myobj->type_id - 42; } else { - int nrefs = myobj->type_id - 421420; + uint64_t nrefs = myobj->type_id - 421420; assert(nrefs < 10000); /* artificial limit, to check for garbage */ if (nrefs == 0) /* weakrefs */ nrefs = 1; diff --git a/c7/test/test_largemalloc.py b/c7/test/test_largemalloc.py --- a/c7/test/test_largemalloc.py +++ b/c7/test/test_largemalloc.py @@ -136,11 +136,15 @@ from_before = set() r = random.Random(1000) - for j in range(50): + for j in range(500): sizes = [random.choice(range(104, 500, 8)) for i in range(20)] all = [lib._stm_large_malloc(size) for size in sizes] print all + for i in range(len(all)): + all[i][50] = chr(65 + i) + all_orig = all[:] + keep_me = set() for i in range(len(all)): if r.random() < 0.5: @@ -152,10 +156,16 @@ seen_for = set() lib._stm_largemalloc_sweep() + if errors: + raise errors[0] assert seen_for == set([i for i in range(len(all)) if all[i] is not None]) lib._stm_large_dump() + from_before = [all[i] for i in keep_me] - if errors: - raise errors[0] + for i in range(len(all)): + if i in keep_me: + assert all[i][50] == chr(65 + i) + else: + assert all_orig[i][50] == '\xDD' diff --git a/c7/test/test_random.py b/c7/test/test_random.py --- a/c7/test/test_random.py +++ b/c7/test/test_random.py @@ -384,6 +384,12 @@ thread_state.pop_roots(ex) thread_state.reload_roots(ex) +def op_major_collect(ex, global_state, thread_state): + thread_state.push_roots(ex) + ex.do('stm_major_collect()') + thread_state.pop_roots(ex) + thread_state.reload_roots(ex) + def op_forget_root(ex, global_state, thread_state): r = thread_state.forget_random_root() @@ -566,6 +572,7 @@ op_assert_size, op_assert_modified, op_minor_collect, + op_major_collect, ] for _ in range(200): # make sure we are in a transaction: _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit