The current MJIT relies on SIGCHLD and fork(2) to be performant, and
it's something mswin can't offer. You could run Linux MJIT on WSL
instead.

[Misc #18968]
This commit is contained in:
Takashi Kokubun 2022-08-20 18:35:36 -07:00 коммит произвёл GitHub
Родитель e85db84959
Коммит ddf96b7693
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 13 добавлений и 465 удалений

334
mjit.c
Просмотреть файл

@ -98,14 +98,9 @@
#include "insns_info.inc"
#include "internal/compile.h"
#ifdef _WIN32
#include <winsock2.h>
#include <windows.h>
#else
#include <sys/wait.h>
#include <sys/time.h>
#include <dlfcn.h>
#endif
#include <errno.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
@ -122,34 +117,11 @@
# define MAXPATHLEN 1024
#endif
#ifdef _WIN32
#define dlopen(name,flag) ((void*)LoadLibrary(name))
#define dlerror() strerror(rb_w32_map_errno(GetLastError()))
#define dlsym(handle,name) ((void*)GetProcAddress((handle),(name)))
#define dlclose(handle) (!FreeLibrary(handle))
#define RTLD_NOW -1
#define waitpid(pid,stat_loc,options) (WaitForSingleObject((HANDLE)(pid), INFINITE), GetExitCodeProcess((HANDLE)(pid), (LPDWORD)(stat_loc)), CloseHandle((HANDLE)pid), (pid))
#define WIFEXITED(S) ((S) != STILL_ACTIVE)
#define WEXITSTATUS(S) (S)
#define WIFSIGNALED(S) (0)
typedef intptr_t pid_t;
#endif
// Atomically set function pointer if possible.
#define MJIT_ATOMIC_SET(var, val) (void)ATOMIC_PTR_EXCHANGE(var, val)
#define MJIT_TMP_PREFIX "_ruby_mjit_"
// JIT compaction requires the header transformation because linking multiple .o files
// doesn't work without having `static` in the same function definitions. We currently
// don't support transforming the MJIT header on Windows.
#ifdef _WIN32
# define USE_JIT_COMPACTION 0
#else
# define USE_JIT_COMPACTION 1
#endif
// Linked list of struct rb_mjit_unit.
struct rb_mjit_unit_list {
struct ccan_list_head head;
@ -237,15 +209,8 @@ static struct rb_mjit_unit *current_cc_unit = NULL;
// PID of currently running C compiler process. 0 if nothing is running.
static pid_t current_cc_pid = 0; // TODO: make this part of unit?
#ifndef _MSC_VER
// Name of the header file.
static char *header_file;
#endif
#ifdef _WIN32
// Linker option to enable libruby.
static char *libruby_pathflag;
#endif
#include "mjit_config.h"
@ -261,7 +226,7 @@ static char *libruby_pathflag;
// Use `-nodefaultlibs -nostdlib` for GCC where possible, which does not work on cygwin, AIX, and OpenBSD.
// This seems to improve MJIT performance on GCC.
#if defined __GNUC__ && !defined __clang__ && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(_AIX) && !defined(__OpenBSD__)
#if defined __GNUC__ && !defined __clang__ && !defined(__CYGWIN__) && !defined(_AIX) && !defined(__OpenBSD__)
# define GCC_NOSTDLIB_FLAGS "-nodefaultlibs", "-nostdlib",
#else
# define GCC_NOSTDLIB_FLAGS // empty
@ -286,7 +251,7 @@ static const char *const CC_LINKER_ARGS[] = {
};
static const char *const CC_LIBS[] = {
#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(__CYGWIN__)
MJIT_LIBS // mswin, cygwin
#endif
#if defined __GNUC__ && !defined __clang__
@ -371,22 +336,6 @@ remove_file(const char *filename)
}
}
// Lazily delete .so files.
static void
clean_temp_files(struct rb_mjit_unit *unit)
{
#if defined(_WIN32)
if (unit->so_file) {
char *so_file = unit->so_file;
unit->so_file = NULL;
// unit->so_file is set only when mjit_opts.save_temps is false.
remove_file(so_file);
free(so_file);
}
#endif
}
// This is called in the following situations:
// 1) On dequeue or `unload_units()`, associated ISeq is already GCed.
// 2) The unit is not called often and unloaded by `unload_units()`.
@ -409,7 +358,6 @@ free_unit(struct rb_mjit_unit *unit)
if (unit->handle && dlclose(unit->handle)) { // handle is NULL if it's in queue
mjit_warning("failed to close handle for u%d: %s", unit->id, dlerror());
}
clean_temp_files(unit);
free(unit);
}
@ -556,22 +504,6 @@ start_process(const char *abspath, char *const *argv)
}
pid_t pid;
#ifdef _WIN32
extern HANDLE rb_w32_start_process(const char *abspath, char *const *argv, int out_fd);
int out_fd = 0;
if (mjit_opts.verbose <= 1) {
// Discard cl.exe's outputs like:
// _ruby_mjit_p12u3.c
// Creating library C:.../_ruby_mjit_p12u3.lib and object C:.../_ruby_mjit_p12u3.exp
out_fd = dev_null;
}
pid = (pid_t)rb_w32_start_process(abspath, argv, out_fd);
if (pid == 0) {
verbose(1, "MJIT: Failed to create process: %s", dlerror());
return -1;
}
#else
if ((pid = vfork()) == 0) { /* TODO: reuse some function in process.c */
umask(0077);
if (mjit_opts.verbose == 0) {
@ -589,7 +521,6 @@ start_process(const char *abspath, char *const *argv)
verbose(1, "MJIT: Error in execv: %s", abspath);
_exit(1);
}
#endif
(void)close(dev_null);
return pid;
}
@ -629,14 +560,7 @@ exec_process(const char *path, char *const argv[])
static void
remove_so_file(const char *so_file, struct rb_mjit_unit *unit)
{
#if defined(_WIN32)
// Windows can't remove files while it's used.
unit->so_file = strdup(so_file); // lazily delete on `clean_temp_files()`
if (unit->so_file == NULL)
mjit_warning("failed to allocate memory to lazily remove '%s': %s", so_file, strerror(errno));
#else
remove_file(so_file);
#endif
}
// Print _mjitX, but make a human-readable funcname when --mjit-debug is used
@ -683,87 +607,6 @@ static const int c_file_access_mode =
#define append_str(p, str) append_str2(p, str, sizeof(str)-1)
#define append_lit(p, str) append_str2(p, str, rb_strlen_lit(str))
#ifdef _MSC_VER
// Compile C file to so. It returns true if it succeeds. (mswin)
static bool
compile_c_to_so(const char *c_file, const char *so_file)
{
const char *files[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, "-link", libruby_pathflag, NULL };
char *p;
// files[0] = "-Fe*.dll"
files[0] = p = alloca(sizeof(char) * (rb_strlen_lit("-Fe") + strlen(so_file) + 1));
p = append_lit(p, "-Fe");
p = append_str2(p, so_file, strlen(so_file));
*p = '\0';
// files[1] = "-Fo*.obj"
// We don't need .obj file, but it's somehow created to cwd without -Fo and we want to control the output directory.
files[1] = p = alloca(sizeof(char) * (rb_strlen_lit("-Fo") + strlen(so_file) - rb_strlen_lit(DLEXT) + rb_strlen_lit(".obj") + 1));
char *obj_file = p = append_lit(p, "-Fo");
p = append_str2(p, so_file, strlen(so_file) - rb_strlen_lit(DLEXT));
p = append_lit(p, ".obj");
*p = '\0';
// files[2] = "-Yu*.pch"
files[2] = p = alloca(sizeof(char) * (rb_strlen_lit("-Yu") + strlen(pch_file) + 1));
p = append_lit(p, "-Yu");
p = append_str2(p, pch_file, strlen(pch_file));
*p = '\0';
// files[3] = "C:/.../rb_mjit_header-*.obj"
files[3] = p = alloca(sizeof(char) * (strlen(pch_file) + 1));
p = append_str2(p, pch_file, strlen(pch_file) - strlen(".pch"));
p = append_lit(p, ".obj");
*p = '\0';
// files[4] = "-Tc*.c"
files[4] = p = alloca(sizeof(char) * (rb_strlen_lit("-Tc") + strlen(c_file) + 1));
p = append_lit(p, "-Tc");
p = append_str2(p, c_file, strlen(c_file));
*p = '\0';
// files[5] = "-Fd*.pdb"
// Generate .pdb file in temporary directory instead of cwd.
files[5] = p = alloca(sizeof(char) * (rb_strlen_lit("-Fd") + strlen(so_file) - rb_strlen_lit(DLEXT) + rb_strlen_lit(".pdb") + 1));
p = append_lit(p, "-Fd");
p = append_str2(p, so_file, strlen(so_file) - rb_strlen_lit(DLEXT));
p = append_lit(p, ".pdb");
*p = '\0';
// files[6] = "-Z7"
// Put this last to override any debug options that came previously.
files[6] = p = alloca(sizeof(char) * rb_strlen_lit("-Z7") + 1);
p = append_lit(p, "-Z7");
*p = '\0';
char **args = form_args(5, CC_LDSHARED_ARGS, CC_CODEFLAG_ARGS,
files, CC_LIBS, CC_DLDFLAGS_ARGS);
if (args == NULL)
return false;
int exit_code = exec_process(cc_path, args);
free(args);
if (exit_code == 0) {
// remove never-used files (.obj, .lib, .exp, .pdb). XXX: Is there any way not to generate this?
if (!mjit_opts.save_temps) {
char *before_dot;
remove_file(obj_file);
before_dot = obj_file + strlen(obj_file) - rb_strlen_lit(".obj");
append_lit(before_dot, ".lib"); remove_file(obj_file);
append_lit(before_dot, ".exp"); remove_file(obj_file);
append_lit(before_dot, ".pdb"); remove_file(obj_file);
}
}
else {
verbose(2, "compile_c_to_so: compile error: %d", exit_code);
}
return exit_code == 0;
}
#else // _MSC_VER
// The function producing the pre-compiled header.
static void
make_pch(void)
@ -805,9 +648,6 @@ compile_c_to_so(const char *c_file, const char *so_file)
{
const char *so_args[] = {
"-o", so_file,
# ifdef _WIN32
libruby_pathflag,
# endif
# ifdef __clang__
"-include-pch", pch_file,
# endif
@ -832,9 +672,7 @@ compile_c_to_so(const char *c_file, const char *so_file)
free(args);
return exit_code;
}
#endif // _MSC_VER
#if USE_JIT_COMPACTION
static void compile_prelude(FILE *f);
// Compile all JIT code into a single .c file
@ -961,7 +799,6 @@ load_compact_funcs_from_so(struct rb_mjit_unit *unit, char *c_file, char *so_fil
}
verbose(1, "JIT compaction (%.1fms): Compacted %d methods %s -> %s", end_time - current_cc_ms, active_units.length, c_file, so_file);
}
#endif // USE_JIT_COMPACTION
static void *
load_func_from_so(const char *so_file, const char *funcname, struct rb_mjit_unit *unit)
@ -1015,11 +852,6 @@ compile_prelude(FILE *f)
}
fprintf(f, "\"\n");
#endif
#ifdef _WIN32
fprintf(f, "void _pei386_runtime_relocator(void){}\n");
fprintf(f, "int __stdcall DllMainCRTStartup(void* hinstDLL, unsigned int fdwReason, void* lpvReserved) { return 1; }\n");
#endif
}
// Compile ISeq in UNIT and return function pointer of JIT-ed code.
@ -1093,77 +925,6 @@ start_mjit_compile(struct rb_mjit_unit *unit)
}
}
#ifdef _WIN32
// Compile ISeq in UNIT and return function pointer of JIT-ed code.
// It may return NOT_COMPILED_JIT_ISEQ_FUNC if something went wrong.
static mjit_func_t
convert_unit_to_func(struct rb_mjit_unit *unit)
{
static const char c_ext[] = ".c";
static const char so_ext[] = DLEXT;
char c_file[MAXPATHLEN], so_file[MAXPATHLEN], funcname[MAXPATHLEN];
sprint_uniq_filename(c_file, (int)sizeof(c_file), unit->id, MJIT_TMP_PREFIX, c_ext);
sprint_uniq_filename(so_file, (int)sizeof(so_file), unit->id, MJIT_TMP_PREFIX, so_ext);
sprint_funcname(funcname, unit);
FILE *f;
int fd = rb_cloexec_open(c_file, c_file_access_mode, 0600);
if (fd < 0 || (f = fdopen(fd, "w")) == NULL) {
int e = errno;
if (fd >= 0) (void)close(fd);
verbose(1, "Failed to fopen '%s', giving up JIT for it (%s)", c_file, strerror(e));
return (mjit_func_t)NOT_COMPILED_JIT_ISEQ_FUNC;
}
// print #include of MJIT header, etc.
compile_prelude(f);
// To make MJIT worker thread-safe against GC.compact, copy ISeq values while `in_jit` is true.
long iseq_lineno = 0;
if (FIXNUM_P(ISEQ_BODY(unit->iseq)->location.first_lineno))
// FIX2INT may fallback to rb_num2long(), which is a method call and dangerous in MJIT worker. So using only FIX2LONG.
iseq_lineno = FIX2LONG(ISEQ_BODY(unit->iseq)->location.first_lineno);
char *iseq_label = alloca(RSTRING_LEN(ISEQ_BODY(unit->iseq)->location.label) + 1);
char *iseq_path = alloca(RSTRING_LEN(rb_iseq_path(unit->iseq)) + 1);
strcpy(iseq_label, RSTRING_PTR(ISEQ_BODY(unit->iseq)->location.label));
strcpy(iseq_path, RSTRING_PTR(rb_iseq_path(unit->iseq)));
verbose(2, "start compilation: %s@%s:%ld -> %s", iseq_label, iseq_path, iseq_lineno, c_file);
fprintf(f, "/* %s@%s:%ld */\n\n", iseq_label, iseq_path, iseq_lineno);
bool success = mjit_compile(f, unit->iseq, funcname, unit->id);
fclose(f);
if (!success) {
if (!mjit_opts.save_temps)
remove_file(c_file);
verbose(1, "JIT failure: %s@%s:%ld -> %s", iseq_label, iseq_path, iseq_lineno, c_file);
return (mjit_func_t)NOT_COMPILED_JIT_ISEQ_FUNC;
}
double start_time = real_ms_time();
success = compile_c_to_so(c_file, so_file);
if (!mjit_opts.save_temps)
remove_file(c_file);
double end_time = real_ms_time();
if (!success) {
verbose(2, "Failed to generate so: %s", so_file);
return (mjit_func_t)NOT_COMPILED_JIT_ISEQ_FUNC;
}
void *func = load_func_from_so(so_file, funcname, unit);
if (!mjit_opts.save_temps)
remove_so_file(so_file, unit);
if ((uintptr_t)func > (uintptr_t)LAST_JIT_ISEQ_FUNC) {
verbose(1, "JIT success (%.1fms): %s@%s:%ld -> %s",
end_time - start_time, iseq_label, iseq_path, iseq_lineno, c_file);
}
return (mjit_func_t)func;
}
#endif
// Capture cc entries of `captured_iseq` and append them to `compiled_iseq->jit_unit->cc_entries`.
// This is needed when `captured_iseq` is inlined by `compiled_iseq` and GC needs to mark inlined cc.
//
@ -1412,7 +1173,6 @@ free_list(struct rb_mjit_unit_list *list, bool close_handle_p)
if (unit->handle && dlclose(unit->handle)) {
mjit_warning("failed to close handle for u%d: %s", unit->id, dlerror());
}
clean_temp_files(unit);
free(unit);
}
else {
@ -1510,15 +1270,6 @@ check_unit_queue(void)
struct rb_mjit_unit *unit = get_from_list(&unit_queue);
if (unit == NULL) return;
#ifdef _WIN32
// Synchronously compile methods on Windows.
// mswin: No SIGCHLD, MinGW: directly compiling .c to .so doesn't work
mjit_func_t func = convert_unit_to_func(unit);
MJIT_ATOMIC_SET(ISEQ_BODY(unit->iseq)->jit_func, func);
if ((uintptr_t)func > (uintptr_t)LAST_JIT_ISEQ_FUNC) {
add_to_list(unit, &active_units);
}
#else
current_cc_ms = real_ms_time();
current_cc_unit = unit;
current_cc_pid = start_mjit_compile(unit);
@ -1534,7 +1285,6 @@ check_unit_queue(void)
if (mjit_opts.wait) {
mjit_wait(unit->iseq->body);
}
#endif
}
// Create unit for `iseq`. This function may be called from an MJIT worker.
@ -1561,7 +1311,6 @@ create_unit(const rb_iseq_t *iseq)
static void
check_compaction(void)
{
#if USE_JIT_COMPACTION
// Allow only `max_cache_size / 100` times (default: 100) of compaction.
// Note: GC of compacted code has not been implemented yet.
int max_compact_size = mjit_opts.max_cache_size / 100;
@ -1583,7 +1332,6 @@ check_compaction(void)
// TODO: check -1
}
}
#endif
}
// Check the current CC process if any, and start a next C compiler process as needed.
@ -1616,12 +1364,8 @@ mjit_notify_waitpid(int status)
char so_file[MAXPATHLEN];
sprint_uniq_filename(so_file, (int)sizeof(so_file), current_cc_unit->id, MJIT_TMP_PREFIX, DLEXT);
if (current_cc_unit->compact_p) { // Compact unit
#if USE_JIT_COMPACTION
load_compact_funcs_from_so(current_cc_unit, c_file, so_file);
current_cc_unit = NULL;
#else
RUBY_ASSERT(!current_cc_unit->compact_p);
#endif
}
else { // Normal unit
// Load the function from so
@ -1833,16 +1577,6 @@ init_header_filename(void)
const char *basedir = "";
size_t baselen = 0;
char *p;
#ifdef _WIN32
static const char libpathflag[] =
# ifdef _MSC_VER
"-LIBPATH:"
# else
"-L"
# endif
;
const size_t libpathflag_len = sizeof(libpathflag) - 1;
#endif
#ifdef LOAD_RELATIVE
basedir_val = ruby_prefix_path;
@ -1884,7 +1618,6 @@ init_header_filename(void)
}
else
#endif
#ifndef _MSC_VER
{
// A name of the header file included in any C file generated by MJIT for iseqs.
static const char header_name[] = MJIT_HEADER_INSTALL_DIR "/" MJIT_MIN_HEADER_NAME;
@ -1904,56 +1637,15 @@ init_header_filename(void)
}
pch_file = get_uniq_filename(0, MJIT_TMP_PREFIX "h", ".h.gch");
#else
{
static const char pch_name[] = MJIT_HEADER_INSTALL_DIR "/" MJIT_PRECOMPILED_HEADER_NAME;
const size_t pch_name_len = sizeof(pch_name) - 1;
pch_file = xmalloc(baselen + pch_name_len + 1);
p = append_str2(pch_file, basedir, baselen);
p = append_str2(p, pch_name, pch_name_len + 1);
if ((fd = rb_cloexec_open(pch_file, O_RDONLY, 0)) < 0) {
verbose(1, "Cannot access precompiled header file: %s", pch_file);
xfree(pch_file);
pch_file = NULL;
return false;
}
(void)close(fd);
}
#endif
#ifdef _WIN32
basedir_val = ruby_archlibdir_path;
basedir = StringValuePtr(basedir_val);
baselen = RSTRING_LEN(basedir_val);
libruby_pathflag = p = xmalloc(libpathflag_len + baselen + 1);
p = append_str(p, libpathflag);
p = append_str2(p, basedir, baselen);
*p = '\0';
#endif
return true;
}
#ifdef _WIN32
UINT rb_w32_system_tmpdir(WCHAR *path, UINT len);
#endif
static char *
system_default_tmpdir(void)
{
// c.f. ext/etc/etc.c:etc_systmpdir()
#ifdef _WIN32
WCHAR tmppath[_MAX_PATH];
UINT len = rb_w32_system_tmpdir(tmppath, numberof(tmppath));
if (len) {
int blen = WideCharToMultiByte(CP_UTF8, 0, tmppath, len, NULL, 0, NULL, NULL);
char *tmpdir = xmalloc(blen + 1);
WideCharToMultiByte(CP_UTF8, 0, tmppath, len, tmpdir, blen, NULL, NULL);
tmpdir[blen] = '\0';
return tmpdir;
}
#elif defined _CS_DARWIN_USER_TEMP_DIR
#if defined _CS_DARWIN_USER_TEMP_DIR
char path[MAXPATHLEN];
size_t len = confstr(_CS_DARWIN_USER_TEMP_DIR, path, sizeof(path));
if (len > 0) {
@ -1981,19 +1673,17 @@ check_tmpdir(const char *dir)
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
if (!S_ISDIR(st.st_mode)) return FALSE;
#ifndef _WIN32
# ifndef S_IWOTH
#ifndef S_IWOTH
# define S_IWOTH 002
# endif
#endif
if (st.st_mode & S_IWOTH) {
# ifdef S_ISVTX
#ifdef S_ISVTX
if (!(st.st_mode & S_ISVTX)) return FALSE;
# else
#else
return FALSE;
# endif
#endif
}
if (access(dir, W_OK)) return FALSE;
#endif
return TRUE;
}
@ -2141,11 +1831,7 @@ mjit_init(const struct mjit_options *opts)
mjit_opts.max_cache_size = MIN_CACHE_SIZE;
// Initialize variables for compilation
#ifdef _MSC_VER
pch_status = PCH_SUCCESS; // has prebuilt precompiled header
#else
pch_status = PCH_NOT_READY;
#endif
cc_path = CC_COMMON_ARGS[0];
verbose(2, "MJIT: CC defaults to %s", cc_path);
cc_common_args = xmalloc(sizeof(CC_COMMON_ARGS));
@ -2189,10 +1875,8 @@ mjit_init(const struct mjit_options *opts)
// Initialize worker thread
start_worker();
#ifndef _MSC_VER
// TODO: Consider running C compiler asynchronously
make_pch();
#endif
}
static void
@ -2311,12 +1995,10 @@ mjit_finish(bool close_handle_p)
mjit_dump_total_calls();
#endif
#ifndef _MSC_VER // mswin has prebuilt precompiled header
if (!mjit_opts.save_temps && getpid() == pch_owner_pid)
remove_file(pch_file);
xfree(header_file); header_file = NULL;
#endif
xfree((void *)cc_common_args); cc_common_args = NULL;
for (char **flag = cc_added_args; *flag != NULL; flag++)
xfree(*flag);

Просмотреть файл

@ -587,9 +587,6 @@ mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id)
return false;
}
#ifdef _WIN32
fprintf(f, "__declspec(dllexport)\n");
#endif
fprintf(f, "VALUE\n%s(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp)\n{\n", funcname);
bool success = mjit_compile_body(f, iseq, &status);
fprintf(f, "\n} // end of %s\n", funcname);

Просмотреть файл

@ -1128,8 +1128,7 @@ class TestRubyOptions < Test::Unit::TestCase
end
def test_mjit_debug
# mswin uses prebuilt precompiled header. Thus it does not show a pch compilation log to check "-O0 -O1".
if JITSupport.supported? && !RUBY_PLATFORM.match?(/mswin/)
if JITSupport.supported?
env = { 'MJIT_SEARCH_BUILD_DIR' => 'true' }
assert_in_out_err([env, "--disable-yjit", "--mjit-debug=-O0 -O1", "--mjit-verbose=2", "" ], "", [], /-O0 -O1/)
end

Просмотреть файл

@ -169,10 +169,6 @@ module MJITHeader
RUBY_PLATFORM =~ /mswin|mingw|msys/
end
def self.cl_exe?(cc)
cc =~ /\Acl(\z| |\.exe)/
end
# If code has macro which only supported compilers predefine, return true.
def self.supported_header?(code)
SUPPORTED_CC_MACROS.any? { |macro| code =~ /^#\s*define\s+#{Regexp.escape(macro)}\b/ }
@ -220,13 +216,9 @@ end
cc = ARGV[0]
code = File.binread(ARGV[1]) # Current version of the header file.
outfile = ARGV[2]
if MJITHeader.cl_exe?(cc)
cflags = '-DMJIT_HEADER -Zs'
else
cflags = '-S -DMJIT_HEADER -fsyntax-only -Werror=implicit-function-declaration -Werror=implicit-int -Wfatal-errors'
end
cflags = '-S -DMJIT_HEADER -fsyntax-only -Werror=implicit-function-declaration -Werror=implicit-int -Wfatal-errors'
if !MJITHeader.cl_exe?(cc) && !MJITHeader.supported_header?(code)
if !MJITHeader.supported_header?(code)
puts "This compiler (#{cc}) looks not supported for MJIT. Giving up to generate MJIT header."
MJITHeader.write("#error MJIT does not support '#{cc}' yet", outfile)
exit
@ -234,7 +226,7 @@ end
MJITHeader.remove_predefined_macros!(code)
if MJITHeader.windows? # transformation is broken with Windows headers for now
if MJITHeader.windows? # transformation is broken on Windows and the platfor is not supported
MJITHeader.remove_harmful_macros!(code)
MJITHeader.check_code!(code, cc, cflags, 'initial')
puts "\nSkipped transforming external functions to static on Windows."

Просмотреть файл

@ -319,33 +319,7 @@ CPPFLAGS = $(DEFS) $(ARCHDEFS) $(CPPFLAGS)
CPPFLAGS = -DDISABLE_RUBYGEMS $(CPPFLAGS)
!endif
!ifndef MJIT_SUPPORT
MJIT_SUPPORT = yes
!endif
!if "$(CPPOUTFLAG)" == ">"
MJIT_HEADER_FLAGS =
!else
MJIT_HEADER_FLAGS = -P
!endif
MJIT_HEADER_SUFFIX =
MJIT_HEADER_ARCH =
MJIT_HEADER_INSTALL_DIR = include/$(RUBY_VERSION_NAME)/$(arch)
MJIT_PRECOMPILED_HEADER_NAME = rb_mjit_header-$(RUBY_PROGRAM_VERSION).pch
MJIT_PRECOMPILED_HEADER = $(MJIT_HEADER_INSTALL_DIR)/$(MJIT_PRECOMPILED_HEADER_NAME)
!ifndef MJIT_CC
MJIT_CC = $(CC)
!endif
!ifndef MJIT_OPTFLAGS
# TODO: Use only $(OPTFLAGS) for performance. It requires to modify flags for precompiled header too.
# For now, using flags used for building precompiled header to make JIT succeed.
MJIT_OPTFLAGS = -DMJIT_HEADER $(CFLAGS) $(XCFLAGS) $(CPPFLAGS)
!endif
!ifndef MJIT_DEBUGFLAGS
# TODO: Make this work... Another header for debug build needs to be installed first.
MJIT_DEBUGFLAGS = $(empty) $(DEBUGFLAGS) $(empty)
MJIT_DEBUGFLAGS = $(MJIT_DEBUGFLAGS: -Zi = -Z7 )
!endif
!ifndef MJIT_LDSHARED
MJIT_LDSHARED = $(MJIT_CC) -LD
MJIT_SUPPORT = no
!endif
POSTLINK =
@ -918,11 +892,7 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub
#define RUBY_COREDLL "$(RT)"
#define RUBY_PLATFORM "$(arch)"
#define RUBY_SITEARCH "$(sitearch)"
!if "$(MJIT_SUPPORT)" == "yes"
#define USE_MJIT 1
!else
#define USE_MJIT 0
!endif
#endif /* $(guard) */
<<
@ -1338,42 +1308,6 @@ probes.h: {$(VPATH)}probes.dmyh
#include "$(*F).dmyh"
<<KEEP
main: mjit-headers
yes-mjit-headers: $(MJIT_PRECOMPILED_HEADER)
clean-local::
$(Q)$(RM) $(MJIT_PRECOMPILED_HEADER_NAME) $(MJIT_PRECOMPILED_HEADER_NAME:.pch=.)$(OBJEXT)
$(Q)$(RM) $(TIMESTAMPDIR)/$(MJIT_PRECOMPILED_HEADER_NAME:.pch=.time) mjit_config.h
$(Q)$(RM) $(MJIT_HEADER_INSTALL_DIR)/rb_mjit_header-*.pch
$(Q)$(RM) $(MJIT_HEADER_INSTALL_DIR)/rb_mjit_header-*.$(OBJEXT)
-$(Q) $(RMDIRS) $(MJIT_HEADER_INSTALL_DIR) 2> $(NULL) || exit 0
$(Q)$(RM) $(arch_hdrdir)/rb_mjit_header-*.pch
$(Q)$(RM) $(arch_hdrdir)/rb_mjit_header-*.$(OBJEXT)
# Non-mswin environment is not using prebuilt precompiled header because upgrading compiler
# or changing compiler options may break MJIT so build (currently only by --mjit-debug though).
#
# But mswin is building precompiled header because cl.exe cannot leave macro after preprocess.
# As a workaround to use macro without installing many source files, it uses precompiled header
# without sufficient guard for a broken build.
#
# TODO: Fix the above issue by including VC version in header name, and create another header
# for --mjit-debug as well.
$(TIMESTAMPDIR)/$(MJIT_PRECOMPILED_HEADER_NAME:.pch=).time: probes.h vm.$(OBJEXT)
$(ECHO) building $(@F:.time=.pch)
$(Q) $(CC) -DMJIT_HEADER $(CFLAGS: -Zi = -Z7 ) $(XCFLAGS:-DRUBY_EXPORT =) -URUBY_EXPORT $(CPPFLAGS) $(srcdir)/vm.c -c -Yc \
$(COUTFLAG)$(@F:.time=.)$(OBJEXT) -Fd$(@F:.time=.pdb) -Fp$(@F:.time=.pch).new -Z7
$(Q) $(IFCHANGE) "--timestamp=$@" $(@F:.time=.pch) $(@F:.time=.pch).new
$(MJIT_PRECOMPILED_HEADER_NAME): $(TIMESTAMPDIR)/$(MJIT_PRECOMPILED_HEADER_NAME:.pch=).time
$(MJIT_PRECOMPILED_HEADER): $(MJIT_PRECOMPILED_HEADER_NAME)
$(Q) $(MAKEDIRS) $(MJIT_HEADER_INSTALL_DIR)
$(Q) $(MAKE_LINK) $(MJIT_PRECOMPILED_HEADER_NAME) $@
$(Q) $(MAKE_LINK) $(MJIT_PRECOMPILED_HEADER_NAME:.pch=.)$(OBJEXT) $(MJIT_HEADER_INSTALL_DIR)/$(MJIT_PRECOMPILED_HEADER_NAME:.pch=.)$(OBJEXT)
$(Q) $(MAKEDIRS) $(arch_hdrdir)
$(Q) $(MAKE_LINK) $(MJIT_PRECOMPILED_HEADER_NAME) $(arch_hdrdir)/$(MJIT_PRECOMPILED_HEADER_NAME)
$(Q) $(MAKE_LINK) $(MJIT_PRECOMPILED_HEADER_NAME:.pch=.)$(OBJEXT) $(arch_hdrdir)/$(MJIT_PRECOMPILED_HEADER_NAME:.pch=.)$(OBJEXT)
INSNS = opt_sc.inc optinsn.inc optunifs.inc insns.inc insns_info.inc \
vmtc.inc vm.inc mjit_compile.inc
@ -1399,46 +1333,3 @@ loadpath: verconf.h
@$(CPP) $(XCFLAGS) $(CPPFLAGS) $(srcdir)/loadpath.c | \
sed -e '1,/^const char ruby_initial_load_paths/d;/;/,$$d' \
-e '/^^ /!d;s/ *"\\\\0"$$//;s/" *"//g'
mjit_config.h: $(MKFILES) $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub
@echo making <<$@
#ifndef RUBY_MJIT_CONFIG_H
#define RUBY_MJIT_CONFIG_H 1
#define MJIT_CONFIG_ESCAPED_EQ "="
#define MJIT_HEADER_INSTALL_DIR "/$(MJIT_HEADER_INSTALL_DIR)"
#define MJIT_MIN_HEADER_NAME "$(MJIT_MIN_HEADER_NAME)"
#define MJIT_PRECOMPILED_HEADER_NAME "$(MJIT_PRECOMPILED_HEADER_NAME)"
<<KEEP
@
@(set sep=#define MJIT_CC_COMMON ) & \
for %I in ($(MJIT_CC)) do @(call echo.%%sep%%"%%~I", \& set sep= ) >> $@
@echo /* MJIT_CC_COMMON */>> $@
@
@(set sep=#define MJIT_CFLAGS ) & \
for %I in ($(RUNTIMEFLAG) $(ARCH_FLAG)) do @(call echo.%%sep%%"%%~I", \& set sep= ) >> $@
@echo /* MJIT_CFLAGS */>> $@
@
@(set sep=#define MJIT_OPTFLAGS ) & \
for %I in ($(MJIT_OPTFLAGS:^==" MJIT_CONFIG_ESCAPED_EQ ")) do @(call echo.%%sep%%"%%~I", \& set sep= ) >> $@
@echo /* MJIT_OPTFLAGS */>> $@
@
@(set sep=#define MJIT_DEBUGFLAGS ) & \
for %I in ($(MJIT_DEBUGFLAGS:^==" MJIT_CONFIG_ESCAPED_EQ ")) do @(call echo.%%sep%%"%%~I", \& set sep= ) >> $@
@echo /* MJIT_DEBUGFLAGS */>> $@
@
@(set sep=#define MJIT_LDSHARED ) & \
for %I in ($(MJIT_LDSHARED)) do @(call echo.%%sep%%"%%~I", \& set sep= ) >> $@
@echo /* MJIT_LDSHARED */>> $@
@
@(set sep=#define MJIT_DLDFLAGS ) & \
for %I in ($(DLDFLAGS)) do @(call echo.%%sep%%"%%~I", \& set sep= ) >> $@
@echo /* MJIT_DLDFLAGS */>> $@
@
@(set sep=#define MJIT_LIBS ) & \
for %I in ($(LIBRUBYARG_SHARED)) do @(call echo.%%sep%%"%%~I", \& set sep= ) >> $@
@echo /* MJIT_LIBS */>> $@
@
@echo.>> $@
@echo #endif /* RUBY_MJIT_CONFIG_H */>> $@
@$(Q:@=: :) type $@

Просмотреть файл

@ -38,8 +38,6 @@ if "%1" == "--enable-devel" goto :enable-devel
if "%1" == "--disable-devel" goto :disable-devel
if "%1" == "--enable-rubygems" goto :enable-rubygems
if "%1" == "--disable-rubygems" goto :disable-rubygems
if "%1" == "--enable-mjit-support" goto :enable-mjit-support
if "%1" == "--disable-mjit-support" goto :disable-mjit-support
if "%1" == "--extout" goto :extout
if "%1" == "--path" goto :path
if "%1" == "--with-baseruby" goto :baseruby
@ -165,16 +163,6 @@ goto :loop ;
echo>>confargs.tmp %1 \
shift
goto :loop ;
:enable-mjit-support
echo>> ~tmp~.mak "MJIT_SUPPORT=yes" \
echo>>confargs.tmp %1 \
shift
goto :loop ;
:disable-mjit-support
echo>> ~tmp~.mak "MJIT_SUPPORT=no" \
echo>>confargs.tmp %1 \
shift
goto :loop ;
:ntver
echo>> ~tmp~.mak "NTVER=%~2" \
echo>>confargs.tmp %1=%2 \

Просмотреть файл

@ -295,7 +295,6 @@ AS = $(AS) -nologo
(echo AS = $(AS:64=) -nologo) || \
(echo AS = $(AS) -nologo) ) >>$(MAKEFILE)
!endif
@(for %I in (cl.exe) do @set MJIT_CC=%~$$PATH:I) && (call echo MJIT_CC = "%MJIT_CC:\=/%" -nologo>>$(MAKEFILE))
@type << >>$(MAKEFILE)
$(BANG)include $$(srcdir)/win32/Makefile.sub