[pypy-commit] stmgc default: Keep track of how much memory we're using
arigo
noreply at buildbot.pypy.org
Thu Feb 27 17:34:14 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r894:7bd32f8dc1e8
Date: 2014-02-27 17:34 +0100
http://bitbucket.org/pypy/stmgc/changeset/7bd32f8dc1e8/
Log: Keep track of how much memory we're using
diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c
--- a/c7/stm/gcpage.c
+++ b/c7/stm/gcpage.c
@@ -76,6 +76,7 @@
char *addr = _stm_large_malloc(size);
if (addr == NULL)
stm_fatalerror("not enough memory!\n");
+ increment_total_allocated(size + LARGE_MALLOC_OVERHEAD);
if (addr + size > uninitialized_page_start) {
uintptr_t npages;
diff --git a/c7/stm/largemalloc.h b/c7/stm/largemalloc.h
--- a/c7/stm/largemalloc.h
+++ b/c7/stm/largemalloc.h
@@ -12,3 +12,6 @@
void _stm_large_free(char *data);
void _stm_large_dump(void);
+
+
+#define LARGE_MALLOC_OVERHEAD (2 * sizeof(size_t)) /* estimate */
diff --git a/c7/stm/misc.c b/c7/stm/misc.c
--- a/c7/stm/misc.c
+++ b/c7/stm/misc.c
@@ -71,4 +71,12 @@
return (object_t *)list_item(
STM_PSEGMENT->objects_pointing_to_nursery, index);
}
+
+uint64_t _stm_total_allocated(void)
+{
+ mutex_pages_lock();
+ uint64_t result = increment_total_allocated(0);
+ mutex_pages_unlock();
+ return result;
+}
#endif
diff --git a/c7/stm/nursery.c b/c7/stm/nursery.c
--- a/c7/stm/nursery.c
+++ b/c7/stm/nursery.c
@@ -213,10 +213,14 @@
bool locked = false;
wlog_t *item;
TREE_LOOP_FORWARD(*STM_PSEGMENT->young_outside_nursery, item) {
+ assert(!_is_in_nursery((object_t *)item->addr));
if (!locked) {
mutex_pages_lock();
locked = true;
}
+ char *realobj = REAL_ADDRESS(STM_SEGMENT->segment_base,item->addr);
+ ssize_t size = stmcb_size_rounded_up((struct object_s *)realobj);
+ increment_total_allocated(-(size + LARGE_MALLOC_OVERHEAD));
_stm_large_free(stm_object_pages + item->addr);
} TREE_LOOP_END;
diff --git a/c7/stm/pages.c b/c7/stm/pages.c
--- a/c7/stm/pages.c
+++ b/c7/stm/pages.c
@@ -6,10 +6,19 @@
/************************************************************/
static union {
- uint8_t mutex_pages;
+ struct {
+ uint8_t mutex_pages;
+ uint64_t total_allocated; /* keep track of how much memory we're
+ using, ignoring nurseries */
+ };
char reserved[64];
} pages_ctl __attribute__((aligned(64)));
+static void teardown_pages(void)
+{
+ memset(&pages_ctl, 0, sizeof(pages_ctl));
+}
+
static void mutex_pages_lock(void)
{
while (__sync_lock_test_and_set(&pages_ctl.mutex_pages, 1) != 0) {
@@ -28,6 +37,13 @@
return pages_ctl.mutex_pages != 0;
}
+static uint64_t increment_total_allocated(ssize_t add_or_remove)
+{
+ assert(_has_mutex_pages());
+ pages_ctl.total_allocated += add_or_remove;
+ return pages_ctl.total_allocated;
+}
+
/************************************************************/
@@ -108,6 +124,7 @@
}
write_fence();
memset(flag_page_private + pagenum, PRIVATE_PAGE, count);
+ increment_total_allocated(4096 * count);
}
static void _pages_privatize(uintptr_t pagenum, uintptr_t count, bool full)
diff --git a/c7/stm/pages.h b/c7/stm/pages.h
--- a/c7/stm/pages.h
+++ b/c7/stm/pages.h
@@ -23,6 +23,7 @@
static void mutex_pages_lock(void);
static void mutex_pages_unlock(void);
+static uint64_t increment_total_allocated(ssize_t add_or_remove);
inline static void pages_privatize(uintptr_t pagenum, uintptr_t count,
bool full) {
diff --git a/c7/stm/setup.c b/c7/stm/setup.c
--- a/c7/stm/setup.c
+++ b/c7/stm/setup.c
@@ -101,6 +101,7 @@
teardown_sync();
teardown_gcpage();
teardown_nursery();
+ teardown_pages();
}
void _init_shadow_stack(stm_thread_local_t *tl)
diff --git a/c7/stmgc.h b/c7/stmgc.h
--- a/c7/stmgc.h
+++ b/c7/stmgc.h
@@ -92,6 +92,7 @@
long _stm_count_objects_pointing_to_nursery(void);
object_t *_stm_enum_modified_old_objects(long index);
object_t *_stm_enum_objects_pointing_to_nursery(long index);
+uint64_t _stm_total_allocated(void);
#endif
#define _STM_GCFLAG_WRITE_BARRIER 0x01
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -70,6 +70,7 @@
object_t *_stm_enum_objects_pointing_to_nursery(long index);
void stm_collect(long level);
+uint64_t _stm_total_allocated(void);
""")
@@ -215,7 +216,7 @@
}
else {
int nrefs = myobj->type_id - 421420;
- assert(nrefs < 100);
+ assert(nrefs < 10000); /* artificial limit, to check for garbage */
if (nrefs == 0) /* weakrefs */
nrefs = 1;
return sizeof(struct myobj_s) + nrefs * sizeof(void*);
diff --git a/c7/test/test_nursery.py b/c7/test/test_nursery.py
--- a/c7/test/test_nursery.py
+++ b/c7/test/test_nursery.py
@@ -85,13 +85,17 @@
obj_size = lib._STM_FAST_ALLOC + 16
self.start_transaction()
+ assert lib._stm_total_allocated() == 0
seen = set()
for i in range(10):
stm_minor_collect()
new = stm_allocate(obj_size)
assert not is_in_nursery(new)
+ assert lib._stm_total_allocated() == obj_size + 16
seen.add(new)
assert len(seen) < 5 # addresses are reused
+ stm_minor_collect()
+ assert lib._stm_total_allocated() == 0
def test_larger_than_limit_for_nursery_dont_die(self):
obj_nrefs = (lib._STM_FAST_ALLOC + 16) // 8
@@ -115,6 +119,19 @@
lp1 = stm_get_ref(lp1, i)
assert not lp1
+ def test_account_for_privatized_page(self):
+ self.start_transaction()
+ obj = stm_allocate(16)
+ self.push_root(obj)
+ self.commit_transaction()
+ obj = self.pop_root()
+ base = lib._stm_total_allocated()
+ assert base <= 4096
+
+ self.start_transaction()
+ stm_write(obj)
+ assert lib._stm_total_allocated() == base + 4096
+
def test_reset_partial_alloc_pages(self):
py.test.skip("a would-be-nice feature, but not actually needed: "
"the next major GC will take care of it")
More information about the pypy-commit
mailing list