diff options
author | nagachika <nagachika@ruby-lang.org> | 2021-06-03 20:46:01 +0900 |
---|---|---|
committer | nagachika <nagachika@ruby-lang.org> | 2021-06-03 20:46:01 +0900 |
commit | 9680ee97e0b3e87c0fc9a65c01de1ee50a1a178b (patch) | |
tree | 2acf38571cba9ca80cd47cfa2868feebde50bb7d /mjit_worker.c | |
parent | a21ec8d1ecc6e978ea6b18a27046c424e2849752 (diff) |
merge revision(s) 1aac0e88193a82ed36b43e852c46414181b66455: [Backport #17928]
Mark inlined ISeqs during MJIT compilation (#4539)
[Bug #17584]
---
common.mk | 6 ++++++
mjit.c | 18 +++++++++++-----
mjit_compile.c | 24 +++++++++++++++------
mjit_worker.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----
4 files changed, 99 insertions(+), 15 deletions(-)
Diffstat (limited to 'mjit_worker.c')
-rw-r--r-- | mjit_worker.c | 66 |
1 files changed, 62 insertions, 4 deletions
diff --git a/mjit_worker.c b/mjit_worker.c index 9157e3a78a..ad36ec6151 100644 --- a/mjit_worker.c +++ b/mjit_worker.c @@ -93,6 +93,10 @@ #include "ruby/debug.h" #include "ruby/thread.h" #include "ruby/version.h" +#include "builtin.h" +#include "insns.inc" +#include "insns_info.inc" +#include "internal/compile.h" #ifdef _WIN32 #include <winsock2.h> @@ -729,6 +733,51 @@ sprint_funcname(char *funcname, const struct rb_mjit_unit *unit) } } +static const rb_iseq_t **compiling_iseqs = NULL; + +static bool +set_compiling_iseqs(const rb_iseq_t *iseq) +{ + compiling_iseqs = calloc(iseq->body->iseq_size + 2, sizeof(rb_iseq_t *)); // 2: 1 (unit->iseq) + 1 (NULL end) + if (compiling_iseqs == NULL) + return false; + + compiling_iseqs[0] = iseq; + int i = 1; + + unsigned int pos = 0; + while (pos < iseq->body->iseq_size) { +#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE + int insn = rb_vm_insn_addr2insn((void *)iseq->body->iseq_encoded[pos]); +#else + int insn = (int)iseq->body->iseq_encoded[pos]; +#endif + if (insn == BIN(opt_send_without_block)) { + CALL_DATA cd = (CALL_DATA)iseq->body->iseq_encoded[pos + 1]; + extern const rb_iseq_t *rb_mjit_inlinable_iseq(const struct rb_callinfo *ci, const struct rb_callcache *cc); + const rb_iseq_t *iseq = rb_mjit_inlinable_iseq(cd->ci, cd->cc); + if (iseq != NULL) { + compiling_iseqs[i] = iseq; + i++; + } + } + pos += insn_len(insn); + } + return true; +} + +bool +rb_mjit_compiling_iseq_p(const rb_iseq_t *iseq) +{ + assert(compiling_iseqs != NULL); + int i = 0; + while (compiling_iseqs[i]) { + if (compiling_iseqs[i] == iseq) return true; + i++; + } + return false; +} + static const int c_file_access_mode = #ifdef O_BINARY O_BINARY| @@ -951,6 +1000,11 @@ compile_compact_jit_code(char* c_file) // compacted functions (not done yet). bool success = true; list_for_each(&active_units.head, child_unit, unode) { + CRITICAL_SECTION_START(3, "before set_compiling_iseqs"); + success &= set_compiling_iseqs(child_unit->iseq); + CRITICAL_SECTION_FINISH(3, "after set_compiling_iseqs"); + if (!success) continue; + char funcname[MAXPATHLEN]; sprint_funcname(funcname, child_unit); @@ -964,6 +1018,11 @@ compile_compact_jit_code(char* c_file) if (!iseq_label) iseq_label = sep = ""; fprintf(f, "\n/* %s%s%s:%ld */\n", iseq_label, sep, iseq_path, iseq_lineno); success &= mjit_compile(f, child_unit->iseq, funcname, child_unit->id); + + CRITICAL_SECTION_START(3, "before compiling_iseqs free"); + free(compiling_iseqs); + compiling_iseqs = NULL; + CRITICAL_SECTION_FINISH(3, "after compiling_iseqs free"); } // release blocking mjit_gc_start_hook @@ -1103,8 +1162,6 @@ compile_prelude(FILE *f) #endif } -static rb_iseq_t *compiling_iseq = NULL; - // 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 @@ -1139,7 +1196,7 @@ convert_unit_to_func(struct rb_mjit_unit *unit) // We need to check again here because we could've waited on GC above in_jit = (unit->iseq != NULL); if (in_jit) - compiling_iseq = unit->iseq; + in_jit &= set_compiling_iseqs(unit->iseq); CRITICAL_SECTION_FINISH(3, "before mjit_compile to wait GC finish"); if (!in_jit) { fclose(f); @@ -1164,7 +1221,8 @@ convert_unit_to_func(struct rb_mjit_unit *unit) // release blocking mjit_gc_start_hook CRITICAL_SECTION_START(3, "after mjit_compile to wakeup client for GC"); - compiling_iseq = NULL; + free(compiling_iseqs); + compiling_iseqs = NULL; in_jit = false; verbose(3, "Sending wakeup signal to client in a mjit-worker for GC"); rb_native_cond_signal(&mjit_client_wakeup); |