Author: Remi Meier
Branch: c7
Changeset: r654:0e22a7939f9e
Date: 2014-01-21 10:08 +0100
http://bitbucket.org/pypy/stmgc/changeset/0e22a7939f9e/
Log: allocation of large objs < nursery_size
diff --git a/c7/core.c b/c7/core.c
--- a/c7/core.c
+++ b/c7/core.c
@@ -19,7 +19,7 @@
#define NB_PAGES (256*256) // 256MB
#define NB_THREADS 2
#define MAP_PAGES_FLAGS (MAP_SHARED | MAP_ANONYMOUS | MAP_NORESERVE)
-#define LARGE_OBJECT_WORDS 232 // XXX was 36
+#define LARGE_OBJECT_WORDS 36
#define NB_NURSERY_PAGES 1024
#define LENGTH_SHADOW_STACK 163840
@@ -91,7 +91,7 @@
static uint8_t write_locks[READMARKER_END - READMARKER_START];
/************************************************************/
-uintptr_t _stm_reserve_page(void);
+uintptr_t _stm_reserve_pages(int num);
void stm_abort_transaction(void);
localchar_t *_stm_alloc_next_page(size_t i);
void mark_page_as_uncommitted(uintptr_t pagenum);
@@ -212,8 +212,9 @@
object_t *_stm_allocate_old(size_t size)
{
- assert(size <= 4096);
- localchar_t* addr = (localchar_t*)(_stm_reserve_page() * 4096);
+ int pages = (size + 4095) / 4096;
+ localchar_t* addr = (localchar_t*)(_stm_reserve_pages(pages) * 4096);
+
object_t* o = (object_t*)addr;
o->stm_flags |= GCFLAG_WRITE_BARRIER;
return o;
@@ -400,16 +401,21 @@
}
-uintptr_t _stm_reserve_page(void)
+uintptr_t _stm_reserve_pages(int num)
{
/* Grab a free page, initially shared between the threads. */
// XXX look in some free list first
/* Return the index'th object page, which is so far never used. */
- uintptr_t index = __sync_fetch_and_add(&index_page_never_used, 1);
+ uintptr_t index = __sync_fetch_and_add(&index_page_never_used, num);
+
+ int i;
+ for (i = 0; i < num; i++) {
+ assert(flag_page_private[index+i] == SHARED_PAGE);
+ }
assert(flag_page_private[index] == SHARED_PAGE);
- if (index >= NB_PAGES) {
+ if (index + num >= NB_PAGES) {
fprintf(stderr, "Out of mmap'ed memory!\n");
abort();
}
@@ -425,17 +431,23 @@
localchar_t *_stm_alloc_old(size_t size)
{
+ localchar_t *result;
size_t size_class = size / 8;
- alloc_for_size_t *alloc = &_STM_TL2->alloc[size_class];
- localchar_t *result;
+ assert(size_class >= 2);
- if ((uint16_t)((uintptr_t)alloc->next) == alloc->stop)
- result = _stm_alloc_next_page(size_class);
- else {
- result = alloc->next;
- alloc->next += size;
+ if (size_class >= LARGE_OBJECT_WORDS) {
+ result = (localchar_t*)_stm_allocate_old(size);
+ ((object_t*)result)->stm_flags &= ~GCFLAG_WRITE_BARRIER; /* added by
_stm_allocate_old... */
+ } else {
+ alloc_for_size_t *alloc = &_STM_TL2->alloc[size_class];
+
+ if ((uint16_t)((uintptr_t)alloc->next) == alloc->stop)
+ result = _stm_alloc_next_page(size_class);
+ else {
+ result = alloc->next;
+ alloc->next += size;
+ }
}
-
return result;
}
@@ -470,7 +482,7 @@
/* } */
/* reserve a fresh new page */
- page = _stm_reserve_page();
+ page = _stm_reserve_pages(1);
/* mark as UNCOMMITTED_... */
mark_page_as_uncommitted(page);
@@ -557,6 +569,11 @@
_STM_TL2->nursery_current = nursery_base;
}
+void _stm_minor_collect()
+{
+ minor_collect();
+}
+
localchar_t *collect_and_reserve(size_t size)
{
_stm_start_safe_point();
@@ -574,9 +591,7 @@
_stm_stop_safe_point();
assert(_STM_TL2->running_transaction);
assert(size % 8 == 0);
- size_t i = size / 8;
- assert(2 <= i && i < LARGE_OBJECT_WORDS);//XXX
- assert(2 <= i && i < NB_NURSERY_PAGES * 4096);//XXX
+ assert(16 <= size && size < NB_NURSERY_PAGES * 4096);//XXX
localchar_t *current = _STM_TL2->nursery_current;
localchar_t *new_current = current + size;
diff --git a/c7/core.h b/c7/core.h
--- a/c7/core.h
+++ b/c7/core.h
@@ -125,6 +125,8 @@
void stm_abort_transaction(void);
+void _stm_minor_collect();
+
#define stm_become_inevitable(msg) /* XXX implement me! */
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -66,6 +66,7 @@
void _set_ptr(object_t *obj, int n, object_t *v);
object_t * _get_ptr(object_t *obj, int n);
+void _stm_minor_collect();
bool _stm_check_abort_transaction(void);
@@ -302,6 +303,9 @@
if lib._stm_check_stop_safe_point():
raise Conflict()
+def stm_minor_collect():
+ lib._stm_minor_collect()
+
class BaseTest(object):
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
@@ -332,7 +332,26 @@
assert old
assert young
-
+
+ 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.
+ # expects: LARGE_OBJECT_WORDS 36
+ size_class = 1000 # too big
+ obj_size = size_class * 8
+ assert obj_size > 4096 # we want more than 1 page
+ assert obj_size < 4096 * 1024 # in the nursery
+
+ stm_start_transaction()
+ new = stm_allocate(obj_size)
+ assert is_in_nursery(new)
+ stm_push_root(new)
+ stm_minor_collect()
+ stm_minor_collect()
+ new = stm_pop_root()
+
+ assert not is_in_nursery(new)
+
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit