[pypy-commit] stmgc c7: allocate big objects directly outside of the nursery
Remi Meier
noreply at buildbot.pypy.org
Thu Jan 30 16:00:03 CET 2014
Author: Remi Meier
Branch: c7
Changeset: r693:5a99e1398932
Date: 2014-01-30 16:00 +0100
http://bitbucket.org/pypy/stmgc/changeset/5a99e1398932/
Log: allocate big objects directly outside of the nursery
diff --git a/c7/core.h b/c7/core.h
--- a/c7/core.h
+++ b/c7/core.h
@@ -13,6 +13,9 @@
#define NB_NURSERY_PAGES 1024 // 4MB
#define LENGTH_SHADOW_STACK 163840
+#define NURSERY_SECTION (32*4096)
+/* (NB_NURSERY_PAGE * 4096) % NURSERY_SECTION == 0 */
+
#define TOTAL_MEMORY (NB_PAGES * 4096UL * NB_THREADS)
#define READMARKER_END ((NB_PAGES * 4096UL) >> 4)
diff --git a/c7/nursery.c b/c7/nursery.c
--- a/c7/nursery.c
+++ b/c7/nursery.c
@@ -193,24 +193,48 @@
object_t *stm_allocate(size_t size)
{
+ object_t *result;
+
_stm_start_safe_point(LOCK_COLLECT);
/* all collections may happen here */
_stm_stop_safe_point(LOCK_COLLECT);
assert(_STM_TL->active);
assert(size % 8 == 0);
- assert(16 <= size && size < NB_NURSERY_PAGES * 4096);//XXX
+ assert(16 <= size);
+ /* XXX move out of fastpath */
+ if (size >= NURSERY_SECTION) {
+ /* allocate large objects outside the nursery immediately,
+ otherwise they may trigger too many minor collections
+ and degrade performance */
+ bool is_small;
+ result = stm_big_small_alloc_old(size, &is_small);
+
+ memset((void*)real_address(result), 0, size);
+
+ /* object is not committed yet */
+ result->stm_flags |= GCFLAG_NOT_COMMITTED;
+ if (is_small) /* means, not allocated by large-malloc */
+ result->stm_flags |= GCFLAG_SMALL;
+ assert(size == _stm_data_size((struct object_s*)REAL_ADDRESS(get_thread_base(0), result)));
+
+ LIST_APPEND(_STM_TL->uncommitted_objects, result);
+ LIST_APPEND(_STM_TL->old_objects_to_trace, result);
+ return result;
+ }
+
localchar_t *current = _STM_TL->nursery_current;
localchar_t *new_current = current + size;
_STM_TL->nursery_current = new_current;
assert((uintptr_t)new_current < (1L << 32));
+
if ((uintptr_t)new_current > FIRST_AFTER_NURSERY_PAGE * 4096) {
_STM_TL->nursery_current = current; /* reset for nursery-clearing in minor_collect!! */
current = collect_and_reserve(size);
}
- object_t *result = (object_t *)current;
+ result = (object_t *)current;
return result;
}
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -36,6 +36,9 @@
typedef ... jmpbufptr_t;
#define SIZEOF_MYOBJ ...
+#define NB_NURSERY_PAGES ...
+#define NURSERY_SECTION ...
+
void stm_setup(void);
void stm_setup_thread(void);
@@ -244,13 +247,13 @@
size_t stmcb_size(struct object_s *obj)
{
struct myobj_s *myobj = (struct myobj_s*)obj;
- if (myobj->type_id < 42142) {
+ if (myobj->type_id < 421420) {
/* basic case: tid equals 42 plus the size of the object */
assert(myobj->type_id >= 42 + sizeof(struct myobj_s));
return myobj->type_id - 42;
}
else {
- int nrefs = myobj->type_id - 42142;
+ int nrefs = myobj->type_id - 421420;
assert(nrefs < 100);
if (nrefs == 0) /* weakrefs */
nrefs = 1;
@@ -262,11 +265,11 @@
{
int i;
struct myobj_s *myobj = (struct myobj_s*)obj;
- if (myobj->type_id < 42142) {
+ if (myobj->type_id < 421420) {
/* basic case: no references */
return;
}
- for (i=0; i < myobj->type_id - 42142; i++) {
+ for (i=0; i < myobj->type_id - 421420; i++) {
object_t **ref = ((object_t **)(myobj + 1)) + i;
visit(ref);
}
@@ -308,7 +311,7 @@
def stm_allocate_refs(n):
o = lib.stm_allocate(HDR + n * WORD)
- tid = 42142 + n
+ tid = 421420 + n
lib._set_type_id(o, tid)
return o
diff --git a/c7/test/test_basic.py b/c7/test/test_basic.py
--- a/c7/test/test_basic.py
+++ b/c7/test/test_basic.py
@@ -312,9 +312,8 @@
assert stm_get_char(lp1) == 'a'
def test_many_allocs(self):
- # assumes NB_NURSERY_PAGES 1024
obj_size = 1024
- num = 9000 # more than what fits in the nursery (4MB)
+ num = (lib.NB_NURSERY_PAGES * 4096) / obj_size + 100 # more than what fits in the nursery
stm_start_transaction()
for i in range(num):
@@ -333,6 +332,14 @@
assert old
assert young
+ def test_larger_than_section(self):
+ obj_size = lib.NURSERY_SECTION + 16
+
+ stm_start_transaction()
+ new = stm_allocate(obj_size)
+ assert not is_in_nursery(new)
+
+
def test_large_obj_alloc(self):
# test obj which doesn't fit into the size_classes
# for now, we will still allocate it in the nursery.
More information about the pypy-commit
mailing list