[pypy-commit] stmgc c8-private-pages: fix smallmalloc and prebuilt objs
Raemi
noreply at buildbot.pypy.org
Tue Jan 13 11:33:54 CET 2015
Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: c8-private-pages
Changeset: r1521:074ee9be5109
Date: 2015-01-13 11:34 +0100
http://bitbucket.org/pypy/stmgc/changeset/074ee9be5109/
Log: fix smallmalloc and prebuilt objs
diff --git a/c8/stm/gcpage.c b/c8/stm/gcpage.c
--- a/c8/stm/gcpage.c
+++ b/c8/stm/gcpage.c
@@ -63,10 +63,9 @@
{
/* only for tests xxx but stm_setup_prebuilt() uses this now too */
stm_char *p = allocate_outside_nursery_large(size_rounded_up);
- /* hardcode segment 1 */
- memset(get_virtual_address(STM_SEGMENT->segment_num, (object_t *)p), 0, size_rounded_up);
+ object_t *o = (object_t *)p;
- object_t *o = (object_t *)p;
+ memset(get_virtual_address(STM_SEGMENT->segment_num, o), 0, size_rounded_up);
o->stm_flags = GCFLAG_WRITE_BARRIER;
dprintf(("allocate_old(%lu): %p, seg=%d, page=%lu\n",
diff --git a/c8/stm/hash_id.c b/c8/stm/hash_id.c
--- a/c8/stm/hash_id.c
+++ b/c8/stm/hash_id.c
@@ -58,7 +58,7 @@
void stm_set_prebuilt_identityhash(object_t *obj, long hash)
{
struct object_s *realobj = (struct object_s *)
- REAL_ADDRESS(stm_object_pages, obj);
+ get_virtual_address(STM_SEGMENT->segment_num, obj);
assert(realobj->stm_flags == GCFLAG_WRITE_BARRIER);
realobj->stm_flags |= GCFLAG_HAS_SHADOW;
diff --git a/c8/stm/nursery.c b/c8/stm/nursery.c
--- a/c8/stm/nursery.c
+++ b/c8/stm/nursery.c
@@ -93,7 +93,7 @@
realobj = REAL_ADDRESS(STM_SEGMENT->segment_base, obj);
size = stmcb_size_rounded_up((struct object_s *)realobj);
- if (true || 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. */
nobj = (object_t *)allocate_outside_nursery_large(size);
diff --git a/c8/stm/pages.h b/c8/stm/pages.h
--- a/c8/stm/pages.h
+++ b/c8/stm/pages.h
@@ -52,7 +52,7 @@
static inline char *get_virtual_address(long segnum, object_t *obj)
{
- return get_segment_base(segnum) + (uintptr_t)obj;
+ return REAL_ADDRESS(get_segment_base(segnum), obj);
}
static inline bool get_page_status_in(long segnum, uintptr_t pagenum)
diff --git a/c8/stm/prebuilt.c b/c8/stm/prebuilt.c
--- a/c8/stm/prebuilt.c
+++ b/c8/stm/prebuilt.c
@@ -32,7 +32,7 @@
object_t *nobj = _stm_allocate_old(size + sizeof(long));
/* Copy the object */
- char *realnobj = REAL_ADDRESS(stm_object_pages, nobj);
+ char *realnobj = get_virtual_address(STM_SEGMENT->segment_num, nobj);
memcpy(realnobj, (char *)objaddr, size);
/* Fix the flags in the copied object, asserting that it was zero so far */
diff --git a/c8/stm/smallmalloc.c b/c8/stm/smallmalloc.c
--- a/c8/stm/smallmalloc.c
+++ b/c8/stm/smallmalloc.c
@@ -67,11 +67,14 @@
/* if (!_stm_largemalloc_resize_arena(uninitialized_page_stop - base)) */
/* goto out_of_memory; */
- setup_N_pages(uninitialized_page_stop, GCPAGE_NUM_PAGES);
char *p = uninitialized_page_stop;
long i;
for (i = 0; i < GCPAGE_NUM_PAGES; i++) {
+ /* accessible in seg0: */
+ page_mark_accessible(0, (p - stm_object_pages) / 4096UL);
+
+ /* add to free_uniform_pages list */
((struct small_free_loc_s *)p)->nextpage = free_uniform_pages;
free_uniform_pages = (struct small_free_loc_s *)p;
p += 4096;
@@ -120,6 +123,10 @@
smallpage->nextpage)))
goto retry;
+ /* make page accessible in our segment too: */
+ page_mark_accessible(STM_SEGMENT->segment_num,
+ ((char*)smallpage - stm_object_pages) / 4096UL);
+
/* Succeeded: we have a page in 'smallpage', which is not
initialized so far, apart from the 'nextpage' field read
above. Initialize it.
@@ -174,9 +181,9 @@
object_t *_stm_allocate_old_small(ssize_t size_rounded_up)
{
stm_char *p = allocate_outside_nursery_small(size_rounded_up);
- memset(stm_object_pages + (uintptr_t)p, 0, size_rounded_up);
+ object_t *o = (object_t *)p;
- object_t *o = (object_t *)p;
+ memset(get_virtual_address(STM_SEGMENT->segment_num, o), 0, size_rounded_up);
o->stm_flags = GCFLAG_WRITE_BARRIER;
dprintf(("allocate_old_small(%lu): %p, seg=%d, page=%lu\n",
@@ -244,6 +251,17 @@
}
else if (!_smallmalloc_sweep_keep(p)) {
/* the location should be freed now */
+ //dprintf(("free small obj %p\n", (object_t*)(p - stm_object_pages)));
+#ifdef STM_TESTS
+ /* fill location with 0xdd in all segs except seg0 */
+ int j;
+ object_t *obj = (object_t*)(p - stm_object_pages);
+ uintptr_t page = (baseptr - stm_object_pages) / 4096UL;
+ for (j = 1; j < NB_SEGMENTS; j++)
+ if (get_page_status_in(j, page) == PAGE_ACCESSIBLE)
+ memset(get_virtual_address(j, obj), 0xdd, szword*8);
+#endif
+
if (flprev == NULL) {
flprev = (struct small_free_loc_s *)p;
flprev->next = fl;
@@ -262,6 +280,14 @@
}
}
if (!any_object_remaining) {
+ /* give page back to free_uniform_pages and thus make it
+ inaccessible from all other segments again (except seg0) */
+ uintptr_t page = (baseptr - stm_object_pages) / 4096UL;
+ for (i = 1; i < NB_SEGMENTS; i++) {
+ if (get_page_status_in(i, page) == PAGE_ACCESSIBLE)
+ page_mark_inaccessible(i, page);
+ }
+
((struct small_free_loc_s *)baseptr)->nextpage = free_uniform_pages;
free_uniform_pages = (struct small_free_loc_s *)baseptr;
}
diff --git a/c8/test/test_smallmalloc.py b/c8/test/test_smallmalloc.py
--- a/c8/test/test_smallmalloc.py
+++ b/c8/test/test_smallmalloc.py
@@ -42,27 +42,37 @@
def test_sweep_freeing_simple(self):
p1 = stm_allocate_old_small(16)
+ self.has_been_asked_for = []
lib._stm_smallmalloc_sweep()
+ assert p1 in self.has_been_asked_for
def test_sweep_freeing_random_subset(self):
for i in range(50):
+ # allocate a page's worth of objs
page0 = [stm_allocate_old_small(16) for i in range(0, 4096, 16)]
- assert len(set(map(pageof, page0))) == 1
- tid = lib._get_type_id(page0[0])
+ assert len(set(map(pageof, page0))) == 1, "all in the same page"
+ tid = lib._get_type_id(page0[0]) # 58
+
+ # repeatedly free a subset until no objs are left in that page
while len(page0) > 0:
+ # keep half of them around
self.keep_me = set(random.sample(page0, len(page0) // 2))
self.has_been_asked_for = []
lib._stm_smallmalloc_sweep()
- assert sorted(page0) == self.has_been_asked_for
- page0r = []
+ assert sorted(page0) == self.has_been_asked_for, "all objs were observed"
+
+ # get list of objs that were not freed
+ page0remaining = []
for p in page0:
if p in self.keep_me:
assert lib._get_type_id(p) == tid
- page0r.append(p)
- else:
- assert lib._get_type_id(p) != tid
- page0 = page0r
+ page0remaining.append(p)
+ elif len(self.keep_me) > 0: # otherwise page not accessible from seg1
+ assert lib._get_type_id(p) != tid, "should have garbage there now (0xdd)"
+ page0 = page0remaining
+
if len(page0) > 10:
+ # allocate one obj for noise if we do another iteration anyway
p = stm_allocate_old_small(16)
assert pageof(p) == pageof(page0[0])
page0.append(p)
More information about the pypy-commit
mailing list