[interp] Don't change next_jit_code_hash during imethod transform (mono/mono#14240)
authorVlad Brezae <brezaevlad@gmail.com>
Fri, 26 Apr 2019 15:20:33 +0000 (18:20 +0300)
committerBernhard Urban <lewurm@gmail.com>
Fri, 26 Apr 2019 15:20:33 +0000 (17:20 +0200)
This field is used by the internal hash table to link nodes and it can be changed during hash table insertion of other imethods. Copying this field back was leading to random hangs in hash table lookup.

Commit migrated from https://github.com/mono/mono/commit/6fb7b496bd3a0bb0fa9e66cf03761eca38c78ff2

src/mono/mono/mini/interp/transform.c

index 6061b80..2390941 100644 (file)
@@ -5923,9 +5923,10 @@ mono_interp_transform_method (InterpMethod *imethod, ThreadContext *context, Mon
        imethod = real_imethod;
        mono_os_mutex_lock (&calc_section);
        if (!imethod->transformed) {
-               InterpMethod *hash = imethod->next_jit_code_hash;
-               memcpy (imethod, &tmp_imethod, sizeof (InterpMethod));
-               imethod->next_jit_code_hash = hash;
+               // Ignore the first two fields which are unchanged. next_jit_code_hash shouldn't
+               // be modified because it is racy with internal hash table insert.
+               const int start_offset = 2 * sizeof (gpointer);
+               memcpy ((char*)imethod + start_offset, (char*)&tmp_imethod + start_offset, sizeof (InterpMethod) - start_offset);
                mono_memory_barrier ();
                imethod->transformed = TRUE;
                mono_atomic_fetch_add_i32 (&mono_jit_stats.methods_with_interp, 1);