Author: Remi Meier <[email protected]>
Branch: c8-private-pages
Changeset: r1541:6520222bf6c8
Date: 2015-01-19 10:27 +0100
http://bitbucket.org/pypy/stmgc/changeset/6520222bf6c8/
Log: sweep small objs too in major gc
diff --git a/c8/stm/gcpage.c b/c8/stm/gcpage.c
--- a/c8/stm/gcpage.c
+++ b/c8/stm/gcpage.c
@@ -410,6 +410,34 @@
_stm_largemalloc_sweep();
}
+static inline bool smallmalloc_keep_object_at(char *data)
+{
+ /* XXX: identical to largemalloc_keep_object_at()? */
+ /* this is called by _stm_smallmalloc_sweep() */
+ object_t *obj = (object_t *)(data - stm_object_pages);
+ dprintf(("keep small 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.
+ It is probably rare enough, but still, we want to avoid any
+ false conflict. (test_random hits it sometimes) */
+ long i;
+ for (i = 1; i < NB_SEGMENTS; i++) {
+ /* reset read marker */
+ *((char *)(get_segment_base(i) + (((uintptr_t)obj) >> 4))) = 0;
+ }
+ return false;
+ }
+ return true;
+}
+
+static void sweep_small_objects(void)
+{
+ _stm_smallmalloc_sweep();
+}
+
+
+
static void major_collection_now_at_safe_point(void)
{
dprintf(("\n"));
@@ -438,7 +466,7 @@
/* /\* sweeping *\/ */
sweep_large_objects();
- /* //sweep_uniform_pages(); */
+ sweep_small_objects();
dprintf((" | used after collection: %ld\n",
(long)pages_ctl.total_allocated));
diff --git a/c8/stm/gcpage.h b/c8/stm/gcpage.h
--- a/c8/stm/gcpage.h
+++ b/c8/stm/gcpage.h
@@ -21,3 +21,4 @@
static void major_collection_if_requested(void);
static void major_collection_now_at_safe_point(void);
static bool largemalloc_keep_object_at(char *data); /* for largemalloc.c */
+static bool smallmalloc_keep_object_at(char *data); /* for smallmalloc.c */
diff --git a/c8/stm/misc.c b/c8/stm/misc.c
--- a/c8/stm/misc.c
+++ b/c8/stm/misc.c
@@ -104,4 +104,13 @@
{
return increment_total_allocated(0);
}
+
+
+void _stm_smallmalloc_sweep_test()
+{
+ acquire_all_privatization_locks();
+ _stm_smallmalloc_sweep();
+ release_all_privatization_locks();
+}
+
#endif
diff --git a/c8/stm/smallmalloc.c b/c8/stm/smallmalloc.c
--- a/c8/stm/smallmalloc.c
+++ b/c8/stm/smallmalloc.c
@@ -22,7 +22,9 @@
static fpsz_t *get_fpsz(char *smallpage)
{
uintptr_t pagenum = (((char *)smallpage) - END_NURSERY_PAGE * 4096UL -
stm_object_pages) / 4096;
- assert(PAGE_SMSIZE_START <= pagenum && pagenum < PAGE_SMSIZE_END);
+ /* <= PAGE_SMSIZE_END because we may ask for it when there is no
+ page with smallobjs yet and uninit_page_stop == NB_PAGES... */
+ assert(PAGE_SMSIZE_START <= pagenum && pagenum <= PAGE_SMSIZE_END);
return &full_pages_object_size[pagenum - PAGE_SMSIZE_START];
}
@@ -162,6 +164,8 @@
struct small_free_loc_s *result = *fl;
+ increment_total_allocated(size);
+
if (UNLIKELY(result == NULL))
return (stm_char*)
(_allocate_small_slowpath(size) - stm_object_pages);
@@ -201,8 +205,7 @@
return _stm_smallmalloc_keep((char*)(p - stm_object_pages));
}
#endif
- return true;
- //return smallmalloc_keep_object_at(p);
+ return smallmalloc_keep_object_at(p);
}
void check_order_inside_small_page(struct small_free_loc_s *page)
@@ -248,6 +251,7 @@
}
else if (!_smallmalloc_sweep_keep(p)) {
/* the location should be freed now */
+ increment_total_allocated(-szword*8);
#ifdef STM_TESTS
/* fill location with 0xdd in all segs except seg0 */
int j;
@@ -301,7 +305,6 @@
void _stm_smallmalloc_sweep(void)
{
- acquire_all_privatization_locks(); /* should be done outside, but tests...
*/
long i, szword;
for (szword = 2; szword < GC_N_SMALL_REQUESTS; szword++) {
struct small_free_loc_s *page = small_page_lists[szword];
@@ -350,5 +353,4 @@
sweep_small_page(pageptr, NULL, sz);
}
}
- release_all_privatization_locks();
}
diff --git a/c8/stmgc.h b/c8/stmgc.h
--- a/c8/stmgc.h
+++ b/c8/stmgc.h
@@ -96,7 +96,7 @@
char *stm_file_pages;
object_t *_stm_allocate_old_small(ssize_t size_rounded_up);
bool (*_stm_smallmalloc_keep)(char *data);
-void _stm_smallmalloc_sweep(void);
+void _stm_smallmalloc_sweep_test(void);
void _stm_start_safe_point(void);
void _stm_stop_safe_point(void);
diff --git a/c8/test/support.py b/c8/test/support.py
--- a/c8/test/support.py
+++ b/c8/test/support.py
@@ -116,7 +116,7 @@
object_t *_stm_allocate_old_small(ssize_t size_rounded_up);
bool (*_stm_smallmalloc_keep)(char *data);
-void _stm_smallmalloc_sweep(void);
+void _stm_smallmalloc_sweep_test(void);
""")
@@ -291,7 +291,6 @@
}
}
-
''', sources=source_files,
define_macros=[('STM_TESTS', '1'),
('STM_NO_AUTOMATIC_SETJMP', '1'),
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
@@ -331,7 +331,8 @@
def test_small_major_collection(self):
self.start_transaction()
- new = stm_allocate(16)
+ new = stm_allocate(16) # small
+ assert lib._stm_total_allocated() == 0
self.push_root(new)
stm_minor_collect()
assert lib._stm_total_allocated() == 16
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
@@ -40,10 +40,13 @@
assert p == seen[0]
seen.pop(0)
+ def test_sweep_trivial(self):
+ lib._stm_smallmalloc_sweep_test()
+
def test_sweep_freeing_simple(self):
p1 = stm_allocate_old_small(16)
self.has_been_asked_for = []
- lib._stm_smallmalloc_sweep()
+ lib._stm_smallmalloc_sweep_test()
assert p1 in self.has_been_asked_for
def test_sweep_freeing_random_subset(self):
@@ -59,7 +62,7 @@
# keep half of them around
self.keep_me = set(random.sample(page0, len(page0) // 2))
self.has_been_asked_for = []
- lib._stm_smallmalloc_sweep()
+ lib._stm_smallmalloc_sweep_test()
print len(page0), len(self.has_been_asked_for)
assert sorted(page0) == self.has_been_asked_for, "all objs
were observed"
@@ -84,6 +87,6 @@
page0 = [stm_allocate_old_small(16) for i in range(0, 4096, 16)]
tid = lib._get_type_id(page0[0])
self.keep_me = set(page0)
- lib._stm_smallmalloc_sweep()
+ lib._stm_smallmalloc_sweep_test()
for p in page0:
assert lib._get_type_id(p) == tid
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit