return NULL;
}
+
+static gboolean
+mono_type_is_native_blittable (MonoType *t)
+{
+ if (MONO_TYPE_IS_REFERENCE (t))
+ return FALSE;
+
+ if (MONO_TYPE_IS_PRIMITIVE_SCALAR (t))
+ return TRUE;
+
+ MonoClass *klass = mono_class_from_mono_type (t);
+
+ //MonoClass::blitable depends on mono_class_setup_fields being done.
+ mono_class_setup_fields (klass);
+ if (!klass->blittable)
+ return FALSE;
+
+ // If the native marshal size is different we can't convert PtrToStructure to a type load
+ if (mono_class_native_size (klass, NULL) != mono_class_value_size (klass, NULL))
+ return FALSE;
+
+ return TRUE;
+}
+
+
static MonoInst*
mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args)
{
MONO_ADD_INS (cfg->cbb, ins);
return ins;
}
+ } else if (cmethod->klass->image == mono_defaults.corlib &&
+ (strcmp (cmethod->klass->name_space, "System.Runtime.InteropServices") == 0) &&
+ (strcmp (cmethod->klass->name, "Marshal") == 0)) {
+ //Convert Marshal.PtrToStructure<T> of blittable T to direct loads
+ if (strcmp (cmethod->name, "PtrToStructure") == 0 &&
+ cmethod->is_inflated &&
+ fsig->param_count == 1 &&
+ !mini_method_check_context_used (cfg, cmethod)) {
+
+ MonoGenericContext *method_context = mono_method_get_context (cmethod);
+ MonoType *arg0 = method_context->method_inst->type_argv [0];
+ if (mono_type_is_native_blittable (arg0))
+ return mini_emit_memory_load (cfg, arg0, args [0], 0, 0);
+ }
}
#ifdef MONO_ARCH_SIMD_INTRINSICS