1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

mjit.c: make some variables static again

and remove redundant mjit_ prefixes.

mjit_worker.c: ditto

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64290 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
k0kubun 2018-08-11 09:48:07 +00:00
parent a48d1d7991
commit 3c442229d6
2 changed files with 138 additions and 161 deletions

136
mjit.c
View file

@ -1,6 +1,6 @@
/********************************************************************** /**********************************************************************
mjit.c - Interface to MRI method JIT compiler for Ruby's main thread mjit.c - MRI method JIT compiler functions for Ruby's main thread
Copyright (C) 2017 Vladimir Makarov <vmakarov@redhat.com>. Copyright (C) 2017 Vladimir Makarov <vmakarov@redhat.com>.
@ -17,52 +17,6 @@
extern int rb_thread_create_mjit_thread(void (*worker_func)(void)); extern int rb_thread_create_mjit_thread(void (*worker_func)(void));
/* A copy of MJIT portion of MRI options since MJIT initialization. We
need them as MJIT threads still can work when the most MRI data were
freed. */
struct mjit_options mjit_opts;
/* TRUE if MJIT is enabled. */
int mjit_enabled = FALSE;
/* TRUE if JIT-ed code should be called. When `ruby_vm_event_enabled_flags & ISEQ_TRACE_EVENTS`
and `mjit_call_p == FALSE`, any JIT-ed code execution is cancelled as soon as possible. */
int mjit_call_p = FALSE;
/* Priority queue of iseqs waiting for JIT compilation.
This variable is a pointer to head unit of the queue. */
struct rb_mjit_unit_list mjit_unit_queue;
/* List of units which are successfully compiled. */
struct rb_mjit_unit_list mjit_active_units;
/* List of compacted so files which will be deleted in `mjit_finish()`. */
struct rb_mjit_unit_list mjit_compact_units;
/* The number of so far processed ISEQs, used to generate unique id. */
int mjit_current_unit_num;
/* A mutex for conitionals and critical sections. */
rb_nativethread_lock_t mjit_engine_mutex;
/* A thread conditional to wake up `mjit_finish` at the end of PCH thread. */
rb_nativethread_cond_t mjit_pch_wakeup;
/* A thread conditional to wake up the client if there is a change in
executed unit status. */
rb_nativethread_cond_t mjit_client_wakeup;
/* A thread conditional to wake up a worker if there we have something
to add or we need to stop MJIT engine. */
rb_nativethread_cond_t mjit_worker_wakeup;
/* A thread conditional to wake up workers if at the end of GC. */
rb_nativethread_cond_t mjit_gc_wakeup;
/* True when GC is working. */
int mjit_in_gc;
/* True when JIT is working. */
int mjit_in_jit;
/* Path of "/tmp", which can be changed to $TMP in MinGW. */
char *mjit_tmp_dir;
/* Hash like { 1 => true, 2 => true, ... } whose keys are valid `class_serial`s.
This is used to invalidate obsoleted CALL_CACHE. */
VALUE mjit_valid_class_serials;
extern const char *mjit_cc_path;
extern char *mjit_pch_file;
#ifndef _MSC_VER #ifndef _MSC_VER
/* Name of the header file. */ /* Name of the header file. */
extern char *mjit_header_file; extern char *mjit_header_file;
@ -152,7 +106,7 @@ init_list(struct rb_mjit_unit_list *list)
} }
/* Free unit list. This should be called only when worker is finished /* Free unit list. This should be called only when worker is finished
because node of mjit_unit_queue and one of mjit_active_units may have the same unit because node of unit_queue and one of active_units may have the same unit
during proceeding unit. */ during proceeding unit. */
static void static void
free_list(struct rb_mjit_unit_list *list) free_list(struct rb_mjit_unit_list *list)
@ -246,7 +200,7 @@ create_unit(const rb_iseq_t *iseq)
if (unit == NULL) if (unit == NULL)
return; return;
unit->id = mjit_current_unit_num++; unit->id = current_unit_num++;
unit->iseq = iseq; unit->iseq = iseq;
iseq->body->jit_unit = unit; iseq->body->jit_unit = unit;
} }
@ -283,20 +237,20 @@ unload_units(void)
rb_thread_t *th = NULL; rb_thread_t *th = NULL;
struct rb_mjit_unit_node *node, *next, *worst_node; struct rb_mjit_unit_node *node, *next, *worst_node;
struct mjit_cont *cont; struct mjit_cont *cont;
int delete_num, units_num = mjit_active_units.length; int delete_num, units_num = active_units.length;
/* For now, we don't unload units when ISeq is GCed. We should /* For now, we don't unload units when ISeq is GCed. We should
unload such ISeqs first here. */ unload such ISeqs first here. */
for (node = mjit_active_units.head; node != NULL; node = next) { for (node = active_units.head; node != NULL; node = next) {
next = node->next; next = node->next;
if (node->unit->iseq == NULL) { /* ISeq is GCed. */ if (node->unit->iseq == NULL) { /* ISeq is GCed. */
free_unit(node->unit); free_unit(node->unit);
remove_from_list(node, &mjit_active_units); remove_from_list(node, &active_units);
} }
} }
/* Detect units which are in use and can't be unloaded. */ /* Detect units which are in use and can't be unloaded. */
for (node = mjit_active_units.head; node != NULL; node = node->next) { for (node = active_units.head; node != NULL; node = node->next) {
assert(node->unit != NULL && node->unit->iseq != NULL && node->unit->handle != NULL); assert(node->unit != NULL && node->unit->iseq != NULL && node->unit->handle != NULL);
node->unit->used_code_p = FALSE; node->unit->used_code_p = FALSE;
} }
@ -308,13 +262,13 @@ unload_units(void)
} }
/* Remove 1/10 units more to decrease unloading calls. */ /* Remove 1/10 units more to decrease unloading calls. */
/* TODO: Calculate max total_calls in mjit_unit_queue and don't unload units /* TODO: Calculate max total_calls in unit_queue and don't unload units
whose total_calls are larger than the max. */ whose total_calls are larger than the max. */
delete_num = mjit_active_units.length / 10; delete_num = active_units.length / 10;
for (; mjit_active_units.length > mjit_opts.max_cache_size - delete_num;) { for (; active_units.length > mjit_opts.max_cache_size - delete_num;) {
/* Find one unit that has the minimum total_calls. */ /* Find one unit that has the minimum total_calls. */
worst_node = NULL; worst_node = NULL;
for (node = mjit_active_units.head; node != NULL; node = node->next) { for (node = active_units.head; node != NULL; node = node->next) {
if (node->unit->used_code_p) /* We can't unload code on stack. */ if (node->unit->used_code_p) /* We can't unload code on stack. */
continue; continue;
@ -329,9 +283,9 @@ unload_units(void)
verbose(2, "Unloading unit %d (calls=%lu)", worst_node->unit->id, worst_node->unit->iseq->body->total_calls); verbose(2, "Unloading unit %d (calls=%lu)", worst_node->unit->id, worst_node->unit->iseq->body->total_calls);
assert(worst_node->unit->handle != NULL); assert(worst_node->unit->handle != NULL);
free_unit(worst_node->unit); free_unit(worst_node->unit);
remove_from_list(worst_node, &mjit_active_units); remove_from_list(worst_node, &active_units);
} }
verbose(1, "Too many JIT code -- %d units unloaded", units_num - mjit_active_units.length); verbose(1, "Too many JIT code -- %d units unloaded", units_num - active_units.length);
} }
/* Add ISEQ to be JITed in parallel with the current thread. /* Add ISEQ to be JITed in parallel with the current thread.
@ -352,8 +306,8 @@ mjit_add_iseq_to_process(const rb_iseq_t *iseq)
node = create_list_node(iseq->body->jit_unit); node = create_list_node(iseq->body->jit_unit);
CRITICAL_SECTION_START(3, "in add_iseq_to_process"); CRITICAL_SECTION_START(3, "in add_iseq_to_process");
add_to_list(node, &mjit_unit_queue); add_to_list(node, &unit_queue);
if (mjit_active_units.length >= mjit_opts.max_cache_size) { if (active_units.length >= mjit_opts.max_cache_size) {
unload_units(); unload_units();
} }
verbose(3, "Sending wakeup signal to workers in mjit_add_iseq_to_process"); verbose(3, "Sending wakeup signal to workers in mjit_add_iseq_to_process");
@ -394,7 +348,7 @@ mjit_get_iseq_func(struct rb_iseq_constant_body *body)
extern VALUE ruby_archlibdir_path, ruby_prefix_path; extern VALUE ruby_archlibdir_path, ruby_prefix_path;
/* Initialize mjit_header_file, mjit_pch_file, mjit_libruby_pathflag. Return TRUE on success. */ /* Initialize mjit_header_file, pch_file, mjit_libruby_pathflag. Return TRUE on success. */
static int static int
init_header_filename(void) init_header_filename(void)
{ {
@ -447,21 +401,21 @@ init_header_filename(void)
(void)close(fd); (void)close(fd);
} }
mjit_pch_file = get_uniq_filename(0, MJIT_TMP_PREFIX "h", ".h.gch"); pch_file = get_uniq_filename(0, MJIT_TMP_PREFIX "h", ".h.gch");
if (mjit_pch_file == NULL) if (pch_file == NULL)
return FALSE; return FALSE;
#else #else
{ {
static const char pch_name[] = MJIT_PRECOMPILED_HEADER_NAME; static const char pch_name[] = MJIT_PRECOMPILED_HEADER_NAME;
const size_t pch_name_len = sizeof(pch_name) - 1; const size_t pch_name_len = sizeof(pch_name) - 1;
mjit_pch_file = xmalloc(baselen + pch_name_len + 1); pch_file = xmalloc(baselen + pch_name_len + 1);
p = append_str2(mjit_pch_file, basedir, baselen); p = append_str2(pch_file, basedir, baselen);
p = append_str2(p, pch_name, pch_name_len + 1); p = append_str2(p, pch_name, pch_name_len + 1);
if ((fd = rb_cloexec_open(mjit_pch_file, O_RDONLY, 0)) < 0) { if ((fd = rb_cloexec_open(pch_file, O_RDONLY, 0)) < 0) {
verbose(1, "Cannot access precompiled header file: %s", mjit_pch_file); verbose(1, "Cannot access precompiled header file: %s", pch_file);
xfree(mjit_pch_file); xfree(pch_file);
mjit_pch_file = NULL; pch_file = NULL;
return FALSE; return FALSE;
} }
(void)close(fd); (void)close(fd);
@ -638,10 +592,10 @@ mjit_init(struct mjit_options *opts)
#else #else
mjit_pch_status = PCH_NOT_READY; mjit_pch_status = PCH_NOT_READY;
#endif #endif
mjit_cc_path = CC_PATH; cc_path = CC_PATH;
mjit_tmp_dir = system_tmpdir(); tmp_dir = system_tmpdir();
verbose(2, "MJIT: mjit_tmp_dir is %s", mjit_tmp_dir); verbose(2, "MJIT: tmp_dir is %s", tmp_dir);
if (!init_header_filename()) { if (!init_header_filename()) {
mjit_enabled = FALSE; mjit_enabled = FALSE;
@ -649,9 +603,9 @@ mjit_init(struct mjit_options *opts)
return; return;
} }
init_list(&mjit_unit_queue); init_list(&unit_queue);
init_list(&mjit_active_units); init_list(&active_units);
init_list(&mjit_compact_units); init_list(&compact_units);
/* Initialize mutex */ /* Initialize mutex */
rb_native_mutex_initialize(&mjit_engine_mutex); rb_native_mutex_initialize(&mjit_engine_mutex);
@ -661,9 +615,9 @@ mjit_init(struct mjit_options *opts)
rb_native_cond_initialize(&mjit_gc_wakeup); rb_native_cond_initialize(&mjit_gc_wakeup);
/* Initialize class_serials cache for compilation */ /* Initialize class_serials cache for compilation */
mjit_valid_class_serials = rb_hash_new(); valid_class_serials = rb_hash_new();
rb_obj_hide(mjit_valid_class_serials); rb_obj_hide(valid_class_serials);
rb_gc_register_mark_object(mjit_valid_class_serials); rb_gc_register_mark_object(valid_class_serials);
mjit_add_class_serial(RCLASS_SERIAL(rb_cObject)); mjit_add_class_serial(RCLASS_SERIAL(rb_cObject));
mjit_add_class_serial(RCLASS_SERIAL(CLASS_OF(rb_vm_top_self()))); mjit_add_class_serial(RCLASS_SERIAL(CLASS_OF(rb_vm_top_self())));
if (RCLASS_CONST_TBL(rb_cObject)) { if (RCLASS_CONST_TBL(rb_cObject)) {
@ -706,7 +660,7 @@ mjit_pause(int wait_p)
tv.tv_sec = 0; tv.tv_sec = 0;
tv.tv_usec = 1000; tv.tv_usec = 1000;
while (mjit_unit_queue.length > 0) { while (unit_queue.length > 0) {
CRITICAL_SECTION_START(3, "in mjit_pause for a worker wakeup"); CRITICAL_SECTION_START(3, "in mjit_pause for a worker wakeup");
rb_native_cond_broadcast(&mjit_worker_wakeup); rb_native_cond_broadcast(&mjit_worker_wakeup);
CRITICAL_SECTION_FINISH(3, "in mjit_pause for a worker wakeup"); CRITICAL_SECTION_FINISH(3, "in mjit_pause for a worker wakeup");
@ -769,17 +723,17 @@ mjit_finish(void)
#ifndef _MSC_VER /* mswin has prebuilt precompiled header */ #ifndef _MSC_VER /* mswin has prebuilt precompiled header */
if (!mjit_opts.save_temps) if (!mjit_opts.save_temps)
remove_file(mjit_pch_file); remove_file(pch_file);
xfree(mjit_header_file); mjit_header_file = NULL; xfree(mjit_header_file); mjit_header_file = NULL;
#endif #endif
xfree(mjit_tmp_dir); mjit_tmp_dir = NULL; xfree(tmp_dir); tmp_dir = NULL;
xfree(mjit_pch_file); mjit_pch_file = NULL; xfree(pch_file); pch_file = NULL;
mjit_call_p = FALSE; mjit_call_p = FALSE;
free_list(&mjit_unit_queue); free_list(&unit_queue);
free_list(&mjit_active_units); free_list(&active_units);
free_list(&mjit_compact_units); free_list(&compact_units);
finish_conts(); finish_conts();
mjit_enabled = FALSE; mjit_enabled = FALSE;
@ -794,7 +748,7 @@ mjit_mark(void)
return; return;
RUBY_MARK_ENTER("mjit"); RUBY_MARK_ENTER("mjit");
CRITICAL_SECTION_START(4, "mjit_mark"); CRITICAL_SECTION_START(4, "mjit_mark");
for (node = mjit_unit_queue.head; node != NULL; node = node->next) { for (node = unit_queue.head; node != NULL; node = node->next) {
if (node->unit->iseq) { /* ISeq is still not GCed */ if (node->unit->iseq) { /* ISeq is still not GCed */
VALUE iseq = (VALUE)node->unit->iseq; VALUE iseq = (VALUE)node->unit->iseq;
CRITICAL_SECTION_FINISH(4, "mjit_mark rb_gc_mark"); CRITICAL_SECTION_FINISH(4, "mjit_mark rb_gc_mark");
@ -810,7 +764,7 @@ mjit_mark(void)
RUBY_MARK_LEAVE("mjit"); RUBY_MARK_LEAVE("mjit");
} }
/* A hook to update mjit_valid_class_serials. */ /* A hook to update valid_class_serials. */
void void
mjit_add_class_serial(rb_serial_t class_serial) mjit_add_class_serial(rb_serial_t class_serial)
{ {
@ -819,10 +773,10 @@ mjit_add_class_serial(rb_serial_t class_serial)
/* Do not wrap CRITICAL_SECTION here. This function is only called in main thread /* Do not wrap CRITICAL_SECTION here. This function is only called in main thread
and guarded by GVL, and `rb_hash_aset` may cause GC and deadlock in it. */ and guarded by GVL, and `rb_hash_aset` may cause GC and deadlock in it. */
rb_hash_aset(mjit_valid_class_serials, LONG2FIX(class_serial), Qtrue); rb_hash_aset(valid_class_serials, LONG2FIX(class_serial), Qtrue);
} }
/* A hook to update mjit_valid_class_serials. */ /* A hook to update valid_class_serials. */
void void
mjit_remove_class_serial(rb_serial_t class_serial) mjit_remove_class_serial(rb_serial_t class_serial)
{ {
@ -830,6 +784,6 @@ mjit_remove_class_serial(rb_serial_t class_serial)
return; return;
CRITICAL_SECTION_START(3, "in mjit_remove_class_serial"); CRITICAL_SECTION_START(3, "in mjit_remove_class_serial");
rb_hash_delete_entry(mjit_valid_class_serials, LONG2FIX(class_serial)); rb_hash_delete_entry(valid_class_serials, LONG2FIX(class_serial));
CRITICAL_SECTION_FINISH(3, "in mjit_remove_class_serial"); CRITICAL_SECTION_FINISH(3, "in mjit_remove_class_serial");
} }

View file

@ -157,14 +157,6 @@ extern void rb_native_cond_signal(rb_nativethread_cond_t *cond);
extern void rb_native_cond_broadcast(rb_nativethread_cond_t *cond); extern void rb_native_cond_broadcast(rb_nativethread_cond_t *cond);
extern void rb_native_cond_wait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex); extern void rb_native_cond_wait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex);
extern char *mjit_tmp_dir;
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", mjit_tmp_dir, prefix, getpid(), id, suffix);
}
/* Print the arguments according to FORMAT to stderr only if MJIT /* Print the arguments according to FORMAT to stderr only if MJIT
verbose option value is more or equal to LEVEL. */ verbose option value is more or equal to LEVEL. */
PRINTF_ARGS(static void, 2, 3) PRINTF_ARGS(static void, 2, 3)
@ -180,27 +172,6 @@ verbose(int level, const char *format, ...)
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
extern rb_nativethread_lock_t mjit_engine_mutex;
/* Start a critical section. Use message MSG to print debug info at
LEVEL. */
static inline void
CRITICAL_SECTION_START(int level, const char *msg)
{
verbose(level, "Locking %s", msg);
rb_native_mutex_lock(&mjit_engine_mutex);
verbose(level, "Locked %s", msg);
}
/* Finish the current critical section. Use message MSG to print
debug info at LEVEL. */
static inline void
CRITICAL_SECTION_FINISH(int level, const char *msg)
{
verbose(level, "Unlocked %s", msg);
rb_native_mutex_unlock(&mjit_engine_mutex);
}
/* Allocate struct rb_mjit_unit_node and return it. This MUST NOT be /* Allocate struct rb_mjit_unit_node and return it. This MUST NOT be
called inside critical section because that causes deadlock. ZALLOC called inside critical section because that causes deadlock. ZALLOC
may fire GC and GC hooks mjit_gc_start_hook that starts critical section. */ may fire GC and GC hooks mjit_gc_start_hook that starts critical section. */
@ -351,26 +322,54 @@ rb_pid_t ruby_waitpid_locked(rb_vm_t *, rb_pid_t, int *status, int options,
/* Atomically set function pointer if possible. */ /* Atomically set function pointer if possible. */
#define MJIT_ATOMIC_SET(var, val) (void)ATOMIC_PTR_EXCHANGE(var, val) #define MJIT_ATOMIC_SET(var, val) (void)ATOMIC_PTR_EXCHANGE(var, val)
extern struct mjit_options mjit_opts; /* A copy of MJIT portion of MRI options since MJIT initialization. We
extern int mjit_enabled; need them as MJIT threads still can work when the most MRI data were
freed. */
struct mjit_options mjit_opts;
extern struct rb_mjit_unit_list mjit_unit_queue; /* TRUE if MJIT is enabled. */
extern struct rb_mjit_unit_list mjit_active_units; int mjit_enabled = FALSE;
extern struct rb_mjit_unit_list mjit_compact_units; /* TRUE if JIT-ed code should be called. When `ruby_vm_event_enabled_flags & ISEQ_TRACE_EVENTS`
extern int mjit_current_unit_num; and `mjit_call_p == FALSE`, any JIT-ed code execution is cancelled as soon as possible. */
extern rb_nativethread_cond_t mjit_pch_wakeup; int mjit_call_p = FALSE;
extern rb_nativethread_cond_t mjit_client_wakeup;
extern rb_nativethread_cond_t mjit_worker_wakeup;
extern rb_nativethread_cond_t mjit_gc_wakeup;
extern int mjit_in_gc; /* Priority queue of iseqs waiting for JIT compilation.
extern int mjit_in_jit; This variable is a pointer to head unit of the queue. */
static struct rb_mjit_unit_list unit_queue;
/* List of units which are successfully compiled. */
static struct rb_mjit_unit_list active_units;
/* List of compacted so files which will be deleted in `mjit_finish()`. */
static struct rb_mjit_unit_list compact_units;
/* The number of so far processed ISEQs, used to generate unique id. */
static int current_unit_num;
/* A mutex for conitionals and critical sections. */
static rb_nativethread_lock_t mjit_engine_mutex;
/* A thread conditional to wake up `mjit_finish` at the end of PCH thread. */
static rb_nativethread_cond_t mjit_pch_wakeup;
/* A thread conditional to wake up the client if there is a change in
executed unit status. */
static rb_nativethread_cond_t mjit_client_wakeup;
/* A thread conditional to wake up a worker if there we have something
to add or we need to stop MJIT engine. */
static rb_nativethread_cond_t mjit_worker_wakeup;
/* A thread conditional to wake up workers if at the end of GC. */
static rb_nativethread_cond_t mjit_gc_wakeup;
/* True when GC is working. */
static int mjit_in_gc;
/* True when JIT is working. */
static int mjit_in_jit;
/* Path of "/tmp", which can be changed to $TMP in MinGW. */
static char *tmp_dir;
/* Hash like { 1 => true, 2 => true, ... } whose keys are valid `class_serial`s.
This is used to invalidate obsoleted CALL_CACHE. */
static VALUE valid_class_serials;
/* --- Defined in the client thread before starting MJIT threads: --- */ /* --- Defined in the client thread before starting MJIT threads: --- */
/* Used C compiler path. */ /* Used C compiler path. */
const char *mjit_cc_path; const char *cc_path;
/* Name of the precompiled header file. */ /* Name of the precompiled header file. */
char *mjit_pch_file; char *pch_file;
#ifndef _MSC_VER #ifndef _MSC_VER
/* Name of the header file. */ /* Name of the header file. */
@ -382,6 +381,31 @@ char *mjit_header_file;
char *mjit_libruby_pathflag; char *mjit_libruby_pathflag;
#endif #endif
/* Start a critical section. Use message MSG to print debug info at
LEVEL. */
static inline void
CRITICAL_SECTION_START(int level, const char *msg)
{
verbose(level, "Locking %s", msg);
rb_native_mutex_lock(&mjit_engine_mutex);
verbose(level, "Locked %s", msg);
}
/* Finish the current critical section. Use message MSG to print
debug info at LEVEL. */
static inline void
CRITICAL_SECTION_FINISH(int level, const char *msg)
{
verbose(level, "Unlocked %s", msg);
rb_native_mutex_unlock(&mjit_engine_mutex);
}
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 time in milliseconds as a double. */ /* Return time in milliseconds as a double. */
#ifdef __APPLE__ #ifdef __APPLE__
double ruby_real_ms_time(void); double ruby_real_ms_time(void);
@ -447,11 +471,10 @@ enum pch_status_t mjit_pch_status;
int int
mjit_valid_class_serial_p(rb_serial_t class_serial) mjit_valid_class_serial_p(rb_serial_t class_serial)
{ {
extern VALUE mjit_valid_class_serials;
int found_p; int found_p;
CRITICAL_SECTION_START(3, "in valid_class_serial_p"); CRITICAL_SECTION_START(3, "in valid_class_serial_p");
found_p = st_lookup(RHASH_TBL_RAW(mjit_valid_class_serials), LONG2FIX(class_serial), NULL); found_p = st_lookup(RHASH_TBL_RAW(valid_class_serials), LONG2FIX(class_serial), NULL);
CRITICAL_SECTION_FINISH(3, "in valid_class_serial_p"); CRITICAL_SECTION_FINISH(3, "in valid_class_serial_p");
return found_p; return found_p;
} }
@ -648,14 +671,14 @@ compile_c_to_so(const char *c_file, const char *so_file)
*p = '\0'; *p = '\0';
/* files[1] = "-Yu*.pch" */ /* files[1] = "-Yu*.pch" */
files[1] = p = (char *)alloca(sizeof(char) * (rb_strlen_lit("-Yu") + strlen(mjit_pch_file) + 1)); files[1] = p = (char *)alloca(sizeof(char) * (rb_strlen_lit("-Yu") + strlen(pch_file) + 1));
p = append_lit(p, "-Yu"); p = append_lit(p, "-Yu");
p = append_str2(p, mjit_pch_file, strlen(mjit_pch_file)); p = append_str2(p, pch_file, strlen(pch_file));
*p = '\0'; *p = '\0';
/* files[2] = "C:/.../rb_mjit_header-*.obj" */ /* files[2] = "C:/.../rb_mjit_header-*.obj" */
files[2] = p = (char *)alloca(sizeof(char) * (strlen(mjit_pch_file) + 1)); files[2] = p = (char *)alloca(sizeof(char) * (strlen(pch_file) + 1));
p = append_str2(p, mjit_pch_file, strlen(mjit_pch_file) - strlen(".pch")); p = append_str2(p, pch_file, strlen(pch_file) - strlen(".pch"));
p = append_lit(p, ".obj"); p = append_lit(p, ".obj");
*p = '\0'; *p = '\0';
@ -680,7 +703,7 @@ compile_c_to_so(const char *c_file, const char *so_file)
Creating library C:.../_ruby_mjit_p12u3.lib and object C:.../_ruby_mjit_p12u3.exp Creating library C:.../_ruby_mjit_p12u3.lib and object C:.../_ruby_mjit_p12u3.exp
TODO: Don't discard them on --jit-verbose=2+ */ TODO: Don't discard them on --jit-verbose=2+ */
dup2(dev_null, stdout_fileno); dup2(dev_null, stdout_fileno);
exit_code = exec_process(mjit_cc_path, args); exit_code = exec_process(cc_path, args);
dup2(orig_fd, stdout_fileno); dup2(orig_fd, stdout_fileno);
close(orig_fd); close(orig_fd);
@ -710,7 +733,7 @@ make_pch(void)
int len = sizeof(rest_args) / sizeof(const char *); int len = sizeof(rest_args) / sizeof(const char *);
rest_args[len - 2] = mjit_header_file; rest_args[len - 2] = mjit_header_file;
rest_args[len - 3] = mjit_pch_file; rest_args[len - 3] = pch_file;
verbose(2, "Creating precompiled header"); verbose(2, "Creating precompiled header");
args = form_args(3, CC_COMMON_ARGS, CC_CODEFLAG_ARGS, rest_args); args = form_args(3, CC_COMMON_ARGS, CC_CODEFLAG_ARGS, rest_args);
if (args == NULL) { if (args == NULL) {
@ -722,7 +745,7 @@ make_pch(void)
return; return;
} }
exit_code = exec_process(mjit_cc_path, args); exit_code = exec_process(cc_path, args);
free(args); free(args);
CRITICAL_SECTION_START(3, "in make_pch"); CRITICAL_SECTION_START(3, "in make_pch");
@ -755,13 +778,13 @@ compile_c_to_o(const char *c_file, const char *o_file)
files[1] = o_file; files[1] = o_file;
files[2] = c_file; files[2] = c_file;
# ifdef __clang__ # ifdef __clang__
files[4] = mjit_pch_file; files[4] = pch_file;
# endif # endif
args = form_args(5, CC_COMMON_ARGS, CC_CODEFLAG_ARGS, files, CC_LIBS, CC_DLDFLAGS_ARGS); args = form_args(5, CC_COMMON_ARGS, CC_CODEFLAG_ARGS, files, CC_LIBS, CC_DLDFLAGS_ARGS);
if (args == NULL) if (args == NULL)
return FALSE; return FALSE;
exit_code = exec_process(mjit_cc_path, args); exit_code = exec_process(cc_path, args);
free(args); free(args);
if (exit_code != 0) if (exit_code != 0)
@ -789,7 +812,7 @@ link_o_to_so(const char **o_files, const char *so_file)
if (args == NULL) if (args == NULL)
return FALSE; return FALSE;
exit_code = exec_process(mjit_cc_path, args); exit_code = exec_process(cc_path, args);
free(args); free(args);
if (exit_code != 0) if (exit_code != 0)
@ -814,14 +837,14 @@ compact_all_jit_code(void)
/* Abnormal use case of rb_mjit_unit that doesn't have ISeq */ /* Abnormal use case of rb_mjit_unit that doesn't have ISeq */
unit = (struct rb_mjit_unit *)calloc(1, sizeof(struct rb_mjit_unit)); /* To prevent GC, don't use ZALLOC */ unit = (struct rb_mjit_unit *)calloc(1, sizeof(struct rb_mjit_unit)); /* To prevent GC, don't use ZALLOC */
if (unit == NULL) return; if (unit == NULL) return;
unit->id = mjit_current_unit_num++; unit->id = current_unit_num++;
sprint_uniq_filename(so_file, (int)sizeof(so_file), unit->id, MJIT_TMP_PREFIX, so_ext); sprint_uniq_filename(so_file, (int)sizeof(so_file), unit->id, MJIT_TMP_PREFIX, so_ext);
/* NULL-ending for form_args */ /* NULL-ending for form_args */
o_files = (const char **)alloca(sizeof(char *) * (mjit_active_units.length + 1)); o_files = (const char **)alloca(sizeof(char *) * (active_units.length + 1));
o_files[mjit_active_units.length] = NULL; o_files[active_units.length] = NULL;
CRITICAL_SECTION_START(3, "in compact_all_jit_code to keep .o files"); CRITICAL_SECTION_START(3, "in compact_all_jit_code to keep .o files");
for (node = mjit_active_units.head; node != NULL; node = node->next) { for (node = active_units.head; node != NULL; node = node->next) {
o_files[i] = node->unit->o_file; o_files[i] = node->unit->o_file;
i++; i++;
} }
@ -849,7 +872,7 @@ compact_all_jit_code(void)
/* lazily dlclose handle (and .so file for win32) on `mjit_finish()`. */ /* lazily dlclose handle (and .so file for win32) on `mjit_finish()`. */
node = (struct rb_mjit_unit_node *)calloc(1, sizeof(struct rb_mjit_unit_node)); /* To prevent GC, don't use ZALLOC */ node = (struct rb_mjit_unit_node *)calloc(1, sizeof(struct rb_mjit_unit_node)); /* To prevent GC, don't use ZALLOC */
node->unit = unit; node->unit = unit;
add_to_list(node, &mjit_compact_units); add_to_list(node, &compact_units);
if (!mjit_opts.save_temps) { if (!mjit_opts.save_temps) {
# ifdef _WIN32 # ifdef _WIN32
@ -860,7 +883,7 @@ compact_all_jit_code(void)
} }
CRITICAL_SECTION_START(3, "in compact_all_jit_code to read list"); CRITICAL_SECTION_START(3, "in compact_all_jit_code to read list");
for (node = mjit_active_units.head; node != NULL; node = node->next) { for (node = active_units.head; node != NULL; node = node->next) {
void *func; void *func;
char funcname[35]; /* TODO: reconsider `35` */ char funcname[35]; /* TODO: reconsider `35` */
sprintf(funcname, "_mjit%d", node->unit->id); sprintf(funcname, "_mjit%d", node->unit->id);
@ -877,7 +900,7 @@ compact_all_jit_code(void)
} }
} }
CRITICAL_SECTION_FINISH(3, "in compact_all_jit_code to read list"); CRITICAL_SECTION_FINISH(3, "in compact_all_jit_code to read list");
verbose(1, "JIT compaction (%.1fms): Compacted %d methods -> %s", end_time - start_time, mjit_active_units.length, so_file); verbose(1, "JIT compaction (%.1fms): Compacted %d methods -> %s", end_time - start_time, active_units.length, so_file);
} }
else { else {
free(unit); free(unit);
@ -935,11 +958,11 @@ static void
compile_prelude(FILE *f) compile_prelude(FILE *f)
{ {
#ifndef __clang__ /* -include-pch is used for Clang */ #ifndef __clang__ /* -include-pch is used for Clang */
const char *s = mjit_pch_file; const char *s = pch_file;
const char *e = header_name_end(s); const char *e = header_name_end(s);
fprintf(f, "#include \""); fprintf(f, "#include \"");
/* print mjit_pch_file except .gch for gcc, but keep .pch for mswin */ /* print pch_file except .gch for gcc, but keep .pch for mswin */
for (; s < e; s++) { for (; s < e; s++) {
switch(*s) { switch(*s) {
case '\\': case '"': case '\\': case '"':
@ -1079,7 +1102,7 @@ convert_unit_to_func(struct rb_mjit_unit *unit)
if ((uintptr_t)func > (uintptr_t)LAST_JIT_ISEQ_FUNC) { if ((uintptr_t)func > (uintptr_t)LAST_JIT_ISEQ_FUNC) {
struct rb_mjit_unit_node *node = create_list_node(unit); struct rb_mjit_unit_node *node = create_list_node(unit);
CRITICAL_SECTION_START(3, "end of jit"); CRITICAL_SECTION_START(3, "end of jit");
add_to_list(node, &mjit_active_units); add_to_list(node, &active_units);
if (unit->iseq) if (unit->iseq)
print_jit_result("success", unit, end_time - start_time, c_file); print_jit_result("success", unit, end_time - start_time, c_file);
CRITICAL_SECTION_FINISH(3, "end of jit"); CRITICAL_SECTION_FINISH(3, "end of jit");
@ -1119,11 +1142,11 @@ mjit_worker(void)
/* wait until unit is available */ /* wait until unit is available */
CRITICAL_SECTION_START(3, "in worker dequeue"); CRITICAL_SECTION_START(3, "in worker dequeue");
while ((mjit_unit_queue.head == NULL || mjit_active_units.length > mjit_opts.max_cache_size) && !mjit_stop_worker_p) { while ((unit_queue.head == NULL || active_units.length > mjit_opts.max_cache_size) && !mjit_stop_worker_p) {
rb_native_cond_wait(&mjit_worker_wakeup, &mjit_engine_mutex); rb_native_cond_wait(&mjit_worker_wakeup, &mjit_engine_mutex);
verbose(3, "Getting wakeup from client"); verbose(3, "Getting wakeup from client");
} }
node = get_from_list(&mjit_unit_queue); node = get_from_list(&unit_queue);
CRITICAL_SECTION_FINISH(3, "in worker dequeue"); CRITICAL_SECTION_FINISH(3, "in worker dequeue");
if (node) { if (node) {
@ -1134,13 +1157,13 @@ mjit_worker(void)
/* Usage of jit_code might be not in a critical section. */ /* Usage of jit_code might be not in a critical section. */
MJIT_ATOMIC_SET(node->unit->iseq->body->jit_func, func); MJIT_ATOMIC_SET(node->unit->iseq->body->jit_func, func);
} }
remove_from_list(node, &mjit_unit_queue); remove_from_list(node, &unit_queue);
CRITICAL_SECTION_FINISH(3, "in jit func replace"); CRITICAL_SECTION_FINISH(3, "in jit func replace");
#ifndef _MSC_VER #ifndef _MSC_VER
/* Combine .o files to one .so and reload all jit_func to improve memory locality */ /* Combine .o files to one .so and reload all jit_func to improve memory locality */
if ((!mjit_opts.wait && mjit_unit_queue.length == 0 && mjit_active_units.length > 1) if ((!mjit_opts.wait && unit_queue.length == 0 && active_units.length > 1)
|| mjit_active_units.length == mjit_opts.max_cache_size) { || active_units.length == mjit_opts.max_cache_size) {
compact_all_jit_code(); compact_all_jit_code();
} }
#endif #endif