[pypy-commit] stmgc gc-small-uniform: Fixes
arigo
noreply at buildbot.pypy.org
Sun Apr 6 11:19:26 CEST 2014
Author: Armin Rigo <arigo at tunes.org>
Branch: gc-small-uniform
Changeset: r1135:19703dd56de4
Date: 2014-04-05 23:30 +0200
http://bitbucket.org/pypy/stmgc/changeset/19703dd56de4/
Log: Fixes
diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -84,7 +84,6 @@
the common case. Otherwise, we need to compute it based on
its location and size. */
if (is_small_uniform(obj)) {
- abort();
page_privatize(first_page);
}
else {
@@ -336,17 +335,50 @@
uintptr_t start = (uintptr_t)obj;
uintptr_t first_page = start / 4096UL;
+ char *realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj);
+ long i, myself = STM_SEGMENT->segment_num;
if (is_small_uniform(obj)) {
- abort();//XXX WRITE THE FAST CASE
+ /* First copy the object into the shared page, if needed */
+ char *src = REAL_ADDRESS(STM_SEGMENT->segment_base, start);
+ char *dst = REAL_ADDRESS(stm_object_pages, start);
+ ssize_t obj_size = 0; /* computed lazily, only if needed */
+
+ if (is_private_page(myself, first_page)) {
+ obj_size = stmcb_size_rounded_up((struct object_s *)realobj);
+ memcpy(dst, src, obj_size);
+ }
+ else {
+ assert(memcmp(dst, src, /* already identical */
+ stmcb_size_rounded_up((struct object_s *)realobj)) == 0);
+ }
+
+ for (i = 1; i <= NB_SEGMENTS; i++) {
+ if (i == myself)
+ continue;
+
+ src = REAL_ADDRESS(stm_object_pages, start);
+ dst = REAL_ADDRESS(get_segment_base(i), start);
+ if (is_private_page(i, first_page)) {
+ /* The page is a private page. We need to diffuse this
+ object from the shared page to this private page. */
+ if (obj_size == 0) {
+ obj_size =
+ stmcb_size_rounded_up((struct object_s *)src);
+ }
+ memcpy(dst, src, obj_size);
+ }
+ else {
+ assert(memcmp(dst, src, /* already identical */
+ stmcb_size_rounded_up((struct object_s *)src)) == 0);
+ }
+ }
}
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++) {
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -64,7 +64,6 @@
/* takes a normal pointer to a thread-local pointer to an object */
object_t *obj = *pobj;
object_t *nobj;
- uintptr_t nobj_sync_now;
if (obj == NULL)
return;
@@ -93,31 +92,28 @@
obj->stm_flags &= ~GCFLAG_HAS_SHADOW;
realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj);
size = stmcb_size_rounded_up((struct object_s *)realobj);
- goto handle_large_object;
}
}
- /* We need to make a copy of this object. It goes either in
- a largemalloc.c-managed area, or if it's small enough, in
- one of the small uniform pages from gcpage.c.
- */
- realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj);
- size = stmcb_size_rounded_up((struct object_s *)realobj);
+ else {
+ /* We need to make a copy of this object. It goes either in
+ a largemalloc.c-managed area, or if it's small enough, in
+ one of the small uniform pages from gcpage.c.
+ */
+ realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj);
+ size = stmcb_size_rounded_up((struct object_s *)realobj);
- if (size > GC_LAST_SMALL_SIZE) {
+ if (size > GC_LAST_SMALL_SIZE) {
- /* case 1: object is not small enough.
- Ask gcpage.c for an allocation via largemalloc. */
- char *allocated = allocate_outside_nursery_large(size);
- nobj = (object_t *)(allocated - stm_object_pages);
-
- handle_large_object:
- nobj_sync_now = ((uintptr_t)nobj) | FLAG_SYNC_LARGE;
- }
- else {
- /* case "small enough" */
- char *allocated = allocate_outside_nursery_small(size);
- nobj = (object_t *)(allocated - stm_object_pages);
- nobj_sync_now = (uintptr_t)nobj;
+ /* case 1: object is not small enough.
+ Ask gcpage.c for an allocation via largemalloc. */
+ char *allocated = allocate_outside_nursery_large(size);
+ nobj = (object_t *)(allocated - stm_object_pages);
+ }
+ else {
+ /* case "small enough" */
+ char *allocated = allocate_outside_nursery_small(size);
+ nobj = (object_t *)(allocated - stm_object_pages);
+ }
}
/* Copy the object */
@@ -140,7 +136,6 @@
/* a young object outside the nursery */
nobj = obj;
tree_delete_item(STM_PSEGMENT->young_outside_nursery, (uintptr_t)nobj);
- nobj_sync_now = ((uintptr_t)nobj) | FLAG_SYNC_LARGE;
}
/* Set the overflow_number if nedeed */
@@ -150,8 +145,8 @@
}
/* Must trace the object later */
+ uintptr_t nobj_sync_now = (uintptr_t)nobj | !is_small_uniform(nobj);
LIST_APPEND(STM_PSEGMENT->objects_pointing_to_nursery, nobj_sync_now);
- assert(nobj_sync_now == ((uintptr_t)nobj | is_small_uniform(nobj)));
}
static void collect_roots_in_nursery(void)
More information about the pypy-commit
mailing list