[前][次][番号順一覧][スレッド一覧]

ruby-changes:65335

From: Peter <ko1@a...>
Date: Thu, 25 Feb 2021 05:25:48 +0900 (JST)
Subject: [ruby-changes:65335] 785f5eb8f0 (master): Use mmap for allocating heap pages

https://git.ruby-lang.org/ruby.git/commit/?id=785f5eb8f0

From 785f5eb8f0f994c755ac5f1e1479f6e2ec6d0ef3 Mon Sep 17 00:00:00 2001
From: Peter Zhu <peter@p...>
Date: Tue, 23 Feb 2021 16:28:56 -0500
Subject: Use mmap for allocating heap pages

---
 configure.ac |  3 +--
 gc.c         | 50 +++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/configure.ac b/configure.ac
index 41f2879..911ebdf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1931,7 +1931,6 @@ AC_CHECK_FUNCS(lutimes) https://github.com/ruby/ruby/blob/trunk/configure.ac#L1931
 AC_CHECK_FUNCS(malloc_usable_size)
 AC_CHECK_FUNCS(malloc_size)
 AC_CHECK_FUNCS(mblen)
-AC_CHECK_FUNCS(memalign)
 AC_CHECK_FUNCS(memset_s)
 AC_CHECK_FUNCS(writev)
 AC_CHECK_FUNCS(memrchr)
@@ -1939,11 +1938,11 @@ AC_CHECK_FUNCS(memmem) https://github.com/ruby/ruby/blob/trunk/configure.ac#L1938
 AC_CHECK_FUNCS(mkfifo)
 AC_CHECK_FUNCS(mknod)
 AC_CHECK_FUNCS(mktime)
+AC_CHECK_FUNCS(mmap)
 AC_CHECK_FUNCS(openat)
 AC_CHECK_FUNCS(pipe2)
 AC_CHECK_FUNCS(poll)
 AC_CHECK_FUNCS(posix_fadvise)
-AC_CHECK_FUNCS(posix_memalign)
 AC_CHECK_FUNCS(ppoll)
 AC_CHECK_FUNCS(pread)
 AC_CHECK_FUNCS(pwrite)
diff --git a/gc.c b/gc.c
index 8aad4b9..daffb8e 100644
--- a/gc.c
+++ b/gc.c
@@ -1765,14 +1765,14 @@ heap_unlink_page(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *pag https://github.com/ruby/ruby/blob/trunk/gc.c#L1765
     heap->total_slots -= page->total_slots;
 }
 
-static void rb_aligned_free(void *ptr);
+static void rb_aligned_free(void *ptr, size_t size);
 
 static void
 heap_page_free(rb_objspace_t *objspace, struct heap_page *page)
 {
     heap_allocated_pages--;
     objspace->profile.total_freed_pages++;
-    rb_aligned_free(GET_PAGE_BODY(page->start));
+    rb_aligned_free(GET_PAGE_BODY(page->start), HEAP_PAGE_SIZE);
     free(page);
 }
 
@@ -1824,7 +1824,7 @@ heap_page_allocate(rb_objspace_t *objspace) https://github.com/ruby/ruby/blob/trunk/gc.c#L1824
     /* assign heap_page entry */
     page = calloc1(sizeof(struct heap_page));
     if (page == 0) {
-        rb_aligned_free(page_body);
+        rb_aligned_free(page_body, HEAP_PAGE_SIZE);
 	rb_memerror();
     }
 
@@ -10382,15 +10382,36 @@ rb_aligned_malloc(size_t alignment, size_t size) https://github.com/ruby/ruby/blob/trunk/gc.c#L10382
 #elif defined _WIN32
     void *_aligned_malloc(size_t, size_t);
     res = _aligned_malloc(size, alignment);
-#elif defined(HAVE_POSIX_MEMALIGN)
-    if (posix_memalign(&res, alignment, size) == 0) {
-        return res;
-    }
-    else {
+#elif defined(HAVE_MMAP)
+    GC_ASSERT(alignment % sysconf(_SC_PAGE_SIZE) == 0);
+
+    char *ptr = mmap(NULL, alignment + size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+    if (ptr == MAP_FAILED) {
         return NULL;
     }
-#elif defined(HAVE_MEMALIGN)
-    res = memalign(alignment, size);
+
+    char *aligned = ptr + alignment;
+    aligned -= ((VALUE)aligned & (alignment - 1));
+    GC_ASSERT(aligned > ptr);
+    GC_ASSERT(aligned <= ptr + alignment);
+
+    size_t start_out_of_range_size = aligned - ptr;
+    GC_ASSERT(start_out_of_range_size % sysconf(_SC_PAGE_SIZE) == 0);
+    if (start_out_of_range_size > 0) {
+        if (munmap(ptr, start_out_of_range_size)) {
+            rb_bug("rb_aligned_malloc: munmap faile for start");
+        }
+    }
+
+    size_t end_out_of_range_size = alignment - start_out_of_range_size;
+    GC_ASSERT(end_out_of_range_size % sysconf(_SC_PAGE_SIZE) == 0);
+    if (end_out_of_range_size > 0) {
+        if (munmap(aligned + size, end_out_of_range_size)) {
+            rb_bug("rb_aligned_malloc: munmap failed for end");
+        }
+    }
+
+    res = (void *)aligned;
 #else
     char* aligned;
     res = malloc(alignment + size + sizeof(void*));
@@ -10407,14 +10428,17 @@ rb_aligned_malloc(size_t alignment, size_t size) https://github.com/ruby/ruby/blob/trunk/gc.c#L10428
 }
 
 static void
-rb_aligned_free(void *ptr)
+rb_aligned_free(void *ptr, size_t size)
 {
 #if defined __MINGW32__
     __mingw_aligned_free(ptr);
 #elif defined _WIN32
     _aligned_free(ptr);
-#elif defined(HAVE_MEMALIGN) || defined(HAVE_POSIX_MEMALIGN)
-    free(ptr);
+#elif defined HAVE_MMAP
+    GC_ASSERT(size % sysconf(_SC_PAGE_SIZE) == 0);
+    if (munmap(ptr, size)) {
+        rb_bug("rb_aligned_free: munmap failed");
+    }
 #else
     free(((void**)ptr)[-1]);
 #endif
-- 
cgit v1.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]