diff options
-rw-r--r-- | common.mk | 2 | ||||
-rw-r--r-- | internal/cmdlineopt.h | 61 | ||||
-rw-r--r-- | mjit.c | 58 | ||||
-rw-r--r-- | ruby.c | 131 |
4 files changed, 135 insertions, 117 deletions
@@ -9419,6 +9419,7 @@ mjit.$(OBJEXT): $(hdrdir)/ruby/ruby.h mjit.$(OBJEXT): $(hdrdir)/ruby/version.h mjit.$(OBJEXT): $(top_srcdir)/internal/array.h mjit.$(OBJEXT): $(top_srcdir)/internal/class.h +mjit.$(OBJEXT): $(top_srcdir)/internal/cmdlineopt.h mjit.$(OBJEXT): $(top_srcdir)/internal/compile.h mjit.$(OBJEXT): $(top_srcdir)/internal/compilers.h mjit.$(OBJEXT): $(top_srcdir)/internal/cont.h @@ -13162,6 +13163,7 @@ ruby.$(OBJEXT): $(hdrdir)/ruby/ruby.h ruby.$(OBJEXT): $(hdrdir)/ruby/version.h ruby.$(OBJEXT): $(top_srcdir)/internal/array.h ruby.$(OBJEXT): $(top_srcdir)/internal/class.h +ruby.$(OBJEXT): $(top_srcdir)/internal/cmdlineopt.h ruby.$(OBJEXT): $(top_srcdir)/internal/compilers.h ruby.$(OBJEXT): $(top_srcdir)/internal/error.h ruby.$(OBJEXT): $(top_srcdir)/internal/file.h diff --git a/internal/cmdlineopt.h b/internal/cmdlineopt.h new file mode 100644 index 0000000000..7419beb649 --- /dev/null +++ b/internal/cmdlineopt.h @@ -0,0 +1,61 @@ +#ifndef INTERNAL_CMDLINEOPT_H /*-*-C-*-vi:se ft=c:*/ +#define INTERNAL_CMDLINEOPT_H + +#include "mjit.h" +#include "yjit.h" + +typedef struct { + unsigned int mask; + unsigned int set; +} ruby_features_t; + +typedef struct ruby_cmdline_options { + const char *script; + VALUE script_name; + VALUE e_script; + struct { + struct { + VALUE name; + int index; + } enc; + } src, ext, intern; + VALUE req_list; + ruby_features_t features; + ruby_features_t warn; + unsigned int dump; +#if USE_MJIT + struct mjit_options mjit; +#endif +#if YJIT_SUPPORTED_P + struct rb_yjit_options yjit; +#endif + + int sflag, xflag; + unsigned int warning: 1; + unsigned int verbose: 1; + unsigned int do_loop: 1; + unsigned int do_print: 1; + unsigned int do_line: 1; + unsigned int do_split: 1; + unsigned int do_search: 1; + unsigned int setids: 2; +} ruby_cmdline_options_t; + +struct ruby_opt_message { + const char *str; + unsigned short namelen, secondlen; +}; + +#define RUBY_OPT_MESSAGE(shortopt, longopt, desc) { \ + shortopt " " longopt " " desc, \ + (unsigned short)sizeof(shortopt), \ + (unsigned short)sizeof(longopt), \ +} + +#define opt_match(s, l, name) \ + ((((l) > rb_strlen_lit(name)) ? (s)[rb_strlen_lit(name)] == '=' : \ + (l) == rb_strlen_lit(name)) && \ + memcmp((s), name, rb_strlen_lit(name)) == 0 && \ + (((s) += rb_strlen_lit(name)), 1)) + +#endif @@ -19,6 +19,7 @@ #include "id_table.h" #include "internal.h" #include "internal/class.h" +#include "internal/cmdlineopt.h" #include "internal/cont.h" #include "internal/file.h" #include "internal/hash.h" @@ -692,6 +693,63 @@ split_flags(const char *flags) return ret; } +#define opt_match_noarg(s, l, name) \ + opt_match(s, l, name) && (*(s) ? (rb_warn("argument to --mjit-" name " is ignored"), 1) : 1) +#define opt_match_arg(s, l, name) \ + opt_match(s, l, name) && (*(s) ? 1 : (rb_raise(rb_eRuntimeError, "--mjit-" name " needs an argument"), 0)) + +void +mjit_setup_options(const char *s, struct mjit_options *mjit_opt) +{ + const size_t l = strlen(s); + if (l == 0) { + return; + } + else if (opt_match_noarg(s, l, "warnings")) { + mjit_opt->warnings = 1; + } + else if (opt_match(s, l, "debug")) { + if (*s) + mjit_opt->debug_flags = strdup(s + 1); + else + mjit_opt->debug = 1; + } + else if (opt_match_noarg(s, l, "wait")) { + mjit_opt->wait = 1; + } + else if (opt_match_noarg(s, l, "save-temps")) { + mjit_opt->save_temps = 1; + } + else if (opt_match(s, l, "verbose")) { + mjit_opt->verbose = *s ? atoi(s + 1) : 1; + } + else if (opt_match_arg(s, l, "max-cache")) { + mjit_opt->max_cache_size = atoi(s + 1); + } + else if (opt_match_arg(s, l, "min-calls")) { + mjit_opt->min_calls = atoi(s + 1); + } + else { + rb_raise(rb_eRuntimeError, + "invalid MJIT option `%s' (--help will show valid MJIT options)", s); + } +} + +#define M(shortopt, longopt, desc) RUBY_OPT_MESSAGE(shortopt, longopt, desc) +const struct ruby_opt_message mjit_option_messages[] = { + M("--mjit-warnings", "", "Enable printing JIT warnings"), + M("--mjit-debug", "", "Enable JIT debugging (very slow), or add cflags if specified"), + M("--mjit-wait", "", "Wait until JIT compilation finishes every time (for testing)"), + M("--mjit-save-temps", "", "Save JIT temporary files in $TMP or /tmp (for testing)"), + M("--mjit-verbose=num", "", "Print JIT logs of level num or less to stderr (default: 0)"), + M("--mjit-max-cache=num", "", "Max number of methods to be JIT-ed in a cache (default: " + STRINGIZE(DEFAULT_MAX_CACHE_SIZE) ")"), + M("--mjit-min-calls=num", "", "Number of calls to trigger JIT (for testing, default: " + STRINGIZE(DEFAULT_MIN_CALLS_TO_ADD) ")"), + {0} +}; +#undef M + // 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. @@ -47,6 +47,7 @@ #include "dln.h" #include "eval_intern.h" #include "internal.h" +#include "internal/cmdlineopt.h" #include "internal/error.h" #include "internal/file.h" #include "internal/inits.h" @@ -58,8 +59,6 @@ #include "internal/parse.h" #include "internal/process.h" #include "internal/variable.h" -#include "mjit.h" -#include "yjit.h" #include "ruby/encoding.h" #include "ruby/thread.h" #include "ruby/util.h" @@ -159,13 +158,6 @@ enum dump_flag_bits { DUMP_BIT(insns) | DUMP_BIT(insns_without_opt)) }; -typedef struct ruby_cmdline_options ruby_cmdline_options_t; - -typedef struct { - unsigned int mask; - unsigned int set; -} ruby_features_t; - static inline void rb_feature_set_to(ruby_features_t *feat, unsigned int bit_mask, unsigned int bit_set) { @@ -179,38 +171,6 @@ rb_feature_set_to(ruby_features_t *feat, unsigned int bit_mask, unsigned int bit #define FEATURE_SET_RESTORE(feat, save) FEATURE_SET_TO(feat, (save).mask, (save).set & (save).mask) #define FEATURE_SET_P(feat, bits) ((feat).set & (bits)) -struct ruby_cmdline_options { - const char *script; - VALUE script_name; - VALUE e_script; - struct { - struct { - VALUE name; - int index; - } enc; - } src, ext, intern; - VALUE req_list; - ruby_features_t features; - ruby_features_t warn; - unsigned int dump; -#if USE_MJIT - struct mjit_options mjit; -#endif -#if YJIT_SUPPORTED_P - struct rb_yjit_options yjit; -#endif - - int sflag, xflag; - unsigned int warning: 1; - unsigned int verbose: 1; - unsigned int do_loop: 1; - unsigned int do_print: 1; - unsigned int do_line: 1; - unsigned int do_split: 1; - unsigned int do_search: 1; - unsigned int setids: 2; -}; - static void init_ids(ruby_cmdline_options_t *); #define src_encoding_index GET_VM()->src_encoding_index @@ -289,21 +249,14 @@ usage(const char *name, int help, int highlight, int columns) /* This message really ought to be max 23 lines. * Removed -h because the user already knows that option. Others? */ - struct message { - const char *str; - unsigned short namelen, secondlen; - }; -#define M(shortopt, longopt, desc) { \ - shortopt " " longopt " " desc, \ - (unsigned short)sizeof(shortopt), \ - (unsigned short)sizeof(longopt), \ -} +#define M(shortopt, longopt, desc) RUBY_OPT_MESSAGE(shortopt, longopt, desc) + #if YJIT_SUPPORTED_P # define PLATFORM_JIT_OPTION "--yjit" #else # define PLATFORM_JIT_OPTION "--mjit" #endif - static const struct message usage_msg[] = { + static const struct ruby_opt_message usage_msg[] = { M("-0[octal]", "", "specify record separator (\\0, if no argument)"), M("-a", "", "autosplit mode with -n or -p (splits $_ into $F)"), M("-c", "", "check syntax only"), @@ -333,7 +286,7 @@ usage(const char *name, int help, int highlight, int columns) #endif M("-h", "", "show this message, --help for more info"), }; - static const struct message help_msg[] = { + static const struct ruby_opt_message help_msg[] = { M("--copyright", "", "print the copyright"), M("--dump={insns|parsetree|...}[,...]", "", "dump debug information. see below for available dump list"), @@ -346,14 +299,14 @@ usage(const char *name, int help, int highlight, int columns) M("--version", "", "print the version number, then exit"), M("--help", "", "show this message, -h for short message"), }; - static const struct message dumps[] = { + static const struct ruby_opt_message dumps[] = { M("insns", "", "instruction sequences"), M("insns_without_opt", "", "instruction sequences compiled with no optimization"), M("yydebug", "", "yydebug of yacc parser generator"), M("parsetree", "", "AST"), M("parsetree_with_comment", "", "AST with comments"), }; - static const struct message features[] = { + static const struct ruby_opt_message features[] = { M("gems", "", "rubygems (only for debugging, default: "DEFAULT_RUBYGEMS_ENABLED")"), M("error_highlight", "", "error_highlight (default: "DEFAULT_RUBYGEMS_ENABLED")"), M("did_you_mean", "", "did_you_mean (default: "DEFAULT_RUBYGEMS_ENABLED")"), @@ -366,23 +319,15 @@ usage(const char *name, int help, int highlight, int columns) M("yjit", "", "in-process JIT compiler (default: disabled)"), #endif }; - static const struct message warn_categories[] = { + static const struct ruby_opt_message warn_categories[] = { M("deprecated", "", "deprecated features"), M("experimental", "", "experimental features"), }; #if USE_MJIT - static const struct message mjit_options[] = { - M("--mjit-warnings", "", "Enable printing JIT warnings"), - M("--mjit-debug", "", "Enable JIT debugging (very slow), or add cflags if specified"), - M("--mjit-wait", "", "Wait until JIT compilation finishes every time (for testing)"), - M("--mjit-save-temps", "", "Save JIT temporary files in $TMP or /tmp (for testing)"), - M("--mjit-verbose=num", "", "Print JIT logs of level num or less to stderr (default: 0)"), - M("--mjit-max-cache=num", "", "Max number of methods to be JIT-ed in a cache (default: 10000)"), - M("--mjit-min-calls=num", "", "Number of calls to trigger JIT (for testing, default: 10000)"), - }; + extern const struct ruby_opt_message mjit_option_messages[]; #endif #if YJIT_SUPPORTED_P - static const struct message yjit_options[] = { + static const struct ruby_opt_message yjit_options[] = { #if YJIT_STATS M("--yjit-stats", "", "Enable collecting YJIT statistics"), #endif @@ -420,8 +365,8 @@ usage(const char *name, int help, int highlight, int columns) SHOW(warn_categories[i]); #if USE_MJIT printf("%s""MJIT options (experimental):%s\n", sb, se); - for (i = 0; i < numberof(mjit_options); ++i) - SHOW(mjit_options[i]); + for (i = 0; mjit_option_messages[i].str; ++i) + SHOW(mjit_option_messages[i]); #endif #if YJIT_SUPPORTED_P printf("%s""YJIT options (experimental):%s\n", sb, se); @@ -1082,16 +1027,6 @@ set_option_encoding_once(const char *type, VALUE *name, const char *e, long elen #define set_source_encoding_once(opt, e, elen) \ set_option_encoding_once("source", &(opt)->src.enc.name, (e), (elen)) -#define opt_match(s, l, name) \ - ((((l) > rb_strlen_lit(name)) ? (s)[rb_strlen_lit(name)] == '=' : \ - (l) == rb_strlen_lit(name)) && \ - memcmp((s), name, rb_strlen_lit(name)) == 0 && \ - (((s) += rb_strlen_lit(name)), 1)) -#define opt_match_noarg(s, l, name) \ - opt_match(s, l, name) && (*(s) ? (rb_warn("argument to --jit-" name " is ignored"), 1) : 1) -#define opt_match_arg(s, l, name) \ - opt_match(s, l, name) && (*(s) ? 1 : (rb_raise(rb_eRuntimeError, "--jit-" name " needs an argument"), 0)) - #define yjit_opt_match_noarg(s, l, name) \ opt_match(s, l, name) && (*(s) ? (rb_warn("argument to --yjit-" name " is ignored"), 1) : 1) #define yjit_opt_match_arg(s, l, name) \ @@ -1130,45 +1065,6 @@ setup_yjit_options(const char *s, struct rb_yjit_options *yjit_opt) } #endif -#if USE_MJIT -static void -setup_mjit_options(const char *s, struct mjit_options *mjit_opt) -{ - const size_t l = strlen(s); - if (l == 0) { - return; - } - else if (opt_match_noarg(s, l, "warnings")) { - mjit_opt->warnings = 1; - } - else if (opt_match(s, l, "debug")) { - if (*s) - mjit_opt->debug_flags = strdup(s + 1); - else - mjit_opt->debug = 1; - } - else if (opt_match_noarg(s, l, "wait")) { - mjit_opt->wait = 1; - } - else if (opt_match_noarg(s, l, "save-temps")) { - mjit_opt->save_temps = 1; - } - else if (opt_match(s, l, "verbose")) { - mjit_opt->verbose = *s ? atoi(s + 1) : 1; - } - else if (opt_match_arg(s, l, "max-cache")) { - mjit_opt->max_cache_size = atoi(s + 1); - } - else if (opt_match_arg(s, l, "min-calls")) { - mjit_opt->min_calls = atoi(s + 1); - } - else { - rb_raise(rb_eRuntimeError, - "invalid MJIT option `%s' (--help will show valid MJIT options)", s); - } -} -#endif - static long proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt) { @@ -1546,8 +1442,9 @@ proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt) } else if (is_option_with_optarg("mjit", '-', true, false, false)) { #if USE_MJIT + extern void mjit_setup_options(const char *s, struct mjit_options *mjit_opt); FEATURE_SET(opt->features, FEATURE_BIT(mjit)); - setup_mjit_options(s, &opt->mjit); + mjit_setup_options(s, &opt->mjit); #else rb_warn("MJIT support is disabled."); #endif |