[pypy-commit] stmgc c7-more-segments: in-progress
arigo
noreply at buildbot.pypy.org
Sun Mar 16 09:46:32 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch: c7-more-segments
Changeset: r1028:c06abb7b21ca
Date: 2014-03-16 09:46 +0100
http://bitbucket.org/pypy/stmgc/changeset/c06abb7b21ca/
Log: in-progress
diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -238,26 +238,30 @@
return false;
}
-static void synchronize_overflow_object_now(object_t *obj)
+static void synchronize_object_now(object_t *obj, bool assume_local_private)
{
- abort();//XXX
-#if 0
+ /* Copy around the version of 'obj' that lives in our own segment.
+ It is first copied into the shared pages, and then into other
+ segments' own private pages.
+ */
assert(!_is_young(obj));
- assert((obj->stm_flags & GCFLAG_SMALL_UNIFORM) == 0);
assert(obj->stm_flags & GCFLAG_WRITE_BARRIER);
- 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;
- uintptr_t last_page = (end - 1) / 4096UL;
- do {
- if (flag_page_private[first_page] != SHARED_PAGE) {
- /* The page is a PRIVATE_PAGE. We need to diffuse this fragment
- of our object from our own segment to all other segments. */
+ if (obj->stm_flags & GCFLAG_SMALL_UNIFORM) {
+ abort();//XXX WRITE THE FAST CASE
+ }
+ else {
+ 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 end = start + obj_size;
+ uintptr_t last_page = (end - 1) / 4096UL;
+ long i, myself = STM_SEGMENT->segment_num;
+
+ for (; first_page <= last_page; first_page++) {
uintptr_t copy_size;
if (first_page == last_page) {
@@ -265,86 +269,44 @@
copy_size = end - start;
}
else {
- /* this is a non-final fragment, going up to the page's end */
+ /* this is a non-final fragment, going up to the
+ page's end */
copy_size = 4096 - (start & 4095);
}
-
/* double-check that the result fits in one page */
assert(copy_size > 0);
assert(copy_size + (start & 4095) <= 4096);
- long i;
- char *src = REAL_ADDRESS(STM_SEGMENT->segment_base, start);
- for (i = 0; i < NB_SEGMENTS; i++) {
- abort();//XXX
- if (i != STM_SEGMENT->segment_num) {
- char *dst = REAL_ADDRESS(get_segment_base(i), start);
+ /* First copy the object into the shared page, if needed */
+ assert(IMPLY(assume_local_private,
+ is_private_page(myself, first_page)));
+
+ if (assume_local_private || is_private_page(myself, first_page)) {
+ char *src = REAL_ADDRESS(STM_SEGMENT->segment_base, start);
+ char *dst = REAL_ADDRESS(stm_object_pages, start);
+ if (copy_size == 4096)
+ pagecopy(dst, src);
+ else
memcpy(dst, src, copy_size);
- }
}
- }
-
- start = (start + 4096) & ~4095;
- } while (first_page++ < last_page);
-#endif
-}
-
-static void synchronize_object_now(object_t *obj)
-{
- /* Assume that the version of 'obj' in the shared pages is up-to-date.
- Assume also that the version in our own private page is up-to-date.
- This function updates the private page of other threads.
- */
- assert(!_is_young(obj));
- assert(obj->stm_flags & GCFLAG_WRITE_BARRIER);
-
- uintptr_t start = (uintptr_t)obj;
- uintptr_t first_page = start / 4096UL;
- long i;
-
- if (obj->stm_flags & GCFLAG_SMALL_UNIFORM) {
- abort();//XXX WRITE THE FAST CASE
- }
- else {
- char *realobj = REAL_ADDRESS(stm_object_pages, obj);
- ssize_t obj_size = stmcb_size_rounded_up((struct object_s *)realobj);
- assert(obj_size >= 16);
- uintptr_t end = start + obj_size;
- uintptr_t last_page = (end - 1) / 4096UL;
-
- for (; first_page <= last_page; first_page++) {
for (i = 1; i < NB_SEGMENTS; i++) {
-
- if (i == STM_SEGMENT->segment_num)
+ if (i == myself)
continue;
-
if (!is_private_page(i, first_page))
continue;
- /* The page is a PRIVATE_PAGE. We need to diffuse this
+ /* The page is a private page. We need to diffuse this
fragment of object from the shared page to this private
page. */
-
- uintptr_t copy_size;
- if (first_page == last_page) {
- /* this is the final fragment */
- copy_size = end - start;
- }
- else {
- /* this is a non-final fragment, going up to the
- page's end */
- copy_size = 4096 - (start & 4095);
- }
-
- /* double-check that the result fits in one page */
- assert(copy_size > 0);
- assert(copy_size + (start & 4095) <= 4096);
-
char *src = REAL_ADDRESS(stm_object_pages, start);
char *dst = REAL_ADDRESS(get_segment_base(i), start);
- memcpy(dst, src, copy_size);
+ if (copy_size == 4096)
+ pagecopy(dst, src);
+ else
+ memcpy(dst, src, copy_size);
}
+
start = (start + 4096) & ~4095;
}
}
@@ -356,13 +318,11 @@
return;
LIST_FOREACH_R(STM_PSEGMENT->large_overflow_objects, object_t *,
- synchronize_overflow_object_now(item));
+ synchronize_object_now(item, false));
}
static void push_modified_to_other_segments(void)
{
- char *local_base = STM_SEGMENT->segment_base;
-
LIST_FOREACH_R(
STM_PSEGMENT->modified_old_objects,
object_t * /*item*/,
@@ -378,14 +338,8 @@
minor_collection() */
assert((item->stm_flags & GCFLAG_WRITE_BARRIER) != 0);
- /* copy the modified object to the shared copy */
- char *src = REAL_ADDRESS(local_base, item);
- char *dst = REAL_ADDRESS(stm_object_pages, item);
- ssize_t size = stmcb_size_rounded_up((struct object_s *)src);
- memcpy(dst, src, size);
-
/* copy the object to the other private pages as needed */
- synchronize_object_now(item);
+ synchronize_object_now(item, true);
}));
list_clear(STM_PSEGMENT->modified_old_objects);
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -231,4 +231,4 @@
asm("/* workaround for llvm bug */");
}
-static void synchronize_overflow_object_now(object_t *obj);
+static void synchronize_object_now(object_t *obj, bool assume_local_private);
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -199,7 +199,7 @@
content); or add the object to 'large_overflow_objects'.
*/
if (STM_PSEGMENT->minor_collect_will_commit_now)
- synchronize_overflow_object_now(obj);
+ synchronize_object_now(obj, false);
else
LIST_APPEND(STM_PSEGMENT->large_overflow_objects, obj);
}
More information about the pypy-commit
mailing list