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

Reply via email to