Merge pull request #2820 from kumpera/license-change-rebased
authorZoltan Varga <vargaz@gmail.com>
Thu, 31 Mar 2016 17:18:26 +0000 (13:18 -0400)
committerZoltan Varga <vargaz@gmail.com>
Thu, 31 Mar 2016 17:18:26 +0000 (13:18 -0400)
Change license and publish xamarin mono extensions

32 files changed:
1  2 
configure.ac
mono/metadata/appdomain.c
mono/metadata/class-internals.h
mono/metadata/class.c
mono/metadata/icall.c
mono/metadata/loader.c
mono/metadata/marshal.c
mono/metadata/metadata.c
mono/metadata/mono-basic-block.c
mono/metadata/object.c
mono/metadata/reflection.c
mono/metadata/security-core-clr.c
mono/metadata/sgen-client-mono.h
mono/metadata/sgen-mono.c
mono/metadata/sgen-new-bridge.c
mono/metadata/sgen-old-bridge.c
mono/metadata/threadpool-ms.c
mono/metadata/verify.c
mono/mini/Makefile.am.in
mono/mini/aot-compiler.c
mono/mini/exceptions-amd64.c
mono/mini/method-to-ir.c
mono/mini/mini-arm.c
mono/mini/mini-llvm.c
mono/mini/mini-windows.c
mono/sgen/sgen-gc.c
mono/sgen/sgen-marksweep-drain-gray-stack.h
mono/sgen/sgen-pinning.c
mono/sgen/sgen-pinning.h
mono/sgen/sgen-thread-pool.c
mono/sgen/sgen-thread-pool.h
mono/tests/test-runner.cs

diff --combined configure.ac
index 7d6488d50a56caa44a56549bc32da7e4b907ab4c,1cacd417371d286dbcf47c07110f55ede395ece2..5957367b5a31180e8c8cf085793b006ca8db30e6
@@@ -934,11 -934,6 +934,6 @@@ if test x$enable_gsharedvt = xyes; the
        AC_DEFINE(ENABLE_GSHAREDVT,1,[Gsharedvt])
  fi
  
- AC_ARG_ENABLE(native-types, [  --enable-native-types Enable native types], enable_native_types=$enableval, enable_native_types=no)
- if test x$enable_native_types = xyes; then
-       AC_DEFINE(MONO_NATIVE_TYPES,1,[native types])
- fi
  AC_MSG_CHECKING(for visibility __attribute__)
  AC_COMPILE_IFELSE([
        AC_LANG_SOURCE([[
@@@ -3319,12 -3314,6 +3314,12 @@@ AC_ARG_WITH([libgdiplus]
  
  # default install location
  libgdiplus_install_loc=libgdiplus${libsuffix}
 +case "$host" in
 +    *-*-*linux*)
 +    libgdiplus_install_loc=libgdiplus${libsuffix}.0
 +    ;;
 +esac
 +
  case $with_libgdiplus in
      no|installed)
      libgdiplus_loc=
index e7a0db8eb2afaa66d4a204087fd839d4f7f49421,2df1eeda959f4111ea31fae4651e86e19aa5bd11..93169cda59d4ba1ac7fb1a526b6a1b9a352bd489
@@@ -9,6 -9,7 +9,7 @@@
   * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
   * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
   * Copyright 2012 Xamarin Inc
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  #undef ASSEMBLY_LOAD_DEBUG
  #include <config.h>
@@@ -257,6 -258,7 +258,6 @@@ mono_runtime_init_checked (MonoDomain *
        mono_install_assembly_postload_search_hook ((MonoAssemblySearchFunc)mono_domain_assembly_postload_search, GUINT_TO_POINTER (FALSE));
        mono_install_assembly_postload_refonly_search_hook ((MonoAssemblySearchFunc)mono_domain_assembly_postload_search, GUINT_TO_POINTER (TRUE));
        mono_install_assembly_load_hook (mono_domain_fire_assembly_load, NULL);
 -      mono_install_lookup_dynamic_token (mono_reflection_lookup_dynamic_token);
  
        mono_thread_init (start_cb, attach_cb);
  
index 14e50f56b687731ef8500e319d622b32e7e3ff19,18017a341ba5a68045403129d464897243e1d140..b86e7eda40ec5240dd839081662c19c752f968e6
@@@ -1,5 -1,6 +1,6 @@@
  /* 
   * Copyright 2012 Xamarin Inc
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  #ifndef __MONO_METADATA_CLASS_INTERNALS_H__
  #define __MONO_METADATA_CLASS_INTERNALS_H__
@@@ -517,6 -518,7 +518,6 @@@ struct _MonoMethodInflated 
                MonoMethod method;
                MonoMethodPInvoke pinvoke;
        } method;
 -      MonoMethodHeader *header;
        MonoMethod *declaring;          /* the generic method definition. */
        MonoGenericContext context;     /* The current instantiation */
        MonoImageSet *owner; /* The image set that the inflated method belongs to. */
@@@ -917,6 -919,8 +918,6 @@@ extern MonoStats mono_stats
  typedef gpointer (*MonoRemotingTrampoline)       (MonoDomain *domain, MonoMethod *method, MonoRemotingTarget target);
  typedef gpointer (*MonoDelegateTrampoline)       (MonoDomain *domain, MonoClass *klass);
  
 -typedef gpointer (*MonoLookupDynamicToken) (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context);
 -
  typedef gboolean (*MonoGetCachedClassInfo) (MonoClass *klass, MonoCachedClassInfo *res);
  
  typedef gboolean (*MonoGetClassFromName) (MonoImage *image, const char *name_space, const char *name, MonoClass **res);
  mono_install_delegate_trampoline (MonoDelegateTrampoline func);
  
  gpointer
 -mono_lookup_dynamic_token (MonoImage *image, guint32 token, MonoGenericContext *context);
 +mono_lookup_dynamic_token (MonoImage *image, guint32 token, MonoGenericContext *context, MonoError *error);
  
  gpointer
 -mono_lookup_dynamic_token_class (MonoImage *image, guint32 token, gboolean check_token, MonoClass **handle_class, MonoGenericContext *context);
 -
 -void
 -mono_install_lookup_dynamic_token (MonoLookupDynamicToken func);
 +mono_lookup_dynamic_token_class (MonoImage *image, guint32 token, gboolean check_token, MonoClass **handle_class, MonoGenericContext *context, MonoError *error);
  
  gpointer
  mono_runtime_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper);
diff --combined mono/metadata/class.c
index 49225c652e607e7176fe01dff9b5a6f23ef255bd,9422028afd6a3709e0d6a0f8005b0d0c5504b191..f7b36279f4af17942f00dd9af24aea8a7ba2e9b3
@@@ -7,6 -7,7 +7,7 @@@
   * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
   * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
   * Copyright 2012 Xamarin Inc (http://www.xamarin.com)
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  #include <config.h>
  #ifdef HAVE_ALLOCA_H
@@@ -7457,7 -7458,7 +7458,7 @@@ mono_class_get_checked (MonoImage *imag
                        mono_error_set_bad_image (error, image,"Bad token table for dynamic image: %x", table);
                        return NULL;
                }
 -              klass = (MonoClass *)mono_lookup_dynamic_token (image, type_token, NULL); /*FIXME proper error handling*/
 +              klass = (MonoClass *)mono_lookup_dynamic_token (image, type_token, NULL, error);
                goto done;
        }
  
@@@ -7507,11 -7508,8 +7508,11 @@@ mono_type_get_checked (MonoImage *image
        mono_error_init (error);
  
        //FIXME: this will not fix the very issue for which mono_type_get_full exists -but how to do it then?
 -      if (image_is_dynamic (image))
 -              return mono_class_get_type ((MonoClass *)mono_lookup_dynamic_token (image, type_token, context));
 +      if (image_is_dynamic (image)) {
 +              MonoClass *klass = (MonoClass *)mono_lookup_dynamic_token (image, type_token, context, error);
 +              return_val_if_nok (error, NULL);
 +              return mono_class_get_type (klass);
 +      }
  
        if ((type_token & 0xff000000) != MONO_TOKEN_TYPE_SPEC) {
                MonoClass *klass = mono_class_get_checked (image, type_token, error);
@@@ -8786,9 -8784,8 +8787,9 @@@ mono_ldtoken_checked (MonoImage *image
  
        if (image_is_dynamic (image)) {
                MonoClass *tmp_handle_class;
 -              gpointer obj = mono_lookup_dynamic_token_class (image, token, TRUE, &tmp_handle_class, context);
 +              gpointer obj = mono_lookup_dynamic_token_class (image, token, TRUE, &tmp_handle_class, context, error);
  
 +              mono_error_assert_ok (error);
                g_assert (tmp_handle_class);
                if (handle_class)
                        *handle_class = tmp_handle_class;
        return NULL;
  }
  
 -/**
 - * This function might need to call runtime functions so it can't be part
 - * of the metadata library.
 - */
 -static MonoLookupDynamicToken lookup_dynamic = NULL;
 -
 -void
 -mono_install_lookup_dynamic_token (MonoLookupDynamicToken func)
 -{
 -      lookup_dynamic = func;
 -}
 -
  gpointer
 -mono_lookup_dynamic_token (MonoImage *image, guint32 token, MonoGenericContext *context)
 +mono_lookup_dynamic_token (MonoImage *image, guint32 token, MonoGenericContext *context, MonoError *error)
  {
        MonoClass *handle_class;
 -
 -      return lookup_dynamic (image, token, TRUE, &handle_class, context);
 +      mono_error_init (error);
 +      return mono_reflection_lookup_dynamic_token (image, token, TRUE, &handle_class, context, error);
  }
  
  gpointer
 -mono_lookup_dynamic_token_class (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context)
 +mono_lookup_dynamic_token_class (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
  {
 -      return lookup_dynamic (image, token, valid_token, handle_class, context);
 +      return mono_reflection_lookup_dynamic_token (image, token, valid_token, handle_class, context, error);
  }
  
  static MonoGetCachedClassInfo get_cached_class_info = NULL;
diff --combined mono/metadata/icall.c
index f1b296b8eac718abec632c601168c40d05566871,bc7290bc6394410f37caf1781e3ac75576a15bbd..cea8809e84fe18aeeb18f6eb2a16a58168c93fbc
@@@ -11,6 -11,7 +11,7 @@@
   * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
   * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
   * Copyright 2011-2015 Xamarin Inc (http://www.xamarin.com).
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  #include <config.h>
@@@ -1869,11 -1870,8 +1870,11 @@@ ves_icall_MonoField_GetValueInternal (M
                return NULL;
        }
  
 -      if (mono_security_core_clr_enabled ())
 -              mono_security_core_clr_ensure_reflection_access_field (cf);
 +      if (mono_security_core_clr_enabled () &&
 +          !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
 +              mono_error_set_pending_exception (&error);
 +              return NULL;
 +      }
  
        MonoObject * result = mono_field_get_value_object_checked (domain, cf, obj, &error);
        mono_error_set_pending_exception (&error);
@@@ -1894,11 -1892,8 +1895,11 @@@ ves_icall_MonoField_SetValueInternal (M
                return;
        }
  
 -      if (mono_security_core_clr_enabled ())
 -              mono_security_core_clr_ensure_reflection_access_field (cf);
 +      if (mono_security_core_clr_enabled () &&
 +          !mono_security_core_clr_ensure_reflection_access_field (cf, &error)) {
 +              mono_error_set_pending_exception (&error);
 +              return;
 +      }
  
        type = mono_field_get_type_checked (cf, &error);
        if (!mono_error_ok (&error)) {
@@@ -3075,11 -3070,8 +3076,11 @@@ ves_icall_InternalInvoke (MonoReflectio
  
        *exc = NULL;
  
 -      if (mono_security_core_clr_enabled ())
 -              mono_security_core_clr_ensure_reflection_access_method (m);
 +      if (mono_security_core_clr_enabled () &&
 +          !mono_security_core_clr_ensure_reflection_access_method (m, &error)) {
 +              mono_error_set_pending_exception (&error);
 +              return NULL;
 +      }
  
        if (!(m->flags & METHOD_ATTRIBUTE_STATIC)) {
                if (!mono_class_vtable_full (mono_object_domain (method), m->klass, &error)) {
@@@ -5834,13 -5826,10 +5835,13 @@@ mono_memberref_is_method (MonoImage *im
                mono_metadata_decode_blob_size (sig, &sig);
                return (*sig != 0x6);
        } else {
 +              MonoError error;
                MonoClass *handle_class;
  
 -              if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL))
 +              if (!mono_lookup_dynamic_token_class (image, token, FALSE, &handle_class, NULL, &error)) {
 +                      mono_error_cleanup (&error); /* just probing, ignore error */
                        return FALSE;
 +              }
  
                return mono_defaults.methodhandle_class == handle_class;
        }
@@@ -5881,14 -5870,12 +5882,14 @@@ ves_icall_System_Reflection_Module_Reso
  
        if (image_is_dynamic (image)) {
                if ((table == MONO_TABLE_TYPEDEF) || (table == MONO_TABLE_TYPEREF)) {
 -                      klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
 +                      klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
 +                      mono_error_cleanup (&error);
                        return klass ? &klass->byval_arg : NULL;
                }
  
                init_generic_context_from_args (&context, type_args, method_args);
 -              klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context);
 +              klass = (MonoClass *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
 +              mono_error_cleanup (&error);
                return klass ? &klass->byval_arg : NULL;
        }
  
@@@ -5931,11 -5918,8 +5932,11 @@@ ves_icall_System_Reflection_Module_Reso
        }
  
        if (image_is_dynamic (image)) {
 -              if (table == MONO_TABLE_METHOD)
 -                      return (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
 +              if (table == MONO_TABLE_METHOD) {
 +                      method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
 +                      mono_error_cleanup (&error);
 +                      return method;
 +              }
  
                if ((table == MONO_TABLE_MEMBERREF) && !(mono_memberref_is_method (image, token))) {
                        *resolve_error = ResolveTokenError_BadTable;
                }
  
                init_generic_context_from_args (&context, type_args, method_args);
 -              return (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context);
 +              method = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
 +              mono_error_cleanup (&error);
 +              return method;
        }
  
        if ((index <= 0) || (index > image->tables [table].rows)) {
  }
  
  ICALL_EXPORT MonoString*
 -ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *error)
 +ves_icall_System_Reflection_Module_ResolveStringToken (MonoImage *image, guint32 token, MonoResolveTokenError *resolve_error)
  {
 +      MonoError error;
        int index = mono_metadata_token_index (token);
  
 -      *error = ResolveTokenError_Other;
 +      *resolve_error = ResolveTokenError_Other;
  
        /* Validate token */
        if (mono_metadata_token_code (token) != MONO_TOKEN_STRING) {
 -              *error = ResolveTokenError_BadTable;
 +              *resolve_error = ResolveTokenError_BadTable;
                return NULL;
        }
  
 -      if (image_is_dynamic (image))
 -              return (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
 +      if (image_is_dynamic (image)) {
 +              MonoString * result = (MonoString *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
 +              mono_error_cleanup (&error);
 +              return result;
 +      }
  
        if ((index <= 0) || (index >= image->heap_us.size)) {
 -              *error = ResolveTokenError_OutOfRange;
 +              *resolve_error = ResolveTokenError_OutOfRange;
                return NULL;
        }
  
@@@ -6013,11 -5991,8 +6014,11 @@@ ves_icall_System_Reflection_Module_Reso
        }
  
        if (image_is_dynamic (image)) {
 -              if (table == MONO_TABLE_FIELD)
 -                      return (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL);
 +              if (table == MONO_TABLE_FIELD) {
 +                      field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, NULL, &error);
 +                      mono_error_cleanup (&error);
 +                      return field;
 +              }
  
                if (mono_memberref_is_method (image, token)) {
                        *resolve_error = ResolveTokenError_BadTable;
                }
  
                init_generic_context_from_args (&context, type_args, method_args);
 -              return (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context);
 +              field = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, FALSE, NULL, &context, &error);
 +              mono_error_cleanup (&error);
 +              return field;
        }
  
        if ((index <= 0) || (index > image->tables [table].rows)) {
@@@ -6336,13 -6309,8 +6337,13 @@@ ves_icall_System_Delegate_CreateDelegat
        }
  
        if (mono_security_core_clr_enabled ()) {
 -              if (!mono_security_core_clr_ensure_delegate_creation (method, throwOnBindFailure))
 +              if (!mono_security_core_clr_ensure_delegate_creation (method, &error)) {
 +                      if (throwOnBindFailure)
 +                              mono_error_set_pending_exception (&error);
 +                      else
 +                              mono_error_cleanup (&error);
                        return NULL;
 +              }
        }
  
        delegate = mono_object_new_checked (mono_object_domain (type), delegate_class, &error);
@@@ -8036,6 -8004,20 +8037,6 @@@ ves_icall_System_ComponentModel_Win32Ex
        return message;
  }
  
 -ICALL_EXPORT int
 -ves_icall_System_StackFrame_GetILOffsetFromFile (MonoString *path, guint32 method_token, guint32 method_index, int native_offset)
 -{
 -      guint32 il_offset;
 -      char *path_str = mono_string_to_utf8 (path);
 -
 -      if (!mono_seq_point_data_get_il_offset (path_str, method_token, method_index, native_offset, &il_offset))
 -              il_offset = -1;
 -
 -      g_free (path_str);
 -
 -      return il_offset;
 -}
 -
  ICALL_EXPORT gpointer
  ves_icall_Microsoft_Win32_NativeMethods_GetCurrentProcess (void)
  {
diff --combined mono/metadata/loader.c
index 2195d22618f6180bcf37e2755ebdcdac3ee6dcfc,f9b83480b52262a3647136ce9aeb5ebf96025386..56992b3612738bd5ea800a0a50edc2817068c202
@@@ -17,6 -17,7 +17,7 @@@
   * TODO:
   *   This should keep track of the assembly versions that we are loading.
   *
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  #include <config.h>
  #include <glib.h>
@@@ -563,9 -564,7 +564,9 @@@ mono_field_from_token_checked (MonoImag
                MonoClass *handle_class;
  
                *retklass = NULL;
 -              result = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, TRUE, &handle_class, context);
 +              MonoError inner_error;
 +              result = (MonoClassField *)mono_lookup_dynamic_token_class (image, token, TRUE, &handle_class, context, &inner_error);
 +              mono_error_cleanup (&inner_error);
                // This checks the memberref type as well
                if (!result || handle_class != mono_defaults.fieldhandle_class) {
                        mono_error_set_bad_image (error, image, "Bad field token 0x%08x", token);
@@@ -876,31 -875,27 +877,31 @@@ mono_inflate_generic_signature (MonoMet
  static MonoMethodHeader*
  inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context, MonoError *error)
  {
 -      MonoMethodHeader *res;
 -      int i;
 -      res = (MonoMethodHeader *)g_malloc0 (MONO_SIZEOF_METHOD_HEADER + sizeof (gpointer) * header->num_locals);
 +      size_t locals_size = sizeof (gpointer) * header->num_locals;
 +      size_t clauses_size = header->num_clauses * sizeof (MonoExceptionClause);
 +      size_t header_size = MONO_SIZEOF_METHOD_HEADER + locals_size + clauses_size; 
 +      MonoMethodHeader *res = (MonoMethodHeader *)g_malloc0 (header_size);
 +      res->num_locals = header->num_locals;
 +      res->clauses = (MonoExceptionClause *) &res->locals [res->num_locals] ;
 +      memcpy (res->clauses, header->clauses, clauses_size);
 +
        res->code = header->code;
        res->code_size = header->code_size;
        res->max_stack = header->max_stack;
        res->num_clauses = header->num_clauses;
        res->init_locals = header->init_locals;
 -      res->num_locals = header->num_locals;
 -      res->clauses = header->clauses;
 +
 +      res->is_transient = TRUE;
  
        mono_error_init (error);
  
 -      for (i = 0; i < header->num_locals; ++i) {
 +      for (int i = 0; i < header->num_locals; ++i) {
                res->locals [i] = mono_class_inflate_generic_type_checked (header->locals [i], context, error);
                if (!is_ok (error))
                        goto fail;
        }
        if (res->num_clauses) {
 -              res->clauses = (MonoExceptionClause *)g_memdup (header->clauses, sizeof (MonoExceptionClause) * res->num_clauses);
 -              for (i = 0; i < header->num_clauses; ++i) {
 +              for (int i = 0; i < header->num_clauses; ++i) {
                        MonoExceptionClause *clause = &res->clauses [i];
                        if (clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
                                continue;
@@@ -1879,8 -1874,7 +1880,8 @@@ mono_get_method_from_token (MonoImage *
        if (image_is_dynamic (image)) {
                MonoClass *handle_class;
  
 -              result = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, TRUE, &handle_class, context);
 +              result = (MonoMethod *)mono_lookup_dynamic_token_class (image, token, TRUE, &handle_class, context, error);
 +              mono_error_assert_ok (error);
                mono_loader_assert_no_error ();
  
                // This checks the memberref type as well
@@@ -2834,7 -2828,20 +2835,7 @@@ mono_method_get_header_checked (MonoMet
                        return NULL;
                }
  
 -              mono_image_lock (img);
 -
 -              if (imethod->header) {
 -                      mono_metadata_free_mh (iheader);
 -                      mono_image_unlock (img);
 -                      return imethod->header;
 -              }
 -
 -              mono_memory_barrier ();
 -              imethod->header = iheader;
 -
 -              mono_image_unlock (img);
 -
 -              return imethod->header;
 +              return iheader;
        }
  
        if (method->wrapper_type != MONO_WRAPPER_NONE || method->sre_method) {
diff --combined mono/metadata/marshal.c
index 9b7eca1ffce41cca0086710387a74c9d10f9157c,e39b4dbcb610814da8e0e9f74f8a8eb5bf3c9aa4..18f93d260e3897cc70f53bbfde9b45a0229526fb
@@@ -8,6 -8,7 +8,7 @@@
   * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
   * Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
   *
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  #include "config.h"
@@@ -211,11 -212,11 +212,11 @@@ init_safe_handle (
  }
  
  static void
 -register_icall (gpointer func, const char *name, const char *sigstr, gboolean save)
 +register_icall (gpointer func, const char *name, const char *sigstr, gboolean no_wrapper)
  {
        MonoMethodSignature *sig = mono_create_icall_signature (sigstr);
  
 -      mono_register_jit_icall (func, name, sig, save);
 +      mono_register_jit_icall (func, name, sig, no_wrapper);
  }
  
  MonoMethodSignature*
diff --combined mono/metadata/metadata.c
index d4e404554a076584d50f615f961a9bbc2eb07b9e,73f60caca141753eaab42cdef4d3fa8fd0d2d061..b778e3964c6671db6efa1ab09eb69e10035b0521
@@@ -7,6 -7,7 +7,7 @@@
   *
   * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
   * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  #include <config.h>
@@@ -1837,11 -1838,8 +1838,11 @@@ mono_metadata_parse_signature (MonoImag
        guint32 sig;
        const char *ptr;
  
 -      if (image_is_dynamic (image))
 -              return (MonoMethodSignature *)mono_lookup_dynamic_token (image, token, NULL);
 +      if (image_is_dynamic (image)) {
 +              ret = (MonoMethodSignature *)mono_lookup_dynamic_token (image, token, NULL, &error);
 +              mono_error_raise_exception (&error); /* FIXME don't raise here */
 +              return ret;
 +      }
  
        g_assert (mono_metadata_token_table(token) == MONO_TABLE_STANDALONESIG);
                
@@@ -2775,6 -2773,18 +2776,6 @@@ free_inflated_method (MonoMethodInflate
        if (method->signature)
                mono_metadata_free_inflated_signature (method->signature);
  
 -      if (!((method->flags & METHOD_ATTRIBUTE_ABSTRACT) || (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))) {
 -              MonoMethodHeader *header = imethod->header;
 -
 -              if (header) {
 -                      /* Allocated in inflate_generic_header () */
 -                      for (i = 0; i < header->num_locals; ++i)
 -                              mono_metadata_free_type (header->locals [i]);
 -                      g_free (header->clauses);
 -                      g_free (header);
 -              }
 -      }
 -
        g_free (method);
  }
  
@@@ -3376,10 -3386,6 +3377,10 @@@ do_mono_metadata_parse_type (MonoType *
                        return FALSE;
  
                type->data.klass = mono_class_from_mono_type (etype);
 +
 +              if (transient)
 +                      mono_metadata_free_type (etype);
 +
                g_assert (type->data.klass); //This was previously a check for NULL, but mcfmt should never fail. It can return a borken MonoClass, but should return at least something.
                break;
        }
index 5f9aa0736f401205a52d5500a3eb9fdee31d8010,f4cbdcffc0fd0a115a9e754c25e022e310c4b089..53f21530024f24659ec67200a40fab23b4d548f6
@@@ -5,6 -5,7 +5,7 @@@
   *   Rodrigo Kumpera (rkumpera@novell.com)
   *
   * Copyright 2010 Novell, Inc (http://www.novell.com)
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  #include <config.h>
@@@ -514,11 -515,20 +515,11 @@@ mono_basic_block_free (MonoSimpleBasicB
   * Return the list of basic blocks of method. Return NULL on failure and set @error.
  */
  MonoSimpleBasicBlock*
 -mono_basic_block_split (MonoMethod *method, MonoError *error)
 +mono_basic_block_split (MonoMethod *method, MonoError *error, MonoMethodHeader *header)
  {
        MonoError inner_error;
        MonoSimpleBasicBlock *bb, *root;
        const unsigned char *start, *end;
 -      MonoMethodHeader *header = mono_method_get_header_checked (method, &inner_error);
 -
 -      mono_error_init (error);
 -
 -      if (!header) {
 -              mono_error_set_not_verifiable (error, method, "Could not decode header due to %s", mono_error_get_message (&inner_error));
 -              mono_error_cleanup (&inner_error);
 -              return NULL;
 -      }
  
        start = header->code;
        end = start + header->code_size;
        dump_bb_list (bb, &root, g_strdup_printf("AFTER LIVENESS %s", mono_method_full_name (method, TRUE)));
  #endif
  
 -      mono_metadata_free_mh (header);
        return bb;
  
  fail:
 -      mono_metadata_free_mh (header);
        mono_basic_block_free (bb);
        return NULL;
  }
diff --combined mono/metadata/object.c
index 92a733b34bdb66ebc7420b7e075980975ab7315f,6525f3fc0969dd71446a62cc20b5c3c1da3b3eb3..dc20b4e83212449db9ba9826eb4a0be57d796369
@@@ -8,6 -8,7 +8,7 @@@
   * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
   * Copyright 2004-2011 Novell, Inc (http://www.novell.com)
   * Copyright 2001 Xamarin Inc (http://www.xamarin.com)
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  #include <config.h>
  #ifdef HAVE_ALLOCA_H
@@@ -6295,11 -6296,9 +6296,11 @@@ MonoString
  mono_ldstr (MonoDomain *domain, MonoImage *image, guint32 idx)
  {
        MONO_REQ_GC_UNSAFE_MODE;
 +      MonoError error;
  
        if (image->dynamic) {
 -              MonoString *str = (MonoString *)mono_lookup_dynamic_token (image, MONO_TOKEN_STRING | idx, NULL);
 +              MonoString *str = (MonoString *)mono_lookup_dynamic_token (image, MONO_TOKEN_STRING | idx, NULL, &error);
 +              mono_error_raise_exception (&error); /* FIXME don't raise here */
                return str;
        } else {
                if (!mono_verifier_verify_string_signature (image, idx, NULL))
index c49153f85a1615f3052355b6c3fc37086d85f0a2,3de48250000206c7ebec645cd688053728a7eaee..200c41e5f804fa015801317184020629b1c46501
@@@ -8,6 -8,7 +8,7 @@@
   * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
   * Copyright 2011 Rodrigo Kumpera
   *
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  #include <config.h>
  #include "mono/utils/mono-digest.h"
@@@ -13695,27 -13696,25 +13696,27 @@@ mono_reflection_lookup_signature (MonoI
   * LOCKING: Take the loader lock
   */
  gpointer
 -mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context)
 +mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context, MonoError *error)
  {
 -      MonoError error;
        MonoDynamicImage *assembly = (MonoDynamicImage*)image;
        MonoObject *obj;
        MonoClass *klass;
  
 +      mono_error_init (error);
 +      
        obj = lookup_dyn_token (assembly, token);
        if (!obj) {
                if (valid_token)
                        g_error ("Could not find required dynamic token 0x%08x", token);
 -              else
 +              else {
 +                      mono_error_set_execution_engine (error, "Could not find dynamic token 0x%08x", token);
                        return NULL;
 +              }
        }
  
        if (!handle_class)
                handle_class = &klass;
 -      gpointer result = resolve_object (image, obj, handle_class, context, &error);
 -      mono_error_raise_exception (&error); /* FIXME don't raise here */
 +      gpointer result = resolve_object (image, obj, handle_class, context, error);
        return result;
  }
  
index 235b9bec417f26a6ade591c7bd550cd43e3ec7ec,4c6589176b8da7d36be39242e0997c12c5e40afa..f874043e15b6e58f423ea2752fdcc12795a4fbe6
@@@ -6,6 -6,7 +6,7 @@@
   *    Sebastien Pouliot  <sebastien@ximian.com>
   *
   * Copyright 2007-2010 Novell, Inc (http://www.novell.com)
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  #include <mono/metadata/class-internals.h>
@@@ -624,38 -625,34 +625,38 @@@ get_method_access_exception (const cha
   *    Transparent code cannot access to Critical fields and can only use
   *    them if they are visible from it's point of view.
   *
 - *    A FieldAccessException is thrown if the field is cannot be accessed.
 + *    Returns TRUE if acess is allowed.  Otherwise returns FALSE and sets @error to a FieldAccessException if the field is cannot be accessed.
   */
 -void
 -mono_security_core_clr_ensure_reflection_access_field (MonoClassField *field)
 +gboolean
 +mono_security_core_clr_ensure_reflection_access_field (MonoClassField *field, MonoError *error)
  {
 +      mono_error_init (error);
        MonoMethod *caller = get_reflection_caller ();
        /* CoreCLR restrictions applies to Transparent code/caller */
        if (mono_security_core_clr_method_level (caller, TRUE) != MONO_SECURITY_CORE_CLR_TRANSPARENT)
 -              return;
 +              return TRUE;
  
        if (mono_security_core_clr_get_options () & MONO_SECURITY_CORE_CLR_OPTIONS_RELAX_REFLECTION) {
                if (!mono_security_core_clr_is_platform_image (mono_field_get_parent(field)->image))
 -                      return;
 +                      return TRUE;
        }
  
        /* Transparent code cannot [get|set]value on Critical fields */
        if (mono_security_core_clr_class_level (mono_field_get_parent (field)) == MONO_SECURITY_CORE_CLR_CRITICAL) {
 -              mono_raise_exception (get_field_access_exception (
 +              mono_error_set_exception_instance (error, get_field_access_exception (
                        "Transparent method %s cannot get or set Critical field %s.", 
                        caller, field));
 +              return FALSE;
        }
  
        /* also it cannot access a fields that is not visible from it's (caller) point of view */
        if (!check_field_access (caller, field)) {
 -              mono_raise_exception (get_field_access_exception (
 +              mono_error_set_exception_instance (error, get_field_access_exception (
                        "Transparent method %s cannot get or set private/internal field %s.", 
                        caller, field));
 +              return FALSE;
        }
 +      return TRUE;
  }
  
  /*
   *    Transparent code cannot call Critical methods and can only call them
   *    if they are visible from it's point of view.
   *
 - *    A MethodAccessException is thrown if the field is cannot be accessed.
 + *    If access is allowed returns TRUE.  Returns FALSE and sets @error to a MethodAccessException if the field is cannot be accessed.
   */
 -void
 -mono_security_core_clr_ensure_reflection_access_method (MonoMethod *method)
 +gboolean
 +mono_security_core_clr_ensure_reflection_access_method (MonoMethod *method, MonoError *error)
  {
 +      mono_error_init (error);
        MonoMethod *caller = get_reflection_caller ();
        /* CoreCLR restrictions applies to Transparent code/caller */
        if (mono_security_core_clr_method_level (caller, TRUE) != MONO_SECURITY_CORE_CLR_TRANSPARENT)
 -              return;
 +              return TRUE;
  
        if (mono_security_core_clr_get_options () & MONO_SECURITY_CORE_CLR_OPTIONS_RELAX_REFLECTION) {
                if (!mono_security_core_clr_is_platform_image (method->klass->image))
 -                      return;
 +                      return TRUE;
        }
  
        /* Transparent code cannot invoke, even using reflection, Critical code */
        if (mono_security_core_clr_method_level (method, TRUE) == MONO_SECURITY_CORE_CLR_CRITICAL) {
 -              mono_raise_exception (get_method_access_exception (
 +              mono_error_set_exception_instance (error, get_method_access_exception (
                        "Transparent method %s cannot invoke Critical method %s.", 
                        caller, method));
 +              return FALSE;
        }
  
        /* also it cannot invoke a method that is not visible from it's (caller) point of view */
        if (!check_method_access (caller, method)) {
 -              mono_raise_exception (get_method_access_exception (
 +              mono_error_set_exception_instance (error, get_method_access_exception (
                        "Transparent method %s cannot invoke private/internal method %s.", 
                        caller, method));
 +              return FALSE;
        }
 +      return TRUE;
  }
  
  /*
@@@ -734,20 -727,19 +735,20 @@@ can_avoid_corlib_reflection_delegate_op
  /*
   * mono_security_core_clr_ensure_delegate_creation:
   *
 - *    Return TRUE if a delegate can be created on the specified method. 
 - *    CoreCLR also affect the binding, so throwOnBindFailure must be 
 - *    FALSE to let this function return (FALSE) normally, otherwise (if
 - *    throwOnBindFailure is TRUE) it will throw an ArgumentException.
 + *    Return TRUE if a delegate can be created on the specified
 + *    method.  CoreCLR can also affect the binding, this function may
 + *    return (FALSE) and set @error to an ArgumentException.
   *
 - *    A MethodAccessException is thrown if the specified method is not
 + *    @error is set to a MethodAccessException if the specified method is not
   *    visible from the caller point of view.
   */
  gboolean
 -mono_security_core_clr_ensure_delegate_creation (MonoMethod *method, gboolean throwOnBindFailure)
 +mono_security_core_clr_ensure_delegate_creation (MonoMethod *method, MonoError *error)
  {
        MonoMethod *caller;
  
 +      mono_error_init (error);
 +
        /* note: mscorlib creates delegates to avoid reflection (optimization), we ignore those cases */
        if (can_avoid_corlib_reflection_delegate_optimization (method))
                return TRUE;
  
        /* otherwise it (as a Transparent caller) cannot create a delegate on a Critical method... */
        if (mono_security_core_clr_method_level (method, TRUE) == MONO_SECURITY_CORE_CLR_CRITICAL) {
 -              /* but this throws only if 'throwOnBindFailure' is TRUE */
 -              if (!throwOnBindFailure)
 -                      return FALSE;
 -
 -              mono_raise_exception (get_argument_exception (
 +              mono_error_set_exception_instance (error, get_argument_exception (
                        "Transparent method %s cannot create a delegate on Critical method %s.", 
                        caller, method));
 +              return FALSE;
        }
  
        if (mono_security_core_clr_get_options () & MONO_SECURITY_CORE_CLR_OPTIONS_RELAX_DELEGATE) {
  
        /* also it cannot create the delegate on a method that is not visible from it's (caller) point of view */
        if (!check_method_access (caller, method)) {
 -              mono_raise_exception (get_method_access_exception (
 +              mono_error_set_exception_instance (error, get_method_access_exception (
                        "Transparent method %s cannot create a delegate on private/internal method %s.", 
                        caller, method));
 +              return FALSE;
        }
  
        return TRUE;
@@@ -1056,24 -1050,19 +1057,24 @@@ mono_security_core_clr_require_elevated
        return FALSE;
  }
  
 -void
 -mono_security_core_clr_ensure_reflection_access_field (MonoClassField *field)
 +gboolean
 +mono_security_core_clr_ensure_reflection_access_field (MonoClassField *field, MonoError *error)
  {
 +      mono_error_init (error);
 +      return TRUE;
  }
  
  void
 -mono_security_core_clr_ensure_reflection_access_method (MonoMethod *method)
 +mono_security_core_clr_ensure_reflection_access_method (MonoMethod *method, MonoError *error)
  {
 +      mono_error_init (error);
 +      return TRUE;
  }
  
  gboolean
 -mono_security_core_clr_ensure_delegate_creation (MonoMethod *method, gboolean throwOnBindFailure)
 +mono_security_core_clr_ensure_delegate_creation (MonoMethod *method, MonoError *error)
  {
 +      mono_error_init (error);
        return TRUE;
  }
  
index d0eaa26e14e014df49aa86ef63fa043d644d896e,a468337ab2a5ff835fa2fe59e40afc8ba6d530f4..54630c6ee033853a8ac63065b70eb7cfa1f3a100
@@@ -3,18 -3,7 +3,7 @@@
   *
   * Copyright (C) 2014 Xamarin Inc
   *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
-  * License 2.0 as published by the Free Software Foundation;
-  *
-  * This library is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  * Library General Public License for more details.
-  *
-  * You should have received a copy of the GNU Library General Public
-  * License 2.0 along with this library; if not, write to the Free
-  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  #ifdef SGEN_DEFINE_OBJECT_VTABLE
@@@ -731,7 -720,7 +720,7 @@@ extern MonoNativeTlsKey thread_info_key
  
  #define SGEN_TV_DECLARE(name) gint64 name
  #define SGEN_TV_GETTIME(tv) tv = mono_100ns_ticks ()
 -#define SGEN_TV_ELAPSED(start,end) ((long)(end-start))
 +#define SGEN_TV_ELAPSED(start,end) ((gint64)(end-start))
  
  typedef MonoSemType SgenSemaphore;
  
index efa0e892eccf3bd312a72915c482e115c8fad163,2f0e4163daf3b3fbe1ffc079309b25d8939f8f72..2956d95420a1460145c6ab4a3c8e688ef5ce00f4
@@@ -3,18 -3,7 +3,7 @@@
   *
   * Copyright (C) 2014 Xamarin Inc
   *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
-  * License 2.0 as published by the Free Software Foundation;
-  *
-  * This library is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  * Library General Public License for more details.
-  *
-  * You should have received a copy of the GNU Library General Public
-  * License 2.0 along with this library; if not, write to the Free
-  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  #include "config.h"
@@@ -37,7 -26,6 +26,7 @@@
  #include "metadata/handle.h"
  #include "utils/mono-memory-model.h"
  #include "utils/mono-logger-internals.h"
 +#include "sgen/sgen-thread-pool.h"
  
  #ifdef HEAVY_STATISTICS
  static guint64 stat_wbarrier_set_arrayref = 0;
@@@ -2979,7 -2967,6 +2968,7 @@@ mono_gc_base_init (void
  void
  mono_gc_base_cleanup (void)
  {
 +      sgen_thread_pool_shutdown ();
  }
  
  gboolean
index a4f05e63ac954da9942505ad65d012ef0ec6d861,a93b4a4bd162afd6357078f74cd243fd5f21a3b5..462680a63fe5c2f59b379cf4147da2e02f8e8f15
@@@ -3,38 -3,10 +3,10 @@@
   *
   * Copyright 2011 Novell, Inc (http://www.novell.com)
   * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
-  *
-  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
-  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
-  *
-  * Permission is hereby granted to use or copy this program
-  * for any purpose,  provided the above notices are retained on all copies.
-  * Permission to modify the code and to distribute modified code is granted,
-  * provided the above notices are retained, and a notice that the code was
-  * modified is included with the above copyright notice.
-  *
-  *
   * Copyright 2001-2003 Ximian, Inc
   * Copyright 2003-2010 Novell, Inc.
   *
-  * Permission is hereby granted, free of charge, to any person obtaining
-  * a copy of this software and associated documentation files (the
-  * "Software"), to deal in the Software without restriction, including
-  * without limitation the rights to use, copy, modify, merge, publish,
-  * distribute, sublicense, and/or sell copies of the Software, and to
-  * permit persons to whom the Software is furnished to do so, subject to
-  * the following conditions:
-  *
-  * The above copyright notice and this permission notice shall be
-  * included in all copies or substantial portions of the Software.
-  *
-  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  #include "config.h"
@@@ -968,7 -940,7 +940,7 @@@ compare_hash_entries (const HashEntry *
  
  DEF_QSORT_INLINE(hash_entries, HashEntry*, compare_hash_entries)
  
 -static unsigned long step_1, step_2, step_3, step_4, step_5, step_6;
 +static gint64 step_1, step_2, step_3, step_4, step_5, step_6;
  static int fist_pass_links, second_pass_links, sccs_links;
  static int max_sccs_links = 0;
  
index f8437fe4810ccb775aa0858ddc85bce4e30207ce,fef6fb65e552c2bdaa08a1c9043ef7e440d3578e..a93cc7734ade79befcc811e6a8a4bf05047531a8
@@@ -3,38 -3,9 +3,9 @@@
   *
   * Copyright 2011 Novell, Inc (http://www.novell.com)
   * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
-  *
-  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
-  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
-  *
-  * Permission is hereby granted to use or copy this program
-  * for any purpose,  provided the above notices are retained on all copies.
-  * Permission to modify the code and to distribute modified code is granted,
-  * provided the above notices are retained, and a notice that the code was
-  * modified is included with the above copyright notice.
-  *
-  *
   * Copyright 2001-2003 Ximian, Inc
   * Copyright 2003-2010 Novell, Inc.
-  *
-  * Permission is hereby granted, free of charge, to any person obtaining
-  * a copy of this software and associated documentation files (the
-  * "Software"), to deal in the Software without restriction, including
-  * without limitation the rights to use, copy, modify, merge, publish,
-  * distribute, sublicense, and/or sell copies of the Software, and to
-  * permit persons to whom the Software is furnished to do so, subject to
-  * the following conditions:
-  *
-  * The above copyright notice and this permission notice shall be
-  * included in all copies or substantial portions of the Software.
-  *
-  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  #include "config.h"
@@@ -616,7 -587,7 +587,7 @@@ compare_hash_entries (const HashEntry *
  
  DEF_QSORT_INLINE(hash_entries, HashEntry*, compare_hash_entries)
  
 -static unsigned long step_1, step_2, step_3, step_4, step_5, step_6;
 +static gint64 step_1, step_2, step_3, step_4, step_5, step_6;
  static int fist_pass_links, second_pass_links, sccs_links;
  static int max_sccs_links = 0;
  
index d495d45d99f412925757c0fe2cdf75fd045e0b8a,db40521860fc8316da0ccc6508eabc7dbc9e35b6..62fc34aef3f2b11e470b7a8912c819bbf68a6db1
@@@ -5,6 -5,7 +5,7 @@@
   *    Ludovic Henry (ludovic.henry@xamarin.com)
   *
   * Copyright 2015 Xamarin, Inc (http://www.xamarin.com)
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  //
@@@ -528,7 -529,7 +529,7 @@@ worker_park (void
                if (interrupted)
                        goto done;
  
 -              if (mono_coop_cond_timedwait (&threadpool->parked_threads_cond, &threadpool->active_threads_lock, rand_next ((void **)rand_handle, 5 * 1000, 60 * 1000)) != 0)
 +              if (mono_coop_cond_timedwait (&threadpool->parked_threads_cond, &threadpool->active_threads_lock, rand_next (&rand_handle, 5 * 1000, 60 * 1000)) != 0)
                        timeout = TRUE;
  
                mono_thread_info_uninstall_interrupt (&interrupted);
diff --combined mono/metadata/verify.c
index 383ced4f1bf4a5540004bfc16ceb5fa8efa207e6,54651bc2b3cac02ede81eb4ba04cacdd65df7551..1d291ddb459d2d26df9f940b10ba05548fd50630
@@@ -7,6 -7,7 +7,7 @@@
   * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
   * Copyright 2004-2009 Novell, Inc (http://www.novell.com)
   * Copyright 2011 Rodrigo Kumpera
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  #include <config.h>
  
@@@ -5016,7 -5017,7 +5017,7 @@@ mono_method_verify (MonoMethod *method
        if (!ctx.valid)
                goto cleanup;
  
 -      original_bb = bb = mono_basic_block_split (method, &error);
 +      original_bb = bb = mono_basic_block_split (method, &error, ctx.header);
        if (!mono_error_ok (&error)) {
                ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Invalid branch target: %s", mono_error_get_message (&error)));
                mono_error_cleanup (&error);
diff --combined mono/mini/Makefile.am.in
index f75db695f358153a26e0a0ec5c21958fec9390f4,d2cc3cd3a5b82bd699bfddb77fd9564728191e8c..98fbf90fede8c2dc242a2d86403b040638c2e906
@@@ -304,13 -304,18 +304,18 @@@ x86_sources = 
        mini-x86.c              \
        mini-x86.h              \
        exceptions-x86.c        \
-       tramp-x86.c
+       tramp-x86.c     \
+       mini-x86-gsharedvt.c    \
+       tramp-x86-gsharedvt.c
  
  amd64_sources = \
        mini-amd64.c            \
        mini-amd64.h            \
        exceptions-amd64.c      \
-       tramp-amd64.c
+       tramp-amd64.c   \
+       mini-amd64-gsharedvt.c  \
+       mini-amd64-gsharedvt.h  \
+       tramp-amd64-gsharedvt.c
  
  ppc_sources = \
        mini-ppc.c              \
@@@ -324,13 -329,17 +329,17 @@@ arm_sources = 
        mini-arm.h              \
        mini-arm-tls.h          \
        exceptions-arm.c        \
-       tramp-arm.c
+       tramp-arm.c     \
+       mini-arm-gsharedvt.c    \
+       tramp-arm-gsharedvt.c
  
  arm64_sources = \
        mini-arm64.c            \
        mini-arm64.h            \
        exceptions-arm64.c      \
-       tramp-arm64.c
+       tramp-arm64.c   \
+       mini-arm64-gsharedvt.c  \
+       tramp-arm64-gsharedvt.c
  
  mips_sources = \
        mini-mips.c             \
@@@ -425,9 -434,11 +434,11 @@@ common_sources = 
        graph.c                 \
        mini-codegen.c          \
        mini-exceptions.c       \
+       mini-exceptions-native-unwinder.c       \
        mini-trampolines.c      \
        branch-opts.c           \
        mini-generic-sharing.c  \
+       mini-generic-sharing-gsharedvt.c        \
        simd-methods.h          \
        tasklets.c              \
        tasklets.h              \
@@@ -725,9 -736,9 +736,9 @@@ FULLAOT_LIBS = 
  fullaotcheck: $(mono) $(fullaot_regtests)
        rm -rf fullaot-tmp
        mkdir fullaot-tmp
 -      $(MAKE) fullaot-libs AOT_FLAGS=full GSHAREDVT=$(GSHAREDVT)
 +      $(MAKE) fullaot-libs AOT_FLAGS="full,$(MONO_FULLAOT_ADDITIONAL_ARGS)" GSHAREDVT=$(GSHAREDVT)
        cp $(regtests) $(fullaot_regtests) generics-variant-types.dll TestDriver.dll fullaot-tmp/
 -      MONO_PATH=fullaot-tmp $(top_builddir)/runtime/mono-wrapper $(LLVM_AOT_RUNTIME_OPTS) $(GSHAREDVT_RUNTIME_OPTS) --aot=full fullaot-tmp/{generics-variant-types.dll,TestDriver.dll,*.exe} || exit 1
 +      MONO_PATH=fullaot-tmp $(top_builddir)/runtime/mono-wrapper $(LLVM_AOT_RUNTIME_OPTS) $(GSHAREDVT_RUNTIME_OPTS) --aot="full,$(MONO_FULLAOT_ADDITIONAL_ARGS)" fullaot-tmp/{generics-variant-types.dll,TestDriver.dll,*.exe} || exit 1
        ln -s $(if $(MONO_EXECUTABLE),$(MONO_EXECUTABLE),$$PWD/mono) fullaot-tmp/
        for i in $(fullaot_regtests); do echo $$i; MONO_PATH=fullaot-tmp $(top_builddir)/runtime/mono-wrapper --full-aot fullaot-tmp/$$i --exclude '!FULLAOT' $(ARCH_FULLAOT_EXCLUDE) || exit 1; done
  
@@@ -748,7 -759,7 +759,7 @@@ llvmonly_regtests = $(fullaot_regtests
  llvmonlycheck: mono $(llvmonly_regtests)
        rm -rf fullaot-tmp
        mkdir fullaot-tmp
 -      $(MAKE) fullaot-libs AOT_FLAGS=llvmonly
 +      $(MAKE) fullaot-libs AOT_FLAGS="llvmonly,$(MONO_FULLAOT_ADDITIONAL_ARGS)"
        cp $(llvmonly_regtests) generics-variant-types.dll TestDriver.dll fullaot-tmp/
        MONO_PATH=fullaot-tmp $(top_builddir)/runtime/mono-wrapper  --aot=llvmonly fullaot-tmp/{generics-variant-types.dll,TestDriver.dll,*.exe} || exit 1
        ln -s $$PWD/mono fullaot-tmp/
diff --combined mono/mini/aot-compiler.c
index b74b1107fbfb328cc1cd69361a9c3d68449052cd,0622a8b334c806c51633a9ca35b35fa48f55a19b..dd2780edac9e524123b6483fca0e54cb4e5ff95b
@@@ -8,6 -8,7 +8,7 @@@
   * (C) 2002 Ximian, Inc.
   * Copyright 2003-2011 Novell, Inc 
   * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  #include "config.h"
@@@ -857,7 -858,331 +858,331 @@@ arch_init (MonoAotCompile *acfg
  
  #ifdef TARGET_ARM64
  
- #include "../../../mono-extensions/mono/mini/aot-compiler-arm64.c"
+ /* Load the contents of GOT_SLOT into dreg, clobbering ip0 */
+ static void
+ arm64_emit_load_got_slot (MonoAotCompile *acfg, int dreg, int got_slot)
+ {
+       int offset;
+       g_assert (acfg->fp);
+       emit_unset_mode (acfg);
+       /* r16==ip0 */
+       offset = (int)(got_slot * sizeof (gpointer));
+ #ifdef TARGET_MACH
+       /* clang's integrated assembler */
+       fprintf (acfg->fp, "adrp x16, %s@PAGE+%d\n", acfg->got_symbol, offset & 0xfffff000);
+       fprintf (acfg->fp, "add x16, x16, %s@PAGEOFF\n", acfg->got_symbol);
+       fprintf (acfg->fp, "ldr x%d, [x16, #%d]\n", dreg, offset & 0xfff);
+ #else
+       /* Linux GAS */
+       fprintf (acfg->fp, "adrp x16, %s+%d\n", acfg->got_symbol, offset & 0xfffff000);
+       fprintf (acfg->fp, "add x16, x16, :lo12:%s\n", acfg->got_symbol);
+       fprintf (acfg->fp, "ldr x%d, [x16, %d]\n", dreg, offset & 0xfff);
+ #endif
+ }
+ static void
+ arm64_emit_objc_selector_ref (MonoAotCompile *acfg, guint8 *code, int index, int *code_size)
+ {
+       int reg;
+       g_assert (acfg->fp);
+       emit_unset_mode (acfg);
+       /* ldr rt, target */
+       reg = arm_get_ldr_lit_reg (code);
+       fprintf (acfg->fp, "adrp x%d, L_OBJC_SELECTOR_REFERENCES_%d@PAGE\n", reg, index);
+       fprintf (acfg->fp, "add x%d, x%d, L_OBJC_SELECTOR_REFERENCES_%d@PAGEOFF\n", reg, reg, index);
+       fprintf (acfg->fp, "ldr x%d, [x%d]\n", reg, reg);
+       *code_size = 12;
+ }
+ static void
+ arm64_emit_direct_call (MonoAotCompile *acfg, const char *target, gboolean external, gboolean thumb, MonoJumpInfo *ji, int *call_size)
+ {
+       g_assert (acfg->fp);
+       emit_unset_mode (acfg);
+       if (ji && ji->relocation == MONO_R_ARM64_B) {
+               fprintf (acfg->fp, "b %s\n", target);
+       } else {
+               if (ji)
+                       g_assert (ji->relocation == MONO_R_ARM64_BL);
+               fprintf (acfg->fp, "bl %s\n", target);
+       }
+       *call_size = 4;
+ }
+ static void
+ arm64_emit_got_access (MonoAotCompile *acfg, guint8 *code, int got_slot, int *code_size)
+ {
+       int reg;
+       /* ldr rt, target */
+       reg = arm_get_ldr_lit_reg (code);
+       arm64_emit_load_got_slot (acfg, reg, got_slot);
+       *code_size = 12;
+ }
+ static void
+ arm64_emit_plt_entry (MonoAotCompile *acfg, const char *got_symbol, int offset, int info_offset)
+ {
+       arm64_emit_load_got_slot (acfg, ARMREG_R16, offset / sizeof (gpointer));
+       fprintf (acfg->fp, "br x16\n");
+       /* Used by mono_aot_get_plt_info_offset () */
+       fprintf (acfg->fp, "%s %d\n", acfg->inst_directive, info_offset);
+ }
+ static void
+ arm64_emit_tramp_page_common_code (MonoAotCompile *acfg, int pagesize, int arg_reg, int *size)
+ {
+       guint8 buf [256];
+       guint8 *code;
+       int imm;
+       /* The common code */
+       code = buf;
+       imm = pagesize;
+       /* The trampoline address is in IP0 */
+       arm_movzx (code, ARMREG_IP1, imm & 0xffff, 0);
+       arm_movkx (code, ARMREG_IP1, (imm >> 16) & 0xffff, 16);
+       /* Compute the data slot address */
+       arm_subx (code, ARMREG_IP0, ARMREG_IP0, ARMREG_IP1);
+       /* Trampoline argument */
+       arm_ldrx (code, arg_reg, ARMREG_IP0, 0);
+       /* Address */
+       arm_ldrx (code, ARMREG_IP0, ARMREG_IP0, 8);
+       arm_brx (code, ARMREG_IP0);
+       /* Emit it */
+       emit_code_bytes (acfg, buf, code - buf);
+       *size = code - buf;
+ }
+ static void
+ arm64_emit_tramp_page_specific_code (MonoAotCompile *acfg, int pagesize, int common_tramp_size, int specific_tramp_size)
+ {
+       guint8 buf [256];
+       guint8 *code;
+       int i, count;
+       count = (pagesize - common_tramp_size) / specific_tramp_size;
+       for (i = 0; i < count; ++i) {
+               code = buf;
+               arm_adrx (code, ARMREG_IP0, code);
+               /* Branch to the generic code */
+               arm_b (code, code - 4 - (i * specific_tramp_size) - common_tramp_size);
+               /* This has to be 2 pointers long */
+               arm_nop (code);
+               arm_nop (code);
+               g_assert (code - buf == specific_tramp_size);
+               emit_code_bytes (acfg, buf, code - buf);
+       }
+ }
+ static void
+ arm64_emit_specific_trampoline_pages (MonoAotCompile *acfg)
+ {
+       guint8 buf [128];
+       guint8 *code;
+       guint8 *labels [16];
+       int common_tramp_size;
+       int specific_tramp_size = 2 * 8;
+       int imm, pagesize;
+       char symbol [128];
+       if (!acfg->aot_opts.use_trampolines_page)
+               return;
+ #ifdef TARGET_MACH
+       /* Have to match the target pagesize */
+       pagesize = 16384;
+ #else
+       pagesize = mono_pagesize ();
+ #endif
+       acfg->tramp_page_size = pagesize;
+       /* The specific trampolines */
+       sprintf (symbol, "%sspecific_trampolines_page", acfg->user_symbol_prefix);
+       emit_alignment (acfg, pagesize);
+       emit_global (acfg, symbol, TRUE);
+       emit_label (acfg, symbol);
+       /* The common code */
+       arm64_emit_tramp_page_common_code (acfg, pagesize, ARMREG_IP1, &common_tramp_size);
+       acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_SPECIFIC] = common_tramp_size;
+       arm64_emit_tramp_page_specific_code (acfg, pagesize, common_tramp_size, specific_tramp_size);
+       /* The rgctx trampolines */
+       /* These are the same as the specific trampolines, but they load the argument into MONO_ARCH_RGCTX_REG */
+       sprintf (symbol, "%srgctx_trampolines_page", acfg->user_symbol_prefix);
+       emit_alignment (acfg, pagesize);
+       emit_global (acfg, symbol, TRUE);
+       emit_label (acfg, symbol);
+       /* The common code */
+       arm64_emit_tramp_page_common_code (acfg, pagesize, MONO_ARCH_RGCTX_REG, &common_tramp_size);
+       acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_STATIC_RGCTX] = common_tramp_size;
+       arm64_emit_tramp_page_specific_code (acfg, pagesize, common_tramp_size, specific_tramp_size);
+       /* The gsharedvt arg trampolines */
+       /* These are the same as the specific trampolines */
+       sprintf (symbol, "%sgsharedvt_arg_trampolines_page", acfg->user_symbol_prefix);
+       emit_alignment (acfg, pagesize);
+       emit_global (acfg, symbol, TRUE);
+       emit_label (acfg, symbol);
+       arm64_emit_tramp_page_common_code (acfg, pagesize, ARMREG_IP1, &common_tramp_size);
+       acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_GSHAREDVT_ARG] = common_tramp_size;
+       arm64_emit_tramp_page_specific_code (acfg, pagesize, common_tramp_size, specific_tramp_size);
+       /* The IMT trampolines */
+       sprintf (symbol, "%simt_trampolines_page", acfg->user_symbol_prefix);
+       emit_alignment (acfg, pagesize);
+       emit_global (acfg, symbol, TRUE);
+       emit_label (acfg, symbol);
+       code = buf;
+       imm = pagesize;
+       /* The trampoline address is in IP0 */
+       arm_movzx (code, ARMREG_IP1, imm & 0xffff, 0);
+       arm_movkx (code, ARMREG_IP1, (imm >> 16) & 0xffff, 16);
+       /* Compute the data slot address */
+       arm_subx (code, ARMREG_IP0, ARMREG_IP0, ARMREG_IP1);
+       /* Trampoline argument */
+       arm_ldrx (code, ARMREG_IP1, ARMREG_IP0, 0);
+       /* Same as arch_emit_imt_thunk () */
+       labels [0] = code;
+       arm_ldrx (code, ARMREG_IP0, ARMREG_IP1, 0);
+       arm_cmpx (code, ARMREG_IP0, MONO_ARCH_RGCTX_REG);
+       labels [1] = code;
+       arm_bcc (code, ARMCOND_EQ, 0);
+       /* End-of-loop check */
+       labels [2] = code;
+       arm_cbzx (code, ARMREG_IP0, 0);
+       /* Loop footer */
+       arm_addx_imm (code, ARMREG_IP1, ARMREG_IP1, 2 * 8);
+       arm_b (code, labels [0]);
+       /* Match */
+       mono_arm_patch (labels [1], code, MONO_R_ARM64_BCC);
+       /* Load vtable slot addr */
+       arm_ldrx (code, ARMREG_IP0, ARMREG_IP1, 8);
+       /* Load vtable slot */
+       arm_ldrx (code, ARMREG_IP0, ARMREG_IP0, 0);
+       arm_brx (code, ARMREG_IP0);
+       /* No match */
+       mono_arm_patch (labels [2], code, MONO_R_ARM64_CBZ);
+       /* Load fail addr */
+       arm_ldrx (code, ARMREG_IP0, ARMREG_IP1, 8);
+       arm_brx (code, ARMREG_IP0);
+       emit_code_bytes (acfg, buf, code - buf);
+       common_tramp_size = code - buf;
+       acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_IMT_THUNK] = common_tramp_size;
+       arm64_emit_tramp_page_specific_code (acfg, pagesize, common_tramp_size, specific_tramp_size);
+ }
+ static void
+ arm64_emit_specific_trampoline (MonoAotCompile *acfg, int offset, int *tramp_size)
+ {
+       /* Load argument from second GOT slot */
+       arm64_emit_load_got_slot (acfg, ARMREG_R17, offset + 1);
+       /* Load generic trampoline address from first GOT slot */
+       arm64_emit_load_got_slot (acfg, ARMREG_R16, offset);
+       fprintf (acfg->fp, "br x16\n");
+       *tramp_size = 7 * 4;
+ }
+ static void
+ arm64_emit_unbox_trampoline (MonoAotCompile *acfg, MonoCompile *cfg, MonoMethod *method, const char *call_target)
+ {
+       emit_unset_mode (acfg);
+       fprintf (acfg->fp, "add x0, x0, %d\n", (int)(sizeof (MonoObject)));
+       fprintf (acfg->fp, "b %s\n", call_target);
+ }
+ static void
+ arm64_emit_static_rgctx_trampoline (MonoAotCompile *acfg, int offset, int *tramp_size)
+ {
+       /* Similar to the specific trampolines, but use the rgctx reg instead of ip1 */
+       /* Load argument from first GOT slot */
+       g_assert (MONO_ARCH_RGCTX_REG == 27);
+       arm64_emit_load_got_slot (acfg, ARMREG_R27, offset);
+       /* Load generic trampoline address from second GOT slot */
+       arm64_emit_load_got_slot (acfg, ARMREG_R16, offset + 1);
+       fprintf (acfg->fp, "br x16\n");
+       *tramp_size = 7 * 4;
+ }
+ static void
+ arm64_emit_imt_thunk (MonoAotCompile *acfg, int offset, int *tramp_size)
+ {
+       guint8 buf [128];
+       guint8 *code, *labels [16];
+       /* Load parameter from GOT slot into ip1 */
+       arm64_emit_load_got_slot (acfg, ARMREG_R17, offset);
+       code = buf;
+       labels [0] = code;
+       arm_ldrx (code, ARMREG_IP0, ARMREG_IP1, 0);
+       arm_cmpx (code, ARMREG_IP0, MONO_ARCH_RGCTX_REG);
+       labels [1] = code;
+       arm_bcc (code, ARMCOND_EQ, 0);
+       /* End-of-loop check */
+       labels [2] = code;
+       arm_cbzx (code, ARMREG_IP0, 0);
+       /* Loop footer */
+       arm_addx_imm (code, ARMREG_IP1, ARMREG_IP1, 2 * 8);
+       arm_b (code, labels [0]);
+       /* Match */
+       mono_arm_patch (labels [1], code, MONO_R_ARM64_BCC);
+       /* Load vtable slot addr */
+       arm_ldrx (code, ARMREG_IP0, ARMREG_IP1, 8);
+       /* Load vtable slot */
+       arm_ldrx (code, ARMREG_IP0, ARMREG_IP0, 0);
+       arm_brx (code, ARMREG_IP0);
+       /* No match */
+       mono_arm_patch (labels [2], code, MONO_R_ARM64_CBZ);
+       /* Load fail addr */
+       arm_ldrx (code, ARMREG_IP0, ARMREG_IP1, 8);
+       arm_brx (code, ARMREG_IP0);
+       emit_code_bytes (acfg, buf, code - buf);
+       *tramp_size = code - buf + (3 * 4);
+ }
+ static void
+ arm64_emit_gsharedvt_arg_trampoline (MonoAotCompile *acfg, int offset, int *tramp_size)
+ {
+       /* Similar to the specific trampolines, but the address is in the second slot */
+       /* Load argument from first GOT slot */
+       arm64_emit_load_got_slot (acfg, ARMREG_R17, offset);
+       /* Load generic trampoline address from second GOT slot */
+       arm64_emit_load_got_slot (acfg, ARMREG_R16, offset + 1);
+       fprintf (acfg->fp, "br x16\n");
+       *tramp_size = 7 * 4;
+ }
  
  #endif
  
@@@ -6676,15 -7001,6 +7001,15 @@@ wrap_path (gchar * path
        return clean;
  }
  
 +// Duplicate a char range and add it to a ptrarray, but only if it is nonempty
 +static void
 +ptr_array_add_range_if_nonempty(GPtrArray *args, gchar const *start, gchar const *end)
 +{
 +      ptrdiff_t len = end-start;
 +      if (len > 0)
 +              g_ptr_array_add (args, g_strndup (start, len));
 +}
 +
  static GPtrArray *
  mono_aot_split_options (const char *aot_options)
  {
  
        next:
                aot_options++;
 +      restart:
                // If the next character is end of string, then process the last option.
                if (*(aot_options) == '\0') {
                        end_of_string = TRUE;
                continue;
  
        new_opt:
 -              g_ptr_array_add (args, g_strndup (opt_start, aot_options - opt_start));
 +              ptr_array_add_range_if_nonempty (args, opt_start, aot_options);
                opt_start = ++aot_options;
                if (end_of_string)
                        break;
 -              goto next;
 +              goto restart; // Check for null and continue loop
        }
  
        return args;
@@@ -9560,6 -9875,7 +9885,6 @@@ compile_asm (MonoAotCompile *acfg
  #define AS_OPTIONS "--64"
  #elif defined(TARGET_POWERPC64)
  #define AS_OPTIONS "-a64 -mppc64"
 -#define LD_OPTIONS "-m elf64ppc"
  #elif defined(sparc) && SIZEOF_VOID_P == 8
  #define AS_OPTIONS "-xarch=v9"
  #elif defined(TARGET_X86) && defined(TARGET_MACH) && !defined(__native_client_codegen__)
  #define AS_NAME "as"
  #endif
  
 -#ifndef LD_OPTIONS
 -#define LD_OPTIONS ""
 -#endif
 -
  #if defined(sparc)
 -#define LD_NAME "ld -shared -G"
 +#define LD_NAME "ld"
 +#define LD_OPTIONS "-shared -G"
  #elif defined(__ppc__) && defined(TARGET_MACH)
 -#define LD_NAME "gcc -dynamiclib"
 +#define LD_NAME "gcc"
 +#define LD_OPTIONS "-dynamiclib"
  #elif defined(TARGET_AMD64) && defined(TARGET_MACH)
 -#define LD_NAME "clang --shared"
 +#define LD_NAME "clang"
 +#define LD_OPTIONS "--shared"
  #elif defined(TARGET_WIN32) && !defined(TARGET_ANDROID)
 -#define LD_NAME "gcc -shared --dll"
 +#define LD_NAME "gcc"
 +#define LD_OPTIONS "-shared"
  #elif defined(TARGET_X86) && defined(TARGET_MACH) && !defined(__native_client_codegen__)
 -#define LD_NAME "clang -m32 -dynamiclib"
 +#define LD_NAME "clang"
 +#define LD_OPTIONS "-m32 -dynamiclib"
  #elif defined(TARGET_ARM) && !defined(TARGET_ANDROID)
 -#define LD_NAME "gcc --shared"
 +#define LD_NAME "gcc"
 +#define LD_OPTIONS "--shared"
 +#elif defined(TARGET_POWERPC64)
 +#define LD_OPTIONS "-m elf64ppc"
 +#endif
 +
 +#ifndef LD_OPTIONS
 +#define LD_OPTIONS ""
  #endif
  
        if (acfg->aot_opts.asm_only) {
                ld_flags = g_strdup_printf ("%s %s", ld_flags, "-lstdc++");
  
  #ifdef LD_NAME
 -      command = g_strdup_printf ("%s -o %s %s %s %s", LD_NAME,
 +      command = g_strdup_printf ("%s%s %s -o %s %s %s %s", tool_prefix, LD_NAME, LD_OPTIONS,
                wrap_path (tmp_outfile_name), wrap_path (llvm_ofile),
                wrap_path (g_strdup_printf ("%s.o", acfg->tmpfname)), ld_flags);
  #else
 +      // Default (linux)
        command = g_strdup_printf ("\"%sld\" %s -shared -o %s %s %s %s", tool_prefix, LD_OPTIONS,
                wrap_path (tmp_outfile_name), wrap_path (llvm_ofile),
                wrap_path (g_strdup_printf ("%s.o", acfg->tmpfname)), ld_flags);
@@@ -10116,7 -10423,7 +10441,7 @@@ mono_compile_assembly (MonoAssembly *as
  
        //acfg->aot_opts.print_skipped_methods = TRUE;
  
- #if !defined(ENABLE_GSHAREDVT)
+ #if !defined(MONO_ARCH_GSHAREDVT_SUPPORTED)
        if (opts & MONO_OPT_GSHAREDVT) {
                aot_printerrf (acfg, "-O=gsharedvt not supported on this platform.\n");
                return 1;
  #endif
  
        if (acfg->aot_opts.llvm_only) {
- #ifndef ENABLE_GSHAREDVT
-               aot_printerrf (acfg, "--aot=llvmonly requires a runtime compiled with --enable-gsharedvt.\n");
+ #ifndef MONO_ARCH_GSHAREDVT_SUPPORTED
+               aot_printerrf (acfg, "--aot=llvmonly requires a runtime that supports gsharedvt.\n");
                return 1;
  #endif
        }
  
- #if defined(ENABLE_GSHAREDVT) && defined(MONO_ARCH_GSHAREDVT_SUPPORTED)
+ #if defined(MONO_ARCH_GSHAREDVT_SUPPORTED)
        acfg->opts |= MONO_OPT_GSHAREDVT;
        opts |= MONO_OPT_GSHAREDVT;
  #endif
index cab03fc0f2eae39d21165e0a02250a666d7cbd79,e4e15d6314e9cfdbb6e1e46ba9271bed244df6a1..06c0fd710fc830a14454225d2867b41b8823f999
@@@ -6,6 -6,7 +6,7 @@@
   *
   * (C) 2001 Ximian, Inc.
   * Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  #include <config.h>
@@@ -417,7 -418,10 +418,7 @@@ get_throw_trampoline (MonoTrampInfo **i
        amd64_lea_membase (code, AMD64_RAX, AMD64_RSP, stack_size + sizeof(mgreg_t));
        amd64_mov_membase_reg (code, AMD64_RSP, regs_offset + (AMD64_RSP * sizeof(mgreg_t)), X86_EAX, sizeof(mgreg_t));
        /* Save IP */
 -      if (llvm_abs)
 -              amd64_alu_reg_reg (code, X86_XOR, AMD64_RAX, AMD64_RAX);
 -      else
 -              amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RSP, stack_size, sizeof(mgreg_t));
 +      amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RSP, stack_size, sizeof(mgreg_t));
        amd64_mov_membase_reg (code, AMD64_RSP, regs_offset + (AMD64_RIP * sizeof(mgreg_t)), AMD64_RAX, sizeof(mgreg_t));
        /* Set arg1 == ctx */
        amd64_lea_membase (code, AMD64_RAX, AMD64_RSP, ctx_offset);
        if (resume_unwind) {
                amd64_mov_membase_imm (code, AMD64_RSP, arg_offsets [2], 0, sizeof(mgreg_t));
        } else if (corlib) {
 -              amd64_mov_membase_reg (code, AMD64_RSP, arg_offsets [2], AMD64_ARG_REG2, sizeof(mgreg_t));
                if (llvm_abs)
 -                      /* 
 -                       * The caller is LLVM code which passes the absolute address not a pc offset,
 -                       * so compensate by passing 0 as 'rip' and passing the negated abs address as
 -                       * the pc offset.
 +                      /*
 +                       * The caller doesn't pass in a pc/pc offset, instead we simply use the
 +                       * caller ip. Negate the pc adjustment done in mono_amd64_throw_corlib_exception ().
                         */
 -                      amd64_neg_membase (code, AMD64_RSP, arg_offsets [2]);
 +                      amd64_mov_membase_imm (code, AMD64_RSP, arg_offsets [2], 1, sizeof(mgreg_t));
 +              else
 +                      amd64_mov_membase_reg (code, AMD64_RSP, arg_offsets [2], AMD64_ARG_REG2, sizeof(mgreg_t));
        } else {
                amd64_mov_membase_imm (code, AMD64_RSP, arg_offsets [2], rethrow, sizeof(mgreg_t));
        }
diff --combined mono/mini/method-to-ir.c
index 71ed0310656e5baaf0aabe72ac577e1979ca1bdc,30abb09c124dace0910d03a2a61cc4a50588a3c7..aed8309edf6ef795d06aca1840712df51809916c
@@@ -8,6 -8,7 +8,7 @@@
   * (C) 2002 Ximian, Inc.
   * Copyright 2003-2010 Novell, Inc (http://www.novell.com)
   * Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  #include <config.h>
@@@ -8578,7 -8579,7 +8579,7 @@@ mono_method_to_ir (MonoCompile *cfg, Mo
  
        skip_dead_blocks = !dont_verify;
        if (skip_dead_blocks) {
 -              original_bb = bb = mono_basic_block_split (method, &cfg->error);
 +              original_bb = bb = mono_basic_block_split (method, &cfg->error, header);
                CHECK_CFG_ERROR;
                g_assert (bb);
        }
diff --combined mono/mini/mini-arm.c
index a7df6fc1c1b282990ba87401cf50423291a546f0,a103384a3f330a20fda4b304c2c7cbd41123a305..86d4e123919cb97908c28153de6b512f1bc5d644
@@@ -8,6 -8,7 +8,7 @@@
   * (C) 2003 Ximian, Inc.
   * Copyright 2003-2011 Novell, Inc (http://www.novell.com)
   * Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  #include "mini.h"
  #include <string.h>
@@@ -903,7 -904,7 +904,7 @@@ mono_arch_init (void
        mono_aot_register_jit_icall ("mono_arm_throw_exception", mono_arm_throw_exception);
        mono_aot_register_jit_icall ("mono_arm_throw_exception_by_token", mono_arm_throw_exception_by_token);
        mono_aot_register_jit_icall ("mono_arm_resume_unwind", mono_arm_resume_unwind);
- #if defined(ENABLE_GSHAREDVT)
+ #if defined(MONO_ARCH_GSHAREDVT_SUPPORTED)
        mono_aot_register_jit_icall ("mono_arm_start_gsharedvt_call", mono_arm_start_gsharedvt_call);
  #endif
        mono_aot_register_jit_icall ("mono_arm_unaligned_stack", mono_arm_unaligned_stack);
@@@ -1159,50 -1160,6 +1160,6 @@@ mono_arch_flush_icache (guint8 *code, g
  #endif
  }
  
- typedef enum {
-       RegTypeNone,
-       /* Passed/returned in an ireg */
-       RegTypeGeneral,
-       /* Passed/returned in a pair of iregs */
-       RegTypeIRegPair,
-       /* Passed on the stack */
-       RegTypeBase,
-       /* First word in r3, second word on the stack */
-       RegTypeBaseGen,
-       /* FP value passed in either an ireg or a vfp reg */
-       RegTypeFP,
-       RegTypeStructByVal,
-       RegTypeStructByAddr,
-       /* gsharedvt argument passed by addr in greg */
-       RegTypeGSharedVtInReg,
-       /* gsharedvt argument passed by addr on stack */
-       RegTypeGSharedVtOnStack,
-       RegTypeHFA
- } ArgStorage;
- typedef struct {
-       gint32  offset;
-       guint16 vtsize; /* in param area */
-       /* RegTypeHFA */
-       int esize;
-       /* RegTypeHFA */
-       int nregs;
-       guint8  reg;
-       ArgStorage  storage;
-       gint32  struct_size;
-       guint8  size    : 4; /* 1, 2, 4, 8, or regs used by RegTypeStructByVal */
- } ArgInfo;
- typedef struct {
-       int nargs;
-       guint32 stack_usage;
-       /* The index of the vret arg in the argument list for RegTypeStructByAddr */
-       int vret_arg_index;
-       ArgInfo ret;
-       ArgInfo sig_cookie;
-       ArgInfo args [1];
- } CallInfo;
  #define DEBUG(a)
  
  static void inline
@@@ -6827,7 -6784,7 +6784,7 @@@ mono_arch_emit_exceptions (MonoCompile 
                        patch_info->ip.i = code - cfg->native_code;
                        ARM_BL (code, 0);
                        cfg->thunk_area += THUNK_SIZE;
 -                      *(guint32*)(gpointer)code = exc_class->type_token;
 +                      *(guint32*)(gpointer)code = exc_class->type_token - MONO_TOKEN_TYPE_DEF;
                        code += 4;
  #endif
                        break;
@@@ -7664,8 -7621,8 +7621,8 @@@ mono_arch_opcode_supported (int opcode
        }
  }
  
- #if defined(ENABLE_GSHAREDVT)
- #include "../../../mono-extensions/mono/mini/mini-arm-gsharedvt.c"
- #endif /* !MONOTOUCH */
+ CallInfo*
+ mono_arch_get_call_info (MonoMemPool *mp, MonoMethodSignature *sig)
+ {
+       return get_call_info (mp, sig);
+ }
diff --combined mono/mini/mini-llvm.c
index f8aa239061589f9c9092ff6b246e76eecfa98591,c07a6f56e08c5a5190985b8a73b4cafa009c4674..adec297e3c3ebfaff926f66a07fea1c05851de76
@@@ -3,6 -3,7 +3,7 @@@
   *
   * Copyright 2009-2011 Novell Inc (http://www.novell.com)
   * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  #include "mini.h"
@@@ -2068,11 -2069,6 +2069,11 @@@ emit_cond_system_exception (EmitContex
        MonoClass *exc_class;
        LLVMValueRef args [2];
        LLVMValueRef callee;
 +      gboolean no_pc = FALSE;
 +
 +      if (IS_TARGET_AMD64)
 +              /* Some platforms don't require the pc argument */
 +              no_pc = TRUE;
        
        ex_bb = gen_bb (ctx, "EX_BB");
        if (ctx->llvm_only)
                LLVMTypeRef sig;
                const char *icall_name;
  
 -              sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
 +              if (no_pc)
 +                      sig = LLVMFunctionType1 (LLVMVoidType (), LLVMInt32Type (), FALSE);
 +              else
 +                      sig = LLVMFunctionType2 (LLVMVoidType (), LLVMInt32Type (), LLVMPointerType (LLVMInt8Type (), 0), FALSE);
                icall_name = "llvm_throw_corlib_exception_abs_trampoline";
  
                if (ctx->cfg->compile_aot) {
                }
        }
  
 -      if (IS_TARGET_X86 || IS_TARGET_AMD64)
 -              args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
 -      else
 -              args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
 +      args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
  
        /*
         * The LLVM mono branch contains changes so a block address can be passed as an
         * argument to a call.
         */
 -      args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
 -      emit_call (ctx, bb, &builder, callee, args, 2);
 +      if (no_pc) {
 +              emit_call (ctx, bb, &builder, callee, args, 1);
 +      } else {
 +              args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
 +              emit_call (ctx, bb, &builder, callee, args, 2);
 +      }
  
        LLVMBuildUnreachable (builder);
  
diff --combined mono/mini/mini-windows.c
index 41f12051f906929073be867a6b0076a04b8dbf11,e7764e91beb749709474b294aef00cb5c30932ce..621a7a5fc31970e22d3e75e4993623ae10dddece
@@@ -8,6 -8,7 +8,7 @@@
   * Copyright 2003-2008 Ximian, Inc.
   *
   * See LICENSE for licensing information.
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  #include <config.h>
  #include <signal.h>
@@@ -58,14 -59,12 +59,14 @@@ voi
  mono_runtime_install_handlers (void)
  {
  #ifndef MONO_CROSS_COMPILE
 -      win32_seh_init();
 -      win32_seh_set_handler(SIGFPE, mono_sigfpe_signal_handler);
 -      win32_seh_set_handler(SIGILL, mono_sigill_signal_handler);
 -      win32_seh_set_handler(SIGSEGV, mono_sigsegv_signal_handler);
 -      if (mini_get_debug_options ()->handle_sigint)
 -              win32_seh_set_handler(SIGINT, mono_sigint_signal_handler);
 +      if (!mono_aot_only) {
 +              win32_seh_init();
 +              win32_seh_set_handler(SIGFPE, mono_sigfpe_signal_handler);
 +              win32_seh_set_handler(SIGILL, mono_sigill_signal_handler);
 +              win32_seh_set_handler(SIGSEGV, mono_sigsegv_signal_handler);
 +              if (mini_get_debug_options ()->handle_sigint)
 +                      win32_seh_set_handler(SIGINT, mono_sigint_signal_handler);
 +      }
  #endif
  }
  
@@@ -73,9 -72,7 +74,9 @@@ voi
  mono_runtime_cleanup_handlers (void)
  {
  #ifndef MONO_CROSS_COMPILE
 -      win32_seh_cleanup();
 +      if (!mono_aot_only) {
 +              win32_seh_cleanup();
 +      }
  #endif
  }
  
diff --combined mono/sgen/sgen-gc.c
index 62e1e88fe8e0f21b26e9dc398b3beb6ef89e2e3c,498abf6b8e9f0818b4bc80bacfc3333b49f0be26..f3077a6759c9b59f006c71c62f30cd028d211bcd
   * Copyright 2011 Xamarin, Inc.
   * Copyright (C) 2012 Xamarin Inc
   *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
-  * License 2.0 as published by the Free Software Foundation;
-  *
-  * This library is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  * Library General Public License for more details.
-  *
-  * You should have received a copy of the GNU Library General Public
-  * License 2.0 along with this library; if not, write to the Free
-  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   *
   * Important: allocation provides always zeroed memory, having to do
   * a memset after allocation is deadly for performance.
@@@ -1169,7 -1158,7 +1158,7 @@@ finish_gray_stack (int generation, Scan
        sgen_client_clear_togglerefs (start_addr, end_addr, ctx);
  
        TV_GETTIME (btv);
 -      SGEN_LOG (2, "Finalize queue handling scan for %s generation: %ld usecs %d ephemeron rounds", generation_name (generation), TV_ELAPSED (atv, btv), ephemeron_rounds);
 +      SGEN_LOG (2, "Finalize queue handling scan for %s generation: %lld usecs %d ephemeron rounds", generation_name (generation), TV_ELAPSED (atv, btv), ephemeron_rounds);
  
        /*
         * handle disappearing links
@@@ -1561,7 -1550,7 +1550,7 @@@ collect_nursery (SgenGrayQueue *unpin_q
  
        TV_GETTIME (atv);
        time_minor_pinning += TV_ELAPSED (btv, atv);
 -      SGEN_LOG (2, "Finding pinned pointers: %zd in %ld usecs", sgen_get_pinned_count (), TV_ELAPSED (btv, atv));
 +      SGEN_LOG (2, "Finding pinned pointers: %zd in %lld usecs", sgen_get_pinned_count (), TV_ELAPSED (btv, atv));
        SGEN_LOG (4, "Start scan with %zd pinned objects", sgen_get_pinned_count ());
  
        sj = (ScanJob*)sgen_thread_pool_job_alloc ("scan remset", job_remembered_set_scan, sizeof (ScanJob));
        /* we don't have complete write barrier yet, so we scan all the old generation sections */
        TV_GETTIME (btv);
        time_minor_scan_remsets += TV_ELAPSED (atv, btv);
 -      SGEN_LOG (2, "Old generation scan: %ld usecs", TV_ELAPSED (atv, btv));
 +      SGEN_LOG (2, "Old generation scan: %lld usecs", TV_ELAPSED (atv, btv));
  
        sgen_pin_stats_print_class_stats ();
  
        sgen_client_binary_protocol_reclaim_end (GENERATION_NURSERY);
        TV_GETTIME (btv);
        time_minor_fragment_creation += TV_ELAPSED (atv, btv);
 -      SGEN_LOG (2, "Fragment creation: %ld usecs, %lu bytes available", TV_ELAPSED (atv, btv), (unsigned long)fragment_total);
 +      SGEN_LOG (2, "Fragment creation: %lld usecs, %lu bytes available", TV_ELAPSED (atv, btv), (unsigned long)fragment_total);
  
        if (consistency_check_at_minor_collection)
                sgen_check_major_refs ();
@@@ -1713,7 -1702,7 +1702,7 @@@ major_copy_or_mark_from_roots (size_t *
  
        sgen_client_pre_collection_checks ();
  
 -      if (!concurrent) {
 +      if (mode != COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT) {
                /* Remsets are not useful for a major collection */
                remset.clear_cards ();
        }
        sgen_init_pinning ();
        SGEN_LOG (6, "Collecting pinned addresses");
        pin_from_roots ((void*)lowest_heap_address, (void*)highest_heap_address, ctx);
 -
 +      if (mode == COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT) {
 +              /* Pin cemented objects that were forced */
 +              sgen_pin_cemented_objects ();
 +      }
        sgen_optimize_pin_queue ();
 +      if (mode == COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT) {
 +              /*
 +               * Cemented objects that are in the pinned list will be marked. When
 +               * marking concurrently we won't mark mod-union cards for these objects.
 +               * Instead they will remain cemented until the next major collection,
 +               * when we will recheck if they are still pinned in the roots.
 +               */
 +              sgen_cement_force_pinned ();
 +      }
  
        sgen_client_collecting_major_1 ();
  
  
        TV_GETTIME (btv);
        time_major_pinning += TV_ELAPSED (atv, btv);
 -      SGEN_LOG (2, "Finding pinned pointers: %zd in %ld usecs", sgen_get_pinned_count (), TV_ELAPSED (atv, btv));
 +      SGEN_LOG (2, "Finding pinned pointers: %zd in %lld usecs", sgen_get_pinned_count (), TV_ELAPSED (atv, btv));
        SGEN_LOG (4, "Start scan with %zd pinned objects", sgen_get_pinned_count ());
  
        major_collector.init_to_space ();
  
        SGEN_ASSERT (0, sgen_workers_all_done (), "Why are the workers not done when we start or finish a major collection?");
 -      /*
 -       * The concurrent collector doesn't move objects, neither on
 -       * the major heap nor in the nursery, so we can mark even
 -       * before pinning has finished.  For the non-concurrent
 -       * collector we start the workers after pinning.
 -       */
 -      if (mode == COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT) {
 -              if (precleaning_enabled) {
 -                      ScanJob *sj;
 -                      /* Mod union preclean job */
 -                      sj = (ScanJob*)sgen_thread_pool_job_alloc ("preclean mod union cardtable", job_mod_union_preclean, sizeof (ScanJob));
 -                      sj->ops = object_ops;
 -                      sgen_workers_start_all_workers (object_ops, &sj->job);
 -              } else {
 -                      sgen_workers_start_all_workers (object_ops, NULL);
 -              }
 -              gray_queue_enable_redirect (WORKERS_DISTRIBUTE_GRAY_QUEUE);
 -      } else if (mode == COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT) {
 +      if (mode == COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT) {
                if (sgen_workers_have_idle_work ()) {
 +                      /*
 +                       * We force the finish of the worker with the new object ops context
 +                       * which can also do copying. We need to have finished pinning.
 +                       */
                        sgen_workers_start_all_workers (object_ops, NULL);
                        sgen_workers_join ();
                }
  
        sgen_client_collecting_major_3 (&fin_ready_queue, &critical_fin_queue);
  
 -      /*
 -       * FIXME: is this the right context?  It doesn't seem to contain a copy function
 -       * unless we're concurrent.
 -       */
 -      enqueue_scan_from_roots_jobs (heap_start, heap_end, object_ops, mode == COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT);
 +      enqueue_scan_from_roots_jobs (heap_start, heap_end, object_ops, FALSE);
  
        TV_GETTIME (btv);
        time_major_scan_roots += TV_ELAPSED (atv, btv);
  
 +      /*
 +       * We start the concurrent worker after pinning and after we scanned the roots
 +       * in order to make sure that the worker does not finish before handling all
 +       * the roots.
 +       */
 +      if (mode == COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT) {
 +              if (precleaning_enabled) {
 +                      ScanJob *sj;
 +                      /* Mod union preclean job */
 +                      sj = (ScanJob*)sgen_thread_pool_job_alloc ("preclean mod union cardtable", job_mod_union_preclean, sizeof (ScanJob));
 +                      sj->ops = object_ops;
 +                      sgen_workers_start_all_workers (object_ops, &sj->job);
 +              } else {
 +                      sgen_workers_start_all_workers (object_ops, NULL);
 +              }
 +              gray_queue_enable_redirect (WORKERS_DISTRIBUTE_GRAY_QUEUE);
 +      }
 +
        if (mode == COPY_OR_MARK_FROM_ROOTS_FINISH_CONCURRENT) {
                ScanJob *sj;
  
@@@ -1863,6 -1839,11 +1852,6 @@@ static voi
  major_finish_copy_or_mark (CopyOrMarkFromRootsMode mode)
  {
        if (mode == COPY_OR_MARK_FROM_ROOTS_START_CONCURRENT) {
 -              /*
 -               * Prepare the pin queue for the next collection.  Since pinning runs on the worker
 -               * threads we must wait for the jobs to finish before we can reset it.
 -               */
 -              sgen_workers_wait_for_jobs_finished ();
                sgen_finish_pinning ();
  
                sgen_pin_stats_reset ();
index a0bff286fa3236e19464d2e6225f468c4b49e8f3,15ccf336df6f9eddb4d909ad0b448a54c62793eb..ad2bb6fe272a44cbf08ce80ac65da5dbd177a0c7
@@@ -4,18 -4,7 +4,7 @@@
   *
   * Copyright (C) 2014 Xamarin Inc
   *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
-  * License 2.0 as published by the Free Software Foundation;
-  *
-  * This library is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  * Library General Public License for more details.
-  *
-  * You should have received a copy of the GNU Library General Public
-  * License 2.0 along with this library; if not, write to the Free
-  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  /*
@@@ -234,7 -223,7 +223,7 @@@ SCAN_OBJECT_FUNCTION_NAME (GCObject *fu
                                COPY_OR_MARK_FUNCTION_NAME ((ptr), __old, queue); \
                        }                                               \
                } else {                                                \
 -                      if (G_UNLIKELY (sgen_ptr_in_nursery (__old) && !sgen_ptr_in_nursery ((ptr)))) \
 +                      if (G_UNLIKELY (sgen_ptr_in_nursery (__old) && !sgen_ptr_in_nursery ((ptr)) && !sgen_cement_is_forced (__old))) \
                                mark_mod_union_card ((full_object), (void**)(ptr), __old); \
                        }                                               \
                } while (0)
                        PREFETCH_READ (__old);                  \
                        COPY_OR_MARK_FUNCTION_NAME ((ptr), __old, queue); \
                } else {                                                \
 -                      if (G_UNLIKELY (sgen_ptr_in_nursery (__old) && !sgen_ptr_in_nursery ((ptr)))) \
 +                      if (G_UNLIKELY (sgen_ptr_in_nursery (__old) && !sgen_ptr_in_nursery ((ptr)) && !sgen_cement_is_forced (__old))) \
                                mark_mod_union_card ((full_object), (void**)(ptr), __old); \
                        }                                               \
                } while (0)
diff --combined mono/sgen/sgen-pinning.c
index 4ed5d0a6b5b879bdc0788d1b0b4ac50f0a0973b6,b3588117c2823484218902a3758452cfa8b7ea8e..eedd1f0343a93e720cac0838ec29ff70e8bd773e
@@@ -5,18 -5,7 +5,7 @@@
   * Copyright 2003-2010 Novell, Inc.
   * Copyright (C) 2012 Xamarin Inc
   *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
-  * License 2.0 as published by the Free Software Foundation;
-  *
-  * This library is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  * Library General Public License for more details.
-  *
-  * You should have received a copy of the GNU Library General Public
-  * License 2.0 along with this library; if not, write to the Free
-  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  #include "config.h"
@@@ -182,7 -171,6 +171,7 @@@ typedef struct _CementHashEntry CementH
  struct _CementHashEntry {
        GCObject *obj;
        unsigned int count;
 +      gboolean forced; /* if it should stay cemented after the finishing pause */
  };
  
  static CementHashEntry cement_hash [SGEN_CEMENT_HASH_SIZE];
@@@ -198,70 -186,10 +187,70 @@@ sgen_cement_init (gboolean enabled
  void
  sgen_cement_reset (void)
  {
 -      memset (cement_hash, 0, sizeof (cement_hash));
 +      int i;
 +      for (i = 0; i < SGEN_CEMENT_HASH_SIZE; i++) {
 +              if (cement_hash [i].forced) {
 +                      cement_hash [i].forced = FALSE;
 +              } else {
 +                      cement_hash [i].obj = NULL;
 +                      cement_hash [i].count = 0;
 +              }
 +      }
        binary_protocol_cement_reset ();
  }
  
 +
 +/*
 + * The pin_queue should be full and sorted, without entries from the cemented
 + * objects. We traverse the cement hash and check if each object is pinned in
 + * the pin_queue (the pin_queue contains entries between obj and obj+obj_len)
 + */
 +void
 +sgen_cement_force_pinned (void)
 +{
 +      int i;
 +
 +      if (!cement_enabled)
 +              return;
 +
 +      for (i = 0; i < SGEN_CEMENT_HASH_SIZE; i++) {
 +              GCObject *obj = cement_hash [i].obj;
 +              size_t index;
 +              if (!obj)
 +                      continue;
 +              if (cement_hash [i].count < SGEN_CEMENT_THRESHOLD)
 +                      continue;
 +              SGEN_ASSERT (0, !cement_hash [i].forced, "Why do we have a forced cemented object before forcing ?");
 +
 +              /* Returns the index of the target or of the first element greater than it */
 +              index = sgen_pointer_queue_search (&pin_queue, obj);
 +              if (index == pin_queue.next_slot)
 +                      continue;
 +              SGEN_ASSERT (0, pin_queue.data [index] >= (gpointer)obj, "Binary search should return a pointer greater than the search target");
 +              if (pin_queue.data [index] < (gpointer)((char*)obj + sgen_safe_object_get_size (obj)))
 +                      cement_hash [i].forced = TRUE;
 +      }
 +}
 +
 +gboolean
 +sgen_cement_is_forced (GCObject *obj)
 +{
 +      guint hv = sgen_aligned_addr_hash (obj);
 +      int i = SGEN_CEMENT_HASH (hv);
 +
 +      SGEN_ASSERT (5, sgen_ptr_in_nursery (obj), "Looking up cementing for non-nursery objects makes no sense");
 +
 +      if (!cement_enabled)
 +              return FALSE;
 +
 +      if (!cement_hash [i].obj)
 +              return FALSE;
 +      if (cement_hash [i].obj != obj)
 +              return FALSE;
 +
 +      return cement_hash [i].forced;
 +}
 +
  gboolean
  sgen_cement_lookup (GCObject *obj)
  {
diff --combined mono/sgen/sgen-pinning.h
index 50d0f966ac046cba52c326989a1d77c492843f0a,568ac946199fabd05887feb8463bd7702b0dc9f2..00eb20dd819830f40a45a620981e812426673df2
@@@ -4,18 -4,7 +4,7 @@@
   * Copyright 2011 Xamarin Inc (http://www.xamarin.com)
   * Copyright (C) 2012 Xamarin Inc
   *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
-  * License 2.0 as published by the Free Software Foundation;
-  *
-  * This library is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  * Library General Public License for more details.
-  *
-  * You should have received a copy of the GNU Library General Public
-  * License 2.0 along with this library; if not, write to the Free
-  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  #ifndef __MONO_SGEN_PINNING_H__
  #define __MONO_SGEN_PINNING_H__
@@@ -56,8 -45,6 +45,8 @@@ void sgen_pin_stats_reset (void)
  
  void sgen_cement_init (gboolean enabled);
  void sgen_cement_reset (void);
 +void sgen_cement_force_pinned (void);
 +gboolean sgen_cement_is_forced (GCObject *obj);
  gboolean sgen_cement_lookup (GCObject *obj);
  gboolean sgen_cement_lookup_or_register (GCObject *obj);
  void sgen_pin_cemented_objects (void);
index 3371d2bfab736b19cb852957758f234d7dc0617d,d3738f661fe123853190948014a342d7efbd33ed..f1664f6a23fcb7fd727fe533a45cea606d00134b
@@@ -3,18 -3,7 +3,7 @@@
   *
   * Copyright (C) 2015 Xamarin Inc
   *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
-  * License 2.0 as published by the Free Software Foundation;
-  *
-  * This library is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  * Library General Public License for more details.
-  *
-  * You should have received a copy of the GNU Library General Public
-  * License 2.0 along with this library; if not, write to the Free
-  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  #include "config.h"
@@@ -41,9 -30,6 +30,9 @@@ static SgenThreadPoolThreadInitFunc thr
  static SgenThreadPoolIdleJobFunc idle_job_func;
  static SgenThreadPoolContinueIdleJobFunc continue_idle_job_func;
  
 +static volatile gboolean threadpool_shutdown;
 +static volatile gboolean thread_finished;
 +
  enum {
        STATE_WAITING,
        STATE_IN_PROGRESS,
@@@ -112,7 -98,7 +101,7 @@@ thread_func (void *thread_data
                gboolean do_idle = continue_idle_job ();
                SgenThreadPoolJob *job = get_job_and_set_in_progress ();
  
 -              if (!job && !do_idle) {
 +              if (!job && !do_idle && !threadpool_shutdown) {
                        /*
                         * pthread_cond_wait() can return successfully despite the condition
                         * not being signalled, so we have to run this in a loop until we
                         * have to broadcast.
                         */
                        mono_os_cond_signal (&done_cond);
 -              } else {
 -                      SGEN_ASSERT (0, do_idle, "Why did we unlock if we still have to wait for idle?");
 +              } else if (do_idle) {
                        SGEN_ASSERT (0, idle_job_func, "Why do we have idle work when there's no idle job function?");
                        do {
                                idle_job_func (thread_data);
  
                        if (!do_idle)
                                mono_os_cond_signal (&done_cond);
 +              } else {
 +                      SGEN_ASSERT (0, threadpool_shutdown, "Why did we unlock if no jobs and not shutting down?");
 +                      mono_os_mutex_lock (&lock);
 +                      thread_finished = TRUE;
 +                      mono_os_cond_signal (&done_cond);
 +                      mono_os_mutex_unlock (&lock);
 +                      return 0;
                }
        }
  
@@@ -177,24 -157,6 +166,24 @@@ sgen_thread_pool_init (int num_threads
        mono_native_thread_create (&thread, thread_func, thread_datas ? thread_datas [0] : NULL);
  }
  
 +void
 +sgen_thread_pool_shutdown (void)
 +{
 +      if (!thread)
 +              return;
 +
 +      mono_os_mutex_lock (&lock);
 +      threadpool_shutdown = TRUE;
 +      mono_os_cond_signal (&work_cond);
 +      while (!thread_finished)
 +              mono_os_cond_wait (&done_cond, &lock);
 +      mono_os_mutex_unlock (&lock);
 +
 +      mono_os_mutex_destroy (&lock);
 +      mono_os_cond_destroy (&work_cond);
 +      mono_os_cond_destroy (&done_cond);
 +}
 +
  SgenThreadPoolJob*
  sgen_thread_pool_job_alloc (const char *name, SgenThreadPoolJobFunc func, size_t size)
  {
index 6e227521a3f6a0932f8fc2ff398abc726078808c,b9d56e928c7419e7da956e3de68fa294b0b08d31..339526ca59876dac1ca4422a818e67421d68ee47
@@@ -3,18 -3,7 +3,7 @@@
   *
   * Copyright (C) 2015 Xamarin Inc
   *
-  * This library is free software; you can redistribute it and/or
-  * modify it under the terms of the GNU Library General Public
-  * License 2.0 as published by the Free Software Foundation;
-  *
-  * This library is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  * Library General Public License for more details.
-  *
-  * You should have received a copy of the GNU Library General Public
-  * License 2.0 along with this library; if not, write to the Free
-  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
   */
  
  #ifndef __MONO_SGEN_THREAD_POOL_H__
@@@ -37,8 -26,6 +26,8 @@@ typedef gboolean (*SgenThreadPoolContin
  
  void sgen_thread_pool_init (int num_threads, SgenThreadPoolThreadInitFunc init_func, SgenThreadPoolIdleJobFunc idle_func, SgenThreadPoolContinueIdleJobFunc continue_idle_func, void **thread_datas);
  
 +void sgen_thread_pool_shutdown (void);
 +
  SgenThreadPoolJob* sgen_thread_pool_job_alloc (const char *name, SgenThreadPoolJobFunc func, size_t size);
  /* This only needs to be called on jobs that are not enqueued. */
  void sgen_thread_pool_job_free (SgenThreadPoolJob *job);
index 358be81312cc452d0caa25fcd034069da5baa168,80a294566dfec3e5f4357d1c142976badb608f22..ae52220e335db404bdfe5ff59d2c6d0aa701d702
@@@ -6,24 -6,7 +6,7 @@@
  //
  // Copyright (C) 2008 Novell, Inc (http://www.novell.com)
  //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- // 
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- // 
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
  //
  using System;
  using System.IO;
@@@ -33,7 -16,6 +16,7 @@@ using System.Collections.Generic
  using System.Globalization;
  using System.Xml;
  using System.Text.RegularExpressions;
 +using Mono.Unix.Native;
  
  //
  // This is a simple test runner with support for parallel execution
@@@ -269,13 -251,6 +252,13 @@@ public class TestRunne
                                                        timedout.Add (data);
                                                }
  
 +                                              // Force the process to print a thread dump
 +                                              try {
 +                                                      Syscall.kill (p.Id, Signum.SIGQUIT);
 +                                                      Thread.Sleep (1000);
 +                                              } catch {
 +                                              }
 +
                                                output.Write ("timed out");
  
                                                p.Kill ();