From: Bernhard Urban Date: Wed, 17 May 2017 11:40:58 +0000 (+0200) Subject: [interp] intrinsify System.Array.UnsafeLoad X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=mono.git;a=commitdiff_plain;h=908e8381f067f41e4b456464944d0cb0eabcb4a7 [interp] intrinsify System.Array.UnsafeLoad --- diff --git a/mono/mini/interp/interp.c b/mono/mini/interp/interp.c index 9000d63448b..87d1781d6ab 100644 --- a/mono/mini/interp/interp.c +++ b/mono/mini/interp/interp.c @@ -564,7 +564,7 @@ ves_array_create (MonoInvocation *frame, MonoDomain *domain, MonoClass *klass, M } static gint32 -ves_array_calculate_index (MonoArray *ao, stackval *sp, MonoInvocation *frame) +ves_array_calculate_index (MonoArray *ao, stackval *sp, MonoInvocation *frame, gboolean safe) { g_assert (!frame->ex); MonoClass *ac = ((MonoObject *) ao)->vtable->klass; @@ -575,7 +575,7 @@ ves_array_calculate_index (MonoArray *ao, stackval *sp, MonoInvocation *frame) guint32 idx = sp [i].data.i; guint32 lower = ao->bounds [i].lower_bound; guint32 len = ao->bounds [i].length; - if (idx < lower || (idx - lower) >= len) { + if (safe && (idx < lower || (idx - lower) >= len)) { frame->ex = mono_get_exception_index_out_of_range (); FILL_IN_TRACE (frame->ex, frame); return -1; @@ -584,7 +584,7 @@ ves_array_calculate_index (MonoArray *ao, stackval *sp, MonoInvocation *frame) } } else { pos = sp [0].data.i; - if (pos >= ao->max_length) { + if (safe && pos >= ao->max_length) { frame->ex = mono_get_exception_index_out_of_range (); FILL_IN_TRACE (frame->ex, frame); return -1; @@ -604,7 +604,7 @@ ves_array_set (MonoInvocation *frame) g_assert (ac->rank >= 1); - gint32 pos = ves_array_calculate_index (ao, sp, frame); + gint32 pos = ves_array_calculate_index (ao, sp, frame, TRUE); if (frame->ex) return; @@ -627,7 +627,7 @@ ves_array_set (MonoInvocation *frame) } static void -ves_array_get (MonoInvocation *frame) +ves_array_get (MonoInvocation *frame, gboolean safe) { stackval *sp = frame->stack_args + 1; @@ -637,7 +637,7 @@ ves_array_get (MonoInvocation *frame) g_assert (ac->rank >= 1); - gint32 pos = ves_array_calculate_index (ao, sp, frame); + gint32 pos = ves_array_calculate_index (ao, sp, frame, safe); if (frame->ex) return; @@ -655,7 +655,7 @@ ves_array_element_address (MonoInvocation *frame, MonoClass *required_type, Mono g_assert (ac->rank >= 1); - gint32 pos = ves_array_calculate_index (ao, sp, frame); + gint32 pos = ves_array_calculate_index (ao, sp, frame, TRUE); if (frame->ex) return NULL; @@ -982,6 +982,10 @@ ves_runtime_method (MonoInvocation *frame, ThreadContext *context) stackval_from_data (mt, frame->retval, (char *) frame->stack_args, FALSE); return; } + if (!strcmp (method->name, "UnsafeLoad")) { + ves_array_get (frame, FALSE); + return; + } } isinst_obj = mono_object_isinst_checked (obj, mono_defaults.array_class, &error); @@ -992,7 +996,7 @@ ves_runtime_method (MonoInvocation *frame, ThreadContext *context) return; } if (*name == 'G' && (strcmp (name, "Get") == 0)) { - ves_array_get (frame); + ves_array_get (frame, TRUE); return; } } diff --git a/mono/mini/interp/transform.c b/mono/mini/interp/transform.c index 69ef2c13fb6..9354aa8737c 100644 --- a/mono/mini/interp/transform.c +++ b/mono/mini/interp/transform.c @@ -3523,7 +3523,7 @@ mono_interp_transform_method (RuntimeMethod *runtime_method, ThreadContext *cont header = mono_method_get_header (nm); mono_os_mutex_unlock(&calc_section); } else if (method->klass == mono_defaults.array_class) { - if (!strcmp (method->name, "UnsafeMov")) { + if (!strcmp (method->name, "UnsafeMov") || !strcmp (method->name, "UnsafeLoad")) { mono_os_mutex_lock (&calc_section); if (!runtime_method->transformed) { runtime_method->code = g_malloc (sizeof (short)); @@ -3535,9 +3535,7 @@ mono_interp_transform_method (RuntimeMethod *runtime_method, ThreadContext *cont mono_os_mutex_unlock(&calc_section); mono_profiler_method_end_jit (method, NULL, MONO_PROFILE_OK); return NULL; - } else if (!strcmp (method->name, "UnsafeStore)")) { - g_error ("TODO"); - } else if (!strcmp (method->name, "UnsafeLoad)")) { + } else if (!strcmp (method->name, "UnsafeStore")) { g_error ("TODO"); } }