Merge pull request #2801 from BrzVlad/feature-conc-cementing
authorVlad Brezae <brezaevlad@gmail.com>
Tue, 29 Mar 2016 17:45:10 +0000 (00:45 +0700)
committerVlad Brezae <brezaevlad@gmail.com>
Tue, 29 Mar 2016 17:45:10 +0000 (00:45 +0700)
[sgen] Cementing for the finishing pause

32 files changed:
external/referencesource
mcs/build/gensources.sh
mcs/class/System.Web/System.Web.Handlers/AssemblyResourceLoader.cs
mcs/class/System/System.Diagnostics/DefaultTraceListener.cs
mcs/class/corlib/System/Console.cs
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/object-internals.h
mono/metadata/object.c
mono/metadata/reflection.c
mono/metadata/sgen-client-mono.h
mono/metadata/sgen-new-bridge.c
mono/metadata/sgen-old-bridge.c
mono/mini/Makefile.am.in
mono/mini/aot-compiler.c
mono/mini/exceptions-amd64.c
mono/mini/exceptions-arm.c
mono/mini/exceptions-ia64.c
mono/mini/exceptions-ppc.c
mono/mini/genmdesc.c
mono/mini/image-writer.c
mono/mini/mini-arm.c
mono/mini/mini-llvm.c
mono/mini/mini-windows.c
mono/mini/unwind.c
mono/sgen/sgen-gc.c
mono/utils/mono-signal-handler.h

index df1c00441047e7cc439608aa1aa083f585f5ace0..6c6e36218c4a0b6dfb85bd27fa6746467761e8a0 160000 (submodule)
@@ -1 +1 @@
-Subproject commit df1c00441047e7cc439608aa1aa083f585f5ace0
+Subproject commit 6c6e36218c4a0b6dfb85bd27fa6746467761e8a0
index 2eb4995bdd80c6569867178350c70fdaad71a2b6..14a0a01db59d07b4503b9a5d1ae8882e25442524 100644 (file)
@@ -43,7 +43,7 @@ sort -u $outfile.inc > $outfile.inc_s
 rm -f $outfile.inc
 
 
-if test -n "$excfile"; then
+if test -n "$excfile" -a -f "$excfile"; then
     process_includes $excfile $outfile.exc
 fi
 
index a8cd2f842cb2d887242b5e8292085c3e6410e5e2..7f59b52e22b47f90653406803db3f8ef8acc6c08 100644 (file)
@@ -79,7 +79,9 @@ namespace System.Web.Handlers
                                        if (!hashAlg.CanReuseTransform) {
                                                canReuseHashAlg = false;
                                                hashAlg = null;
+                                               return null;
                                        }
+                                       hashAlg.Key = MachineKeySectionUtils.GetValidationKey (mks);
                                }
 
                                if (hashAlg != null)
index 2bf4cab23c6e5641bcf5c351a09c2c7444058b10..fb31ace627b679a46f3b9eece4154858108a0c14 100644 (file)
@@ -255,10 +255,10 @@ namespace System.Diagnostics {
                                WritePrefix ();
                        }
 
-                       WriteDebugString (message);
-
                        if (Debugger.IsLogging())
                                Debugger.Log (0, null, message);
+                       else
+                               WriteDebugString (message);
 
                        WriteLogFile (message, LogFileName);
                }
index aee50509f8f299f121260c1a47ac362951d5d504..f75547ab13d55a425298a88f431b885aa0462a08 100644 (file)
@@ -96,11 +96,6 @@ namespace System
 
                static Console ()
                {
-#if NET_2_1
-                       Encoding inputEncoding;
-                       Encoding outputEncoding;
-#endif
-
                        if (Environment.IsRunningOnWindows) {
                                //
                                // On Windows, follow the Windows tradition
@@ -524,7 +519,6 @@ namespace System
 
 #endif
 
-#if !NET_2_1
                // FIXME: Console should use these encodings when changed
                static Encoding inputEncoding;
                static Encoding outputEncoding;
@@ -545,6 +539,7 @@ namespace System
                        }
                }
 
+#if !NET_2_1
                public static ConsoleColor BackgroundColor {
                        get { return ConsoleDriver.BackgroundColor; }
                        set { ConsoleDriver.BackgroundColor = value; }
index d525ca0c47e971326dff7656848e39bfa406ed48..e7a0db8eb2afaa66d4a204087fd839d4f7f49421 100644 (file)
@@ -257,7 +257,6 @@ mono_runtime_init_checked (MonoDomain *domain, MonoThreadStartCB start_cb, MonoT
        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 51d6b04a1830bc292a564151b4792b20f05bee4c..1258f92b703e3005173b1123ed7fca841bccd5e5 100644 (file)
@@ -918,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);
@@ -1011,13 +1009,10 @@ void
 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);
index 801d7851be5ba77b9b9a35cf80353b53de76a7fd..49225c652e607e7176fe01dff9b5a6f23ef255bd 100644 (file)
@@ -7457,7 +7457,7 @@ mono_class_get_checked (MonoImage *image, guint32 type_token, MonoError *error)
                        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,8 +7507,11 @@ mono_type_get_checked (MonoImage *image, guint32 type_token, MonoGenericContext
        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);
@@ -8783,8 +8786,9 @@ mono_ldtoken_checked (MonoImage *image, guint32 token, MonoClass **handle_class,
 
        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;
@@ -8864,30 +8868,18 @@ mono_ldtoken_checked (MonoImage *image, guint32 token, MonoClass **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;
index 7cdd170e90c21362efb46c2441889359a96c24d5..7b2d955ce7783cf5ce9bea727fe3005ff92286f8 100644 (file)
@@ -5825,10 +5825,13 @@ mono_memberref_is_method (MonoImage *image, guint32 token)
                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;
        }
@@ -5869,12 +5872,14 @@ ves_icall_System_Reflection_Module_ResolveTypeToken (MonoImage *image, guint32 t
 
        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;
        }
 
@@ -5917,8 +5922,11 @@ ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32
        }
 
        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;
@@ -5926,7 +5934,9 @@ ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32
                }
 
                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)) {
@@ -5946,23 +5956,27 @@ ves_icall_System_Reflection_Module_ResolveMethodToken (MonoImage *image, guint32
 }
 
 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;
        }
 
@@ -5990,8 +6004,11 @@ ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32
        }
 
        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;
@@ -5999,7 +6016,9 @@ ves_icall_System_Reflection_Module_ResolveFieldToken (MonoImage *image, guint32
                }
 
                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)) {
index 56630da1eddbdf44b210c32f3670351a49b502e7..ce1acea177162f157d0e84b6bf90710a19e3a634 100644 (file)
@@ -563,7 +563,9 @@ mono_field_from_token_checked (MonoImage *image, guint32 token, MonoClass **retk
                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);
@@ -1873,7 +1875,8 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass,
        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
index 675bd2c7129bb462c89b689ef9843085a318e8c7..9b7eca1ffce41cca0086710387a74c9d10f9157c 100644 (file)
@@ -211,11 +211,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*
index a96f8cee6380ae2adf0e67ff0d5f0c2cddf019ab..d7de3b2869d8767f19b124304db61c047d21a542 100644 (file)
@@ -1837,8 +1837,11 @@ mono_metadata_parse_signature (MonoImage *image, guint32 token)
        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);
                
index 0abd946be1810387f47d20ff7af0020acda250a3..4a316f33cc1da1bf8920ab2a73cb3b729bfe394a 100644 (file)
@@ -1383,7 +1383,7 @@ MonoArray  *mono_reflection_sighelper_get_signature_field (MonoReflectionSigHelp
 MonoReflectionMarshalAsAttribute* mono_reflection_marshal_as_attribute_from_marshal_spec (MonoDomain *domain, MonoClass *klass, MonoMarshalSpec *spec, MonoError *error);
 
 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);
 
 gboolean
 mono_reflection_call_is_assignable_to (MonoClass *klass, MonoClass *oklass, MonoError *error);
index 55f5c898b3b42bb6822c399458f82575e145b07f..92a733b34bdb66ebc7420b7e075980975ab7315f 100644 (file)
@@ -6295,9 +6295,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 b40ce1bf90ecc9853074ad36b3778b99217dda83..c49153f85a1615f3052355b6c3fc37086d85f0a2 100644 (file)
@@ -13695,25 +13695,27 @@ mono_reflection_lookup_signature (MonoImage *image, MonoMethod *method, guint32
  * 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 fd36c3941eeee0e0f2bc1ba44f3b1acc3b8d97b2..d0eaa26e14e014df49aa86ef63fa043d644d896e 100644 (file)
@@ -731,7 +731,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 20fdb460adde86c416d941f2625f335516b3e1bb..a4f05e63ac954da9942505ad65d012ef0ec6d861 100644 (file)
@@ -968,7 +968,7 @@ compare_hash_entries (const HashEntry *e1, const HashEntry *e2)
 
 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 83f991d5b867ce64bd230021fe7a96381fc09158..f8437fe4810ccb775aa0858ddc85bce4e30207ce 100644 (file)
@@ -616,7 +616,7 @@ compare_hash_entries (const HashEntry *e1, const HashEntry *e2)
 
 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 2366d17c3377b188fad1685e65a70182d3a17d61..f75db695f358153a26e0a0ec5c21958fec9390f4 100755 (executable)
@@ -725,9 +725,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 +748,7 @@ llvmonly_regtests = $(fullaot_regtests) gshared.exe
 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/
index 63327ec449843186befd139b376e058bcd0e0301..b74b1107fbfb328cc1cd69361a9c3d68449052cd 100644 (file)
@@ -6676,6 +6676,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)
 {
@@ -6731,6 +6740,7 @@ 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;
@@ -6739,11 +6749,11 @@ mono_aot_split_options (const char *aot_options)
                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;
@@ -9550,7 +9560,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__)
@@ -9571,22 +9580,30 @@ compile_asm (MonoAotCompile *acfg)
 #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) {
@@ -9662,10 +9679,11 @@ compile_asm (MonoAotCompile *acfg)
                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);
index 9ec2caa843208d23fdba7cd08592078886829602..cab03fc0f2eae39d21165e0a02250a666d7cbd79 100644 (file)
@@ -417,10 +417,7 @@ get_throw_trampoline (MonoTrampInfo **info, gboolean rethrow, gboolean corlib, g
        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);
@@ -434,14 +431,14 @@ get_throw_trampoline (MonoTrampInfo **info, gboolean rethrow, gboolean corlib, g
        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));
        }
index 366e086c8b3fe5e225d67979e8ec53eccb55e0bd..4c2b5ce821db200b5cbb1765ac463eb54cde8463 100644 (file)
@@ -167,12 +167,13 @@ mono_arm_throw_exception (MonoObject *exc, mgreg_t pc, mgreg_t sp, mgreg_t *int_
 }
 
 void
-mono_arm_throw_exception_by_token (guint32 type_token, mgreg_t pc, mgreg_t sp, mgreg_t *int_regs, gdouble *fp_regs)
+mono_arm_throw_exception_by_token (guint32 ex_token_index, mgreg_t pc, mgreg_t sp, mgreg_t *int_regs, gdouble *fp_regs)
 {
+       guint32 ex_token = MONO_TOKEN_TYPE_DEF | ex_token_index;
        /* Clear thumb bit */
        pc &= ~1;
 
-       mono_arm_throw_exception ((MonoObject*)mono_exception_from_token (mono_defaults.corlib, type_token), pc, sp, int_regs, fp_regs);
+       mono_arm_throw_exception ((MonoObject*)mono_exception_from_token (mono_defaults.corlib, ex_token), pc, sp, int_regs, fp_regs);
 }
 
 void
@@ -247,9 +248,15 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm
        /* exc is already in place in r0 */
        if (corlib) {
                /* The caller ip is already in R1 */
-               if (llvm)
-                       /* Negate the ip adjustment done in mono_arm_throw_exception */
-                       ARM_ADD_REG_IMM8 (code, ARMREG_R1, ARMREG_R1, 4);
+               if (llvm) {
+                       /*
+                        * The address passed by llvm might point to before the call,
+                        * thus outside the eh range recorded by llvm. Use the return
+                        * address instead.
+                        * FIXME: Do this on more platforms.
+                        */
+                       ARM_MOV_REG_REG (code, ARMREG_R1, ARMREG_LR); /* caller ip */
+               }
        } else {
                ARM_MOV_REG_REG (code, ARMREG_R1, ARMREG_LR); /* caller ip */
        }
index 2f5324c69e7b75453b360a70c0e4a2d2305552f8..adae20f2b5f2fb83a57d67b3b08b30a77f007483 100644 (file)
@@ -242,7 +242,7 @@ throw_exception (MonoObject *exc, guint64 rethrow)
        unw_word_t ip, sp;
        int res;
 
-       if (mono_object_isinst (exc, mono_defaults.exception_class, &error)) {
+       if (mono_object_isinst_checked (exc, mono_defaults.exception_class, &error)) {
                MonoException *mono_ex = (MonoException*)exc;
                if (!rethrow) {
                        mono_ex->stack_trace = NULL;
index df828692ac3289c5ec99ffc57fe4c9255c67cede..80a579b05eb87e539e3b1c344edf636991b4c667 100644 (file)
@@ -332,7 +332,7 @@ mono_ppc_throw_exception (MonoObject *exc, unsigned long eip, unsigned long esp,
        memcpy (&ctx.regs, int_regs, sizeof (mgreg_t) * MONO_SAVED_GREGS);
        memcpy (&ctx.fregs, fp_regs, sizeof (double) * MONO_SAVED_FREGS);
 
-       if (mono_object_isinst (exc, mono_defaults.exception_class, &error)) {
+       if (mono_object_isinst_checked (exc, mono_defaults.exception_class, &error)) {
                MonoException *mono_ex = (MonoException*)exc;
                if (!rethrow) {
                        mono_ex->stack_trace = NULL;
index b996f8f83b55a07a401a31409d4f5c437228d43c..7118e19c8cec06cd9fb7588d5e7c89f2e9564706 100644 (file)
@@ -54,6 +54,14 @@ static GHashTable *template_table;
 
 #define eat_whitespace(s) while (*(s) && isspace (*(s))) s++;
 
+// Per spec isalnum() expects input in the range 0-255
+// and can misbehave if you pass in a signed char.
+static int
+isalnum_char(char c)
+{
+       return isalnum ((unsigned char)c);
+}
+
 static int
 load_file (const char *name) {
        FILE *f;
@@ -163,7 +171,7 @@ load_file (const char *name) {
                                OpDesc *tdesc;
                                p += 9;
                                tname = p;
-                               while (*p && isalnum (*p)) ++p;
+                               while (*p && isalnum_char (*p)) ++p;
                                *p++ = 0;
                                tdesc = (OpDesc *)g_hash_table_lookup (template_table, tname);
                                if (!tdesc)
@@ -181,7 +189,7 @@ load_file (const char *name) {
                                        g_error ("Duplicated name tag in template %s at '%s' at line %d in %s\n", desc->name, p, line, name);
                                p += 5;
                                tname = p;
-                               while (*p && isalnum (*p)) ++p;
+                               while (*p && isalnum_char (*p)) ++p;
                                *p++ = 0;
                                if (g_hash_table_lookup (template_table, tname))
                                        g_error ("Duplicated template %s at line %d in %s\n", tname, line, name);
@@ -220,7 +228,7 @@ init_table (void) {
 
 static void
 output_char (FILE *f, char c) {
-       if (isalnum (c))
+       if (isalnum_char (c))
                fprintf (f, "%c", c);
        else
                fprintf (f, "\\x%x\" \"", (guint8)c);
index c060fdc99a66028193f1d3efa63033a18d6a0eca..4992565ba0d162951515dee73e1177f56124f4f8 100644 (file)
@@ -1762,8 +1762,14 @@ asm_writer_emit_symbol_type (MonoImageWriter *acfg, const char *name, gboolean f
                stype = "object";
 
        asm_writer_emit_unset_mode (acfg);
+
 #if defined(TARGET_ASM_APPLE)
 
+#elif defined(TARGET_WIN32)
+       if (func)
+               fprintf (acfg->fp, "\t.def %s; .scl 2; .type 32; .endef\n", name);
+       else
+               fprintf (acfg->fp, "\t.data\n");
 #elif defined(TARGET_ARM)
        fprintf (acfg->fp, "\t.type %s,#%s\n", name, stype);
 #else
@@ -1786,7 +1792,7 @@ asm_writer_emit_local_symbol (MonoImageWriter *acfg, const char *name, const cha
 {
        asm_writer_emit_unset_mode (acfg);
 
-#ifndef TARGET_ASM_APPLE
+#if !defined(TARGET_ASM_APPLE) && !defined(TARGET_WIN32)
        fprintf (acfg->fp, "\t.local %s\n", name);
 #endif
 
@@ -1798,7 +1804,8 @@ asm_writer_emit_symbol_size (MonoImageWriter *acfg, const char *name, const char
 {
        asm_writer_emit_unset_mode (acfg);
 
-#ifndef TARGET_ASM_APPLE
+
+#if !defined(TARGET_ASM_APPLE) && !defined(TARGET_WIN32)
        fprintf (acfg->fp, "\t.size %s,%s-%s\n", name, end_label, name);
 #endif
 }
index c584d6c8b4249fc36ef7ddd76f8762dab64367e5..a7df6fc1c1b282990ba87401cf50423291a546f0 100644 (file)
@@ -6827,7 +6827,7 @@ mono_arch_emit_exceptions (MonoCompile *cfg)
                        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;
index 558db05357e9a8a6085d952badbdbb1b470e6339..f8aa239061589f9c9092ff6b246e76eecfa98591 100644 (file)
@@ -2068,6 +2068,11 @@ emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *ex
        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)
@@ -2112,7 +2117,10 @@ emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *ex
                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) {
@@ -2144,17 +2152,18 @@ emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *ex
                }
        }
 
-       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);
 
index 4bcc19b5bfb64d86d12da04f3653159639057a1f..41f12051f906929073be867a6b0076a04b8dbf11 100644 (file)
@@ -58,12 +58,14 @@ void
 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
 }
 
@@ -71,7 +73,9 @@ void
 mono_runtime_cleanup_handlers (void)
 {
 #ifndef MONO_CROSS_COMPILE
-       win32_seh_cleanup();
+       if (!mono_aot_only) {
+               win32_seh_cleanup();
+       }
 #endif
 }
 
index 82f14d7882255940ad311339fbe8c50073075a1b..ef3c65a7f225790813dfa5ab71f9a5e11b8c8ed4 100644 (file)
@@ -652,8 +652,12 @@ mono_unwind_cleanup (void)
 
                g_free (cached);
        }
-
        g_free (cached_info);
+
+       for (GSList *cursor = cached_info_list; cursor != NULL; cursor = cursor->next)
+               g_free (cursor->data);
+
+       g_slist_free (cached_info_list);
 }
 
 /*
@@ -708,10 +712,10 @@ mono_cache_unwind_info (guint8 *unwind_info, guint32 unwind_info_len)
 
                mono_memory_barrier ();
 
-               cached_info = new_table;
-
                cached_info_list = g_slist_prepend (cached_info_list, cached_info);
 
+               cached_info = new_table;
+
                cached_info_size *= 2;
        }
 
index 1dfa1d18ea11c0226e0a9c59a2505b42c7ad5582..2274febcb108a57359ff380aec845c0554feb08f 100644 (file)
@@ -1169,7 +1169,7 @@ finish_gray_stack (int generation, ScanCopyContext ctx)
        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 +1561,7 @@ collect_nursery (SgenGrayQueue *unpin_queue, gboolean finish_up_concurrent_mark)
 
        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));
@@ -1571,7 +1571,7 @@ collect_nursery (SgenGrayQueue *unpin_queue, gboolean finish_up_concurrent_mark)
        /* 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 ();
 
@@ -1612,7 +1612,7 @@ collect_nursery (SgenGrayQueue *unpin_queue, gboolean finish_up_concurrent_mark)
        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 ();
@@ -1789,7 +1789,7 @@ major_copy_or_mark_from_roots (size_t *old_next_pin_slot, CopyOrMarkFromRootsMod
 
        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 ();
index fbe798eeb0e6321667023429bfc88b4cb65bb1ce..94335964cd08a58b4c50f791f171ef2b1ffe50fd 100644 (file)
@@ -9,10 +9,53 @@
 
 #include "config.h"
 
-#ifdef ENABLE_EXTENSION_MODULE
-#include "../../../mono-extensions/mono/utils/mono-signal-handler.h"
+/*
+ * When a signal is delivered to a thread on a Krait Android device
+ * that's in the middle of skipping over an "IT" block, such as this
+ * one:
+ *
+ * 0x40184ef0 <dlfree+1308>:   ldr     r1, [r3, #0]
+ * 0x40184ef2 <dlfree+1310>:   add.w   r5, r12, r2, lsl #3
+ * 0x40184ef6 <dlfree+1314>:   lsls.w  r2, r0, r2
+ * 0x40184efa <dlfree+1318>:   tst     r2, r1
+ * ### this is the IT instruction
+ * 0x40184efc <dlfree+1320>:   itt     eq
+ * 0x40184efe <dlfree+1322>:   orreq   r2, r1
+ * ### signal arrives here
+ * 0x40184f00 <dlfree+1324>:   streq   r2, [r3, #0]
+ * 0x40184f02 <dlfree+1326>:   beq.n   0x40184f1a <dlfree+1350>
+ * 0x40184f04 <dlfree+1328>:   ldr     r2, [r5, #8]
+ * 0x40184f06 <dlfree+1330>:   ldr     r3, [r3, #16]
+ *
+ * then the first few (at most four, one would assume) instructions of
+ * the signal handler (!) might be skipped.  They happen to be the
+ * push of the frame pointer and return address, so once the signal
+ * handler has done its work, it returns into a SIGSEGV.
+ */
+
+#if defined (TARGET_ARM) && defined (HAVE_ARMV7) && defined (TARGET_ANDROID)
+#define KRAIT_IT_BUG_WORKAROUND        1
+#endif
+
+#ifdef KRAIT_IT_BUG_WORKAROUND
+#define MONO_SIGNAL_HANDLER_FUNC(access, name, arglist)                \
+       static void __krait_ ## name arglist;   \
+       __attribute__ ((naked)) access void                             \
+       name arglist                                                    \
+       {                                                               \
+               asm volatile (                                          \
+                             "mov r0, r0\n\t"                          \
+                             "mov r0, r0\n\t"                          \
+                             "mov r0, r0\n\t"                          \
+                             "mov r0, r0\n\t");                        \
+               asm volatile (                                          \
+                             "bx %0"                                   \
+                             : : "r" (__krait_ ## name));              \
+       }       \
+       static void __krait_ ## name arglist
 #endif
 
+
 /* Don't use this */
 #ifndef MONO_SIGNAL_HANDLER_FUNC
 #define MONO_SIGNAL_HANDLER_FUNC(access, name, arglist) access void name arglist