From ddf96b7693639e354e95b4d0c6021586968a5a5f Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Sat, 20 Aug 2022 18:35:36 -0700 Subject: [PATCH] Drop mswin support of MJIT (#6265) 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] --- mjit.c | 334 +--------------------------------- mjit_compile.c | 3 - test/ruby/test_rubyoptions.rb | 3 +- tool/transform_mjit_header.rb | 14 +- win32/Makefile.sub | 111 +---------- win32/configure.bat | 12 -- win32/setup.mak | 1 - 7 files changed, 13 insertions(+), 465 deletions(-) diff --git a/mjit.c b/mjit.c index 7912f8fb8d..e519a3091d 100644 --- a/mjit.c +++ b/mjit.c @@ -98,14 +98,9 @@ #include "insns_info.inc" #include "internal/compile.h" -#ifdef _WIN32 -#include -#include -#else #include #include #include -#endif #include #ifdef HAVE_FCNTL_H #include @@ -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); diff --git a/mjit_compile.c b/mjit_compile.c index 1bf5beb6a3..e85eaaa6cb 100644 --- a/mjit_compile.c +++ b/mjit_compile.c @@ -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); diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb index ed2bc3538c..cf6829cf88 100644 --- a/test/ruby/test_rubyoptions.rb +++ b/test/ruby/test_rubyoptions.rb @@ -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 diff --git a/tool/transform_mjit_header.rb b/tool/transform_mjit_header.rb index 8867c556f0..503e4c3593 100644 --- a/tool/transform_mjit_header.rb +++ b/tool/transform_mjit_header.rb @@ -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." diff --git a/win32/Makefile.sub b/win32/Makefile.sub index bea24450ed..1aa27a9119 100644 --- a/win32/Makefile.sub +++ b/win32/Makefile.sub @@ -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" < $(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)" -<> $@ - @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 $@ diff --git a/win32/configure.bat b/win32/configure.bat index 4602b41ec5..a3df0bb4eb 100755 --- a/win32/configure.bat +++ b/win32/configure.bat @@ -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 \ diff --git a/win32/setup.mak b/win32/setup.mak index fd804a84ce..17e321b984 100644 --- a/win32/setup.mak +++ b/win32/setup.mak @@ -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