mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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.
This commit is contained in:
parent
bdc62dfc8e
commit
a19d625e66
5 changed files with 48 additions and 3 deletions
32
mjit.c
32
mjit.c
|
@ -700,6 +700,33 @@ start_worker(void)
|
|||
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)
|
|||
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)
|
|||
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;
|
||||
|
||||
|
|
2
mjit.h
2
mjit.h
|
@ -43,6 +43,8 @@ struct mjit_options {
|
|||
// 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.
|
||||
|
|
|
@ -221,6 +221,8 @@ static VALUE valid_class_serials;
|
|||
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)
|
|||
};
|
||||
|
||||
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)
|
|||
"-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;
|
||||
|
||||
|
|
5
ruby.c
5
ruby.c
|
@ -298,7 +298,7 @@ usage(const char *name, int help)
|
|||
};
|
||||
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)
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -1043,6 +1043,12 @@ class TestRubyOptions < Test::Unit::TestCase
|
|||
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?
|
||||
|
|
Loading…
Add table
Reference in a new issue