about summary refs log tree commit homepage
path: root/ext/mwrap/mwrap.c
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2022-08-20 21:35:22 +0000
committerEric Wong <mwrap-public@80x24.org>2022-08-22 17:11:39 +0000
commit7ec73b9ccdeaed30e813884f7765281be422bc21 (patch)
tree537eff656a6d8b0cc3bcb1dc6ec1582891270849 /ext/mwrap/mwrap.c
parenta90e237d93256ded3088c83520683fc5835da72d (diff)
downloadmwrap-7ec73b9ccdeaed30e813884f7765281be422bc21.tar.gz
HEAP_PAGE_SIZE no longer estimates malloc overhead in Ruby 3.0.x,
but we can now rely on the GC::INTERNAL_CONSTANTS hash to access
the true value.

We also need to account for Ractors in 3.0+, and thus we need to
rely on thread-specific `ruby_current_ec' instead of process-wide
`ruby_current_execution_context_ptr' (which no longer exists in
3.0+).

Finally, the VM seems prone to making some small immortal
allocations in a few places we were not expecting in 2.7 and
earlier.  Account for that and loosen some exact checks to
account for it.

Tested on Ruby 3.0.3 and 3.0.4
Diffstat (limited to 'ext/mwrap/mwrap.c')
-rw-r--r--ext/mwrap/mwrap.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/ext/mwrap/mwrap.c b/ext/mwrap/mwrap.c
index 8592ea7..cd68eed 100644
--- a/ext/mwrap/mwrap.c
+++ b/ext/mwrap/mwrap.c
@@ -3,7 +3,7 @@
  * License: GPL-2.0+ <https://www.gnu.org/licenses/gpl-2.0.txt>
  */
 #define _LGPL_SOURCE /* allows URCU to inline some stuff */
-#include <ruby/ruby.h>
+#include <ruby.h> /* defines HAVE_RUBY_RACTOR_H on 3.0+ */
 #include <ruby/thread.h>
 #include <ruby/io.h>
 #include <execinfo.h>
@@ -22,10 +22,24 @@
 #include <urcu/rculist.h>
 #include "jhash.h"
 
+#if __STDC_VERSION__ >= 201112
+#        define MWRAP_TSD _Thread_local
+#elif defined(__GNUC__)
+#        define MWRAP_TSD __thread
+#else
+#        error _Thread_local nor __thread supported
+#endif
+
 static ID id_uminus;
 const char *rb_source_location_cstr(int *line); /* requires 2.6.0dev */
 extern int __attribute__((weak)) ruby_thread_has_gvl_p(void);
+
+#ifdef HAVE_RUBY_RACTOR_H /* Ruby 3.0+ */
+extern MWRAP_TSD void * __attribute__((weak)) ruby_current_ec;
+#else /* Ruby 2.6-2.7 */
 extern void * __attribute__((weak)) ruby_current_execution_context_ptr;
+#        define ruby_current_ec ruby_current_execution_context_ptr
+#endif
 extern void * __attribute__((weak)) ruby_current_vm_ptr; /* for rb_gc_count */
 extern size_t __attribute__((weak)) rb_gc_count(void);
 extern VALUE __attribute__((weak)) rb_cObject;
@@ -40,9 +54,12 @@ static size_t total_bytes_inc, total_bytes_dec;
 /* match values in Ruby gc.c */
 #define HEAP_PAGE_ALIGN_LOG 14
 enum {
-        HEAP_PAGE_ALIGN = (1UL << HEAP_PAGE_ALIGN_LOG),
+        HEAP_PAGE_ALIGN = (1UL << HEAP_PAGE_ALIGN_LOG)
+#ifndef HEAP_PAGE_SIZE /* Ruby 2.6-2.7 only */
+        ,
         REQUIRED_SIZE_BY_MALLOC = (sizeof(size_t) * 5),
         HEAP_PAGE_SIZE = (HEAP_PAGE_ALIGN - REQUIRED_SIZE_BY_MALLOC)
+#endif
 };
 
 #define IS_HEAP_PAGE_BODY ((struct src_loc *)-1)
@@ -75,7 +92,7 @@ static int resolving_malloc;
         } \
 } while (0)
 
-static __thread size_t locating;
+static MWRAP_TSD size_t locating;
 static size_t generation;
 static size_t page_size;
 static struct cds_lfht *totals;
@@ -214,7 +231,7 @@ static char *int2str(int num, char *dst, size_t * size)
 static int has_ec_p(void)
 {
         return (ruby_thread_has_gvl_p() && ruby_current_vm_ptr &&
-                ruby_current_execution_context_ptr);
+                ruby_current_ec);
 }
 
 struct acc {