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

ruby-changes:59015

From: Takashi <ko1@a...>
Date: Sun, 1 Dec 2019 18:00:12 +0900 (JST)
Subject: [ruby-changes:59015] a19d625e66 (master): Allow specifying arbitrary MJIT flags by --jit-debug

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

From a19d625e667024fe27dcee04dd748e914bc24762 Mon Sep 17 00:00:00 2001
From: Takashi Kokubun <takashikkbn@g...>
Date: Sun, 1 Dec 2019 00:56:27 -0800
Subject: Allow specifying arbitrary MJIT flags by --jit-debug

This is a secret feature for me. It's only for testing and any behavior
with this flag override is unsupported.

I needed this because I sometimes want to add debug options but do not
want to disable optimizations, for using Linux perf.

diff --git a/mjit.c b/mjit.c
index f1e3934..5749f21 100644
--- a/mjit.c
+++ b/mjit.c
@@ -700,6 +700,33 @@ start_worker(void) https://github.com/ruby/ruby/blob/trunk/mjit.c#L700
     return true;
 }
 
+// Convert "foo bar" to {"foo", "bar", NULL} array. Caller is responsible for
+// freeing a returned buffer and its elements.
+static char **
+split_flags(char *flags)
+{
+    char *buf[MAXPATHLEN];
+    int i = 0;
+    char *next;
+    for (; flags != NULL; flags = next) {
+        next = strchr(flags, ' ');
+        if (next == NULL) {
+            if (strlen(flags) > 0)
+                buf[i++] = strdup(flags);
+        }
+        else {
+            if (next > flags)
+                buf[i++] = strndup(flags, next - flags);
+            next++; // skip space
+        }
+    }
+    buf[i] = NULL;
+
+    char **ret = xmalloc(sizeof(char **) * i);
+    memcpy((void *)ret, buf, sizeof(char **) * i);
+    return ret;
+}
+
 // Initialize MJIT.  Start a thread creating the precompiled header and
 // processing ISeqs.  The function should be called first for using MJIT.
 // If everything is successful, MJIT_INIT_P will be TRUE.
@@ -728,6 +755,8 @@ mjit_init(struct mjit_options *opts) https://github.com/ruby/ruby/blob/trunk/mjit.c#L755
     verbose(2, "MJIT: CC defaults to %s", cc_path);
     cc_common_args = xmalloc(sizeof(CC_COMMON_ARGS));
     memcpy((void *)cc_common_args, CC_COMMON_ARGS, sizeof(CC_COMMON_ARGS));
+    cc_added_args = split_flags(opts->debug_flags);
+    xfree(opts->debug_flags);
 #if MJIT_CFLAGS_PIPE
     { // eliminate a flag incompatible with `-pipe`
         size_t i, j;
@@ -921,6 +950,9 @@ mjit_finish(bool close_handle_p) https://github.com/ruby/ruby/blob/trunk/mjit.c#L950
     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);
+    xfree((void *)cc_added_args); cc_added_args = NULL;
     xfree(tmp_dir); tmp_dir = NULL;
     xfree(pch_file); pch_file = NULL;
 
diff --git a/mjit.h b/mjit.h
index e89a2b9..ff16c0f 100644
--- a/mjit.h
+++ b/mjit.h
@@ -43,6 +43,8 @@ struct mjit_options { https://github.com/ruby/ruby/blob/trunk/mjit.h#L43
     // Disable compiler optimization and add debug symbols. It can be
     // very slow.
     char debug;
+    // Add arbitrary cflags.
+    char* debug_flags;
     // If not 0, all ISeqs are synchronously compiled. For testing.
     unsigned int wait;
     // Number of calls to trigger JIT compilation. For testing.
diff --git a/mjit_worker.c b/mjit_worker.c
index b23baf6..ce8133a 100644
--- a/mjit_worker.c
+++ b/mjit_worker.c
@@ -221,6 +221,8 @@ static VALUE valid_class_serials; https://github.com/ruby/ruby/blob/trunk/mjit_worker.c#L221
 static const char *cc_path;
 // Used C compiler flags.
 static const char **cc_common_args;
+// Used C compiler flags added by --jit-debug=...
+static char **cc_added_args;
 // Name of the precompiled header file.
 static char *pch_file;
 // The process id which should delete the pch_file on mjit_finish.
@@ -759,7 +761,7 @@ make_pch(void) https://github.com/ruby/ruby/blob/trunk/mjit_worker.c#L761
     };
 
     verbose(2, "Creating precompiled header");
-    char **args = form_args(3, cc_common_args, CC_CODEFLAG_ARGS, rest_args);
+    char **args = form_args(4, cc_common_args, CC_CODEFLAG_ARGS, cc_added_args, rest_args);
     if (args == NULL) {
         mjit_warning("making precompiled header failed on forming args");
         CRITICAL_SECTION_START(3, "in make_pch");
@@ -796,7 +798,7 @@ compile_c_to_o(const char *c_file, const char *o_file) https://github.com/ruby/ruby/blob/trunk/mjit_worker.c#L798
         "-c", NULL
     };
 
-    char **args = form_args(4, cc_common_args, CC_CODEFLAG_ARGS, files, CC_LINKER_ARGS);
+    char **args = form_args(5, cc_common_args, CC_CODEFLAG_ARGS, cc_added_args, files, CC_LINKER_ARGS);
     if (args == NULL)
         return false;
 
diff --git a/ruby.c b/ruby.c
index 6edc5c4..69963e3 100644
--- a/ruby.c
+++ b/ruby.c
@@ -298,7 +298,7 @@ usage(const char *name, int help) https://github.com/ruby/ruby/blob/trunk/ruby.c#L298
     };
     static const struct message mjit_options[] = {
         M("--jit-warnings",      "", "Enable printing JIT warnings"),
-        M("--jit-debug",         "", "Enable JIT debugging (very slow)"),
+        M("--jit-debug",         "", "Enable JIT debugging (very slow), or add cflags if specified"),
         M("--jit-wait",          "", "Wait until JIT compilation is finished everytime (for testing)"),
         M("--jit-save-temps",    "", "Save JIT temporary files in $TMP or /tmp (for testing)"),
         M("--jit-verbose=num",   "", "Print JIT logs of level num or less to stderr (default: 0)"),
@@ -969,6 +969,9 @@ setup_mjit_options(const char *s, struct mjit_options *mjit_opt) https://github.com/ruby/ruby/blob/trunk/ruby.c#L969
     else if (strcmp(s, "-warnings") == 0) {
         mjit_opt->warnings = 1;
     }
+    else if (strncmp(s, "-debug=", 7) == 0) {
+        mjit_opt->debug_flags = strdup(s + 7);
+    }
     else if (strcmp(s, "-debug") == 0) {
         mjit_opt->debug = 1;
     }
diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb
index 10d5455..abdacc5 100644
--- a/test/ruby/test_rubyoptions.rb
+++ b/test/ruby/test_rubyoptions.rb
@@ -1043,6 +1043,12 @@ class TestRubyOptions < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_rubyoptions.rb#L1043
     assert_in_out_err([IO::NULL], success: true)
   end
 
+  def test_jit_debug
+    if JITSupport.supported?
+      assert_in_out_err(["--jit-debug=-O0 -O1", "--jit-verbose=2", ""], "", [], /-O0 -O1/)
+    end
+  end
+
   private
 
   def mjit_force_enabled?
-- 
cgit v0.10.2


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

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