From 252492cc8a112559c88deaafab51f406922dd1c2 Mon Sep 17 00:00:00 2001 From: Rodrigo Kumpera Date: Sun, 7 Mar 2010 20:18:02 +0000 Subject: [PATCH] 2010-03-06 Rodrigo Kumpera * method-to-ir.c: Generate better code for the NewObject intrinsic. svn path=/trunk/mono/; revision=153222 --- mono/mini/ChangeLog | 5 +++ mono/mini/method-to-ir.c | 68 ++++++++++++++++++++++++++-------------- 2 files changed, 50 insertions(+), 23 deletions(-) diff --git a/mono/mini/ChangeLog b/mono/mini/ChangeLog index 796b333f939..c440acb64a9 100755 --- a/mono/mini/ChangeLog +++ b/mono/mini/ChangeLog @@ -1,3 +1,8 @@ +2010-03-07 Rodrigo Kumpera + + * method-to-ir.c: Generate better code for the NewObject + intrinsic. + 2010-03-07 Zoltan Varga * branch-opts.c (mono_if_conversion): Disable one of the cases when deadce diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 7821351e336..756f68432f6 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -8770,37 +8770,59 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b EMIT_NEW_TEMPLOAD (cfg, ins, vtvar->inst_c0); } else { + gboolean use_slow_path = TRUE; if ((ip + 5 < end) && ip_in_bb (cfg, bblock, ip + 5) && ((ip [5] == CEE_CALL) || (ip [5] == CEE_CALLVIRT)) && - (cmethod = mini_get_method (cfg, method, read32 (ip + 6), NULL, generic_context)) && - (cmethod->klass == mono_defaults.monotype_class->parent) && - (strcmp (cmethod->name, "GetTypeFromHandle") == 0)) { - MonoClass *tclass = mono_class_from_mono_type (handle); + (cmethod = mini_get_method (cfg, method, read32 (ip + 6), NULL, generic_context))) { - mono_class_init (tclass); - if (context_used) { - ins = emit_get_rgctx_klass (cfg, context_used, - tclass, MONO_RGCTX_INFO_REFLECTION_TYPE); - } else if (cfg->compile_aot) { - if (method->wrapper_type) { - if (mono_class_get (tclass->image, tclass->type_token) == tclass && !generic_context) { - /* Special case for static synchronized wrappers */ - EMIT_NEW_TYPE_FROM_HANDLE_CONST (cfg, ins, tclass->image, tclass->type_token, generic_context); + if ((cmethod->klass == mono_defaults.monotype_class->parent) && (strcmp (cmethod->name, "GetTypeFromHandle") == 0)) { + MonoClass *tclass = mono_class_from_mono_type (handle); + + mono_class_init (tclass); + if (context_used) { + ins = emit_get_rgctx_klass (cfg, context_used, + tclass, MONO_RGCTX_INFO_REFLECTION_TYPE); + } else if (cfg->compile_aot) { + if (method->wrapper_type) { + if (mono_class_get (tclass->image, tclass->type_token) == tclass && !generic_context) { + /* Special case for static synchronized wrappers */ + EMIT_NEW_TYPE_FROM_HANDLE_CONST (cfg, ins, tclass->image, tclass->type_token, generic_context); + } else { + /* FIXME: n is not a normal token */ + cfg->disable_aot = TRUE; + EMIT_NEW_PCONST (cfg, ins, NULL); + } } else { - /* FIXME: n is not a normal token */ - cfg->disable_aot = TRUE; - EMIT_NEW_PCONST (cfg, ins, NULL); + EMIT_NEW_TYPE_FROM_HANDLE_CONST (cfg, ins, image, n, generic_context); } } else { - EMIT_NEW_TYPE_FROM_HANDLE_CONST (cfg, ins, image, n, generic_context); + EMIT_NEW_PCONST (cfg, ins, mono_type_get_object (cfg->domain, handle)); + } + ins->type = STACK_OBJ; + ins->klass = cmethod->klass; + ip += 5; + use_slow_path = FALSE; + } else if (cmethod->klass->image == mono_defaults.corlib && + !strcmp ("Mono", cmethod->klass->name_space) && + !strcmp ("Runtime", cmethod->klass->name) && + !strcmp ("NewObject", cmethod->name)) { + + /*FIXME relax those restrictions if it's worth the trouble*/ + if (!context_used && !cfg->compile_aot && !(cfg->opt & MONO_OPT_SHARED)) { + MonoClass *klass = mono_class_from_mono_type (handle); + gpointer vtable = mono_class_vtable (cfg->domain, klass); + MonoInst *iargs [1]; + + EMIT_NEW_PCONST (cfg, iargs [0], vtable); + ins = mono_emit_jit_icall (cfg, mono_object_new_specific, iargs); + + ip += 5; + use_slow_path = FALSE; } - } else { - EMIT_NEW_PCONST (cfg, ins, mono_type_get_object (cfg->domain, handle)); } - ins->type = STACK_OBJ; - ins->klass = cmethod->klass; - ip += 5; - } else { + } + + if (use_slow_path) { MonoInst *addr, *vtvar; vtvar = mono_compile_create_var (cfg, &handle_class->byval_arg, OP_LOCAL); -- 2.25.1