diff options
author | Aaron Patterson <[email protected]> | 2020-11-24 14:33:12 -0800 |
---|---|---|
committer | Aaron Patterson <[email protected]> | 2020-11-24 14:48:19 -0800 |
commit | 63ad55cd882e4010fe313d271af006a430b5ffa8 (patch) | |
tree | 734e2ed201a55a075f4f80c6cb2a3a7d0b9ed903 /gc.c | |
parent | 87d21ee996869cecdcd2afa25553654af847fe39 (diff) |
Disable auto compaction on platforms that can't support it
Auto Compaction uses mprotect to implement a read barrier. mprotect can
only work on regions of memory that are a multiple of the OS page size.
Ruby's pages are a multiple of 4kb, but some platforms (like ppc64le)
don't have 4kb page sizes. This commit disables the features on those
platforms.
Fixes [Bug #17306]
Diffstat (limited to 'gc.c')
-rw-r--r-- | gc.c | 21 |
1 files changed, 21 insertions, 0 deletions
@@ -3090,6 +3090,17 @@ Init_heap(void) { rb_objspace_t *objspace = &rb_objspace; +#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE) + /* If Ruby's heap pages are not a multiple of the system page size, we + * cannot use mprotect for the read barrier, so we must disable automatic + * compaction. */ + int pagesize; + pagesize = (int)sysconf(_SC_PAGE_SIZE); + if ((HEAP_PAGE_SIZE % pagesize) != 0) { + ruby_enable_autocompact = 0; + } +#endif + objspace->next_object_id = INT2FIX(OBJ_ID_INITIAL); objspace->id_to_obj_tbl = st_init_table(&object_id_hash_type); objspace->obj_to_id_tbl = st_init_numtable(); @@ -9890,6 +9901,16 @@ gc_disable(rb_execution_context_t *ec, VALUE _) static VALUE gc_set_auto_compact(rb_execution_context_t *ec, VALUE _, VALUE v) { +#if defined(HAVE_SYSCONF) && defined(_SC_PAGE_SIZE) + /* If Ruby's heap pages are not a multiple of the system page size, we + * cannot use mprotect for the read barrier, so we must disable automatic + * compaction. */ + int pagesize; + pagesize = (int)sysconf(_SC_PAGE_SIZE); + if ((HEAP_PAGE_SIZE % pagesize) != 0) { + rb_raise(rb_eNotImpError, "Automatic compaction isn't available on this platform"); + } +#endif ruby_enable_autocompact = RTEST(v); return v; } |