Merge pull request #681 from tritao/dll-api
authorRodrigo Kumpera <kumpera@gmail.com>
Fri, 2 Aug 2013 17:55:19 +0000 (10:55 -0700)
committerRodrigo Kumpera <kumpera@gmail.com>
Fri, 2 Aug 2013 17:55:19 +0000 (10:55 -0700)
Added public API visibility macros

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

diff --combined mono/metadata/marshal.c
index c094574146c845b5e932628805dec6da996f0d5c,475745d261de92092378705680267e9a096cf1c8..301a1f7bae16e7ca926e9fbc611a8c9d60039156
@@@ -98,7 -98,7 +98,7 @@@ emit_struct_conv_full (MonoMethodBuilde
  static void 
  mono_struct_delete_old (MonoClass *klass, char *ptr);
  
- void *
MONO_API void *
  mono_marshal_string_to_utf16 (MonoString *s);
  
  static void *
@@@ -122,14 -122,9 +122,14 @@@ mono_string_from_byvalwstr (gunichar2 *
  static void
  mono_byvalarray_to_array (MonoArray *arr, gpointer native_arr, MonoClass *eltype, guint32 elnum);
  
 +static void
 +mono_byvalarray_to_byte_array (MonoArray *arr, gpointer native_arr, guint32 elnum);
 +
  static void
  mono_array_to_byvalarray (gpointer native_arr, MonoArray *arr, MonoClass *eltype, guint32 elnum);
  
 +static void
 +mono_array_to_byte_byvalarray (gpointer native_arr, MonoArray *arr, guint32 elnum);
  
  static MonoAsyncResult *
  mono_delegate_begin_invoke (MonoDelegate *delegate, gpointer *params);
@@@ -150,7 -145,7 +150,7 @@@ mono_marshal_check_domain_image (gint3
  static MonoObject *
  mono_remoting_wrapper (MonoMethod *method, gpointer *params);
  
- void
MONO_API void
  mono_upgrade_remote_class_wrapper (MonoReflectionType *rtype, MonoTransparentProxy *tproxy);
  
  #endif
@@@ -244,9 -239,7 +244,9 @@@ mono_marshal_init (void
                register_icall (mono_array_to_lparray, "mono_array_to_lparray", "ptr object", FALSE);
                register_icall (mono_free_lparray, "mono_free_lparray", "void object ptr", FALSE);
                register_icall (mono_byvalarray_to_array, "mono_byvalarray_to_array", "void object ptr ptr int32", FALSE);
 +              register_icall (mono_byvalarray_to_byte_array, "mono_byvalarray_to_byte_array", "void object ptr int32", FALSE);
                register_icall (mono_array_to_byvalarray, "mono_array_to_byvalarray", "void ptr object ptr int32", FALSE);
 +              register_icall (mono_array_to_byte_byvalarray, "mono_array_to_byte_byvalarray", "void ptr object int32", FALSE);
                register_icall (mono_delegate_to_ftnptr, "mono_delegate_to_ftnptr", "ptr object", FALSE);
                register_icall (mono_ftnptr_to_delegate, "mono_ftnptr_to_delegate", "object ptr ptr", FALSE);
                register_icall (mono_marshal_asany, "mono_marshal_asany", "ptr object int32 int32", FALSE);
@@@ -699,12 -692,6 +699,12 @@@ mono_byvalarray_to_array (MonoArray *ar
                g_assert_not_reached ();
  }
  
 +static void
 +mono_byvalarray_to_byte_array (MonoArray *arr, gpointer native_arr, guint32 elnum)
 +{
 +      mono_byvalarray_to_array (arr, native_arr, mono_defaults.byte_class, elnum);
 +}
 +
  static void
  mono_array_to_byvalarray (gpointer native_arr, MonoArray *arr, MonoClass *elclass, guint32 elnum)
  {
        }
  }
  
 +static void
 +mono_array_to_byte_byvalarray (gpointer native_arr, MonoArray *arr, guint32 elnum)
 +{
 +      mono_array_to_byvalarray (native_arr, arr, mono_defaults.byte_class, elnum);
 +}
 +
  void
  mono_string_utf8_to_builder (MonoStringBuilder *sb, char *text)
  {
@@@ -1365,8 -1346,9 +1365,8 @@@ emit_ptr_to_object_conv (MonoMethodBuil
                mono_mb_emit_ldloc (mb, 1);
                mono_mb_emit_byte (mb, CEE_LDIND_REF);
                mono_mb_emit_ldloc (mb, 0);
 -              mono_mb_emit_ptr (mb, mono_defaults.byte_class);
                mono_mb_emit_icon (mb, mspec->data.array_data.num_elem);
 -              mono_mb_emit_icall (mb, mono_byvalarray_to_array);
 +              mono_mb_emit_icall (mb, mono_byvalarray_to_byte_array);
                break;
        }
        case MONO_MARSHAL_CONV_STR_BYVALSTR: 
@@@ -1739,8 -1721,9 +1739,8 @@@ emit_object_to_ptr_conv (MonoMethodBuil
                mono_mb_emit_ldloc (mb, 1);
                mono_mb_emit_ldloc (mb, 0);     
                mono_mb_emit_byte (mb, CEE_LDIND_REF);
 -              mono_mb_emit_ptr (mb, mono_defaults.byte_class);
                mono_mb_emit_icon (mb, mspec->data.array_data.num_elem);
 -              mono_mb_emit_icall (mb, mono_array_to_byvalarray);
 +              mono_mb_emit_icall (mb, mono_array_to_byte_byvalarray);
                mono_mb_patch_short_branch (mb, pos);
                break;
        }
@@@ -2592,14 -2575,7 +2592,14 @@@ mono_marshal_method_from_wrapper (MonoM
                res = mono_marshal_get_wrapper_info (wrapper);
                if (res == NULL)
                        return wrapper;
 -              return res;
 +              if (wrapper->is_inflated)
 +                      /*
 +                       * A method cannot be inflated and a wrapper at the same time, so the wrapper info
 +                       * contains an uninflated method.
 +                       */
 +                      return mono_class_inflate_generic_method (res, mono_method_get_context (wrapper));
 +              else
 +                      return res;
        case MONO_WRAPPER_MANAGED_TO_NATIVE:
                info = mono_marshal_get_wrapper_info (wrapper);
                if (info && (info->subtype == WRAPPER_SUBTYPE_NONE || info->subtype == WRAPPER_SUBTYPE_NATIVE_FUNC_AOT))
@@@ -2693,77 -2669,6 +2693,77 @@@ get_wrapper_target_class (MonoImage *im
        return klass;
  }
  
 +/*
 + * Wrappers for generic methods should be instances of generic wrapper methods, i.e .the wrapper for Sort<int> should be
 + * an instance of the wrapper for Sort<T>. This is required for full-aot to work.
 + */
 +
 +/*
 + * check_generic_wrapper_cache:
 + *
 + *   Check CACHE for the wrapper of the generic instance ORIG_METHOD, and return it if it is found.
 + * KEY should be the key for ORIG_METHOD in the cache, while DEF_KEY should be the key of its
 + * generic method definition.
 + */
 +static MonoMethod*
 +check_generic_wrapper_cache (GHashTable *cache, MonoMethod *orig_method, gpointer key, gpointer def_key)
 +{
 +      MonoMethod *res;
 +      MonoMethod *inst, *def;
 +      MonoGenericContext *ctx;
 +      MonoMethod *def_method;
 +
 +      g_assert (orig_method->is_inflated);
 +      def_method = ((MonoMethodInflated*)orig_method)->declaring;
 +      ctx = mono_method_get_context (orig_method);
 +
 +      /*
 +       * Look for the instance
 +       */
 +      res = mono_marshal_find_in_cache (cache, key);
 +      if (res)
 +              return res;
 +
 +      /*
 +       * Look for the definition
 +       */
 +      def = mono_marshal_find_in_cache (cache, def_key);
 +      if (def) {
 +              inst = mono_class_inflate_generic_method (def, ctx);
 +              /* Cache it */
 +              mono_memory_barrier ();
 +              mono_marshal_lock ();
 +              res = g_hash_table_lookup (cache, key);
 +              if (!res) {
 +                      g_hash_table_insert (cache, key, inst);
 +                      res = inst;
 +              }
 +              mono_marshal_unlock ();
 +              return res;
 +      }
 +      return NULL;
 +}
 +
 +static MonoMethod*
 +cache_generic_wrapper (GHashTable *cache, MonoMethod *orig_method, MonoMethod *def, MonoGenericContext *ctx, gpointer key)
 +{
 +      MonoMethod *inst, *res;
 +
 +      /*
 +       * We use the same cache for the generic definition and the instances.
 +       */
 +      inst = mono_class_inflate_generic_method (def, ctx);
 +      mono_memory_barrier ();
 +      mono_marshal_lock ();
 +      res = g_hash_table_lookup (cache, key);
 +      if (!res) {
 +              g_hash_table_insert (cache, key, inst);
 +              res = inst;
 +      }
 +      mono_marshal_unlock ();
 +      return res;
 +}
 +
  static MonoMethod*
  check_generic_delegate_wrapper_cache (GHashTable *cache, MonoMethod *orig_method, MonoMethod *def_method, MonoGenericContext *ctx)
  {
@@@ -4520,12 -4425,9 +4520,12 @@@ mono_marshal_get_string_ctor_signature 
  static MonoType*
  get_runtime_invoke_type (MonoType *t, gboolean ret)
  {
 -      if (t->byref)
 +      if (t->byref) {
 +              if (t->type == MONO_TYPE_GENERICINST && mono_class_is_nullable (mono_class_from_mono_type (t)))
 +                      return t;
                /* Can't share this with 'I' as that needs another indirection */
 -              return t;
 +              return &mono_defaults.int_class->this_arg;
 +      }
  
        if (MONO_TYPE_IS_REFERENCE (t))
                return &mono_defaults.object_class->byval_arg;
@@@ -4944,10 -4846,20 +4944,10 @@@ mono_marshal_get_runtime_invoke (MonoMe
                /* Can't share this as we push a string as this */
                need_direct_wrapper = TRUE;
        } else {
 -              if (method->klass->valuetype && mono_method_signature (method)->hasthis) {
 -                      /* 
 -                       * Valuetype methods receive a managed pointer as the this argument.
 -                       * Create a new signature to reflect this.
 -                       */
 -                      callsig = signature_dup_add_this (method->klass->image, mono_method_signature (method), method->klass);
 -                      /* Can't share this as it would be shared with static methods taking an IntPtr argument */
 -                      need_direct_wrapper = TRUE;
 -              } else {
 -                      if (method->dynamic)
 -                              callsig = signature_dup (method->klass->image, mono_method_signature (method));
 -                      else
 -                              callsig = mono_method_signature (method);
 -              }
 +              if (method->dynamic)
 +                      callsig = signature_dup (method->klass->image, mono_method_signature (method));
 +              else
 +                      callsig = mono_method_signature (method);
        }
  
        target_klass = get_wrapper_target_class (method->klass->image);
  
        csig->ret = &mono_defaults.object_class->byval_arg;
        if (method->klass->valuetype && mono_method_signature (method)->hasthis)
 -              csig->params [0] = callsig->params [0];
 +              csig->params [0] = get_runtime_invoke_type (&method->klass->this_arg, FALSE);
        else
                csig->params [0] = &mono_defaults.object_class->byval_arg;
        csig->params [1] = &mono_defaults.int_class->byval_arg;
@@@ -9476,10 -9388,9 +9476,10 @@@ mono_marshal_get_managed_wrapper (MonoM
                        MonoBoolean set_last_error = 0;
                        MonoBoolean best_fit_mapping = 0;
                        MonoBoolean throw_on_unmappable = 0;
 +                      MonoError error;
  
 -                      mono_reflection_create_custom_attr_data_args (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, &typed_args, &named_args, &arginfo);
 -
 +                      mono_reflection_create_custom_attr_data_args (mono_defaults.corlib, attr->ctor, attr->data, attr->data_size, &typed_args, &named_args, &arginfo, &error);
 +                      g_assert (mono_error_ok (&error));
                        g_assert (mono_array_length (typed_args) == 1);
  
                        /* typed args */
@@@ -10298,19 -10209,6 +10298,19 @@@ mono_marshal_get_synchronized_inner_wra
        WrapperInfo *info;
        MonoMethodSignature *sig;
        MonoMethod *res;
 +      MonoGenericContext *ctx = NULL;
 +      MonoMethod *orig_method = NULL;
 +      MonoGenericContainer *container = NULL;
 +
 +      if (method->is_inflated && !mono_method_get_context (method)->method_inst) {
 +              orig_method = method;
 +              ctx = &((MonoMethodInflated*)method)->context;
 +              method = ((MonoMethodInflated*)method)->declaring;
 +              container = mono_method_get_generic_container (method);
 +              if (!container)
 +                      container = method->klass->generic_container;
 +              g_assert (container);
 +      }
  
        mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_UNKNOWN);
  #ifndef DISABLE_JIT
        info = mono_wrapper_info_create (res, WRAPPER_SUBTYPE_SYNCHRONIZED_INNER);
        info->d.synchronized_inner.method = method;
        mono_marshal_set_wrapper_info (res, info);
 +      if (ctx)
 +              res = mono_class_inflate_generic_method (res, ctx);
        return res;
  }
  
@@@ -10342,39 -10238,15 +10342,39 @@@ mono_marshal_get_synchronized_wrapper (
        MonoMethod *res;
        GHashTable *cache;
        int i, pos, this_local, ret_local = 0;
 +      MonoGenericContext *ctx = NULL;
 +      MonoMethod *orig_method = NULL;
 +      MonoGenericContainer *container = NULL;
  
        g_assert (method);
  
        if (method->wrapper_type == MONO_WRAPPER_SYNCHRONIZED)
                return method;
  
 -      cache = get_cache (&method->klass->image->synchronized_cache, mono_aligned_addr_hash, NULL);
 -      if ((res = mono_marshal_find_in_cache (cache, method)))
 -              return res;
 +      /* FIXME: Support generic methods too */
 +      if (method->is_inflated && !mono_method_get_context (method)->method_inst) {
 +              orig_method = method;
 +              ctx = &((MonoMethodInflated*)method)->context;
 +              method = ((MonoMethodInflated*)method)->declaring;
 +              container = mono_method_get_generic_container (method);
 +              if (!container)
 +                      container = method->klass->generic_container;
 +              g_assert (container);
 +      }
 +
 +      /*
 +       * Check cache
 +       */
 +      if (ctx) {
 +              cache = get_cache (&method->klass->image->synchronized_generic_cache, mono_aligned_addr_hash, NULL);
 +              res = check_generic_wrapper_cache (cache, orig_method, orig_method, method);
 +              if (res)
 +                      return res;
 +      } else {
 +              cache = get_cache (&method->klass->image->synchronized_cache, mono_aligned_addr_hash, NULL);
 +              if ((res = mono_marshal_find_in_cache (cache, method)))
 +                      return res;
 +      }
  
        sig = signature_dup (method->klass->image, mono_method_signature (method));
        sig->pinvoke = 0;
        for (i = 0; i < sig->param_count; i++)
                mono_mb_emit_ldarg (mb, i + (sig->hasthis == TRUE));
  
 -      mono_mb_emit_managed_call (mb, method, NULL);
 +      if (ctx)
 +              mono_mb_emit_managed_call (mb, mono_class_inflate_generic_method (method, &container->context), NULL);
 +      else
 +              mono_mb_emit_managed_call (mb, method, NULL);
  
        if (!MONO_TYPE_IS_VOID (sig->ret))
                mono_mb_emit_stloc (mb, ret_local);
        mono_mb_set_clauses (mb, 1, clause);
  #endif
  
 -      res = mono_mb_create_and_cache (cache, method,
 -                                                                      mb, sig, sig->param_count + 16);
 +      if (ctx) {
 +              MonoMethod *def;
 +              def = mono_mb_create_and_cache (cache, method, mb, sig, sig->param_count + 16);
 +              res = cache_generic_wrapper (cache, orig_method, def, ctx, orig_method);
 +      } else {
 +              res = mono_mb_create_and_cache (cache, method,
 +                                                                              mb, sig, sig->param_count + 16);
 +      }
        mono_mb_free (mb);
  
        return res;     
@@@ -11458,76 -11321,6 +11458,76 @@@ mono_marshal_get_array_address (int ran
        return ret;
  }
  
 +/*
 + * mono_marshal_get_array_accessor_wrapper:
 + *
 + *   Return a wrapper which just calls METHOD, which should be an Array Get/Set/Address method.
 + */
 +MonoMethod *
 +mono_marshal_get_array_accessor_wrapper (MonoMethod *method)
 +{
 +      MonoMethodSignature *sig;
 +      MonoMethodBuilder *mb;
 +      MonoMethod *res;
 +      GHashTable *cache;
 +      int i;
 +      MonoGenericContext *ctx = NULL;
 +      MonoMethod *orig_method = NULL;
 +      MonoGenericContainer *container = NULL;
 +      WrapperInfo *info;
 +
 +      /*
 +       * These wrappers are needed to avoid the JIT replacing the calls to these methods with intrinsics
 +       * inside runtime invoke wrappers, thereby making the wrappers not unshareable.
 +       * FIXME: Use generic methods.
 +       */
 +      /*
 +       * Check cache
 +       */
 +      if (ctx) {
 +              cache = NULL;
 +              g_assert_not_reached ();
 +      } else {
 +              cache = get_cache (&method->klass->image->array_accessor_cache, mono_aligned_addr_hash, NULL);
 +              if ((res = mono_marshal_find_in_cache (cache, method)))
 +                      return res;
 +      }
 +
 +      sig = signature_dup (method->klass->image, mono_method_signature (method));
 +      sig->pinvoke = 0;
 +
 +      mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_UNKNOWN);
 +
 +#ifndef DISABLE_JIT
 +      /* Call the method */
 +      if (sig->hasthis)
 +              mono_mb_emit_ldarg (mb, 0);
 +      for (i = 0; i < sig->param_count; i++)
 +              mono_mb_emit_ldarg (mb, i + (sig->hasthis == TRUE));
 +
 +      if (ctx)
 +              mono_mb_emit_managed_call (mb, mono_class_inflate_generic_method (method, &container->context), NULL);
 +      else
 +              mono_mb_emit_managed_call (mb, method, NULL);
 +      mono_mb_emit_byte (mb, CEE_RET);
 +#endif
 +
 +      if (ctx) {
 +              MonoMethod *def;
 +              def = mono_mb_create_and_cache (cache, method, mb, sig, sig->param_count + 16);
 +              res = cache_generic_wrapper (cache, orig_method, def, ctx, orig_method);
 +      } else {
 +              res = mono_mb_create_and_cache (cache, method,
 +                                                                              mb, sig, sig->param_count + 16);
 +              info = mono_wrapper_info_create (res, WRAPPER_SUBTYPE_ARRAY_ACCESSOR);
 +              info->d.array_accessor.method = method;
 +              mono_marshal_set_wrapper_info (res, info);
 +      }
 +      mono_mb_free (mb);
 +
 +      return res;     
 +}
 +
  void*
  mono_marshal_alloc (gulong size)
  {
diff --combined mono/metadata/marshal.h
index 9046b14589e9a8cd71631811fa1850e5a32242b4,80ffdbd4cfa42cb6384a2b4b0bfe2f115ae150b4..22db7a6b330d99e3f068e5cc47dc9d213bc35b70
@@@ -108,7 -108,6 +108,7 @@@ typedef enum 
        WRAPPER_SUBTYPE_SYNCHRONIZED_INNER,
        WRAPPER_SUBTYPE_GSHAREDVT_IN,
        WRAPPER_SUBTYPE_GSHAREDVT_OUT,
 +      WRAPPER_SUBTYPE_ARRAY_ACCESSOR,
        /* Subtypes of MONO_WRAPPER_MANAGED_TO_MANAGED */
        WRAPPER_SUBTYPE_GENERIC_ARRAY_HELPER
  } WrapperSubtype;
@@@ -152,10 -151,6 +152,10 @@@ typedef struct 
        gpointer func;
  } ICallWrapperInfo;
  
 +typedef struct {
 +      MonoMethod *method;
 +} ArrayAccessorWrapperInfo;
 +
  /*
   * This structure contains additional information to uniquely identify a given wrapper
   * method. It can be retrieved by mono_marshal_get_wrapper_info () for certain types
@@@ -182,8 -177,6 +182,8 @@@ typedef struct 
                GenericArrayHelperWrapperInfo generic_array_helper;
                /* ICALL_WRAPPER */
                ICallWrapperInfo icall;
 +              /* ARRAY_ACCESSOR */
 +              ArrayAccessorWrapperInfo array_accessor;
        } d;
  } WrapperInfo;
  
@@@ -360,9 -353,6 +360,9 @@@ mono_marshal_get_virtual_stelemref_wrap
  MonoMethod*
  mono_marshal_get_array_address (int rank, int elem_size) MONO_INTERNAL;
  
 +MonoMethod *
 +mono_marshal_get_array_accessor_wrapper (MonoMethod *method) MONO_INTERNAL;
 +
  MonoMethod *
  mono_marshal_get_generic_array_helper (MonoClass *class, MonoClass *iface,
                                       gchar *name, MonoMethod *method) MONO_INTERNAL;
@@@ -524,16 -514,16 +524,16 @@@ ves_icall_Mono_Interop_ComInteropProxy_
  MonoComInteropProxy*
  ves_icall_Mono_Interop_ComInteropProxy_FindProxy (gpointer pUnk) MONO_INTERNAL;
  
- void
MONO_API void
  mono_win32_compat_CopyMemory (gpointer dest, gconstpointer source, gsize length);
  
- void
MONO_API void
  mono_win32_compat_FillMemory (gpointer dest, gsize length, guchar fill);
  
- void
MONO_API void
  mono_win32_compat_MoveMemory (gpointer dest, gconstpointer source, gsize length);
  
- void
MONO_API void
  mono_win32_compat_ZeroMemory (gpointer dest, gsize length);
  
  void
index ae7b87601719be46a436d053a491ef2db3689ce3,808b59cf0dad410c4ab5dabe1de71b15a71b353f..072f62153023ad0c6d0afbfc4891122c05818a1e
@@@ -282,8 -282,6 +282,8 @@@ struct _MonoImage 
        GHashTable *cominterop_wrapper_cache; /* LOCKING: marshal lock */
        GHashTable *thunk_invoke_cache;
        GHashTable *wrapper_param_names;
 +      GHashTable *synchronized_generic_cache;
 +      GHashTable *array_accessor_cache;
  
        /*
         * indexed by MonoClass pointers
@@@ -590,7 -588,7 +590,7 @@@ mono_metadata_clean_for_image (MonoImag
  void
  mono_metadata_clean_generic_classes_for_image (MonoImage *image) MONO_INTERNAL;
  
- void
MONO_API void
  mono_metadata_cleanup (void);
  
  const char *   mono_meta_table_name              (int table) MONO_INTERNAL;
@@@ -610,7 -608,7 +610,7 @@@ mono_metadata_parse_array_ful
                                             const char            *ptr,
                                             const char           **rptr) MONO_INTERNAL;
  
- MonoType *
+ MONO_API MonoType *
  mono_metadata_parse_type_full               (MonoImage             *image,
                                             MonoGenericContainer  *container,
                                             MonoParseTypeMode      mode,
@@@ -623,14 -621,14 +623,14 @@@ mono_metadata_parse_signature_ful
                                             MonoGenericContainer  *generic_container,
                                             guint32                token) MONO_INTERNAL;
  
- MonoMethodSignature *
+ MONO_API MonoMethodSignature *
  mono_metadata_parse_method_signature_full   (MonoImage             *image,
                                             MonoGenericContainer  *generic_container,
                                             int                     def,
                                             const char             *ptr,
                                             const char            **rptr);
  
- MonoMethodHeader *
+ MONO_API MonoMethodHeader *
  mono_metadata_parse_mh_full                 (MonoImage             *image,
                                             MonoGenericContainer  *container,
                                             const char            *ptr);
@@@ -689,7 -687,7 +689,7 @@@ mono_assembly_name_parse_full                   (c
                                              gboolean *is_version_defined,
                                                  gboolean *is_token_defined) MONO_INTERNAL;
  
- guint32 mono_metadata_get_generic_param_row (MonoImage *image, guint32 token, guint32 *owner);
MONO_API guint32 mono_metadata_get_generic_param_row (MonoImage *image, guint32 token, guint32 *owner);
  
  void mono_unload_interface_ids (MonoBitSet *bitset) MONO_INTERNAL;
  
@@@ -704,7 -702,7 +704,7 @@@ mono_get_shared_generic_inst (MonoGener
  int
  mono_type_stack_size_internal (MonoType *t, int *align, gboolean allow_open) MONO_INTERNAL;
  
- void            mono_type_get_desc (GString *res, MonoType *type, mono_bool include_namespace);
MONO_API void            mono_type_get_desc (GString *res, MonoType *type, mono_bool include_namespace);
  
  gboolean
  mono_metadata_type_equal_full (MonoType *t1, MonoType *t2, gboolean signature_only) MONO_INTERNAL;
@@@ -715,7 -713,7 +715,7 @@@ mono_metadata_parse_marshal_spec_full (
  guint        mono_metadata_generic_inst_hash (gconstpointer data) MONO_INTERNAL;
  gboolean       mono_metadata_generic_inst_equal (gconstpointer ka, gconstpointer kb) MONO_INTERNAL;
  
- void
MONO_API void
  mono_metadata_field_info_with_mempool (
                                          MonoImage *meta, 
                                      guint32       table_index,
index 40e542dfa61642aea95f69666c460f4611c35d55,98201e3429ac91b7fb2d7f60162a610e324698d1..a856c1cfa6d4da274df5dddbe1bdb0b468cf1363
@@@ -1391,7 -1391,7 +1391,7 @@@ void        mono_reflection_initialize_
  void        mono_reflection_create_unmanaged_type (MonoReflectionType *type) MONO_INTERNAL;
  void        mono_reflection_register_with_runtime (MonoReflectionType *type) MONO_INTERNAL;
  
 -void        mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoArray **typed_args, MonoArray **named_args, CattrNamedArg **named_arg_info) MONO_INTERNAL;
 +void        mono_reflection_create_custom_attr_data_args (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len, MonoArray **typed_args, MonoArray **named_args, CattrNamedArg **named_arg_info, MonoError *error) MONO_INTERNAL;
  MonoMethodSignature * mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32 token) MONO_INTERNAL;
  
  MonoArray* mono_param_get_objects_internal  (MonoDomain *domain, MonoMethod *method, MonoClass *refclass) MONO_INTERNAL;
@@@ -1584,7 -1584,7 +1584,7 @@@ voi
  mono_field_static_get_value_for_thread (MonoInternalThread *thread, MonoVTable *vt, MonoClassField *field, void *value) MONO_INTERNAL;
  
  /* exported, used by the debugger */
- void *
MONO_API void *
  mono_vtable_get_static_field_data (MonoVTable *vt);
  
  char *
diff --combined mono/mini/decompose.c
index 2beeb9e59d57475fa500935d05262777fd834b91,83838900e8bb36816e086032711961027c2d5340..1bbdedb4307d9a26c657231173b7417f68be828c
@@@ -17,7 -17,7 +17,7 @@@
  #ifndef DISABLE_JIT
  
  /* FIXME: This conflicts with the definition in mini.c, so it cannot be moved to mini.h */
- MonoInst* mono_emit_native_call (MonoCompile *cfg, gconstpointer func, MonoMethodSignature *sig, MonoInst **args);
+ MONO_API MonoInst* mono_emit_native_call (MonoCompile *cfg, gconstpointer func, MonoMethodSignature *sig, MonoInst **args);
  void mini_emit_stobj (MonoCompile *cfg, MonoInst *dest, MonoInst *src, MonoClass *klass, gboolean native);
  void mini_emit_initobj (MonoCompile *cfg, MonoInst *dest, const guchar *ip, MonoClass *klass);
  
@@@ -1483,7 -1483,7 +1483,7 @@@ typedef union 
        double vald;
  } DVal;
  
 -#ifdef MONO_ARCH_SOFT_FLOAT
 +#ifdef MONO_ARCH_SOFT_FLOAT_FALLBACK
  
  /**
   * mono_decompose_soft_float:
diff --combined mono/mini/method-to-ir.c
index e081bb01bef0f3d6f7c88c28413b3e16dfc09bf2,d025a3063dd286e133f985325f6db9c11d9a8534..a8a0fd3d60480a3e18d55b0d190459b5345aeb83
@@@ -130,7 -130,7 +130,7 @@@ static int stind_to_store_membase (int 
  int mono_op_to_op_imm (int opcode);
  int mono_op_to_op_imm_noemul (int opcode);
  
- MonoInst* mono_emit_native_call (MonoCompile *cfg, gconstpointer func, MonoMethodSignature *sig, MonoInst **args);
+ MONO_API MonoInst* mono_emit_native_call (MonoCompile *cfg, gconstpointer func, MonoMethodSignature *sig, MonoInst **args);
  
  /* helper methods signatures */
  static MonoMethodSignature *helper_sig_class_init_trampoline = NULL;
@@@ -2337,7 -2337,7 +2337,7 @@@ mono_emit_call_args (MonoCompile *cfg, 
                                         MonoInst **args, int calli, int virtual, int tail, int rgctx, int unbox_trampoline)
  {
        MonoCallInst *call;
 -#ifdef MONO_ARCH_SOFT_FLOAT
 +#ifdef MONO_ARCH_SOFT_FLOAT_FALLBACK
        int i;
  #endif
  
        } else if (!MONO_TYPE_IS_VOID (sig->ret))
                call->inst.dreg = alloc_dreg (cfg, call->inst.type);
  
 -#ifdef MONO_ARCH_SOFT_FLOAT
 +#ifdef MONO_ARCH_SOFT_FLOAT_FALLBACK
        if (COMPILE_SOFT_FLOAT (cfg)) {
                /* 
                 * If the call has a float argument, we would need to do an r8->r4 conversion using 
@@@ -2790,7 -2790,7 +2790,7 @@@ create_write_barrier_bitmap (MonoCompil
  }
  
  static void
 -emit_write_barrier (MonoCompile *cfg, MonoInst *ptr, MonoInst *value, int value_reg)
 +emit_write_barrier (MonoCompile *cfg, MonoInst *ptr, MonoInst *value)
  {
        int card_table_shift_bits;
        gpointer card_table_mask;
  
                MONO_INST_NEW (cfg, wbarrier, OP_CARD_TABLE_WBARRIER);
                wbarrier->sreg1 = ptr->dreg;
 -              if (value)
 -                      wbarrier->sreg2 = value->dreg;
 -              else
 -                      wbarrier->sreg2 = value_reg;
 +              wbarrier->sreg2 = value->dreg;
                MONO_ADD_INS (cfg->cbb, wbarrier);
        } else if (card_table) {
                int offset_reg = alloc_preg (cfg);
                mono_emit_method_call (cfg, write_barrier, &ptr, NULL);
        }
  
 -      if (value) {
 -              EMIT_NEW_DUMMY_USE (cfg, dummy_use, value);
 -      } else {
 -              MONO_INST_NEW (cfg, dummy_use, OP_DUMMY_USE);
 -              dummy_use->sreg1 = value_reg;
 -              MONO_ADD_INS (cfg->cbb, dummy_use);
 -      }
 +      EMIT_NEW_DUMMY_USE (cfg, dummy_use, value);
  }
  
  static gboolean
@@@ -2891,17 -2900,11 +2891,17 @@@ mono_emit_wb_aware_memcpy (MonoCompile 
        EMIT_NEW_UNALU (cfg, iargs [0], OP_MOVE, dest_ptr_reg, destreg);
  
        while (size >= SIZEOF_VOID_P) {
 -              MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOAD_MEMBASE, tmp_reg, srcreg, offset);
 +              MonoInst *load_inst;
 +              MONO_INST_NEW (cfg, load_inst, OP_LOAD_MEMBASE);
 +              load_inst->dreg = tmp_reg;
 +              load_inst->inst_basereg = srcreg;
 +              load_inst->inst_offset = offset;
 +              MONO_ADD_INS (cfg->cbb, load_inst);
 +
                MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREP_MEMBASE_REG, dest_ptr_reg, 0, tmp_reg);
  
                if (need_wb & 0x1)
 -                      emit_write_barrier (cfg, iargs [0], NULL, tmp_reg);
 +                      emit_write_barrier (cfg, iargs [0], load_inst);
  
                offset += SIZEOF_VOID_P;
                size -= SIZEOF_VOID_P;
@@@ -3533,7 -3536,7 +3533,7 @@@ handle_unbox_gsharedvt (MonoCompile *cf
        args [1] = klass_inst;
  
        /* CASTCLASS */
 -      obj = mono_emit_jit_icall (cfg, mono_object_castclass, args);
 +      obj = mono_emit_jit_icall (cfg, mono_object_castclass_unbox, args);
  
        NEW_BBLOCK (cfg, is_ref_bb);
        NEW_BBLOCK (cfg, is_nullable_bb);
@@@ -4283,7 -4286,7 +4283,7 @@@ handle_delegate_ctor (MonoCompile *cfg
                if (cfg->gen_write_barriers) {
                        dreg = alloc_preg (cfg);
                        EMIT_NEW_BIALU_IMM (cfg, ptr, OP_PADD_IMM, dreg, obj->dreg, G_STRUCT_OFFSET (MonoDelegate, target));
 -                      emit_write_barrier (cfg, ptr, target, 0);
 +                      emit_write_barrier (cfg, ptr, target);
                }
        }
  
        if (cfg->gen_write_barriers) {
                dreg = alloc_preg (cfg);
                EMIT_NEW_BIALU_IMM (cfg, ptr, OP_PADD_IMM, dreg, obj->dreg, G_STRUCT_OFFSET (MonoDelegate, method));
 -              emit_write_barrier (cfg, ptr, method_ins, 0);
 +              emit_write_barrier (cfg, ptr, method_ins);
        }
        /* 
         * To avoid looking up the compiled code belonging to the target method
@@@ -4396,7 -4399,7 +4396,7 @@@ mono_method_check_inlining (MonoCompil
  {
        MonoMethodHeaderSummary header;
        MonoVTable *vtable;
 -#ifdef MONO_ARCH_SOFT_FLOAT
 +#ifdef MONO_ARCH_SOFT_FLOAT_FALLBACK
        MonoMethodSignature *sig = mono_method_signature (method);
        int i;
  #endif
        if (mono_security_method_has_declsec (method))
                return FALSE;
  
 -#ifdef MONO_ARCH_SOFT_FLOAT
 -      /* FIXME: */
 -      if (sig->ret && sig->ret->type == MONO_TYPE_R4)
 -              return FALSE;
 -      for (i = 0; i < sig->param_count; ++i)
 -              if (!sig->params [i]->byref && sig->params [i]->type == MONO_TYPE_R4)
 +#ifdef MONO_ARCH_SOFT_FLOAT_FALLBACK
 +      if (mono_arch_is_soft_float ()) {
 +              /* FIXME: */
 +              if (sig->ret && sig->ret->type == MONO_TYPE_R4)
                        return FALSE;
 +              for (i = 0; i < sig->param_count; ++i)
 +                      if (!sig->params [i]->byref && sig->params [i]->type == MONO_TYPE_R4)
 +                              return FALSE;
 +      }
  #endif
  
        return TRUE;
@@@ -4758,7 -4759,7 +4758,7 @@@ emit_array_generic_access (MonoCompile 
                EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, load, &eklass->byval_arg, args [2]->dreg, 0);
                EMIT_NEW_STORE_MEMBASE_TYPE (cfg, store, &eklass->byval_arg, addr->dreg, 0, load->dreg);
                if (mini_type_is_reference (cfg, fsig->params [2]))
 -                      emit_write_barrier (cfg, addr, load, -1);
 +                      emit_write_barrier (cfg, addr, load);
        } else {
                EMIT_NEW_LOAD_MEMBASE_TYPE (cfg, load, &eklass->byval_arg, addr->dreg, 0);
                EMIT_NEW_STORE_MEMBASE_TYPE (cfg, store, &eklass->byval_arg, args [2]->dreg, 0, load->dreg);
@@@ -4818,7 -4819,7 +4818,7 @@@ emit_array_store (MonoCompile *cfg, Mon
                        MonoInst *addr = mini_emit_ldelema_1_ins (cfg, klass, sp [0], sp [1], safety_checks);
                        EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, &klass->byval_arg, addr->dreg, 0, sp [2]->dreg);
                        if (generic_class_is_reference_type (cfg, klass))
 -                              emit_write_barrier (cfg, addr, sp [2], -1);
 +                              emit_write_barrier (cfg, addr, sp [2]);
                }
                return ins;
        }
@@@ -5315,7 -5316,7 +5315,7 @@@ mini_emit_inst_for_method (MonoCompile 
                        }
  
                        if (cfg->gen_write_barriers && is_ref)
 -                              emit_write_barrier (cfg, args [0], args [1], -1);
 +                              emit_write_barrier (cfg, args [0], args [1]);
                }
  #endif /* MONO_ARCH_HAVE_ATOMIC_EXCHANGE */
   
                                /* g_assert_not_reached (); */
                        }
                        if (cfg->gen_write_barriers && is_ref)
 -                              emit_write_barrier (cfg, args [0], args [1], -1);
 +                              emit_write_barrier (cfg, args [0], args [1]);
                }
  #endif /* MONO_ARCH_HAVE_ATOMIC_CAS */
  
@@@ -7598,55 -7599,27 +7598,55 @@@ mono_method_to_ir (MonoCompile *cfg, Mo
                                        /*
                                         * Constrained calls need to behave differently at runtime dependending on whenever the receiver is instantiated as ref type or as a vtype.
                                         */
 -                                      /* Special case Object methods as they are easy to implement */
 -                                      if (cmethod->klass == mono_defaults.object_class) {
 +                                      if ((cmethod->klass != mono_defaults.object_class) && constrained_call->valuetype && cmethod->klass->valuetype) {
 +                                              /* The 'Own method' case below */
 +                                      } else if (((cmethod->klass == mono_defaults.object_class) || (cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE)) &&
 +                                                         (MONO_TYPE_IS_VOID (fsig->ret) || fsig->ret->type == MONO_TYPE_I4 || fsig->ret->type == MONO_TYPE_BOOLEAN || fsig->ret->type == MONO_TYPE_STRING) &&
 +                                                         (fsig->param_count == 0 || (fsig->param_count == 1 && MONO_TYPE_IS_REFERENCE (fsig->params [0])))) {
                                                MonoInst *args [16];
  
 +                                              /*
 +                                               * This case handles calls to object:ToString()/Equals()/GetHashCode(), plus some simple interface calls enough to support
 +                                               * AsyncTaskMethodBuilder.
 +                                               */
 +
                                                args [0] = sp [0];
                                                EMIT_NEW_METHODCONST (cfg, args [1], cmethod);
                                                args [2] = emit_get_rgctx_klass (cfg, mono_class_check_context_used (constrained_call), constrained_call, MONO_RGCTX_INFO_KLASS);
  
 -                                              if (!strcmp (cmethod->name, "ToString")) {
 -                                                      ins = mono_emit_jit_icall (cfg, mono_object_tostring_gsharedvt, args);
 -                                              } else if (!strcmp (cmethod->name, "Equals")) {
 -                                                      args [3] = sp [1];
 -                                                      ins = mono_emit_jit_icall (cfg, mono_object_equals_gsharedvt, args);
 -                                              } else if (!strcmp (cmethod->name, "GetHashCode")) {
 -                                                      ins = mono_emit_jit_icall (cfg, mono_object_gethashcode_gsharedvt, args);
 +                                              if (fsig->param_count) {
 +                                                      /* Pass the arguments using a localloc-ed array using the format expected by runtime_invoke () */
 +                                                      MONO_INST_NEW (cfg, ins, OP_LOCALLOC_IMM);
 +                                                      ins->dreg = alloc_preg (cfg);
 +                                                      ins->inst_imm = fsig->param_count * sizeof (mgreg_t);
 +                                                      MONO_ADD_INS (cfg->cbb, ins);
 +                                                      args [3] = ins;
 +
 +                                                      EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_REG, args [3]->dreg, 0, sp [1]->dreg);
                                                } else {
 -                                                      GSHAREDVT_FAILURE (*ip);
 +                                                      EMIT_NEW_ICONST (cfg, args [3], 0);
                                                }
 +                                              ins = mono_emit_jit_icall (cfg, mono_gsharedvt_constrained_call, args);
 +                                              emit_widen = FALSE;
 +
 +                                              if (fsig->ret->type == MONO_TYPE_I4 || fsig->ret->type == MONO_TYPE_BOOLEAN) {
 +                                                      MonoInst *add;
 +                                                      int dreg;
 +
 +                                                      /* Unbox */
 +                                                      NEW_BIALU_IMM (cfg, add, OP_ADD_IMM, alloc_dreg (cfg, STACK_MP), ins->dreg, sizeof (MonoObject));
 +                                                      MONO_ADD_INS (cfg->cbb, add);
 +                                                      dreg = alloc_ireg (cfg);
 +                                                      /* Load value */
 +                                                      if (fsig->ret->type == MONO_TYPE_BOOLEAN)
 +                                                              NEW_LOAD_MEMBASE (cfg, ins, OP_LOADU1_MEMBASE, dreg, add->dreg, 0);
 +                                                      else
 +                                                              NEW_LOAD_MEMBASE (cfg, ins, OP_LOADI4_MEMBASE, dreg, add->dreg, 0);
 +                                                      MONO_ADD_INS (cfg->cbb, ins);
 +                                                      /* ins represents the call result */
 +                                              }
 +
                                                goto call_end;
 -                                      } else if (constrained_call->valuetype && cmethod->klass->valuetype) {
 -                                              /* The 'Own method' case below */
                                        } else {
                                                GSHAREDVT_FAILURE (*ip);
                                        }
                                        addr = mini_emit_ldelema_ins (cfg, cmethod, sp, ip, TRUE);
                                        EMIT_NEW_STORE_MEMBASE_TYPE (cfg, ins, fsig->params [fsig->param_count - 1], addr->dreg, 0, val->dreg);
                                        if (cfg->gen_write_barriers && val->type == STACK_OBJ && !(val->opcode == OP_PCONST && val->inst_c0 == 0))
 -                                              emit_write_barrier (cfg, addr, val, 0);
 +                                              emit_write_barrier (cfg, addr, val);
                                } else if (strcmp (cmethod->name, "Get") == 0) { /* array Get */
                                        addr = mini_emit_ldelema_ins (cfg, cmethod, sp, ip, FALSE);
  
                         * change the called method to a dummy wrapper, and resolve that wrapper
                         * to the real method in mono_jit_compile_method ().
                         */
 -                      if (cfg->method->wrapper_type == MONO_WRAPPER_SYNCHRONIZED && mono_marshal_method_from_wrapper (cfg->method) == cmethod)
 -                              cmethod = mono_marshal_get_synchronized_inner_wrapper (cmethod);
 +                      if (cfg->method->wrapper_type == MONO_WRAPPER_SYNCHRONIZED) {
 +                              MonoMethod *orig = mono_marshal_method_from_wrapper (cfg->method);
 +                              if (cmethod == orig || (cmethod->is_inflated && mono_method_get_declaring_generic_method (cmethod) == orig))
 +                                      cmethod = mono_marshal_get_synchronized_inner_wrapper (cmethod);
 +                      }
  
                        /* Common call */
                        INLINE_FAILURE ("call");
                                                        ins->klass = mono_class_from_mono_type (ret_type);
                                                }
                                        } else {
 -#ifdef MONO_ARCH_SOFT_FLOAT
 +#ifdef MONO_ARCH_SOFT_FLOAT_FALLBACK
                                                if (COMPILE_SOFT_FLOAT (cfg) && !ret_type->byref && ret_type->type == MONO_TYPE_R4) {
                                                        MonoInst *iargs [1];
                                                        MonoInst *conv;
                        MONO_ADD_INS (bblock, ins);
  
                        if (cfg->gen_write_barriers && *ip == CEE_STIND_REF && method->wrapper_type != MONO_WRAPPER_WRITE_BARRIER && !((sp [1]->opcode == OP_PCONST) && (sp [1]->inst_p0 == 0)))
 -                              emit_write_barrier (cfg, sp [0], sp [1], -1);
 +                              emit_write_barrier (cfg, sp [0], sp [1]);
  
                        inline_costs += 1;
                        ++ip;
                                MONO_ADD_INS (cfg->cbb, store);
  
                                if (cfg->gen_write_barriers && cfg->method->wrapper_type != MONO_WRAPPER_WRITE_BARRIER)
 -                                      emit_write_barrier (cfg, sp [0], sp [1], -1);
 +                                      emit_write_barrier (cfg, sp [0], sp [1]);
                        } else {
                                mini_emit_stobj (cfg, sp [0], sp [1], klass, FALSE);
                        }
                                        EMIT_NEW_PCONST (cfg, args [2], mono_domain_alloc0 (cfg->domain, sizeof (gpointer)));
  
                                /*The wrapper doesn't inline well so the bloat of inlining doesn't pay off.*/
 +                              save_cast_details (cfg, klass, sp [0]->dreg);
                                *sp++ = mono_emit_method_call (cfg, mono_castclass, args, NULL);
 +                              reset_cast_details (cfg);
                                ip += 5;
                                inline_costs += 2;
                        } else if (!context_used && (mono_class_is_marshalbyref (klass) || klass->flags & TYPE_ATTRIBUTE_INTERFACE)) {
                                mono_castclass = mono_marshal_get_castclass (klass); 
                                iargs [0] = sp [0];
                                
 +                              save_cast_details (cfg, klass, sp [0]->dreg);
                                costs = inline_method (cfg, mono_castclass, mono_method_signature (mono_castclass), 
                                                           iargs, ip, cfg->real_offset, dont_inline, TRUE);
 +                              reset_cast_details (cfg);
                                CHECK_CFG_EXCEPTION;
                                g_assert (costs > 0);
                                
  
                                        dreg = alloc_ireg_mp (cfg);
                                        EMIT_NEW_BIALU_IMM (cfg, ptr, OP_PADD_IMM, dreg, sp [0]->dreg, foffset);
 -                                      emit_write_barrier (cfg, ptr, sp [1], -1);
 +                                      emit_write_barrier (cfg, ptr, sp [1]);
                                }
  
                                        store->flags |= ins_flag;
                        if (cfg->gen_write_barriers && cfg->method->wrapper_type != MONO_WRAPPER_WRITE_BARRIER &&
                                        generic_class_is_reference_type (cfg, klass)) {
                                /* insert call to write barrier */
 -                              emit_write_barrier (cfg, sp [0], sp [1], -1);
 +                              emit_write_barrier (cfg, sp [0], sp [1]);
                        }
                        ins_flag = 0;
                        ip += 5;
                        context_used = mini_class_check_context_used (cfg, klass);
  
                        if (sp [0]->type == STACK_I8 || (SIZEOF_VOID_P == 8 && sp [0]->type == STACK_PTR)) {
 -                              MONO_INST_NEW (cfg, ins, OP_LCONV_TO_I4);
 +                              MONO_INST_NEW (cfg, ins, OP_LCONV_TO_OVF_U4);
                                ins->sreg1 = sp [0]->dreg;
                                ins->type = STACK_I4;
                                ins->dreg = alloc_ireg (cfg);
@@@ -12439,13 -12405,10 +12439,13 @@@ mono_handle_global_vregs (MonoCompile *
  #if SIZEOF_REGISTER == 8
                case STACK_I8:
  #endif
 -#if !defined(TARGET_X86) && !defined(MONO_ARCH_SOFT_FLOAT)
 +#if !defined(TARGET_X86)
                /* Enabling this screws up the fp stack on x86 */
                case STACK_R8:
  #endif
 +                      if (mono_arch_is_soft_float ())
 +                              break;
 +
                        /* Arguments are implicitly global */
                        /* Putting R4 vars into registers doesn't work currently */
                        /* The gsharedvt vars are implicitly referenced by ldaddr opcodes, but those opcodes are only generated later */
diff --combined mono/mini/mini.h
index a0867f06baf5d163082324031f52f36dea76e350,950b7f2fb78aa87fc5db83b5d145e4bdf95b3a74..7102b276fb90e5e8bdae9c63a1d246ddabd455fb
  #define LLVM_ENABLED FALSE
  #endif
  
 -#ifdef MONO_ARCH_SOFT_FLOAT
 -#define COMPILE_SOFT_FLOAT(cfg) (!COMPILE_LLVM ((cfg)))
 +#ifdef MONO_ARCH_SOFT_FLOAT_FALLBACK
 +#define COMPILE_SOFT_FLOAT(cfg) (!COMPILE_LLVM ((cfg)) && mono_arch_is_soft_float ())
  #else
 -#define COMPILE_SOFT_FLOAT(cfg) 0
 +#define COMPILE_SOFT_FLOAT(cfg) (0)
  #endif
  
  #ifdef ENABLE_LLVM
  #endif
  
  /* Version number of the AOT file format */
 -#define MONO_AOT_FILE_VERSION 90
 +#define MONO_AOT_FILE_VERSION 92
  
  //TODO: This is x86/amd64 specific.
  #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
@@@ -281,7 -281,7 +281,7 @@@ typedef struct MonoAotFileInf
        guint32 num_rgctx_fetch_trampolines;
  
        /* These are used for sanity checking object layout problems when cross-compiling */
 -      guint32 double_align, long_align;
 +      guint32 double_align, long_align, generic_tramp_num;
  } MonoAotFileInfo;
  
  /* Per-domain information maintained by the JIT */
@@@ -1244,11 -1244,15 +1244,11 @@@ typedef enum 
        MONO_TRAMPOLINE_AOT_PLT,
        MONO_TRAMPOLINE_DELEGATE,
        MONO_TRAMPOLINE_RESTORE_STACK_PROT,
 -#ifndef DISABLE_REMOTING
        MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING,
 -#endif
        MONO_TRAMPOLINE_MONITOR_ENTER,
        MONO_TRAMPOLINE_MONITOR_EXIT,
        MONO_TRAMPOLINE_VCALL,
 -#ifdef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD
        MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD,
 -#endif
        MONO_TRAMPOLINE_NUM
  } MonoTrampolineType;
  
@@@ -1871,8 -1875,8 +1871,8 @@@ enum 
  typedef void (*MonoInstFunc) (MonoInst *tree, gpointer data);
  
  /* main function */
- int         mono_main                      (int argc, char* argv[]);
- void        mono_set_defaults              (int verbose_level, guint32 opts);
MONO_API int         mono_main                      (int argc, char* argv[]);
MONO_API void        mono_set_defaults              (int verbose_level, guint32 opts);
  MonoDomain* mini_init                      (const char *filename, const char *runtime_version) MONO_INTERNAL;
  void        mini_cleanup                   (MonoDomain *domain) MONO_INTERNAL;
  MonoDebugOptions *mini_get_debug_options   (void) MONO_INTERNAL;
@@@ -1888,7 -1892,7 +1888,7 @@@ MonoInst* mono_find_exvar_for_offse
  int       mono_get_block_region_notry       (MonoCompile *cfg, int region) MONO_LLVM_INTERNAL;
  
  void      mono_precompile_assemblies        (void) MONO_INTERNAL;
- int       mono_parse_default_optimizations  (const char* p);
MONO_API int       mono_parse_default_optimizations  (const char* p);
  void      mono_bblock_add_inst              (MonoBasicBlock *bb, MonoInst *inst) MONO_LLVM_INTERNAL;
  void      mono_bblock_insert_after_ins      (MonoBasicBlock *bb, MonoInst *ins, MonoInst *ins_to_insert) MONO_INTERNAL;
  void      mono_bblock_insert_before_ins     (MonoBasicBlock *bb, MonoInst *ins, MonoInst *ins_to_insert) MONO_INTERNAL;
@@@ -1929,10 -1933,10 +1929,10 @@@ void      mono_print_ins_inde
  void      mono_print_ins                    (MonoInst *ins) MONO_INTERNAL;
  void      mono_print_bb                     (MonoBasicBlock *bb, const char *msg) MONO_INTERNAL;
  void      mono_print_code                   (MonoCompile *cfg, const char *msg) MONO_INTERNAL;
- void      mono_print_method_from_ip         (void *ip);
- char     *mono_pmip                         (void *ip);
MONO_API void      mono_print_method_from_ip         (void *ip);
MONO_API char     *mono_pmip                         (void *ip);
  gboolean  mono_debug_count                  (void) MONO_INTERNAL;
- const char* mono_inst_name                  (int op);
MONO_API const char* mono_inst_name                  (int op);
  void      mono_inst_set_src_registers       (MonoInst *ins, int *regs) MONO_INTERNAL;
  int       mono_op_to_op_imm                 (int opcode) MONO_INTERNAL;
  int       mono_op_imm_to_op                 (int opcode) MONO_INTERNAL;
@@@ -1955,8 -1959,8 +1955,8 @@@ gpointer  mono_jit_compile_metho
  MonoLMF * mono_get_lmf                      (void) MONO_INTERNAL;
  MonoLMF** mono_get_lmf_addr                 (void) MONO_INTERNAL;
  void      mono_set_lmf                      (MonoLMF *lmf) MONO_INTERNAL;
- MonoDomain *mono_jit_thread_attach          (MonoDomain *domain);
- void      mono_jit_set_domain               (MonoDomain *domain);
+ MONO_API MonoDomain *mono_jit_thread_attach          (MonoDomain *domain);
MONO_API void      mono_jit_set_domain               (MonoDomain *domain);
  MonoNativeTlsKey mono_get_jit_tls_key       (void) MONO_INTERNAL;
  gint32    mono_get_jit_tls_offset           (void) MONO_INTERNAL;
  gint32    mono_get_lmf_tls_offset           (void) MONO_INTERNAL;
@@@ -2077,9 -2081,9 +2077,9 @@@ void     mono_aot_register_jit_ical
  void*    mono_aot_readonly_field_override   (MonoClassField *field) MONO_INTERNAL;
  
  /* This is an exported function */
- void     mono_aot_register_globals          (gpointer *globals);
MONO_API void     mono_aot_register_globals          (gpointer *globals);
  /* This too */
- void     mono_aot_register_module           (gpointer *aot_info);
MONO_API void     mono_aot_register_module           (gpointer *aot_info);
  
  void     mono_xdebug_init                   (char *xdebug_opts) MONO_INTERNAL;
  void     mono_save_xdebug_info              (MonoCompile *cfg) MONO_INTERNAL;
@@@ -2104,7 -2108,7 +2104,7 @@@ void      mono_draw_grap
  void      mono_add_ins_to_end               (MonoBasicBlock *bb, MonoInst *inst) MONO_INTERNAL;
  gpointer  mono_create_ftnptr                (MonoDomain *domain, gpointer addr) MONO_INTERNAL;
  
- void      mono_replace_ins                  (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, MonoInst **prev, MonoBasicBlock *first_bb, MonoBasicBlock *last_bb);
MONO_API void      mono_replace_ins                  (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, MonoInst **prev, MonoBasicBlock *first_bb, MonoBasicBlock *last_bb);
  
  int               mono_find_method_opcode      (MonoMethod *method) MONO_INTERNAL;
  MonoJitICallInfo *mono_register_jit_icall      (gconstpointer func, const char *name, MonoMethodSignature *sig, gboolean is_save) MONO_INTERNAL;
@@@ -2258,16 -2262,6 +2258,16 @@@ gpointer  mono_arch_get_gsharedvt_tramp
  gpointer  mono_arch_get_gsharedvt_call_info     (gpointer addr, MonoMethodSignature *normal_sig, MonoMethodSignature *gsharedvt_sig, MonoGenericSharingContext *gsctx, gboolean gsharedvt_in, gint32 vcall_offset, gboolean calli) MONO_INTERNAL;
  gboolean  mono_arch_opcode_needs_emulation      (MonoCompile *cfg, int opcode) MONO_INTERNAL;
  
 +#ifdef MONO_ARCH_SOFT_FLOAT_FALLBACK
 +gboolean  mono_arch_is_soft_float               (void) MONO_INTERNAL;
 +#else
 +static inline MONO_ALWAYS_INLINE gboolean
 +mono_arch_is_soft_float (void)
 +{
 +      return FALSE;
 +}
 +#endif
 +
  /* Soft Debug support */
  #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
  void      mono_arch_set_breakpoint              (MonoJitInfo *ji, guint8 *ip) MONO_INTERNAL;
@@@ -2373,8 -2367,8 +2373,8 @@@ typedef gboolean (*MonoJitStackWalk
  void     mono_exceptions_init                   (void) MONO_INTERNAL;
  gboolean mono_handle_exception                  (MonoContext *ctx, gpointer obj) MONO_INTERNAL;
  void     mono_handle_native_sigsegv             (int signal, void *sigctx) MONO_INTERNAL;
- void     mono_print_thread_dump                 (void *sigctx);
- void     mono_print_thread_dump_from_ctx        (MonoContext *ctx);
MONO_API void     mono_print_thread_dump                 (void *sigctx);
MONO_API void     mono_print_thread_dump_from_ctx        (MonoContext *ctx);
  void     mono_walk_stack_with_ctx               (MonoJitStackWalk func, MonoContext *start_ctx, MonoUnwindOptions unwind_options, void *user_data) MONO_INTERNAL;
  void     mono_walk_stack_with_state             (MonoJitStackWalk func, MonoThreadUnwindState *state, MonoUnwindOptions unwind_options, void *user_data) MONO_INTERNAL;
  void     mono_walk_stack                        (MonoJitStackWalk func, MonoUnwindOptions options, void *user_data) MONO_INTERNAL;
@@@ -2452,12 -2446,12 +2452,12 @@@ void      mono_debug_add_aot_metho
                                                 MonoMethod *method, guint8 *code_start, 
                                                 guint8 *debug_info, guint32 debug_info_len) MONO_INTERNAL;
  void      mono_debug_add_icall_wrapper          (MonoMethod *method, MonoJitICallInfo* info) MONO_INTERNAL;
- void      mono_debug_print_vars                 (gpointer ip, gboolean only_arguments);
- void      mono_debugger_run_finally             (MonoContext *start_ctx);
MONO_API void      mono_debug_print_vars                 (gpointer ip, gboolean only_arguments);
MONO_API void      mono_debugger_run_finally             (MonoContext *start_ctx);
  
  extern gssize mono_breakpoint_info_index [MONO_BREAKPOINT_ARRAY_SIZE];
  
- gboolean mono_breakpoint_clean_code (guint8 *method_start, guint8 *code, int offset, guint8 *buf, int size);
MONO_API gboolean mono_breakpoint_clean_code (guint8 *method_start, guint8 *code, int offset, guint8 *buf, int size);
  
  #ifdef MONO_DEBUGGER_SUPPORTED