Author: Remi Meier <[email protected]>
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
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit