From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.1 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id AC3071F454 for ; Tue, 30 Oct 2018 18:46:14 +0000 (UTC) From: Eric Wong To: spew@80x24.org Subject: [PATCH 2/2] mjit_worker: use single argument for process-spawning functions Date: Tue, 30 Oct 2018 18:46:14 +0000 Message-Id: <20181030184614.3830-2-e@80x24.org> In-Reply-To: <20181030184614.3830-1-e@80x24.org> References: <20181030184614.3830-1-e@80x24.org> List-Id: This will make it easier to maintain state and move to an event-based process manager. --- mjit_worker.c | 76 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/mjit_worker.c b/mjit_worker.c index e1f7443ea96..b653ecb115c 100644 --- a/mjit_worker.c +++ b/mjit_worker.c @@ -129,6 +129,19 @@ struct rb_mjit_unit { /* Dlopen handle of the loaded object file. */ void *handle; const rb_iseq_t *iseq; + double start_time; /* TODO: rb_hrtime_t */ + + /* TODO: better packing */ + struct { + struct { + const char *c; + const char **objs; + } src; + struct { + const char *o; + const char *so; + } dst; + } tmp; #ifndef _MSC_VER /* This value is always set for `compact_all_jit_code`. Also used for lazy deletion. */ char *o_file; @@ -636,15 +649,15 @@ exec_process(const char *path, char *const argv[]) } static void -remove_so_file(const char *so_file, struct rb_mjit_unit *unit) +remove_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()` */ + unit->so_file = strdup(unit->tmp.dst.so); /* 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 - remove_file(so_file); + remove_file(unit->tmp.dst.so); #endif } @@ -655,8 +668,10 @@ remove_so_file(const char *so_file, struct rb_mjit_unit *unit) #ifdef _MSC_VER /* Compile C file to so. It returns 1 if it succeeds. (mswin) */ static int -compile_c_to_so(const char *c_file, const char *so_file) +compile_c_to_so(struct rb_mjit_unit *unit) { + const char *c_file = unit->tmp.src.c; + const char *so_file = unit->tmp.dst.so; int exit_code; const char *files[] = { NULL, NULL, NULL, NULL, NULL, NULL, "-link", libruby_pathflag, NULL }; char **args; @@ -773,7 +788,7 @@ make_pch(void) /* Compile .c file to .o file. It returns 1 if it succeeds. (non-mswin) */ static int -compile_c_to_o(const char *c_file, const char *o_file) +compile_c_to_o(struct rb_mjit_unit *unit) { int exit_code; const char *files[] = { @@ -785,8 +800,8 @@ compile_c_to_o(const char *c_file, const char *o_file) }; char **args; - files[1] = o_file; - files[2] = c_file; + files[1] = unit->tmp.dst.o; + files[2] = unit->tmp.src.c; # ifdef __clang__ files[4] = pch_file; # endif @@ -804,7 +819,7 @@ compile_c_to_o(const char *c_file, const char *o_file) /* Link .o files to .so file. It returns 1 if it succeeds. (non-mswin) */ static int -link_o_to_so(const char **o_files, const char *so_file) +link_o_to_so(struct rb_mjit_unit *unit) { int exit_code; const char *options[] = { @@ -816,9 +831,9 @@ link_o_to_so(const char **o_files, const char *so_file) }; char **args; - options[1] = so_file; + options[1] = unit->tmp.dst.so; args = form_args(6, CC_LDSHARED_ARGS, CC_CODEFLAG_ARGS, - options, o_files, CC_LIBS, CC_DLDFLAGS_ARGS); + options, unit->tmp.src.objs, CC_LIBS, CC_DLDFLAGS_ARGS); if (args == NULL) return FALSE; @@ -837,10 +852,9 @@ compact_all_jit_code(void) { # 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; + double end_time; static const char so_ext[] = DLEXT; char so_file[MAXPATHLEN]; - const char **o_files; int i = 0, success; /* Abnormal use case of rb_mjit_unit that doesn't have ISeq */ @@ -850,16 +864,17 @@ compact_all_jit_code(void) sprint_uniq_filename(so_file, (int)sizeof(so_file), unit->id, MJIT_TMP_PREFIX, so_ext); /* NULL-ending for form_args */ - o_files = alloca(sizeof(char *) * (active_units.length + 1)); - o_files[active_units.length] = NULL; + unit->tmp.src.objs = alloca(sizeof(char *) * (active_units.length + 1)); + unit->tmp.src.objs[active_units.length] = NULL; CRITICAL_SECTION_START(3, "in compact_all_jit_code to keep .o files"); list_for_each(&active_units.head, cur, unode) { - o_files[i] = cur->o_file; + unit->tmp.src.objs[i] = cur->o_file; i++; } - start_time = real_ms_time(); - success = link_o_to_so(o_files, so_file); + unit->start_time = real_ms_time(); + unit->tmp.dst.so = so_file; + success = link_o_to_so(unit); end_time = real_ms_time(); /* TODO: Shrink this big critical section. For now, this is needed to prevent failure by missing .o files. @@ -881,7 +896,7 @@ compact_all_jit_code(void) add_to_list(unit, &compact_units); if (!mjit_opts.save_temps) - remove_so_file(so_file, unit); + remove_so_file(unit); CRITICAL_SECTION_START(3, "in compact_all_jit_code to read list"); list_for_each(&active_units.head, cur, unode) { @@ -900,11 +915,13 @@ compact_all_jit_code(void) } } 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, active_units.length, so_file); + verbose(1, "JIT compaction (%.1fms): Compacted %d methods -> %s", + end_time - unit->start_time, active_units.length, so_file); } else { free(unit); - verbose(1, "JIT compaction failure (%.1fms): Failed to compact methods", end_time - start_time); + verbose(1, "JIT compaction failure (%.1fms): Failed to compact methods", + end_time - unit->start_time); } # endif /* _WIN32 */ } @@ -988,7 +1005,7 @@ convert_unit_to_func(struct rb_mjit_unit *unit, struct rb_call_cache *cc_entries int fd; FILE *f; void *func; - double start_time, end_time; + double end_time; int c_file_len = (int)sizeof(c_file_buff); static const char c_ext[] = ".c"; static const char so_ext[] = DLEXT; @@ -1066,15 +1083,20 @@ convert_unit_to_func(struct rb_mjit_unit *unit, struct rb_call_cache *cc_entries return (mjit_func_t)NOT_COMPILED_JIT_ISEQ_FUNC; } - start_time = real_ms_time(); + unit->start_time = real_ms_time(); + unit->tmp.src.c = c_file; #ifdef _MSC_VER - success = compile_c_to_so(c_file, so_file); + unit->tmp.dst.so = so_file; + success = compile_c_to_so(unit); #else /* 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)) != 0) { + unit->tmp.dst.o = o_file; + if ((success = compile_c_to_o(unit)) != 0) { const char *o_files[2] = { NULL, NULL }; o_files[0] = o_file; - success = link_o_to_so(o_files, so_file); + unit->tmp.src.objs = o_files; + unit->tmp.dst.so = so_file; + success = link_o_to_so(unit); /* Alwasy set o_file for compaction. The value is also used for lazy deletion. */ unit->o_file = strdup(o_file); @@ -1095,13 +1117,13 @@ convert_unit_to_func(struct rb_mjit_unit *unit, struct rb_call_cache *cc_entries func = load_func_from_so(so_file, funcname, unit); if (!mjit_opts.save_temps) - remove_so_file(so_file, unit); + remove_so_file(unit); if ((uintptr_t)func > (uintptr_t)LAST_JIT_ISEQ_FUNC) { CRITICAL_SECTION_START(3, "end of jit"); add_to_list(unit, &active_units); if (unit->iseq) - print_jit_result("success", unit, end_time - start_time, c_file); + print_jit_result("success", unit, end_time - unit->start_time, c_file); CRITICAL_SECTION_FINISH(3, "end of jit"); } return (mjit_func_t)func; -- EW