From 808bd30e9391377b2db80040c97ce24d0f00962f Mon Sep 17 00:00:00 2001 From: monojenkins Date: Fri, 13 Mar 2020 18:26:44 -0400 Subject: [PATCH] [jit] Add support for emitting r4/r8 constants outside of the text segment. (#33552) Co-authored-by: vargaz --- src/mono/mono/mini/aot-compiler.c | 4 ++++ src/mono/mono/mini/aot-runtime.c | 7 +++++-- src/mono/mono/mini/aot-runtime.h | 2 +- src/mono/mono/mini/cpu-amd64.md | 4 ++-- src/mono/mono/mini/mini-amd64.c | 20 ++++++++++++++------ src/mono/mono/mini/mini-runtime.c | 6 ++++++ src/mono/mono/mini/mini.h | 4 +++- src/mono/mono/mini/patch-info.h | 8 ++++++++ 8 files changed, 43 insertions(+), 12 deletions(-) diff --git a/src/mono/mono/mini/aot-compiler.c b/src/mono/mono/mini/aot-compiler.c index 318ef23..f92545f 100644 --- a/src/mono/mono/mini/aot-compiler.c +++ b/src/mono/mono/mini/aot-compiler.c @@ -6647,9 +6647,11 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint break; } case MONO_PATCH_INFO_R4: + case MONO_PATCH_INFO_R4_GOT: encode_value (*((guint32 *)patch_info->data.target), p, &p); break; case MONO_PATCH_INFO_R8: + case MONO_PATCH_INFO_R8_GOT: encode_value (((guint32 *)patch_info->data.target) [MINI_LS_WORD_IDX], p, &p); encode_value (((guint32 *)patch_info->data.target) [MINI_MS_WORD_IDX], p, &p); break; @@ -8728,6 +8730,8 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method) flags = (JitFlags)(flags | JIT_FLAG_USE_CURRENT_CPU); if (method_is_externally_callable (acfg, method)) flags = (JitFlags)(flags | JIT_FLAG_SELF_INIT); + if (acfg->flags & MONO_AOT_FILE_FLAG_CODE_EXEC_ONLY) + flags = (JitFlags)(flags | JIT_FLAG_CODE_EXEC_ONLY); jit_time_start = mono_time_track_start (); cfg = mini_method_compile (method, acfg->jit_opts, mono_get_root_domain (), flags, 0, index); diff --git a/src/mono/mono/mini/aot-runtime.c b/src/mono/mono/mini/aot-runtime.c index a7a2369..89d284d 100644 --- a/src/mono/mono/mini/aot-runtime.c +++ b/src/mono/mono/mini/aot-runtime.c @@ -3914,7 +3914,8 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin for (i = 0; i < ji->data.table->table_size; i++) table [i] = (gpointer)(gssize)decode_value (p, &p); break; - case MONO_PATCH_INFO_R4: { + case MONO_PATCH_INFO_R4: + case MONO_PATCH_INFO_R4_GOT: { guint32 val; ji->data.target = mono_domain_alloc0 (mono_domain_get (), sizeof (float)); @@ -3922,10 +3923,12 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin *(float*)ji->data.target = *(float*)&val; break; } - case MONO_PATCH_INFO_R8: { + case MONO_PATCH_INFO_R8: + case MONO_PATCH_INFO_R8_GOT: { guint32 val [2]; guint64 v; + // FIXME: Align to 16 bytes ? ji->data.target = mono_domain_alloc0 (mono_domain_get (), sizeof (double)); val [0] = decode_value (p, &p); diff --git a/src/mono/mono/mini/aot-runtime.h b/src/mono/mono/mini/aot-runtime.h index 9d37c77..cd399c0 100644 --- a/src/mono/mono/mini/aot-runtime.h +++ b/src/mono/mono/mini/aot-runtime.h @@ -11,7 +11,7 @@ #include "mini.h" /* Version number of the AOT file format */ -#define MONO_AOT_FILE_VERSION 174 +#define MONO_AOT_FILE_VERSION 175 #define MONO_AOT_TRAMP_PAGE_SIZE 16384 diff --git a/src/mono/mono/mini/cpu-amd64.md b/src/mono/mono/mini/cpu-amd64.md index cebdeed..85252a9 100644 --- a/src/mono/mono/mini/cpu-amd64.md +++ b/src/mono/mono/mini/cpu-amd64.md @@ -170,8 +170,8 @@ call_reg: dest:a src1:i len:32 clob:c call_membase: dest:a src1:b len:32 clob:c iconst: dest:i len:10 i8const: dest:i len:10 -r4const: dest:f len:14 -r8const: dest:f len:9 +r4const: dest:f len:17 +r8const: dest:f len:12 store_membase_imm: dest:b len:15 store_membase_reg: dest:b src1:i len:9 storei8_membase_reg: dest:b src1:i len:9 diff --git a/src/mono/mono/mini/mini-amd64.c b/src/mono/mono/mini/mini-amd64.c index 51de55d..5de18f7 100644 --- a/src/mono/mono/mini/mini-amd64.c +++ b/src/mono/mono/mini/mini-amd64.c @@ -5840,8 +5840,11 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) if ((d == 0.0) && (mono_signbit (d) == 0)) { amd64_sse_xorpd_reg_reg (code, ins->dreg, ins->dreg); - } - else { + } else if (cfg->compile_aot && (cfg->flags & JIT_FLAG_CODE_EXEC_ONLY)) { + mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_R8_GOT, ins->inst_p0); + amd64_mov_reg_membase (code, AMD64_R11, AMD64_RIP, 0, sizeof(gpointer)); + amd64_sse_movsd_reg_membase (code, ins->dreg, AMD64_R11, 0); + } else { mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_R8, ins->inst_p0); amd64_sse_movsd_reg_membase (code, ins->dreg, AMD64_RIP, 0); } @@ -5855,10 +5858,15 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) amd64_sse_xorps_reg_reg (code, ins->dreg, ins->dreg); else amd64_sse_xorpd_reg_reg (code, ins->dreg, ins->dreg); - } - else { - mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_R4, ins->inst_p0); - amd64_sse_movss_reg_membase (code, ins->dreg, AMD64_RIP, 0); + } else { + if (cfg->compile_aot && (cfg->flags & JIT_FLAG_CODE_EXEC_ONLY)) { + mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_R4_GOT, ins->inst_p0); + amd64_mov_reg_membase (code, AMD64_R11, AMD64_RIP, 0, sizeof(gpointer)); + amd64_sse_movss_reg_membase (code, ins->dreg, AMD64_R11, 0); + } else { + mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_R4, ins->inst_p0); + amd64_sse_movss_reg_membase (code, ins->dreg, AMD64_RIP, 0); + } if (!cfg->r4fp) amd64_sse_cvtss2sd_reg_reg (code, ins->dreg, ins->dreg); } diff --git a/src/mono/mono/mini/mini-runtime.c b/src/mono/mono/mini/mini-runtime.c index e7a890b..60d5860 100644 --- a/src/mono/mono/mini/mini-runtime.c +++ b/src/mono/mono/mini/mini-runtime.c @@ -1273,6 +1273,10 @@ mono_patch_info_hash (gconstpointer data) } case MONO_PATCH_INFO_GSHAREDVT_IN_WRAPPER: return hash | mono_signature_hash (ji->data.sig); + case MONO_PATCH_INFO_R8_GOT: + return hash | (guint32)*(double*)ji->data.target; + case MONO_PATCH_INFO_R4_GOT: + return hash | (guint32)*(float*)ji->data.target; default: printf ("info type: %d\n", ji->type); mono_print_ji (ji); printf ("\n"); @@ -1518,7 +1522,9 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, break; } case MONO_PATCH_INFO_R4: + case MONO_PATCH_INFO_R4_GOT: case MONO_PATCH_INFO_R8: + case MONO_PATCH_INFO_R8_GOT: target = patch_info->data.target; break; case MONO_PATCH_INFO_EXC_NAME: diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h index 730b286..9267f12 100644 --- a/src/mono/mono/mini/mini.h +++ b/src/mono/mono/mini/mini.h @@ -1227,7 +1227,9 @@ typedef enum { /* Allow AOT to use all current CPU instructions */ JIT_FLAG_USE_CURRENT_CPU = (1 << 10), /* Generate code to self-init the method for AOT */ - JIT_FLAG_SELF_INIT = (1 << 11) + JIT_FLAG_SELF_INIT = (1 << 11), + /* Assume code memory is exec only */ + JIT_FLAG_CODE_EXEC_ONLY = (1 << 12), } JitFlags; /* Bit-fields in the MonoBasicBlock.region */ diff --git a/src/mono/mono/mini/patch-info.h b/src/mono/mono/mini/patch-info.h index 2075846..3adcde5 100644 --- a/src/mono/mono/mini/patch-info.h +++ b/src/mono/mono/mini/patch-info.h @@ -74,3 +74,11 @@ PATCH_INFO(SPECIFIC_TRAMPOLINE_LAZY_FETCH_ADDR, "specific_trampoline_lazy_fetch_ PATCH_INFO(SPECIFIC_TRAMPOLINES, "specific_trampolines") /* Address of got slot block in mscorlib_amodule->got belonging to specific trampolines */ PATCH_INFO(SPECIFIC_TRAMPOLINES_GOT_SLOTS_BASE, "specific_trampolines_got_slots_base") + +/* + * PATCH_INFO_R4/R8 is handled by mono_arch_emit_exceptions () by emitting the data + * into the text segment after the method body. These patches emit the data + * elsewhere. + */ +PATCH_INFO(R8_GOT, "r8_got") +PATCH_INFO(R4_GOT, "r4_got") -- 2.7.4