diff options
author | Zoltan Varga <vargaz@gmail.com> | 2020-01-31 17:54:32 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-31 17:54:32 +0300 |
commit | 4ef40a91ed602a0a13730ee4103cfb5d1d300b9a (patch) | |
tree | b7dfd258c3108b0c53395e6df5ad7623c5a0dc5f | |
parent | a6707bfeb9bf02b3f665889e0d564d78268ab35e (diff) |
[jit] Avoid generating wbarriers for vtype stores to the stack. (#18556)
The existing heuristic doesn't work with llvm.
-rw-r--r-- | mono/mini/alias-analysis.c | 9 | ||||
-rw-r--r-- | mono/mini/decompose.c | 2 | ||||
-rw-r--r-- | mono/mini/memory-access.c | 11 | ||||
-rw-r--r-- | mono/mini/mini.h | 2 |
4 files changed, 17 insertions, 7 deletions
diff --git a/mono/mini/alias-analysis.c b/mono/mini/alias-analysis.c index b473fe27b76..ea596ffb006 100644 --- a/mono/mini/alias-analysis.c +++ b/mono/mini/alias-analysis.c @@ -255,9 +255,16 @@ handle_instruction: #endif case OP_STORER8_MEMBASE_REG: case OP_STOREV_MEMBASE: + tmp = NULL; + if (ins->opcode == OP_STOREV_MEMBASE) { + tmp = (MonoInst *)g_hash_table_lookup (addr_loads, GINT_TO_POINTER (ins->dreg)); + if (tmp) + ins->flags |= MONO_INST_STACK_STORE; + } if (ins->inst_offset != 0) continue; - tmp = (MonoInst *)g_hash_table_lookup (addr_loads, GINT_TO_POINTER (ins->dreg)); + if (!tmp) + tmp = (MonoInst *)g_hash_table_lookup (addr_loads, GINT_TO_POINTER (ins->dreg)); if (tmp) { if (cfg->verbose_level > 2) { printf ("Found candidate store:"); mono_print_ins (ins); } if (lower_store (cfg, ins, tmp)) { diff --git a/mono/mini/decompose.c b/mono/mini/decompose.c index a448e218185..bb1916d3b8c 100644 --- a/mono/mini/decompose.c +++ b/mono/mini/decompose.c @@ -1287,7 +1287,7 @@ mono_decompose_vtype_opts (MonoCompile *cfg) dreg = alloc_preg (cfg); EMIT_NEW_BIALU_IMM (cfg, dest, OP_ADD_IMM, dreg, ins->inst_destbasereg, ins->inst_offset); - mini_emit_memory_copy (cfg, dest, src, src_var->klass, src_var->backend.is_pinvoke, 0); + mini_emit_memory_copy (cfg, dest, src, src_var->klass, src_var->backend.is_pinvoke, ins->flags); break; } case OP_LOADV_MEMBASE: { diff --git a/mono/mini/memory-access.c b/mono/mini/memory-access.c index c5d5cd5f5ab..02088f15cb5 100644 --- a/mono/mini/memory-access.c +++ b/mono/mini/memory-access.c @@ -349,7 +349,8 @@ mini_emit_wb_aware_memcpy (MonoCompile *cfg, MonoClass *klass, MonoInst *iargs[4 } static void -mini_emit_memory_copy_internal (MonoCompile *cfg, MonoInst *dest, MonoInst *src, MonoClass *klass, int explicit_align, gboolean native) +mini_emit_memory_copy_internal (MonoCompile *cfg, MonoInst *dest, MonoInst *src, MonoClass *klass, int explicit_align, gboolean native, + gboolean stack_store) { MonoInst *iargs [4]; int size; @@ -404,8 +405,8 @@ mini_emit_memory_copy_internal (MonoCompile *cfg, MonoInst *dest, MonoInst *src, mini_emit_write_barrier (cfg, dest, load); return; - - } else if (cfg->gen_write_barriers && (m_class_has_references (klass) || size_ins) && !native) { /* if native is true there should be no references in the struct */ + } else if (cfg->gen_write_barriers && (m_class_has_references (klass) || size_ins) && + !native && !stack_store) { /* if native is true there should be no references in the struct */ /* Avoid barriers when storing to the stack */ if (!((dest->opcode == OP_ADD_IMM && dest->sreg1 == cfg->frame_reg) || (dest->opcode == OP_LDADDR))) { @@ -504,7 +505,7 @@ mini_emit_memory_store (MonoCompile *cfg, MonoType *type, MonoInst *dest, MonoIn tmp_var = mono_compile_create_var (cfg, type, OP_LOCAL); EMIT_NEW_TEMPSTORE (cfg, mov, tmp_var->inst_c0, value); EMIT_NEW_VARLOADA (cfg, addr, tmp_var, tmp_var->inst_vtype); - mini_emit_memory_copy_internal (cfg, dest, addr, mono_class_from_mono_type_internal (type), 1, FALSE); + mini_emit_memory_copy_internal (cfg, dest, addr, mono_class_from_mono_type_internal (type), 1, FALSE, (ins_flag & MONO_INST_STACK_STORE) != 0); } else { MonoInst *ins; @@ -594,7 +595,7 @@ mini_emit_memory_copy (MonoCompile *cfg, MonoInst *dest, MonoInst *src, MonoClas mini_emit_memory_barrier (cfg, MONO_MEMORY_BARRIER_SEQ); } - mini_emit_memory_copy_internal (cfg, dest, src, klass, explicit_align, native); + mini_emit_memory_copy_internal (cfg, dest, src, klass, explicit_align, native, (ins_flag & MONO_INST_STACK_STORE) != 0); if (ins_flag & MONO_INST_VOLATILE) { /* Volatile loads have acquire semantics, see 12.6.7 in Ecma 335 */ diff --git a/mono/mini/mini.h b/mono/mini/mini.h index 94d8a8d9359..41f50916a5e 100644 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -861,6 +861,8 @@ enum { MONO_INST_LMF = 32, /* On loads, the source address points to a constant value */ MONO_INST_INVARIANT_LOAD = 64, + /* On stores, the destination is the stack */ + MONO_INST_STACK_STORE = 64, /* On variables, the variable needs GC tracking */ MONO_INST_GC_TRACK = 128, /* |