summaryrefslogtreecommitdiff
path: root/mjit_worker.c
diff options
context:
space:
mode:
Diffstat (limited to 'mjit_worker.c')
-rw-r--r--mjit_worker.c297
1 files changed, 146 insertions, 151 deletions
diff --git a/mjit_worker.c b/mjit_worker.c
index 9936c255d9..06d259bc06 100644
--- a/mjit_worker.c
+++ b/mjit_worker.c
@@ -6,9 +6,9 @@
**********************************************************************/
-/* NOTE: All functions in this file are executed on MJIT worker. So don't
- call Ruby methods (C functions that may call rb_funcall) or trigger
- GC (using ZALLOC, xmalloc, xfree, etc.) in this file. */
+// NOTE: All functions in this file are executed on MJIT worker. So don't
+// call Ruby methods (C functions that may call rb_funcall) or trigger
+// GC (using ZALLOC, xmalloc, xfree, etc.) in this file.
/* We utilize widely used C compilers (GCC and LLVM Clang) to
implement MJIT. We feed them a C code generated from ISEQ. The
@@ -97,7 +97,7 @@
#include "dln.h"
#include "ruby/util.h"
-#undef strdup /* ruby_strdup may trigger GC */
+#undef strdup // ruby_strdup may trigger GC
#ifndef MAXPATHLEN
# define MAXPATHLEN 1024
@@ -117,41 +117,41 @@
typedef intptr_t pid_t;
#endif
-/* 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_TMP_PREFIX "_ruby_mjit_"
-/* The unit structure that holds metadata of ISeq for MJIT. */
+// The unit structure that holds metadata of ISeq for MJIT.
struct rb_mjit_unit {
- /* Unique order number of unit. */
+ // Unique order number of unit.
int id;
- /* Dlopen handle of the loaded object file. */
+ // Dlopen handle of the loaded object file.
void *handle;
const rb_iseq_t *iseq;
#ifndef _MSC_VER
- /* This value is always set for `compact_all_jit_code`. Also used for lazy deletion. */
+ // This value is always set for `compact_all_jit_code`. Also used for lazy deletion.
char *o_file;
- /* true if it's inherited from parent Ruby process and lazy deletion should be skipped.
- `o_file = NULL` can't be used to skip lazy deletion because `o_file` could be used
- by child for `compact_all_jit_code`. */
+ // true if it's inherited from parent Ruby process and lazy deletion should be skipped.
+ // `o_file = NULL` can't be used to skip lazy deletion because `o_file` could be used
+ // by child for `compact_all_jit_code`.
bool o_file_inherited_p;
#endif
#if defined(_WIN32)
- /* DLL cannot be removed while loaded on Windows. If this is set, it'll be lazily deleted. */
+ // DLL cannot be removed while loaded on Windows. If this is set, it'll be lazily deleted.
char *so_file;
#endif
- /* Only used by unload_units. Flag to check this unit is currently on stack or not. */
+ // Only used by unload_units. Flag to check this unit is currently on stack or not.
char used_code_p;
struct list_node unode;
// mjit_compile's optimization switches
struct rb_mjit_compile_info compile_info;
};
-/* Linked list of struct rb_mjit_unit. */
+// Linked list of struct rb_mjit_unit.
struct rb_mjit_unit_list {
struct list_head head;
- int length; /* the list length */
+ int length; // the list length
};
extern void rb_native_mutex_lock(rb_nativethread_lock_t *lock);
@@ -165,12 +165,12 @@ 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_wait(rb_nativethread_cond_t *cond, rb_nativethread_lock_t *mutex);
-/* process.c */
+// process.c
extern rb_pid_t ruby_waitpid_locked(rb_vm_t *, rb_pid_t, int *status, int options, rb_nativethread_cond_t *cond);
-/* 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. */
+// 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.
@@ -179,28 +179,28 @@ bool mjit_enabled = false;
// and `mjit_call_p == false`, any JIT-ed code execution is cancelled as soon as possible.
bool mjit_call_p = false;
-/* Priority queue of iseqs waiting for JIT compilation.
- This variable is a pointer to head unit of the queue. */
+// Priority queue of iseqs waiting for JIT compilation.
+// This variable is a pointer to head unit of the queue.
static struct rb_mjit_unit_list unit_queue = { LIST_HEAD_INIT(unit_queue.head) };
-/* List of units which are successfully compiled. */
+// List of units which are successfully compiled.
static struct rb_mjit_unit_list active_units = { LIST_HEAD_INIT(active_units.head) };
-/* List of compacted so files which will be cleaned up by `free_list()` in `mjit_finish()`. */
+// List of compacted so files which will be cleaned up by `free_list()` in `mjit_finish()`.
static struct rb_mjit_unit_list compact_units = { LIST_HEAD_INIT(compact_units.head) };
// List of units before recompilation and just waiting for dlclose().
static struct rb_mjit_unit_list stale_units = { LIST_HEAD_INIT(stale_units.head) };
-/* The number of so far processed ISEQs, used to generate unique id. */
+// The number of so far processed ISEQs, used to generate unique id.
static int current_unit_num;
-/* A mutex for conitionals and critical sections. */
+// 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. */
+// 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. */
+// 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. */
+// 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. */
+// 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 bool in_gc;
@@ -211,31 +211,31 @@ static bool stop_worker_p;
// Set to true if worker is stopped.
static bool worker_stopped;
-/* Path of "/tmp", which can be changed to $TMP in MinGW. */
+// 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. */
+// 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;
-/* Used C compiler path. */
+// Used C compiler path.
static const char *cc_path;
-/* Used C compiler flags. */
+// Used C compiler flags.
static const char **cc_common_args;
-/* Name of the precompiled header file. */
+// Name of the precompiled header file.
static char *pch_file;
-/* The process id which should delete the pch_file on mjit_finish. */
+// The process id which should delete the pch_file on mjit_finish.
static rb_pid_t pch_owner_pid;
-/* Status of the precompiled header creation. The status is
- shared by the workers and the pch thread. */
+// Status of the precompiled header creation. The status is
+// shared by the workers and the pch thread.
static enum {PCH_NOT_READY, PCH_FAILED, PCH_SUCCESS} pch_status;
#ifndef _MSC_VER
-/* Name of the header file. */
+// Name of the header file.
static char *header_file;
#endif
#ifdef _WIN32
-/* Linker option to enable libruby. */
+// Linker option to enable libruby.
static char *libruby_pathflag;
#endif
@@ -256,7 +256,7 @@ static char *libruby_pathflag;
#if defined __GNUC__ && !defined __clang__ && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(_AIX) && !defined(__OpenBSD__)
# define GCC_NOSTDLIB_FLAGS "-nodefaultlibs", "-nostdlib",
#else
-# define GCC_NOSTDLIB_FLAGS /* empty */
+# define GCC_NOSTDLIB_FLAGS // empty
#endif
static const char *const CC_COMMON_ARGS[] = {
@@ -291,8 +291,8 @@ static const char *const CC_LIBS[] = {
#define CC_CODEFLAG_ARGS (mjit_opts.debug ? CC_DEBUG_ARGS : CC_OPTIMIZE_ARGS)
-/* Print the arguments according to FORMAT to stderr only if MJIT
- verbose option value is more or equal to LEVEL. */
+// Print the arguments according to FORMAT to stderr only if MJIT
+// verbose option value is more or equal to LEVEL.
PRINTF_ARGS(static void, 2, 3)
verbose(int level, const char *format, ...)
{
@@ -301,7 +301,7 @@ verbose(int level, const char *format, ...)
size_t len = strlen(format);
char *full_format = alloca(sizeof(char) * (len + 2));
- /* Creating `format + '\n'` to atomically print format and '\n'. */
+ // Creating `format + '\n'` to atomically print format and '\n'.
memcpy(full_format, format, len);
full_format[len] = '\n';
full_format[len+1] = '\0';
@@ -326,8 +326,8 @@ mjit_warning(const char *format, ...)
}
}
-/* Add unit node to the tail of doubly linked LIST. It should be not in
- the list before. */
+// Add unit node to the tail of doubly linked `list`. It should be not in
+// the list before.
static void
add_to_list(struct rb_mjit_unit *unit, struct rb_mjit_unit_list *list)
{
@@ -360,7 +360,7 @@ remove_file(const char *filename)
}
}
-/* Lazily delete .o and/or .so files. */
+// Lazily delete .o and/or .so files.
static void
clean_object_files(struct rb_mjit_unit *unit)
{
@@ -369,8 +369,8 @@ clean_object_files(struct rb_mjit_unit *unit)
char *o_file = unit->o_file;
unit->o_file = NULL;
- /* For compaction, unit->o_file is always set when compilation succeeds.
- So save_temps needs to be checked here. */
+ // For compaction, unit->o_file is always set when compilation succeeds.
+ // So save_temps needs to be checked here.
if (!mjit_opts.save_temps && !unit->o_file_inherited_p)
remove_file(o_file);
free(o_file);
@@ -389,30 +389,29 @@ clean_object_files(struct rb_mjit_unit *unit)
#endif
}
-/* This is called in the following situations:
- 1) On dequeue or `unload_units()`, associated ISeq is already GCed.
- 2) The unit is not called often and unloaded by `unload_units()`.
- 3) Freeing lists on `mjit_finish()`.
-
- `jit_func` value does not matter for 1 and 3 since the unit won't be used anymore.
- For the situation 2, this sets the ISeq's JIT state to NOT_COMPILED_JIT_ISEQ_FUNC
- to prevent the situation that the same methods are continuously compiled. */
+// This is called in the following situations:
+// 1) On dequeue or `unload_units()`, associated ISeq is already GCed.
+// 2) The unit is not called often and unloaded by `unload_units()`.
+// 3) Freeing lists on `mjit_finish()`.
+//
+// `jit_func` value does not matter for 1 and 3 since the unit won't be used anymore.
+// For the situation 2, this sets the ISeq's JIT state to NOT_COMPILED_JIT_ISEQ_FUNC
+// to prevent the situation that the same methods are continuously compiled.
static void
free_unit(struct rb_mjit_unit *unit)
{
- if (unit->iseq) { /* ISeq is not GCed */
+ if (unit->iseq) { // ISeq is not GCed
unit->iseq->body->jit_func = (mjit_func_t)NOT_COMPILED_JIT_ISEQ_FUNC;
unit->iseq->body->jit_unit = NULL;
}
- if (unit->handle && dlclose(unit->handle)) { /* handle is NULL if it's in queue */
+ if (unit->handle && dlclose(unit->handle)) { // handle is NULL if it's in queue
mjit_warning("failed to close handle for u%d: %s", unit->id, dlerror());
}
clean_object_files(unit);
free(unit);
}
-/* Start a critical section. Use message MSG to print debug info at
- LEVEL. */
+// Start a critical section. Use message `msg` to print debug info at `level`.
static inline void
CRITICAL_SECTION_START(int level, const char *msg)
{
@@ -421,8 +420,8 @@ CRITICAL_SECTION_START(int level, const char *msg)
verbose(level, "Locked %s", msg);
}
-/* Finish the current critical section. Use message MSG to print
- debug info at LEVEL. */
+// 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)
{
@@ -436,7 +435,7 @@ sprint_uniq_filename(char *str, size_t size, unsigned long id, const char *prefi
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__
double ruby_real_ms_time(void);
# define real_ms_time() ruby_real_ms_time()
@@ -473,17 +472,17 @@ mjit_valid_class_serial_p(rb_serial_t class_serial)
return found_p;
}
-/* Return the best unit from list. The best is the first
- high priority unit or the unit whose iseq has the biggest number
- of calls so far. */
+// Return the best unit from list. The best is the first
+// high priority unit or the unit whose iseq has the biggest number
+// of calls so far.
static struct rb_mjit_unit *
get_from_list(struct rb_mjit_unit_list *list)
{
struct rb_mjit_unit *unit = NULL, *next, *best = NULL;
- /* Find iseq with max total_calls */
+ // Find iseq with max total_calls
list_for_each_safe(&list->head, unit, next, unode) {
- if (unit->iseq == NULL) { /* ISeq is GCed. */
+ if (unit->iseq == NULL) { // ISeq is GCed.
remove_from_list(unit, list);
free_unit(unit);
continue;
@@ -499,8 +498,7 @@ get_from_list(struct rb_mjit_unit_list *list)
return best;
}
-/* Return length of NULL-terminated array ARGS excluding the NULL
- marker. */
+// Return length of NULL-terminated array `args` excluding the NULL marker.
static size_t
args_len(char *const *args)
{
@@ -511,9 +509,8 @@ args_len(char *const *args)
return i;
}
-/* Concatenate NUM passed NULL-terminated arrays of strings, put the
- result (with NULL end marker) into the heap, and return the
- result. */
+// Concatenate `num` passed NULL-terminated arrays of strings, put the
+// result (with NULL end marker) into the heap, and return the result.
static char **
form_args(int num, ...)
{
@@ -543,16 +540,14 @@ COMPILER_WARNING_PUSH
#ifdef __GNUC__
COMPILER_WARNING_IGNORED(-Wdeprecated-declarations)
#endif
-/* Start an OS process of absolute executable path with arguments ARGV.
- Return PID of the process. */
+// Start an OS process of absolute executable path with arguments `argv`.
+// Return PID of the process.
static pid_t
start_process(const char *abspath, char *const *argv)
{
pid_t pid;
- /*
- * Not calling non-async-signal-safe functions between vfork
- * and execv for safety
- */
+ // Not calling non-async-signal-safe functions between vfork
+ // and execv for safety
int dev_null = rb_cloexec_open(ruby_null_device, O_WRONLY, 0);
if (mjit_opts.verbose >= 2) {
@@ -569,9 +564,9 @@ start_process(const char *abspath, char *const *argv)
extern HANDLE rb_w32_start_process(const char *abspath, char *const *argv, int out_fd);
int out_fd = 0;
if (mjit_opts.verbose <= 1) {
- /* Discard cl.exe's outputs like:
- _ruby_mjit_p12u3.c
- Creating library C:.../_ruby_mjit_p12u3.lib and object C:.../_ruby_mjit_p12u3.exp */
+ // Discard cl.exe's outputs like:
+ // _ruby_mjit_p12u3.c
+ // Creating library C:.../_ruby_mjit_p12u3.lib and object C:.../_ruby_mjit_p12u3.exp
out_fd = dev_null;
}
@@ -585,17 +580,17 @@ start_process(const char *abspath, char *const *argv)
if ((pid = vfork()) == 0) { /* TODO: reuse some function in process.c */
umask(0077);
if (mjit_opts.verbose == 0) {
- /* CC can be started in a thread using a file which has been
- already removed while MJIT is finishing. Discard the
- messages about missing files. */
+ // CC can be started in a thread using a file which has been
+ // already removed while MJIT is finishing. Discard the
+ // messages about missing files.
dup2(dev_null, STDERR_FILENO);
dup2(dev_null, STDOUT_FILENO);
}
(void)close(dev_null);
- pid = execv(abspath, argv); /* Pid will be negative on an error */
- /* Even if we successfully found CC to compile PCH we still can
- fail with loading the CC in very rare cases for some reasons.
- Stop the forked process in this case. */
+ pid = execv(abspath, argv); // Pid will be negative on an error
+ // Even if we successfully found CC to compile PCH we still can
+ // fail with loading the CC in very rare cases for some reasons.
+ // Stop the forked process in this case.
verbose(1, "MJIT: Error in execv: %s", abspath);
_exit(1);
}
@@ -605,9 +600,9 @@ start_process(const char *abspath, char *const *argv)
}
COMPILER_WARNING_POP
-/* Execute an OS process of executable PATH with arguments ARGV.
- Return -1 or -2 if failed to execute, otherwise exit code of the process.
- TODO: Use a similar function in process.c */
+// Execute an OS process of executable PATH with arguments ARGV.
+// Return -1 or -2 if failed to execute, otherwise exit code of the process.
+// TODO: Use a similar function in process.c
static int
exec_process(const char *path, char *const argv[])
{
@@ -655,8 +650,8 @@ static void
remove_so_file(const char *so_file, struct rb_mjit_unit *unit)
{
#if defined(_WIN32)
- /* Windows can't remove files while it's used. */
- unit->so_file = strdup(so_file); /* lazily delete on `clean_object_files()` */
+ // Windows can't remove files while it's used.
+ unit->so_file = strdup(so_file); // lazily delete on `clean_object_files()`
if (unit->so_file == NULL)
mjit_warning("failed to allocate memory to lazily remove '%s': %s", so_file, strerror(errno));
#else
@@ -678,39 +673,39 @@ compile_c_to_so(const char *c_file, const char *so_file)
char **args;
char *p, *obj_file;
- /* files[0] = "-Fe*.dll" */
+ // files[0] = "-Fe*.dll"
files[0] = p = alloca(sizeof(char) * (rb_strlen_lit("-Fe") + strlen(so_file) + 1));
p = append_lit(p, "-Fe");
p = append_str2(p, so_file, strlen(so_file));
*p = '\0';
- /* files[1] = "-Fo*.obj" */
- /* We don't need .obj file, but it's somehow created to cwd without -Fo and we want to control the output directory. */
+ // files[1] = "-Fo*.obj"
+ // We don't need .obj file, but it's somehow created to cwd without -Fo and we want to control the output directory.
files[1] = p = alloca(sizeof(char) * (rb_strlen_lit("-Fo") + strlen(so_file) - rb_strlen_lit(DLEXT) + rb_strlen_lit(".obj") + 1));
obj_file = p = append_lit(p, "-Fo");
p = append_str2(p, so_file, strlen(so_file) - rb_strlen_lit(DLEXT));
p = append_lit(p, ".obj");
*p = '\0';
- /* files[2] = "-Yu*.pch" */
+ // files[2] = "-Yu*.pch"
files[2] = p = alloca(sizeof(char) * (rb_strlen_lit("-Yu") + strlen(pch_file) + 1));
p = append_lit(p, "-Yu");
p = append_str2(p, pch_file, strlen(pch_file));
*p = '\0';
- /* files[3] = "C:/.../rb_mjit_header-*.obj" */
+ // files[3] = "C:/.../rb_mjit_header-*.obj"
files[3] = p = alloca(sizeof(char) * (strlen(pch_file) + 1));
p = append_str2(p, pch_file, strlen(pch_file) - strlen(".pch"));
p = append_lit(p, ".obj");
*p = '\0';
- /* files[4] = "-Tc*.c" */
+ // files[4] = "-Tc*.c"
files[4] = p = alloca(sizeof(char) * (rb_strlen_lit("-Tc") + strlen(c_file) + 1));
p = append_lit(p, "-Tc");
p = append_str2(p, c_file, strlen(c_file));
*p = '\0';
- /* files[5] = "-Fd*.pdb" */
+ // files[5] = "-Fd*.pdb"
files[5] = p = alloca(sizeof(char) * (rb_strlen_lit("-Fd") + strlen(pch_file) + 1));
p = append_lit(p, "-Fd");
p = append_str2(p, pch_file, strlen(pch_file) - rb_strlen_lit(".pch"));
@@ -726,7 +721,7 @@ compile_c_to_so(const char *c_file, const char *so_file)
free(args);
if (exit_code == 0) {
- /* remove never-used files (.obj, .lib, .exp, .pdb). XXX: Is there any way not to generate this? */
+ // remove never-used files (.obj, .lib, .exp, .pdb). XXX: Is there any way not to generate this?
if (!mjit_opts.save_temps) {
char *before_dot;
remove_file(obj_file);
@@ -742,9 +737,9 @@ compile_c_to_so(const char *c_file, const char *so_file)
}
return exit_code == 0;
}
-#else /* _MSC_VER */
+#else // _MSC_VER
-/* The function producing the pre-compiled header. */
+// The function producing the pre-compiled header.
static void
make_pch(void)
{
@@ -849,12 +844,12 @@ link_o_to_so(const char **o_files, const char *so_file)
return exit_code == 0;
}
-/* Link all cached .o files and build a .so file. Reload all JIT func from it. This
- allows to avoid JIT code fragmentation and improve performance to call JIT-ed code. */
+// Link all cached .o files and build a .so file. Reload all JIT func from it. This
+// allows to avoid JIT code fragmentation and improve performance to call JIT-ed code.
static void
compact_all_jit_code(void)
{
-# ifndef _WIN32 /* This requires header transformation but we don't transform header on Windows for now */
+# ifndef _WIN32 // This requires header transformation but we don't transform header on Windows for now
struct rb_mjit_unit *unit, *cur = 0;
double start_time, end_time;
static const char so_ext[] = DLEXT;
@@ -862,13 +857,13 @@ compact_all_jit_code(void)
const char **o_files;
int i = 0;
- /* Abnormal use case of rb_mjit_unit that doesn't have ISeq */
- unit = calloc(1, sizeof(struct rb_mjit_unit)); /* To prevent GC, don't use ZALLOC */
+ // Abnormal use case of rb_mjit_unit that doesn't have ISeq
+ unit = calloc(1, sizeof(struct rb_mjit_unit)); // To prevent GC, don't use ZALLOC
if (unit == NULL) return;
unit->id = current_unit_num++;
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 = alloca(sizeof(char *) * (active_units.length + 1));
o_files[active_units.length] = NULL;
CRITICAL_SECTION_START(3, "in compact_all_jit_code to keep .o files");
@@ -881,10 +876,10 @@ compact_all_jit_code(void)
bool success = link_o_to_so(o_files, so_file);
end_time = real_ms_time();
- /* TODO: Shrink this big critical section. For now, this is needed to prevent failure by missing .o files.
- This assumes that o -> so link doesn't take long time because the bottleneck, which is compiler optimization,
- is already done. But actually it takes about 500ms for 5,000 methods on my Linux machine, so it's better to
- finish this critical section before link_o_to_so by disabling unload_units. */
+ // TODO: Shrink this big critical section. For now, this is needed to prevent failure by missing .o files.
+ // This assumes that o -> so link doesn't take long time because the bottleneck, which is compiler optimization,
+ // is already done. But actually it takes about 500ms for 5,000 methods on my Linux machine, so it's better to
+ // finish this critical section before link_o_to_so by disabling unload_units.
CRITICAL_SECTION_FINISH(3, "in compact_all_jit_code to keep .o files");
if (success) {
@@ -896,7 +891,7 @@ compact_all_jit_code(void)
}
unit->handle = handle;
- /* lazily dlclose handle (and .so file for win32) on `mjit_finish()`. */
+ // lazily dlclose handle (and .so file for win32) on `mjit_finish()`.
add_to_list(unit, &compact_units);
if (!mjit_opts.save_temps)
@@ -905,7 +900,7 @@ compact_all_jit_code(void)
CRITICAL_SECTION_START(3, "in compact_all_jit_code to read list");
list_for_each(&active_units.head, cur, unode) {
void *func;
- char funcname[35]; /* TODO: reconsider `35` */
+ char funcname[35]; // TODO: reconsider `35`
sprintf(funcname, "_mjit%d", cur->id);
if ((func = dlsym(handle, funcname)) == NULL) {
@@ -913,8 +908,8 @@ compact_all_jit_code(void)
continue;
}
- if (cur->iseq) { /* Check whether GCed or not */
- /* Usage of jit_code might be not in a critical section. */
+ if (cur->iseq) { // Check whether GCed or not
+ // Usage of jit_code might be not in a critical section.
MJIT_ATOMIC_SET(cur->iseq->body->jit_func, (mjit_func_t)func);
}
}
@@ -925,10 +920,10 @@ compact_all_jit_code(void)
free(unit);
verbose(1, "JIT compaction failure (%.1fms): Failed to compact methods", end_time - start_time);
}
-# endif /* _WIN32 */
+# endif // _WIN32
}
-#endif /* _MSC_VER */
+#endif // _MSC_VER
static void *
load_func_from_so(const char *so_file, const char *funcname, struct rb_mjit_unit *unit)
@@ -959,10 +954,10 @@ static const char *
header_name_end(const char *s)
{
const char *e = s + strlen(s);
-# ifdef __GNUC__ /* don't chomp .pch for mswin */
+# ifdef __GNUC__ // don't chomp .pch for mswin
static const char suffix[] = ".gch";
- /* chomp .gch suffix */
+ // chomp .gch suffix
if (e > s+sizeof(suffix)-1 && strcmp(e-sizeof(suffix)+1, suffix) == 0) {
e -= sizeof(suffix)-1;
}
@@ -971,16 +966,16 @@ header_name_end(const char *s)
}
#endif
-/* Print platform-specific prerequisites in generated code. */
+// Print platform-specific prerequisites in generated code.
static void
compile_prelude(FILE *f)
{
-#ifndef __clang__ /* -include-pch is used for Clang */
+#ifndef __clang__ // -include-pch is used for Clang
const char *s = pch_file;
const char *e = header_name_end(s);
fprintf(f, "#include \"");
- /* print 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++) {
switch(*s) {
case '\\': case '"':
@@ -997,12 +992,12 @@ compile_prelude(FILE *f)
#endif
}
-/* Compile ISeq in UNIT and return function pointer of JIT-ed code.
- It may return NOT_COMPILED_JIT_ISEQ_FUNC if something went wrong. */
+// Compile ISeq in UNIT and return function pointer of JIT-ed code.
+// It may return NOT_COMPILED_JIT_ISEQ_FUNC if something went wrong.
static mjit_func_t
convert_unit_to_func(struct rb_mjit_unit *unit)
{
- char c_file_buff[MAXPATHLEN], *c_file = c_file_buff, *so_file, funcname[35]; /* TODO: reconsider `35` */
+ char c_file_buff[MAXPATHLEN], *c_file = c_file_buff, *so_file, funcname[35]; // TODO: reconsider `35`
int fd;
FILE *f;
void *func;
@@ -1047,17 +1042,17 @@ convert_unit_to_func(struct rb_mjit_unit *unit)
return (mjit_func_t)NOT_COMPILED_JIT_ISEQ_FUNC;
}
- /* print #include of MJIT header, etc. */
+ // print #include of MJIT header, etc.
compile_prelude(f);
- /* wait until mjit_gc_finish_hook is called */
+ // wait until mjit_gc_finish_hook is called
CRITICAL_SECTION_START(3, "before mjit_compile to wait GC finish");
while (in_gc) {
verbose(3, "Waiting wakeup from GC");
rb_native_cond_wait(&mjit_gc_wakeup, &mjit_engine_mutex);
}
- /* We need to check again here because we could've waited on GC above */
+ // We need to check again here because we could've waited on GC above
if (unit->iseq == NULL) {
fclose(f);
if (!mjit_opts.save_temps)
@@ -1083,7 +1078,7 @@ convert_unit_to_func(struct rb_mjit_unit *unit)
}
bool success = mjit_compile(f, unit->iseq, funcname);
- /* release blocking mjit_gc_start_hook */
+ // release blocking mjit_gc_start_hook
CRITICAL_SECTION_START(3, "after mjit_compile to wakeup client for GC");
in_jit = false;
verbose(3, "Sending wakeup signal to client in a mjit-worker for GC");
@@ -1102,13 +1097,13 @@ convert_unit_to_func(struct rb_mjit_unit *unit)
#ifdef _MSC_VER
success = compile_c_to_so(c_file, so_file);
#else
- /* splitting .c -> .o step and .o -> .so step, to cache .o files in the future */
+ // splitting .c -> .o step and .o -> .so step, to cache .o files in the future
if ((success = compile_c_to_o(c_file, o_file)) != false) {
const char *o_files[2] = { NULL, NULL };
o_files[0] = o_file;
success = link_o_to_so(o_files, so_file);
- /* Always set o_file for compaction. The value is also used for lazy deletion. */
+ // Always set o_file for compaction. The value is also used for lazy deletion.
unit->o_file = strdup(o_file);
if (unit->o_file == NULL) {
mjit_warning("failed to allocate memory to remember '%s' (%s), removing it...", o_file, strerror(errno));
@@ -1146,13 +1141,13 @@ typedef struct {
bool finish_p;
} mjit_copy_job_t;
-/* Singleton MJIT copy job. This is made global since it needs to be durable even when MJIT worker thread is stopped.
- (ex: register job -> MJIT pause -> MJIT resume -> dispatch job. Actually this should be just cancelled by finish_p check) */
+// Singleton MJIT copy job. This is made global since it needs to be durable even when MJIT worker thread is stopped.
+// (ex: register job -> MJIT pause -> MJIT resume -> dispatch job. Actually this should be just cancelled by finish_p check)
static mjit_copy_job_t mjit_copy_job = { .iseq = NULL, .finish_p = true };
static void mjit_copy_job_handler(void *data);
-/* vm_trace.c */
+// vm_trace.c
int rb_workqueue_register(unsigned flags, rb_postponed_job_func_t , void *);
// Copy inline cache values of `iseq` to `cc_entries` and `is_entries`.
@@ -1209,9 +1204,9 @@ mjit_copy_cache_from_main_thread(const rb_iseq_t *iseq, struct rb_call_cache *cc
return result;
}
-/* The function implementing a worker. It is executed in a separate
- thread by rb_thread_create_mjit_thread. It compiles precompiled header
- and then compiles requested ISeqs. */
+// The function implementing a worker. It is executed in a separate
+// thread by rb_thread_create_mjit_thread. It compiles precompiled header
+// and then compiles requested ISeqs.
void
mjit_worker(void)
{
@@ -1227,14 +1222,14 @@ mjit_worker(void)
verbose(3, "Sending wakeup signal to client in a mjit-worker");
rb_native_cond_signal(&mjit_client_wakeup);
CRITICAL_SECTION_FINISH(3, "in worker to update worker_stopped");
- return; /* TODO: do the same thing in the latter half of mjit_finish */
+ return; // TODO: do the same thing in the latter half of mjit_finish
}
- /* main worker loop */
+ // main worker loop
while (!stop_worker_p) {
struct rb_mjit_unit *unit;
- /* wait until unit is available */
+ // wait until unit is available
CRITICAL_SECTION_START(3, "in worker dequeue");
while ((list_empty(&unit_queue.head) || active_units.length >= mjit_opts.max_cache_size) && !stop_worker_p) {
rb_native_cond_wait(&mjit_worker_wakeup, &mjit_engine_mutex);
@@ -1254,18 +1249,18 @@ mjit_worker(void)
break;
CRITICAL_SECTION_START(3, "in jit func replace");
- while (in_gc) { /* Make sure we're not GC-ing when touching ISeq */
+ while (in_gc) { // Make sure we're not GC-ing when touching ISeq
verbose(3, "Waiting wakeup from GC");
rb_native_cond_wait(&mjit_gc_wakeup, &mjit_engine_mutex);
}
- if (unit->iseq) { /* Check whether GCed or not */
- /* Usage of jit_code might be not in a critical section. */
+ if (unit->iseq) { // Check whether GCed or not
+ // Usage of jit_code might be not in a critical section.
MJIT_ATOMIC_SET(unit->iseq->body->jit_func, func);
}
CRITICAL_SECTION_FINISH(3, "in jit func replace");
#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 && unit_queue.length == 0 && active_units.length > 1)
|| active_units.length == mjit_opts.max_cache_size) {
compact_all_jit_code();