Bug #19267
closedCompile fails when enabling YJIT on x64-mingw-ucrt
Description
Ruby fails to compile with msys2/ucrt64 when enabling yjit.
Error:
In file included from ./include/ruby/defines.h:72,
from ./include/ruby/ruby.h:25,
from eval_intern.h:4,
from vm.c:13:
vm.c: In function 'mjit_check_iseq':
vm.c:393:12: warning: implicit declaration of function 'MJIT_FUNC_STATE_P' [-Wimplicit-function-declaration]
393 | ASSUME(MJIT_FUNC_STATE_P(mjit_state));
| ^~~~~~~~~~~~~~~~~
./include/ruby/backward/2/assume.h:43:46: note: in definition of macro 'RB_LIKELY'
43 | # define RB_LIKELY(x) (__builtin_expect(!!(x), 1))
| ^
./include/ruby/backward/2/assume.h:27:28: note: in expansion of macro 'RBIMPL_ASSUME'
27 | #define ASSUME RBIMPL_ASSUME /**< @old{RBIMPL_ASSUME} */
| ^~~~~~~~~~~~~
vm.c:393:5: note: in expansion of macro 'ASSUME'
393 | ASSUME(MJIT_FUNC_STATE_P(mjit_state));
| ^~~~~~
vm.c:394:19: error: conversion to incomplete type
394 | switch ((enum rb_mjit_func_state)mjit_state) {
| ^~~~~~~~~~~~~~~~~~
vm.c:395:12: error: 'MJIT_FUNC_NOT_COMPILED' undeclared (first use in this function)
395 | case MJIT_FUNC_NOT_COMPILED:
The problem:
In ruby-3.2.0.ext\include\x64-mingw-ucrt\ruby\config.h
#define USE_MJIT 0
#define USE_YJIT 1
But in mjit.h:
# if USE_MJIT
...
// Return true if jit_func is part of enum rb_mjit_func_state
#define MJIT_FUNC_STATE_P(jit_func) ((uintptr_t)(jit_func) <= (uintptr_t)MJIT_FUNC_FAILED)
...
# end
So MJIT_FUNC_STATE_P is never defined.
Then in vm.c:
#if USE_MJIT || USE_YJIT
# ifdef MJIT_HEADER
NOINLINE(static COLDFUNC VALUE mjit_check_iseq(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_iseq_constant_body *body));
# else
static inline VALUE mjit_check_iseq(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_iseq_constant_body *body);
# endif
static VALUE
mjit_check_iseq(rb_execution_context_t *ec, const rb_iseq_t *iseq, struct rb_iseq_constant_body *body)
{
uintptr_t mjit_state = (uintptr_t)(body->jit_func);
ASSUME(MJIT_FUNC_STATE_P(mjit_state));
etc
Note that MJIT_HEADER is not defined.
Note this is just the first of many errors that you will encounter.
To get Ruby 3.2.0 to compile, I had to do a significant rearrangement of mjit.h which I have attached.
However, when yjit.c then compiles:
yjit.c: In function 'rb_yjit_mark_unused':
yjit.c:93:5: warning: implicit declaration of function 'madvise'; did you mean 'raise'? [-Wimplicit-function-declaratio
]
93 | madvise(mem_block, mem_size, MADV_DONTNEED);
| ^~~~~~~
| raise
yjit.c:93:34: error: 'MADV_DONTNEED' undeclared (first use in this function)
93 | madvise(mem_block, mem_size, MADV_DONTNEED);
This is because the check in yjit.c (line 32) is:
// For mmapp(), sysconf()
#if defined _WIN32
#include <unistd.h>
#include <sys/mman.h>
#endif
UCRT doesn't define _WIN32, it defines _WIN64
However, then the next issue - there is no sys/mman.h header with mingw.
So enabling yjit on mingw breaks the compile and is apparently unsupported.
Files
Updated by k0kubun (Takashi Kokubun) almost 2 years ago
- Status changed from Open to Feedback
https://github.com/ruby/ruby/blob/master/doc/yjit/yjit.md
It currently only supports macOS and Linux on x86-64 and arm64/aarch64 CPUs.
I'm not sure if YJIT supports msys2/ucrt64. If you manually passed --enable-yjit
to ./configure
(./configure
does that automatically for supported platforms when rustc 1.58.0+ is available), you might want to stop doing so until the platform gets supported.
Updated by cfis (Charlie Savage) almost 2 years ago
Yes, I will disable yjit.