|
42 | 42 | #error MMTk does not use transient heap. |
43 | 43 | #endif // USE_TRANSIENT_HEAP |
44 | 44 | #include "mmtk.h" |
| 45 | +#include "internal/cmdlineopt.h" |
45 | 46 |
|
46 | 47 | RubyUpcalls ruby_upcalls; |
47 | 48 | #endif |
@@ -156,6 +157,13 @@ RubyUpcalls ruby_upcalls; |
156 | 157 | #define MAP_ANONYMOUS MAP_ANON |
157 | 158 | #endif |
158 | 159 |
|
| 160 | +#ifdef USE_THIRD_PARTY_HEAP |
| 161 | +static char *mmtk_env_plan = NULL; |
| 162 | +static char *mmtk_pre_arg_plan = NULL; |
| 163 | +static char *mmtk_post_arg_plan = NULL; |
| 164 | +static char *mmtk_chosen_plan = NULL; |
| 165 | +#endif |
| 166 | + |
159 | 167 | static inline struct rbimpl_size_mul_overflow_tag |
160 | 168 | size_add_overflow(size_t x, size_t y) |
161 | 169 | { |
@@ -1442,7 +1450,7 @@ asan_poison_object_restore(VALUE obj, void *ptr) |
1442 | 1450 | #define FL_SET2(x,f) FL_CHECK2("FL_SET2", x, RBASIC(x)->flags |= (f)) |
1443 | 1451 | #define FL_UNSET2(x,f) FL_CHECK2("FL_UNSET2", x, RBASIC(x)->flags &= ~(f)) |
1444 | 1452 |
|
1445 | | -// Comment for easy location |
| 1453 | +// Comment for easy location |
1446 | 1454 | #ifdef USE_THIRD_PARTY_HEAP |
1447 | 1455 | #define RVALUE_MARK_BITMAP(obj) 0 |
1448 | 1456 | #define RVALUE_PIN_BITMAP(obj) 0 |
@@ -1863,10 +1871,20 @@ rb_objspace_alloc(void) |
1863 | 1871 | dont_gc_on(); |
1864 | 1872 |
|
1865 | 1873 | #ifdef USE_THIRD_PARTY_HEAP |
| 1874 | + if (!mmtk_env_plan && setenv("MMTK_PLAN", mmtk_chosen_plan, 0) != 0) { |
| 1875 | + fputs("[FATAL] could not set MMTK_PLAN\n", stderr); |
| 1876 | + exit(EXIT_FAILURE); |
| 1877 | + } |
| 1878 | + |
1866 | 1879 | // Note: the limit is currently broken for NoGC, but we still attempt to |
1867 | 1880 | // initialise it properly regardless. |
1868 | 1881 | // See https://github.com/mmtk/mmtk-core/issues/214 |
1869 | 1882 | mmtk_init_binding(rb_mmtk_heap_limit(), &ruby_upcalls); |
| 1883 | + |
| 1884 | + if (!mmtk_env_plan && unsetenv("MMTK_PLAN") != 0) { |
| 1885 | + fputs("[FATAL] could not unset MMTK_PLAN\n", stderr); |
| 1886 | + exit(EXIT_FAILURE); |
| 1887 | + } |
1870 | 1888 | #endif |
1871 | 1889 |
|
1872 | 1890 | return objspace; |
@@ -15092,4 +15110,93 @@ size_t rb_mmtk_heap_limit(void) { |
15092 | 15110 | } |
15093 | 15111 | } |
15094 | 15112 |
|
| 15113 | +void rb_mmtk_pre_process_opts(int argc, char **argv) { |
| 15114 | + bool enable_rubyopt = true; |
| 15115 | + |
| 15116 | + mmtk_env_plan = getenv("MMTK_PLAN"); |
| 15117 | + |
| 15118 | + for (int n = 1; n < argc; n++) { |
| 15119 | + if (strcmp(argv[n], "--") == 0) { |
| 15120 | + break; |
| 15121 | + } |
| 15122 | + else if (strcmp(argv[n], "--enable-rubyopt") == 0 |
| 15123 | + || strcmp(argv[n], "--enable=rubyopt") == 0) { |
| 15124 | + enable_rubyopt = true; |
| 15125 | + } |
| 15126 | + else if (strcmp(argv[n], "--disable-rubyopt") == 0 |
| 15127 | + || strcmp(argv[n], "--disable=rubyopt") == 0) { |
| 15128 | + enable_rubyopt = false; |
| 15129 | + } |
| 15130 | + else if (strncmp(argv[n], "--mmtk-plan=", strlen("--mmtk-plan=")) == 0) { |
| 15131 | + mmtk_pre_arg_plan = argv[n] + strlen("--mmtk-plan="); |
| 15132 | + } |
| 15133 | + } |
| 15134 | + |
| 15135 | + if (enable_rubyopt) { |
| 15136 | + char *env_args = getenv("RUBYOPT"); |
| 15137 | + if (env_args != NULL) { |
| 15138 | + while (*env_args != '\0') { |
| 15139 | + if (ISSPACE(*env_args)) { |
| 15140 | + env_args++; |
| 15141 | + } |
| 15142 | + else { |
| 15143 | + size_t length = 0; |
| 15144 | + while (env_args[length] != '\0' && !ISSPACE(env_args[length])) { |
| 15145 | + length++; |
| 15146 | + } |
| 15147 | + |
| 15148 | + if (strncmp(env_args, "--mmtk-plan=", strlen("--mmtk-plan=")) == 0) { |
| 15149 | + mmtk_pre_arg_plan = strndup(env_args + strlen("--mmtk-plan="), length - strlen("--mmtk-plan=")); |
| 15150 | + if (mmtk_pre_arg_plan == NULL) { |
| 15151 | + rb_bug("could not allocate space for argument"); |
| 15152 | + } |
| 15153 | + } |
| 15154 | + |
| 15155 | + env_args += length; |
| 15156 | + } |
| 15157 | + } |
| 15158 | + } |
| 15159 | + } |
| 15160 | + |
| 15161 | + if (enable_rubyopt && mmtk_env_plan && mmtk_pre_arg_plan && strcmp(mmtk_env_plan, mmtk_pre_arg_plan) != 0) { |
| 15162 | + fputs("[FATAL] MMTK_PLAN and --mmtk-plan do not agree\n", stderr); |
| 15163 | + exit(EXIT_FAILURE); |
| 15164 | + } |
| 15165 | + |
| 15166 | + if (enable_rubyopt && mmtk_env_plan) { |
| 15167 | + mmtk_chosen_plan = mmtk_env_plan; |
| 15168 | + } |
| 15169 | + else if (mmtk_pre_arg_plan) { |
| 15170 | + mmtk_chosen_plan = mmtk_pre_arg_plan; |
| 15171 | + } |
| 15172 | + else { |
| 15173 | + mmtk_chosen_plan = MMTK_DEFAULT_PLAN; |
| 15174 | + } |
| 15175 | +} |
| 15176 | + |
| 15177 | +#define opt_match_noarg(s, l, name) \ |
| 15178 | + opt_match(s, l, name) && (*(s) ? (rb_warn("argument to --mmtk-" name " is ignored"), 1) : 1) |
| 15179 | +#define opt_match_arg(s, l, name) \ |
| 15180 | + opt_match(s, l, name) && (*(s) ? 1 : (rb_raise(rb_eRuntimeError, "--mmtk-" name " needs an argument"), 0)) |
| 15181 | + |
| 15182 | +void rb_mmtk_post_process_opts(char *s) { |
| 15183 | + const size_t l = strlen(s); |
| 15184 | + if (l == 0) { |
| 15185 | + return; |
| 15186 | + } |
| 15187 | + if (opt_match_arg(s, l, "plan")) { |
| 15188 | + mmtk_post_arg_plan = s + 1; |
| 15189 | + } |
| 15190 | + else { |
| 15191 | + rb_raise(rb_eRuntimeError, |
| 15192 | + "invalid MMTk option `%s' (--help will show valid MMTk options)", s); |
| 15193 | + } |
| 15194 | +} |
| 15195 | + |
| 15196 | +void rb_mmtk_post_process_opts_finish(void) { |
| 15197 | + if (strcmp(mmtk_pre_arg_plan ? mmtk_pre_arg_plan : "", mmtk_post_arg_plan ? mmtk_post_arg_plan : "") != 0) { |
| 15198 | + rb_raise(rb_eRuntimeError, "--mmtk-plan values disagree"); |
| 15199 | + } |
| 15200 | +} |
| 15201 | + |
15095 | 15202 | #endif |
0 commit comments