From f5ddbba9a233c2d32118507158c5ef451167cfe0 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Thu, 30 Apr 2020 22:58:07 -0700 Subject: [PATCH] Include unit id in a function name of an inlined method I'm trying to make it possible to include all JIT-ed code in a single C file. This is needed to guarantee uniqueness of all function names --- mjit.h | 2 +- mjit_compile.c | 13 +++++++------ mjit_worker.c | 2 +- tool/ruby_vm/views/_mjit_compile_send.erb | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/mjit.h b/mjit.h index 94e0b7bd85..5fe7b939bb 100644 --- a/mjit.h +++ b/mjit.h @@ -83,7 +83,7 @@ extern struct rb_mjit_compile_info* rb_mjit_iseq_compile_info(const struct rb_is extern void rb_mjit_recompile_iseq(const rb_iseq_t *iseq); RUBY_SYMBOL_EXPORT_END -extern bool mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname); +extern bool mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id); extern void mjit_init(const struct mjit_options *opts); extern void mjit_gc_start_hook(void); extern void mjit_gc_exit_hook(void); diff --git a/mjit_compile.c b/mjit_compile.c index 4d0a6252fc..c3b44bdb1f 100644 --- a/mjit_compile.c +++ b/mjit_compile.c @@ -55,6 +55,7 @@ struct compile_status { int cc_entries_index; // A pointer to root (i.e. not inlined) iseq being compiled. const struct rb_iseq_constant_body *compiled_iseq; + int compiled_id; // Just a copy of compiled_iseq->jit_unit->id // Mutated optimization levels struct rb_mjit_compile_info *compile_info; // If `inlined_iseqs[pos]` is not NULL, `mjit_compile_body` tries to inline ISeq there. @@ -439,7 +440,7 @@ precompile_inlinable_iseqs(FILE *f, const rb_iseq_t *iseq, struct compile_status RSTRING_PTR(child_iseq->body->location.label), RSTRING_PTR(rb_iseq_path(child_iseq)), FIX2INT(child_iseq->body->location.first_lineno)); - struct compile_status child_status = { .compiled_iseq = status->compiled_iseq }; + struct compile_status child_status = { .compiled_iseq = status->compiled_iseq, .compiled_id = status->compiled_id }; INIT_COMPILE_STATUS(child_status, child_iseq->body, false); child_status.inline_context = (struct inlined_call_context){ .orig_argc = vm_ci_argc(ci), @@ -452,12 +453,12 @@ precompile_inlinable_iseqs(FILE *f, const rb_iseq_t *iseq, struct compile_status return false; } - fprintf(f, "ALWAYS_INLINE(static VALUE _mjit_inlined_%d(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, const VALUE orig_self, const rb_iseq_t *original_iseq));\n", pos); - fprintf(f, "static inline VALUE\n_mjit_inlined_%d(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, const VALUE orig_self, const rb_iseq_t *original_iseq)\n{\n", pos); + fprintf(f, "ALWAYS_INLINE(static VALUE _mjit%d_inlined_%d(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, const VALUE orig_self, const rb_iseq_t *original_iseq));\n", status->compiled_id, pos); + fprintf(f, "static inline VALUE\n_mjit%d_inlined_%d(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp, const VALUE orig_self, const rb_iseq_t *original_iseq)\n{\n", status->compiled_id, pos); fprintf(f, " const VALUE *orig_pc = reg_cfp->pc;\n"); fprintf(f, " const VALUE *orig_sp = reg_cfp->sp;\n"); bool success = mjit_compile_body(f, child_iseq, &child_status); - fprintf(f, "\n} /* end of _mjit_inlined_%d */\n\n", pos); + fprintf(f, "\n} /* end of _mjit%d_inlined_%d */\n\n", status->compiled_id, pos); if (!success) return false; @@ -470,7 +471,7 @@ precompile_inlinable_iseqs(FILE *f, const rb_iseq_t *iseq, struct compile_status // Compile ISeq to C code in `f`. It returns true if it succeeds to compile. bool -mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname) +mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname, int id) { // For performance, we verify stack size only on compilation time (mjit_compile.inc.erb) without --jit-debug if (!mjit_opts.debug) { @@ -478,7 +479,7 @@ mjit_compile(FILE *f, const rb_iseq_t *iseq, const char *funcname) fprintf(f, "#define OPT_CHECKED_RUN 0\n\n"); } - struct compile_status status = { .compiled_iseq = iseq->body }; + struct compile_status status = { .compiled_iseq = iseq->body, .compiled_id = id }; INIT_COMPILE_STATUS(status, iseq->body, true); if ((iseq->body->ci_size > 0 && status.cc_entries_index == -1) || (status.is_entries != NULL && !mjit_copy_cache_from_main_thread(iseq, status.is_entries))) { diff --git a/mjit_worker.c b/mjit_worker.c index 04eac1f55f..791a6ab76f 100644 --- a/mjit_worker.c +++ b/mjit_worker.c @@ -1120,7 +1120,7 @@ convert_unit_to_func(struct rb_mjit_unit *unit) verbose(2, "start compilation: %s@%s:%ld -> %s", iseq_label, iseq_path, iseq_lineno, c_file); fprintf(f, "/* %s@%s:%ld */\n\n", iseq_label, iseq_path, iseq_lineno); - bool success = mjit_compile(f, unit->iseq, funcname); + bool success = mjit_compile(f, unit->iseq, funcname, unit->id); // release blocking mjit_gc_start_hook CRITICAL_SECTION_START(3, "after mjit_compile to wakeup client for GC"); diff --git a/tool/ruby_vm/views/_mjit_compile_send.erb b/tool/ruby_vm/views/_mjit_compile_send.erb index 2b1ecdb2f3..d1f4692b5f 100644 --- a/tool/ruby_vm/views/_mjit_compile_send.erb +++ b/tool/ruby_vm/views/_mjit_compile_send.erb @@ -50,7 +50,7 @@ fprintf(f, " {\n"); fprintf(f, " VALUE orig_self = reg_cfp->self;\n"); fprintf(f, " reg_cfp->self = stack[%d];\n", b->stack_size + sp_inc - 1); - fprintf(f, " stack[%d] = _mjit_inlined_%d(ec, reg_cfp, orig_self, original_iseq);\n", b->stack_size + sp_inc - 1, pos); + fprintf(f, " stack[%d] = _mjit%d_inlined_%d(ec, reg_cfp, orig_self, original_iseq);\n", b->stack_size + sp_inc - 1, status->compiled_id, pos); fprintf(f, " reg_cfp->self = orig_self;\n"); fprintf(f, " }\n"); }