[前][次][番号順一覧][スレッド一覧]

ruby-changes:72997

From: Takashi <ko1@a...>
Date: Sun, 21 Aug 2022 08:33:22 +0900 (JST)
Subject: [ruby-changes:72997] dc8d70e461 (master): Execute MJIT in a forked Ruby process (#6264)

https://git.ruby-lang.org/ruby.git/commit/?id=dc8d70e461

From dc8d70e4615cdf12378322fbcd4396486270ddbe Mon Sep 17 00:00:00 2001
From: Takashi Kokubun <takashikkbn@g...>
Date: Sat, 20 Aug 2022 16:33:03 -0700
Subject: Execute MJIT in a forked Ruby process (#6264)

[Misc #18968]
---
 mjit.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 62 insertions(+), 23 deletions(-)

diff --git a/mjit.c b/mjit.c
index 98f4af3d18..7912f8fb8d 100644
--- a/mjit.c
+++ b/mjit.c
@@ -431,10 +431,12 @@ CRITICAL_SECTION_FINISH(int level, const char *msg) https://github.com/ruby/ruby/blob/trunk/mjit.c#L431
     rb_native_mutex_unlock(&mjit_engine_mutex);
 }
 
+static pid_t mjit_pid = 0;
+
 static int
 sprint_uniq_filename(char *str, size_t size, unsigned long id, const char *prefix, const char *suffix)
 {
-    return snprintf(str, size, "%s/%sp%"PRI_PIDT_PREFIX"uu%lu%s", tmp_dir, prefix, getpid(), id, suffix);
+    return snprintf(str, size, "%s/%sp%"PRI_PIDT_PREFIX"uu%lu%s", tmp_dir, prefix, mjit_pid, id, suffix);
 }
 
 // Return time in milliseconds as a double.
@@ -798,8 +800,8 @@ make_pch(void) https://github.com/ruby/ruby/blob/trunk/mjit.c#L800
     }
 }
 
-static pid_t
-start_compiling_c_to_so(const char *c_file, const char *so_file)
+static int
+compile_c_to_so(const char *c_file, const char *so_file)
 {
     const char *so_args[] = {
         "-o", so_file,
@@ -821,18 +823,14 @@ start_compiling_c_to_so(const char *c_file, const char *so_file) https://github.com/ruby/ruby/blob/trunk/mjit.c#L823
 
     char **args = form_args(8, CC_LDSHARED_ARGS, CC_CODEFLAG_ARGS, cc_added_args,
                             so_args, loader_args, CC_LIBS, CC_DLDFLAGS_ARGS, CC_LINKER_ARGS);
-    if (args == NULL) return -1;
-
-    rb_vm_t *vm = GET_VM();
-    rb_native_mutex_lock(&vm->waitpid_lock);
+    if (args == NULL) return 1;
 
-    pid_t pid = start_process(cc_path, args);
-    mjit_add_waiting_pid(vm, pid);
-
-    rb_native_mutex_unlock(&vm->waitpid_lock);
+    int exit_code = exec_process(cc_path, args);
+    if (!mjit_opts.save_temps)
+        remove_file(c_file);
 
     free(args);
-    return pid;
+    return exit_code;
 }
 #endif // _MSC_VER
 
@@ -888,8 +886,8 @@ mjit_compact(char* c_file) https://github.com/ruby/ruby/blob/trunk/mjit.c#L886
 
 // Compile all cached .c files and build a single .so file. Reload all JIT func from it.
 // This improves the code locality for better performance in terms of iTLB and iCache.
-static pid_t
-start_mjit_compact(struct rb_mjit_unit *unit)
+static int
+mjit_compact_unit(struct rb_mjit_unit *unit)
 {
     static const char c_ext[] = ".c";
     static const char so_ext[] = DLEXT;
@@ -900,9 +898,30 @@ start_mjit_compact(struct rb_mjit_unit *unit) https://github.com/ruby/ruby/blob/trunk/mjit.c#L898
 
     bool success = mjit_compact(c_file);
     if (success) {
-        return start_compiling_c_to_so(c_file, so_file);
+        return compile_c_to_so(c_file, so_file);
+    }
+    return 1;
+}
+
+static pid_t
+start_mjit_compact(struct rb_mjit_unit *unit)
+{
+    rb_vm_t *vm = GET_VM();
+    rb_native_mutex_lock(&vm->waitpid_lock);
+
+    pid_t pid = fork();
+    if (pid == 0) {
+        rb_native_mutex_unlock(&vm->waitpid_lock);
+
+        int exit_code = mjit_compact_unit(unit);
+        exit(exit_code);
+    }
+    else {
+        mjit_add_waiting_pid(vm, pid);
+        rb_native_mutex_unlock(&vm->waitpid_lock);
+
+        return pid;
     }
-    return -1;
 }
 
 static void
@@ -1005,8 +1024,8 @@ compile_prelude(FILE *f) https://github.com/ruby/ruby/blob/trunk/mjit.c#L1024
 
 // 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 pid_t
-start_mjit_compile(struct rb_mjit_unit *unit)
+static int
+mjit_compile_unit(struct rb_mjit_unit *unit)
 {
     static const char c_ext[] = ".c";
     static const char so_ext[] = DLEXT;
@@ -1022,7 +1041,7 @@ start_mjit_compile(struct rb_mjit_unit *unit) https://github.com/ruby/ruby/blob/trunk/mjit.c#L1041
         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 -1;
+        return 1;
     }
 
     // print #include of MJIT header, etc.
@@ -1047,10 +1066,31 @@ start_mjit_compile(struct rb_mjit_unit *unit) https://github.com/ruby/ruby/blob/trunk/mjit.c#L1066
         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 -1;
+        return 1;
     }
 
-    return start_compiling_c_to_so(c_file, so_file);
+    return compile_c_to_so(c_file, so_file);
+}
+
+static pid_t
+start_mjit_compile(struct rb_mjit_unit *unit)
+{
+    rb_vm_t *vm = GET_VM();
+    rb_native_mutex_lock(&vm->waitpid_lock);
+
+    pid_t pid = fork();
+    if (pid == 0) {
+        rb_native_mutex_unlock(&vm->waitpid_lock);
+
+        int exit_code = mjit_compile_unit(unit);
+        exit(exit_code);
+    }
+    else {
+        mjit_add_waiting_pid(vm, pid);
+        rb_native_mutex_unlock(&vm->waitpid_lock);
+
+        return pid;
+    }
 }
 
 #ifdef _WIN32
@@ -1556,8 +1596,6 @@ mjit_notify_waitpid(int status) https://github.com/ruby/ruby/blob/trunk/mjit.c#L1596
     // Delete .c file
     char c_file[MAXPATHLEN];
     sprint_uniq_filename(c_file, (int)sizeof(c_file), current_cc_unit->id, MJIT_TMP_PREFIX, ".c");
-    if (!mjit_opts.save_temps)
-        remove_file(c_file);
 
     // Check the result
     bool success = false;
@@ -2092,6 +2130,7 @@ mjit_init(const struct mjit_options *opts) https://github.com/ruby/ruby/blob/trunk/mjit.c#L2130
     mjit_opts = *opts;
     mjit_enabled = true;
     mjit_call_p = true;
+    mjit_pid = getpid();
 
     // Normalize options
     if (mjit_opts.min_calls == 0)
-- 
cgit v1.2.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]