[pypy-commit] stmgc default: in-progress. still a bug left
arigo
noreply at buildbot.pypy.org
Sat Mar 1 20:04:16 CET 2014
Author: Armin Rigo <arigo at 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:
More information about the pypy-commit
mailing list