Merge pull request #2489 from ludovic-henry/monoerror-mono_array_new_specific
authorRodrigo Kumpera <kumpera@gmail.com>
Mon, 25 Jan 2016 22:42:33 +0000 (17:42 -0500)
committerRodrigo Kumpera <kumpera@gmail.com>
Mon, 25 Jan 2016 22:42:33 +0000 (17:42 -0500)
[runtime] Use MonoError for mono_array_new_specific

1  2 
mono/metadata/icall.c
mono/metadata/object-internals.h
mono/mini/decompose.c
mono/mini/method-to-ir.c
mono/mini/mini-runtime.c

diff --combined mono/metadata/icall.c
index 99611d04ccb8949e3aeb03fa15c5c74df7480ff9,4ad21bfd258b04c6ac891a660ee3c423d172ba5c..8bfbdb3c1a515594c880f65fb62fb27fb362a550
@@@ -827,10 -827,9 +827,10 @@@ ves_icall_System_Runtime_CompilerServic
  #define SWAP(n) {                                                             \
        guint ## n *data = (guint ## n *) mono_array_addr (array, char, 0);     \
        guint ## n *src = (guint ## n *) field_data;                            \
 -      int i;                                                                  \
 +      int i,                                                                  \
 +          nEnt = (size / sizeof(guint ## n));                                 \
                                                                                \
 -      for (i = 0; i < (size / sizeof(guint ## n)); i++) {                     \
 +      for (i = 0; i < nEnt; i++) {                                            \
                data[i] = read ## n (&src[i]);                                  \
        }                                                                       \
  }
@@@ -3467,6 -3466,7 +3467,7 @@@ ICALL_EXPORT MonoArray
  ves_icall_Type_GetMethodsByName (MonoReflectionType *type, MonoString *name, guint32 bflags, MonoBoolean ignore_case, MonoReflectionType *reftype)
  {
        static MonoClass *MethodInfo_array;
+       MonoError error;
        MonoDomain *domain; 
        MonoArray *res;
        MonoVTable *array_vtable;
        refklass = mono_class_from_mono_type (reftype->type);
        domain = ((MonoObject *)type)->vtable->domain;
        array_vtable = mono_class_vtable_full (domain, MethodInfo_array, TRUE);
-       if (type->type->byref)
-               return mono_array_new_specific (array_vtable, 0);
+       if (type->type->byref) {
+               res = mono_array_new_specific_checked (array_vtable, 0, &error);
+               mono_error_raise_exception (&error);
+               return res;
+       }
  
        if (name)
                mname = mono_string_to_utf8 (name);
                return NULL;
        }
  
-       res = mono_array_new_specific (array_vtable, method_array->len);
+       res = mono_array_new_specific_checked (array_vtable, method_array->len, &error);
+       mono_error_raise_exception (&error);
  
        for (i = 0; i < method_array->len; ++i) {
                MonoMethod *method = (MonoMethod *)g_ptr_array_index (method_array, i);
index 09c516fd7a86fb2bb9513b313c0841c89b252c4c,36c9ad9b00dc68c03a323cb174b870127e30ef90..fd15d8804f06857829ab3f67e2cc9d2e5710a176
@@@ -11,6 -11,7 +11,7 @@@
  #include <mono/io-layer/io-layer.h>
  #include "mono/utils/mono-compiler.h"
  #include "mono/utils/mono-error.h"
+ #include "mono/utils/mono-error-internals.h"
  #include "mono/utils/mono-stack-unwinding.h"
  #include "mono/utils/mono-tls.h"
  #include "mono/utils/mono-coop-mutex.h"
                        }; \
                        tmp_klass; })
  /* eclass should be a run-time constant */
- #define mono_array_new_cached(domain, eclass, size) mono_array_new_specific (mono_class_vtable ((domain), mono_array_class_get_cached ((eclass), 1)), (size))
+ #define mono_array_new_cached(domain, eclass, size) ({        \
+                       MonoError __error;      \
+                       MonoVTable *__vtable = mono_class_vtable ((domain), mono_array_class_get_cached ((eclass), 1)); \
+                       MonoArray *__arr = mono_array_new_specific_checked (__vtable, (size), &__error);        \
+                       mono_error_raise_exception (&__error); /* FIXME don't raise here */     \
+                       __arr; })
  
  #else
  
@@@ -786,8 -792,7 +792,8 @@@ struct _MonoDelegate 
        MonoObject *target;
        MonoMethod *method;
        gpointer delegate_trampoline;
 -      gpointer rgctx;
 +      /* Extra argument passed to the target method in llvmonly mode */
 +      gpointer extra_arg;
        /* 
         * If non-NULL, this points to a memory location which stores the address of 
         * the compiled code of the method, or NULL if it is not yet compiled.
@@@ -1489,6 -1494,12 +1495,12 @@@ mono_array_calc_byte_len (MonoClass *kl
  MonoArray*
  mono_array_new_full_checked (MonoDomain *domain, MonoClass *array_class, uintptr_t *lengths, intptr_t *lower_bounds, MonoError *error);
  
+ MonoArray*
+ mono_array_new_specific_checked (MonoVTable *vtable, uintptr_t n, MonoError *error);
+ MonoArray*
+ ves_icall_array_new_specific (MonoVTable *vtable, uintptr_t n);
  #ifndef DISABLE_REMOTING
  MonoObject *
  mono_remoting_invoke      (MonoObject *real_proxy, MonoMethodMessage *msg, 
diff --combined mono/mini/decompose.c
index 1bb364a588d0174fbc365cdecae98541730b7e2a,fe2e6b22c9a14b98f2a23d1649f5c4d0d15de588..ea53056e69531214470fbd73a9eefad910f35dde
@@@ -1521,7 -1521,7 +1521,7 @@@ mono_decompose_array_access_opts (MonoC
                                                if (managed_alloc)
                                                        dest = mono_emit_method_call (cfg, managed_alloc, iargs, NULL);
                                                else
-                                                       dest = mono_emit_jit_icall (cfg, mono_array_new_specific, iargs);
+                                                       dest = mono_emit_jit_icall (cfg, ves_icall_array_new_specific, iargs);
                                                dest->dreg = ins->dreg;
                                        }
                                        break;
@@@ -1936,8 -1936,7 +1936,8 @@@ mono_local_emulate_ops (MonoCompile *cf
         * at IR level, instead of inlining the icall wrapper. FIXME
         */
        if (inlined_wrapper) {
 -              mono_decompose_long_opts (cfg);
 +              if (!COMPILE_LLVM (cfg))
 +                      mono_decompose_long_opts (cfg);
                if (cfg->opt & (MONO_OPT_CONSPROP | MONO_OPT_COPYPROP))
                        mono_local_cprop (cfg);
        }
diff --combined mono/mini/method-to-ir.c
index 7d64d16da87a34352068e2b7c88f9aca1184ac39,3566609d383a24d70571fab7a716b8ec7605ab8b..4c0a925becfeda42c3460cbe2b8bb122ad7dc503
@@@ -5032,6 -5032,22 +5032,6 @@@ handle_delegate_ctor (MonoCompile *cfg
        if (!obj)
                return NULL;
  
 -      if (cfg->llvm_only) {
 -              MonoInst *args [16];
 -
 -              /*
 -               * If the method to be called needs an rgctx, we can't fall back to mono_delegate_ctor (), since it might receive
 -               * the address of a gshared method. So use a JIT icall.
 -               * FIXME: Optimize this.
 -               */
 -              args [0] = obj;
 -              args [1] = target;
 -              args [2] = emit_get_rgctx_method (cfg, context_used, method, MONO_RGCTX_INFO_METHOD);
 -              mono_emit_jit_icall (cfg, virtual_ ? mono_llvmonly_init_delegate_virtual : mono_llvmonly_init_delegate, args);
 -
 -              return obj;
 -      }
 -
        /* Inline the contents of mono_delegate_ctor */
  
        /* Set target field */
                MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, obj->dreg, MONO_STRUCT_OFFSET (MonoDelegate, method_code), code_slot_ins->dreg);                
        }
  
 +      if (cfg->llvm_only) {
 +              MonoInst *args [16];
 +
 +              if (virtual_) {
 +                      args [0] = obj;
 +                      args [1] = target;
 +                      args [2] = emit_get_rgctx_method (cfg, context_used, method, MONO_RGCTX_INFO_METHOD);
 +                      mono_emit_jit_icall (cfg, mono_llvmonly_init_delegate_virtual, args);
 +              } else {
 +                      args [0] = obj;
 +                      mono_emit_jit_icall (cfg, mono_llvmonly_init_delegate, args);
 +              }
 +
 +              return obj;
 +      }
 +
        if (cfg->compile_aot) {
                MonoDelegateClassMethodPair *del_tramp;
  
@@@ -11852,7 -11852,7 +11852,7 @@@ mono_method_to_ir (MonoCompile *cfg, Mo
                                if (managed_alloc)
                                        ins = mono_emit_method_call (cfg, managed_alloc, args, NULL);
                                else
-                                       ins = mono_emit_jit_icall (cfg, mono_array_new_specific, args);
+                                       ins = mono_emit_jit_icall (cfg, ves_icall_array_new_specific, args);
                        } else {
                                if (cfg->opt & MONO_OPT_SHARED) {
                                        /* Decompose now to avoid problems with references to the domainvar */
diff --combined mono/mini/mini-runtime.c
index d679769a2eb6b7302c73a495599a05c0caf37637,045601610902800ce5566d6e0c56b00546cab58c..c7270e2a8ec311f47d68d912de9746cb29895a65
@@@ -2287,14 -2287,15 +2287,14 @@@ create_runtime_invoke_info (MonoDomain 
  #ifndef ENABLE_GSHAREDVT
                        g_assert_not_reached ();
  #endif
 +                      info->gsharedvt_invoke = TRUE;
                        if (!callee_gsharedvt) {
                                /* Invoke a gsharedvt out wrapper instead */
                                MonoMethod *wrapper = mini_get_gsharedvt_out_sig_wrapper (sig);
                                MonoMethodSignature *wrapper_sig = mini_get_gsharedvt_out_sig_wrapper_signature (sig->hasthis, sig->ret->type != MONO_TYPE_VOID, sig->param_count);
  
 -                              info->gsharedvt_invoke = TRUE;
                                info->wrapper_arg = g_malloc0 (2 * sizeof (gpointer));
 -                              info->wrapper_arg [0] = info->compiled_method;
 -                              info->wrapper_arg [1] = mono_method_needs_static_rgctx_invoke (method, TRUE) ? mini_method_get_rgctx (method) : NULL;
 +                              info->wrapper_arg [0] = mini_add_method_wrappers_llvmonly (method, info->compiled_method, FALSE, FALSE, &(info->wrapper_arg [1]));
  
                                /* Pass has_rgctx == TRUE since the wrapper has an extra arg */
                                invoke = mono_marshal_get_runtime_invoke_for_sig (wrapper_sig);
                                /* The out wrapper has the same signature as the compiled gsharedvt method */
                                MonoMethodSignature *wrapper_sig = mini_get_gsharedvt_out_sig_wrapper_signature (sig->hasthis, sig->ret->type != MONO_TYPE_VOID, sig->param_count);
  
 -                              info->gsharedvt_invoke = TRUE;
                                info->wrapper_arg = mono_method_needs_static_rgctx_invoke (method, TRUE) ? mini_method_get_rgctx (method) : NULL;
  
                                invoke = mono_marshal_get_runtime_invoke_for_sig (wrapper_sig);
@@@ -3029,32 -3031,26 +3029,32 @@@ is_callee_gsharedvt_variable (gpointer 
        return callee_gsharedvt;
  }
  
 -void
 -mini_init_delegate (MonoDelegate *del)
 +gpointer
 +mini_get_delegate_arg (MonoMethod *method, gpointer method_ptr)
  {
 -      if (mono_llvm_only) {
 -              MonoMethod *method = del->method;
 +      gpointer arg = NULL;
  
 -              if (mono_method_needs_static_rgctx_invoke (method, FALSE))
 -                      del->rgctx = mini_method_get_rgctx (method);
 +      if (mono_method_needs_static_rgctx_invoke (method, FALSE))
 +              arg = mini_method_get_rgctx (method);
  
 -              /*
 -               * Avoid adding gsharedvt in wrappers since they might not exist if
 -               * this delegate is called through a gsharedvt delegate invoke wrapper.
 -               * Instead, encode that the method is gsharedvt in del->rgctx,
 -               * the CEE_MONO_CALLI_EXTRA_ARG implementation in the JIT depends on this.
 -               */
 -              if (is_callee_gsharedvt_variable (del->method_ptr)) {
 -                      g_assert ((((mgreg_t)del->rgctx) & 1) == 0);
 -                      del->rgctx = (gpointer)(((mgreg_t)del->rgctx) | 1);
 -              }
 +      /*
 +       * Avoid adding gsharedvt in wrappers since they might not exist if
 +       * this delegate is called through a gsharedvt delegate invoke wrapper.
 +       * Instead, encode that the method is gsharedvt in del->extra_arg,
 +       * the CEE_MONO_CALLI_EXTRA_ARG implementation in the JIT depends on this.
 +       */
 +      if (method->is_inflated && is_callee_gsharedvt_variable (method_ptr)) {
 +              g_assert ((((mgreg_t)arg) & 1) == 0);
 +              arg = (gpointer)(((mgreg_t)arg) | 1);
        }
 +      return arg;
 +}
 +
 +void
 +mini_init_delegate (MonoDelegate *del)
 +{
 +      if (mono_llvm_only)
 +              del->extra_arg = mini_get_delegate_arg (del->method, del->method_ptr);
  }
  
  gpointer
@@@ -3867,7 -3863,7 +3867,7 @@@ register_icalls (void
        register_icall (mono_object_new, "mono_object_new", "object ptr ptr", FALSE);
        register_icall (ves_icall_object_new_specific, "ves_icall_object_new_specific", "object ptr", FALSE);
        register_icall (mono_array_new, "mono_array_new", "object ptr ptr int32", FALSE);
-       register_icall (mono_array_new_specific, "mono_array_new_specific", "object ptr int32", FALSE);
+       register_icall (ves_icall_array_new_specific, "ves_icall_array_new_specific", "object ptr int32", FALSE);
        register_icall (mono_runtime_class_init, "mono_runtime_class_init", "void ptr", FALSE);
        register_icall (mono_ldftn, "mono_ldftn", "ptr ptr", FALSE);
        register_icall (mono_ldvirtfn, "mono_ldvirtfn", "ptr object ptr", FALSE);
        register_icall_no_wrapper (mono_llvmonly_get_calling_assembly, "mono_llvmonly_get_calling_assembly", "object");
        /* This needs a wrapper so it can have a preserveall cconv */
        register_icall (mono_init_vtable_slot, "mono_init_vtable_slot", "ptr ptr int", FALSE);
 -      register_icall (mono_llvmonly_init_delegate, "mono_llvmonly_init_delegate", "void object object ptr", TRUE);
 +      register_icall (mono_llvmonly_init_delegate, "mono_llvmonly_init_delegate", "void object", TRUE);
        register_icall (mono_llvmonly_init_delegate_virtual, "mono_llvmonly_init_delegate_virtual", "void object object ptr", TRUE);
        register_icall (mono_get_assembly_object, "mono_get_assembly_object", "object ptr", TRUE);
        register_icall (mono_get_method_object, "mono_get_method_object", "object ptr", TRUE);