Author: Remi Meier <remi.me...@inf.ethz.ch> Branch: c8-private-pages Changeset: r1534:8c3e4f9f95a9 Date: 2015-01-16 11:42 +0100 http://bitbucket.org/pypy/stmgc/changeset/8c3e4f9f95a9/
Log: make old allocations happen in the sharing segment, fix not tracing them and add a test diff --git a/c8/stm/core.c b/c8/stm/core.c --- a/c8/stm/core.c +++ b/c8/stm/core.c @@ -151,8 +151,9 @@ if (copy_from_segnum == -1) { /* this page is only accessible in the sharing segment so far (new - allocation). We can thus simply mark it accessible here and - not care about its contents so far. */ + allocation). We can thus simply mark it accessible here. */ + pagecopy(get_virtual_page(my_segnum, pagenum), + get_virtual_page(0, pagenum)); release_all_privatization_locks(); return; } @@ -287,9 +288,6 @@ break; if (first_cl->next == INEV_RUNNING) { -#if STM_TESTS - stm_abort_transaction(); -#endif /* need to reach safe point if an INEV transaction is waiting for us, otherwise deadlock */ break; @@ -473,6 +471,15 @@ { if (!_stm_validate()) stm_abort_transaction(); + +#if STM_TESTS + if (STM_PSEGMENT->transaction_state != TS_INEVITABLE + && STM_PSEGMENT->last_commit_log_entry->next == INEV_RUNNING) { + /* abort for tests... */ + stm_abort_transaction(); + } +#endif + } @@ -1043,6 +1050,7 @@ if (i == 0 || (get_page_status_in(i, page) != PAGE_NO_ACCESS)) { /* shared or private, but never segfault */ char *dst = REAL_ADDRESS(get_segment_base(i), frag); + dprintf(("-> flush %p to seg %lu\n", frag, i)); memcpy(dst, src, frag_size); } } diff --git a/c8/stm/gcpage.c b/c8/stm/gcpage.c --- a/c8/stm/gcpage.c +++ b/c8/stm/gcpage.c @@ -58,8 +58,13 @@ if (addr == NULL) stm_fatalerror("not enough memory!"); - if (LIKELY(addr + size <= uninitialized_page_start)) + if (LIKELY(addr + size <= uninitialized_page_start)) { + dprintf(("allocate_outside_nursery_large(%lu): %p, page=%lu\n", + size, (char*)(addr - stm_object_pages), + (uintptr_t)(addr - stm_object_pages) / 4096UL)); + return (stm_char*)(addr - stm_object_pages); + } /* uncommon case: need to initialize some more pages */ @@ -95,9 +100,15 @@ stm_char *p = allocate_outside_nursery_large(size_rounded_up); object_t *o = (object_t *)p; - memset(get_virtual_address(STM_SEGMENT->segment_num, o), 0, size_rounded_up); + // sharing seg0 needs to be current: + assert(STM_SEGMENT->segment_num == 0); + memset(REAL_ADDRESS(STM_SEGMENT->segment_base, o), 0, size_rounded_up); o->stm_flags = GCFLAG_WRITE_BARRIER; + if (testing_prebuilt_objs == NULL) + testing_prebuilt_objs = list_create(); + LIST_APPEND(testing_prebuilt_objs, o); + dprintf(("allocate_old(%lu): %p, seg=%d, page=%lu\n", size_rounded_up, p, get_segment_of_linear_address(stm_object_pages + (uintptr_t)p), @@ -374,7 +385,7 @@ { /* this is called by _stm_largemalloc_sweep() */ object_t *obj = (object_t *)(data - stm_object_pages); - //dprintf(("keep obj %p ? -> %d\n", obj, mark_visited_test(obj))); + dprintf(("keep obj %p ? -> %d\n", obj, mark_visited_test(obj))); if (!mark_visited_test_and_clear(obj)) { /* This is actually needed in order to avoid random write-read conflicts with objects read and freed long in the past. diff --git a/c8/stm/nursery.c b/c8/stm/nursery.c --- a/c8/stm/nursery.c +++ b/c8/stm/nursery.c @@ -78,14 +78,16 @@ *pobj = pforwarded_array[1]; /* already moved */ return; } - else { - /* really has a shadow */ - nobj = find_existing_shadow(obj); - obj->stm_flags &= ~GCFLAG_HAS_SHADOW; - realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj); - size = stmcb_size_rounded_up((struct object_s *)realobj); - goto copy_large_object; - } + + /* really has a shadow */ + nobj = find_existing_shadow(obj); + obj->stm_flags &= ~GCFLAG_HAS_SHADOW; + realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj); + size = stmcb_size_rounded_up((struct object_s *)realobj); + + dprintf(("has_shadow(%p): %p, sz:%lu\n", + obj, nobj, size)); + goto copy_large_object; } realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj); @@ -454,6 +456,8 @@ tree_insert(STM_PSEGMENT->nursery_objects_shadows, (uintptr_t)obj, (uintptr_t)nobj); + + dprintf(("allocate_shadow(%p): %p\n", obj, nobj)); return nobj; } diff --git a/c8/stm/pages.c b/c8/stm/pages.c --- a/c8/stm/pages.c +++ b/c8/stm/pages.c @@ -63,7 +63,7 @@ static void page_mark_accessible(long segnum, uintptr_t pagenum) { - assert(get_page_status_in(segnum, pagenum) == PAGE_NO_ACCESS); + assert(segnum==0 || get_page_status_in(segnum, pagenum) == PAGE_NO_ACCESS); dprintf(("page_mark_accessible(%lu) in seg:%ld\n", pagenum, segnum)); dprintf(("RW(seg%ld, page%lu)\n", segnum, pagenum)); @@ -82,7 +82,7 @@ __attribute__((unused)) static void page_mark_inaccessible(long segnum, uintptr_t pagenum) { - assert(get_page_status_in(segnum, pagenum) == PAGE_ACCESSIBLE); + assert(segnum==0 || get_page_status_in(segnum, pagenum) == PAGE_ACCESSIBLE); dprintf(("page_mark_inaccessible(%lu) in seg:%ld\n", pagenum, segnum)); set_page_status_in(segnum, pagenum, PAGE_NO_ACCESS); diff --git a/c8/stm/pages.h b/c8/stm/pages.h --- a/c8/stm/pages.h +++ b/c8/stm/pages.h @@ -63,7 +63,7 @@ static inline bool get_page_status_in(long segnum, uintptr_t pagenum) { /* reading page status requires "read"-lock: */ - assert(STM_PSEGMENT->privatization_lock); + assert(STM_SEGMENT->segment_num==0 || STM_PSEGMENT->privatization_lock); OPT_ASSERT(segnum < 8 * sizeof(struct page_shared_s)); volatile struct page_shared_s *ps = (volatile struct page_shared_s *) diff --git a/c8/stm/smallmalloc.c b/c8/stm/smallmalloc.c --- a/c8/stm/smallmalloc.c +++ b/c8/stm/smallmalloc.c @@ -169,6 +169,8 @@ (_allocate_small_slowpath(size) - stm_object_pages); *fl = result->next; + dprintf(("allocate_outside_nursery_small(%lu): %p\n", + size, (char*)((char *)result - stm_object_pages))); return (stm_char*) ((char *)result - stm_object_pages); } @@ -178,7 +180,9 @@ stm_char *p = allocate_outside_nursery_small(size_rounded_up); object_t *o = (object_t *)p; - memset(get_virtual_address(STM_SEGMENT->segment_num, o), 0, size_rounded_up); + // sharing seg0 needs to be current: + assert(STM_SEGMENT->segment_num == 0); + memset(REAL_ADDRESS(STM_SEGMENT->segment_base, o), 0, size_rounded_up); o->stm_flags = GCFLAG_WRITE_BARRIER; dprintf(("allocate_old_small(%lu): %p, seg=%d, page=%lu\n", diff --git a/c8/test/support.py b/c8/test/support.py --- a/c8/test/support.py +++ b/c8/test/support.py @@ -497,8 +497,8 @@ self.tls = [_allocate_thread_local() for i in range(self.NB_THREADS)] self.current_thread = 0 # force-switch back to segment 0 so that when we do something - # outside of transactions before the test, it happens in seg0 - self.switch_to_segment(0) + # outside of transactions before the test, it happens in sharing seg0 + lib._stm_test_switch_segment(-1) def teardown_method(self, meth): lib.stmcb_expand_marker = ffi.NULL diff --git a/c8/test/test_gcpage.py b/c8/test/test_gcpage.py --- a/c8/test/test_gcpage.py +++ b/c8/test/test_gcpage.py @@ -281,3 +281,11 @@ p1 = self.pop_root() assert stm_get_char(p1) == 'o' assert stm_get_char(p2) == 't' + + def test_keepalive_prebuilt(self): + stm_allocate_old(64) + self.start_transaction() + assert lib._stm_total_allocated() == 64 + LMO # large malloc'd + stm_major_collect() + assert lib._stm_total_allocated() == 64 + LMO # large malloc'd + self.commit_transaction() diff --git a/c8/test/test_random.py b/c8/test/test_random.py --- a/c8/test/test_random.py +++ b/c8/test/test_random.py @@ -11,7 +11,7 @@ self.executed = [] def do(self, cmd): - color = ">> \033[%dm" % (31 + (self.thread_num + 5) % 6) + color = ">> \033[%dm" % (31 + (self.thread_num + 6) % 6) print >> sys.stderr, color + cmd + "\033[0m" self.executed.append(cmd) exec cmd in globals(), self.content @@ -579,7 +579,7 @@ op_assert_size, op_assert_modified, op_minor_collect, - #op_major_collect, + op_major_collect, ] for _ in range(2000): # make sure we are in a transaction: _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit