Merge pull request #2611 from akoeplinger/cleanup
authorAlexander Köplinger <alex.koeplinger@outlook.com>
Sat, 13 Feb 2016 11:45:56 +0000 (12:45 +0100)
committerAlexander Köplinger <alex.koeplinger@outlook.com>
Sat, 13 Feb 2016 11:45:56 +0000 (12:45 +0100)
[corlib] Remove FIXME_CORLIB_CMP section from Makefile

29 files changed:
mcs/class/corlib/Makefile
mcs/class/corlib/Test/System/StringTest.cs
mono/metadata/icall-def.h
mono/metadata/icall.c
mono/metadata/reflection-internals.h
mono/metadata/reflection.c
mono/metadata/reflection.h
mono/metadata/sgen-mono.c
mono/mini/aot-runtime.c
mono/mini/mini-llvm-cpp.cpp
mono/mini/mini-llvm-cpp.h
mono/mini/mini-llvm.c
mono/mini/mini-runtime.c
mono/mini/mini-trampolines.c
mono/mini/mini.h
mono/sgen/sgen-alloc.c
mono/sgen/sgen-conf.h
mono/sgen/sgen-gc.c
mono/sgen/sgen-gc.h
mono/sgen/sgen-los.c
mono/sgen/sgen-marksweep.c
mono/sgen/sgen-memory-governor.c
mono/sgen/sgen-memory-governor.h
mono/tests/Makefile.am
mono/tests/load-exceptions.cs
mono/tests/load-missing.il
mono/tests/process-stress-1.cs [deleted file]
mono/tests/process-stress-2.cs [deleted file]
mono/tests/process-stress-3.cs [deleted file]

index 2134836157922de20670218d16eea59a04c02d73..2540e23603143f4999cba59f4c9b11cdc42d6a09 100644 (file)
@@ -67,7 +67,7 @@ CORLIB_MONO_POSIX_REF = -r:Mono.Posix.dll
 endif
 
 # System.IO/DirectoryInfoTest.cs needs Mono.Posix
-TEST_MCS_FLAGS += -debug -nowarn:168,219,618,672 -unsafe $(CORLIB_MONO_POSIX_REF) -r:System.Core.dll \
+TEST_MCS_FLAGS += -debug -nowarn:168,219,618,672 -unsafe $(CORLIB_MONO_POSIX_REF) -r:System.Core.dll -r:System.dll \
                                 -define:MONO_DATACONVERTER_STATIC_METHODS $(TEST_RESX_RESOURCES:%=-resource:%)
 
 EXTRA_DISTFILES = \
index 7119236c8aab2bb638ec9916a2191e761088ed7c..fdcccded4ba23da27a12b25e55644f0ffb37c97d 100644 (file)
@@ -16,6 +16,10 @@ using System.Globalization;
 using System.Reflection;
 using System.Threading;
 
+#if !MOBILE
+using System.Diagnostics;
+#endif
+
 using NUnit.Framework;
 
 namespace MonoTests.System
@@ -92,19 +96,36 @@ public class StringTest
                }
        }
 
+       // Several tests in this file, to run properly, allocate 4GB objects.
+       // Obviously this creates problems on several kinds of systems, so we
+       // conservatively skip these tests unless we find a high-RAM environment.
+       // Checking RAM requires PerformanceCounter which is absent on mobile,
+       // so any test that calls this must be category MobileNotWorking.
+       static void RequireHighMemoryTestEnvironment ()
+       {
+#if MOBILE
+               Assert.Ignore("PerformanceCounter not available.")
+#else
+               if (!Environment.Is64BitProcess)
+                       Assert.Ignore("This test cannot run on a 32-bit system.");
+
+               // Require 6 GB physical RAM, for the 4GB string plus 2GB headroom
+               var pc = new PerformanceCounter ("Mono Memory", "Total Physical Memory");
+
+               if (pc.RawValue < 6L*1024L*1024L*1024L)
+                       Assert.Ignore("This machine may not have enough RAM to run this test.");
+#endif
+       }
+
        [Test] // ctor (Char, Int32)
+       [Category ("MobileNotWorking")]
        public void Constructor4_LargeString ()
        {
-               try {
-                       var x = new String ('A', int.MaxValue);
-                       if (Environment.Is64BitProcess) {
-                               Assert.AreEqual ('A', x[0]);
-                               Assert.AreEqual ('A', x[int.MaxValue - 1]);
-                       }
-                       else
-                               Assert.Fail ("Expected OutOfMemoryException.");
-               } catch (OutOfMemoryException) {
-               }
+               RequireHighMemoryTestEnvironment();
+
+               var x = new String ('A', int.MaxValue);
+               Assert.AreEqual ('A', x[0]);
+               Assert.AreEqual ('A', x[int.MaxValue - 1]);
        }
 
        [Test] // ctor (Char [], Int32, Int32)
@@ -3008,18 +3029,14 @@ public class StringTest
        }
 
        [Test]
+       [Category ("MobileNotWorking")]
        public void PadLeft_LargeString ()
        {
-               try {
-                       var x = "x".PadLeft (int.MaxValue, '-');
-                       if (Environment.Is64BitProcess) {
-                               Assert.AreEqual ('-', x[0]);
-                               Assert.AreEqual ('x', x[int.MaxValue - 1]);
-                       }
-                       else
-                               Assert.Fail ("Expected OutOfMemoryException.");
-               } catch (OutOfMemoryException) {
-               }
+               RequireHighMemoryTestEnvironment();
+
+               var x = "x".PadLeft (int.MaxValue, '-');
+               Assert.AreEqual ('-', x[0]);
+               Assert.AreEqual ('x', x[int.MaxValue - 1]);
        }
 
        [Test] // PadRight (Int32)
@@ -3064,18 +3081,14 @@ public class StringTest
        }
 
        [Test]
+       [Category ("MobileNotWorking")]
        public void PadRight_LargeString ()
        {
-               try {
-                       var x = "x".PadRight (int.MaxValue, '-');
-                       if (Environment.Is64BitProcess) {
-                               Assert.AreEqual ('x', x[0]);
-                               Assert.AreEqual ('-', x[int.MaxValue - 1]);
-                       }
-                       else
-                               Assert.Fail ("Expected OutOfMemoryException.");
-               } catch (OutOfMemoryException) {
-               }
+               RequireHighMemoryTestEnvironment();
+
+               var x = "x".PadRight (int.MaxValue, '-');
+               Assert.AreEqual ('x', x[0]);
+               Assert.AreEqual ('-', x[int.MaxValue - 1]);
        }
 
        [Test] // Remove (Int32, Int32)
index 538371bf50cf4938bd72ceefb026f1e6a48348f2..9a4aafe05979712ab971ba788ace1a40c142612f 100644 (file)
@@ -399,7 +399,7 @@ ICALL(MATH_17, "Tan", ves_icall_System_Math_Tan)
 ICALL(MATH_18, "Tanh", ves_icall_System_Math_Tanh)
 
 ICALL_TYPE(MCATTR, "System.MonoCustomAttrs", MCATTR_1)
-ICALL(MCATTR_1, "GetCustomAttributesDataInternal", mono_reflection_get_custom_attrs_data)
+ICALL(MCATTR_1, "GetCustomAttributesDataInternal", ves_icall_MonoCustomAttrs_GetCustomAttributesDataInternal)
 ICALL(MCATTR_2, "GetCustomAttributesInternal", custom_attrs_get_by_type)
 ICALL(MCATTR_3, "IsDefinedInternal", custom_attrs_defined_internal)
 
index 4c456dfaedd0f5c6d7df87a90350a68992b60d64..ebf8c2f8e16e57c21d37b44a2b90600537fc3f21 100644 (file)
@@ -7741,6 +7741,17 @@ custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
        }
 }
 
+ICALL_EXPORT MonoArray*
+ves_icall_MonoCustomAttrs_GetCustomAttributesDataInternal (MonoObject *obj)
+{
+       MonoError error;
+       MonoArray *result;
+       result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
+}
+
+
 ICALL_EXPORT MonoString*
 ves_icall_Mono_Runtime_GetDisplayName (void)
 {
index 9ff3b451281e4940dbc2b47e8f1917ad989e0352..f445b436172f47095af789edaddac055c35dffdb 100644 (file)
@@ -11,6 +11,9 @@
 MonoObject*
 mono_custom_attrs_get_attr_checked (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass, MonoError *error);
 
+MonoArray*
+mono_reflection_get_custom_attrs_data_checked (MonoObject *obj, MonoError *error);
+
 char*
 mono_identifier_unescape_type_name_chars (char* identifier);
 
index d568f3614d8bbd3d39c51ddd8efda9557aac6add..49cac40c7adb4c7b782d3718bd00118507e94f60 100644 (file)
@@ -10018,10 +10018,31 @@ mono_reflection_get_custom_attrs (MonoObject *obj)
  */
 MonoArray*
 mono_reflection_get_custom_attrs_data (MonoObject *obj)
+{
+       MonoError error;
+       MonoArray* result;
+       result = mono_reflection_get_custom_attrs_data_checked (obj, &error);
+       mono_error_cleanup (&error); /* FIXME new API that doesn't swallow the error */
+       return result;
+}
+
+/*
+ * mono_reflection_get_custom_attrs_data_checked:
+ * @obj: a reflection obj handle
+ * @error: set on error
+ *
+ * Returns an array of System.Reflection.CustomAttributeData,
+ * which include information about attributes reflected on
+ * types loaded using the Reflection Only methods
+ */
+MonoArray*
+mono_reflection_get_custom_attrs_data_checked (MonoObject *obj, MonoError *error)
 {
        MonoArray *result;
        MonoCustomAttrInfo *cinfo;
 
+       mono_error_init (error);
+
        cinfo = mono_reflection_get_custom_attrs_info (obj);
        if (cinfo) {
                result = mono_custom_attrs_data_construct (cinfo);
@@ -10030,6 +10051,9 @@ mono_reflection_get_custom_attrs_data (MonoObject *obj)
        } else
                result = mono_array_new (mono_domain_get (), mono_defaults.customattribute_data_class, 0);
 
+       if (mono_loader_get_last_error ())
+               mono_error_set_from_loader_error (error);
+
        return result;
 }
 
index e3e84f11e7311e200c42f3f07696affb8fbad8e4..a8bdff969b0d1ba22e7bae710de50b99775c5f40 100644 (file)
@@ -70,6 +70,7 @@ MONO_API MonoObject *mono_get_dbnull_object (MonoDomain *domain);
 
 MONO_API MonoArray*  mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass, MonoError *error);
 MONO_API MonoArray*  mono_reflection_get_custom_attrs (MonoObject *obj);
+MONO_RT_EXTERNAL_ONLY
 MONO_API MonoArray*  mono_reflection_get_custom_attrs_data (MonoObject *obj);
 MONO_API MonoArray*  mono_reflection_get_custom_attrs_blob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *porpValues, MonoArray *fields, MonoArray* fieldValues);
 
index 74ee377c49a8eb5f2275bbc7f8f2e9539398b801..8f86228dce17bece01892b1e24934f67aa7af264 100644 (file)
@@ -2738,7 +2738,7 @@ sgen_client_degraded_allocation (size_t size)
        static int last_major_gc_warned = -1;
        static int num_degraded = 0;
 
-       if (last_major_gc_warned < gc_stats.major_gc_count) {
+       if (last_major_gc_warned < (int)gc_stats.major_gc_count) {
                ++num_degraded;
                if (num_degraded == 1 || num_degraded == 3)
                        mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "Warning: Degraded allocation.  Consider increasing nursery-size if the warning persists.");
index 5248748953ad7c2bb04e7673b673a759d4cf3d03..b082a6e3b0f2f7b0ed66b398e7e2d495020f6cbf 100644 (file)
@@ -4599,7 +4599,7 @@ mono_aot_patch_plt_entry (guint8 *code, guint8 *plt_entry, gpointer *got, mgreg_
  * Returns NULL if the something cannot be loaded.
  */
 gpointer
-mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code)
+mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code, MonoError *error)
 {
 #ifdef MONO_ARCH_AOT_SUPPORTED
        guint8 *p, *target, *plt_entry;
@@ -4607,9 +4607,10 @@ mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code
        MonoAotModule *module = (MonoAotModule*)aot_module;
        gboolean res, no_ftnptr = FALSE;
        MonoMemPool *mp;
-       MonoError error;
        gboolean using_gsharedvt = FALSE;
 
+       mono_error_init (error);
+
        //printf ("DYN: %p %d\n", aot_module, plt_info_offset);
 
        p = &module->blob [plt_info_offset];
@@ -4636,12 +4637,14 @@ mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code
         */
        if (mono_aot_only && ji.type == MONO_PATCH_INFO_METHOD && !ji.data.method->is_generic && !mono_method_check_context_used (ji.data.method) && !(ji.data.method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) &&
                !mono_method_needs_static_rgctx_invoke (ji.data.method, FALSE) && !using_gsharedvt) {
-               target = (guint8 *)mono_jit_compile_method (ji.data.method, &error);
-               if (!mono_error_ok (&error))
-                       mono_error_raise_exception (&error);
+               target = (guint8 *)mono_jit_compile_method (ji.data.method, error);
+               if (!mono_error_ok (error))
+                       return NULL;
                no_ftnptr = TRUE;
        } else {
-               target = (guint8 *)mono_resolve_patch_target (NULL, mono_domain_get (), NULL, &ji, TRUE);
+               target = (guint8 *)mono_resolve_patch_target_checked (NULL, mono_domain_get (), NULL, &ji, TRUE, error);
+               if (!mono_error_ok (error))
+                       return NULL;
        }
 
        /*
@@ -5728,7 +5731,7 @@ mono_aot_get_plt_entry (guint8 *code)
 }
 
 gpointer
-mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code)
+mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code, MonoError *error)
 {
        return NULL;
 }
index cb5ddd33e79032ea2a81781d811f6df9ef68e754..6fab934f479b6d7503dffc9e043e367814bc9db2 100644 (file)
@@ -28,6 +28,7 @@
 #include <llvm/IR/Function.h>
 #include <llvm/IR/IRBuilder.h>
 #include <llvm/IR/Module.h>
+#include <llvm/IR/DIBuilder.h>
 
 #include "mini-llvm-cpp.h"
 
@@ -216,3 +217,11 @@ mono_llvm_set_call_preserveall_cc (LLVMValueRef func)
 {
        unwrap<CallInst>(func)->setCallingConv (CallingConv::PreserveAll);
 }
+
+void
+mono_llvm_create_di_compile_unit (LLVMModuleRef module)
+{
+       DIBuilder d(*unwrap(module));
+
+       d.createCompileUnit (0, "X", "Y", "Z", false, "", 0, "", DIBuilder::DebugEmissionKind::FullDebug, true);
+}
index 78bccd07ff9422a5adcc1ddc75af0343f5a84a8c..9e551e2557d8ace03612505abb36b9c4f2c2310f 100644 (file)
@@ -111,6 +111,9 @@ mono_llvm_set_unhandled_exception_handler (void);
 void
 default_mono_llvm_unhandled_exception (void);
 
+void
+mono_llvm_create_di_compile_unit (LLVMModuleRef module);
+
 G_END_DECLS
 
 #endif /* __MONO_MINI_LLVM_CPP_H__ */  
index 3484ed3faecd954d4e87bd83f8e16699f43d47a8..ae0767d176978ff9c286055cca1c9e96de665d47 100644 (file)
@@ -7999,6 +7999,8 @@ mono_llvm_emit_aot_module (const char *filename, const char *cu_name)
        emit_dbg_info (&aot_module, filename, cu_name);
        emit_aot_file_info (&aot_module);
 
+       mono_llvm_create_di_compile_unit (aot_module.lmodule);
+
        /*
         * Replace GOT entries for directly callable methods with the methods themselves.
         * It would be easier to implement this by predefining all methods before compiling
index 52aaacbdd551f022f7159f1456e5e8ccd9523ba8..170cc65e7bd98d7bab78a20e6b21c046a19554cf 100644 (file)
@@ -1355,11 +1355,13 @@ mono_patch_info_equal (gconstpointer ka, gconstpointer kb)
 }
 
 gpointer
-mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *patch_info, gboolean run_cctors)
+mono_resolve_patch_target_checked (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *patch_info, gboolean run_cctors, MonoError *error)
 {
        unsigned char *ip = patch_info->ip.i + code;
        gconstpointer target = NULL;
 
+       mono_error_init (error);
+
        switch (patch_info->type) {
        case MONO_PATCH_INFO_BB:
                /*
@@ -1572,29 +1574,27 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
        case MONO_PATCH_INFO_TYPE_FROM_HANDLE: {
                gpointer handle;
                MonoClass *handle_class;
-               MonoError error;
 
                handle = mono_ldtoken_checked (patch_info->data.token->image,
-                                                          patch_info->data.token->token, &handle_class, patch_info->data.token->has_context ? &patch_info->data.token->context : NULL, &error);
-               if (!mono_error_ok (&error))
-                       g_error ("Could not patch ldtoken due to %s", mono_error_get_message (&error));
+                                                          patch_info->data.token->token, &handle_class, patch_info->data.token->has_context ? &patch_info->data.token->context : NULL, error);
+               if (!mono_error_ok (error))
+                       g_error ("Could not patch ldtoken due to %s", mono_error_get_message (error));
                mono_class_init (handle_class);
                mono_class_init (mono_class_from_mono_type ((MonoType *)handle));
 
-               target = mono_type_get_object_checked (domain, (MonoType *)handle, &error);
-               mono_error_raise_exception (&error);
-
+               target = mono_type_get_object_checked (domain, (MonoType *)handle, error);
+               if (!mono_error_ok (error))
+                       return NULL;
                break;
        }
        case MONO_PATCH_INFO_LDTOKEN: {
                gpointer handle;
                MonoClass *handle_class;
-               MonoError error;
 
                handle = mono_ldtoken_checked (patch_info->data.token->image,
-                                                          patch_info->data.token->token, &handle_class, patch_info->data.token->has_context ? &patch_info->data.token->context : NULL, &error);
-               if (!mono_error_ok (&error))
-                       g_error ("Could not patch ldtoken due to %s", mono_error_get_message (&error));
+                                                          patch_info->data.token->token, &handle_class, patch_info->data.token->has_context ? &patch_info->data.token->context : NULL, error);
+               if (!mono_error_ok (error))
+                       g_error ("Could not patch ldtoken due to %s", mono_error_get_message (error));
                mono_class_init (handle_class);
 
                target = handle;
@@ -1612,8 +1612,10 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                        if (run_cctors) {
                                target = mono_lookup_pinvoke_call (patch_info->data.method, &exc_class, &exc_arg);
                                if (!target) {
-                                       if (mono_aot_only)
-                                               mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
+                                       if (mono_aot_only) {
+                                               mono_error_set_exception_instance (error, mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
+                                               return NULL;
+                                       }
                                        g_error ("Unable to resolve pinvoke method '%s' Re-run with MONO_LOG_LEVEL=debug for more information.\n", mono_method_full_name (patch_info->data.method, TRUE));
                                }
                        } else {
@@ -1728,6 +1730,17 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
        return (gpointer)target;
 }
 
+gpointer
+mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *patch_info, gboolean run_cctors)
+{
+       MonoError error;
+       gpointer res;
+
+       res = mono_resolve_patch_target_checked (method, domain, code, patch_info, run_cctors, &error);
+       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       return res;
+}
+
 void
 mini_init_gsctx (MonoDomain *domain, MonoMemPool *mp, MonoGenericContext *context, MonoGenericSharingContext *gsctx)
 {
index a28fd9168d38616ba856829ab4f7987fbee9db3a..a624f37d37e1aa1a857c73f886feaeee657cbca4 100644 (file)
@@ -1006,11 +1006,16 @@ mono_aot_plt_trampoline (mgreg_t *regs, guint8 *code, guint8 *aot_module,
 {
        guint32 plt_info_offset = mono_aot_get_plt_info_offset (regs, code);
        gpointer res;
+       MonoError error;
 
        trampoline_calls ++;
 
-       res = mono_aot_plt_resolve (aot_module, plt_info_offset, code);
+       res = mono_aot_plt_resolve (aot_module, plt_info_offset, code, &error);
        if (!res) {
+               if (!mono_error_ok (&error)) {
+                       mono_error_set_pending_exception (&error);
+                       return NULL;
+               }
                if (mono_loader_get_last_error ()) {
                        MonoError error;
 
index 81ef032a467a828e45969b030b7a06130135b251..1b1c728f248b36ad128429b235aa9607940e4754 100644 (file)
@@ -2324,6 +2324,7 @@ guint     mono_patch_info_hash (gconstpointer data);
 gint      mono_patch_info_equal (gconstpointer ka, gconstpointer kb);
 MonoJumpInfo *mono_patch_info_list_prepend  (MonoJumpInfo *list, int ip, MonoJumpInfoType type, gconstpointer target);
 gpointer  mono_resolve_patch_target         (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *patch_info, gboolean run_cctors) MONO_LLVM_INTERNAL;
+gpointer  mono_resolve_patch_target_checked (MonoMethod *method, MonoDomain *domain, guint8 *code, MonoJumpInfo *patch_info, gboolean run_cctors, MonoError *error) MONO_LLVM_INTERNAL;
 gpointer  mono_jit_find_compiled_method_with_jit_info (MonoDomain *domain, MonoMethod *method, MonoJitInfo **ji);
 gpointer  mono_jit_find_compiled_method     (MonoDomain *domain, MonoMethod *method);
 gpointer  mono_jit_compile_method           (MonoMethod *method, MonoError *error);
@@ -2438,7 +2439,7 @@ guint32   mono_aot_get_plt_info_offset      (mgreg_t *regs, guint8 *code);
 gboolean  mono_aot_get_cached_class_info    (MonoClass *klass, MonoCachedClassInfo *res);
 gboolean  mono_aot_get_class_from_name      (MonoImage *image, const char *name_space, const char *name, MonoClass **klass);
 MonoJitInfo* mono_aot_find_jit_info         (MonoDomain *domain, MonoImage *image, gpointer addr);
-gpointer mono_aot_plt_resolve               (gpointer aot_module, guint32 plt_info_offset, guint8 *code);
+gpointer mono_aot_plt_resolve               (gpointer aot_module, guint32 plt_info_offset, guint8 *code, MonoError *error);
 void     mono_aot_patch_plt_entry           (guint8 *code, guint8 *plt_entry, gpointer *got, mgreg_t *regs, guint8 *addr);
 gpointer mono_aot_get_method_from_vt_slot   (MonoDomain *domain, MonoVTable *vtable, int slot);
 gpointer mono_aot_create_specific_trampoline   (MonoImage *image, gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len);
index 349eff5401457757c9757591a398a275d7990aab..2c69c7d932f24a5109cbc92e289676dcb2fc86ca 100644 (file)
@@ -101,7 +101,7 @@ alloc_degraded (GCVTable vtable, size_t size, gboolean for_mature)
        if (!for_mature) {
                sgen_client_degraded_allocation (size);
                SGEN_ATOMIC_ADD_P (degraded_mode, size);
-               sgen_ensure_free_space (size);
+               sgen_ensure_free_space (size, GENERATION_OLD);
        } else {
                if (sgen_need_major_collection (size))
                        sgen_perform_collection (size, GENERATION_OLD, "mature allocation failure", !for_mature);
@@ -271,7 +271,7 @@ sgen_alloc_obj_nolock (GCVTable vtable, size_t size)
                                         * always loop we will loop endlessly in the case of
                                         * OOM).
                                         */
-                                       sgen_ensure_free_space (real_size);
+                                       sgen_ensure_free_space (real_size, GENERATION_NURSERY);
                                        if (!degraded_mode)
                                                p = (void **)sgen_nursery_alloc (size);
                                }
@@ -288,7 +288,7 @@ sgen_alloc_obj_nolock (GCVTable vtable, size_t size)
                                p = (void **)sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
                                if (!p) {
                                        /* See comment above in similar case. */
-                                       sgen_ensure_free_space (tlab_size);
+                                       sgen_ensure_free_space (tlab_size, GENERATION_NURSERY);
                                        if (!degraded_mode)
                                                p = (void **)sgen_nursery_alloc_range (tlab_size, size, &alloc_size);
                                }
index 5a0e871e22fecc779083f53fea42bc4945f6849a..11a8998478e765e8083e337c57a9f48c6fb7a9ee 100644 (file)
@@ -190,12 +190,6 @@ typedef mword SgenDescriptor;
  */
 #define SGEN_DEFAULT_ALLOWANCE_HEAP_SIZE_RATIO 0.33
 
-/*
- * How much more we allow the heap to grow, relative to the allowance, while doing
- * a concurrent collection, before forcing its finish.
- */
-#define SGEN_DEFAULT_CONCURRENT_HEAP_ALLOWANCE_RATIO 0.25
-
 /*
  * Default ratio of memory we want to release in a major collection in relation to the the current heap size.
  *
index 34da3f15ab339c4b84d83585d4d265832fdc1c24..1956af35772abe1839f3fc8736377b71161fbf87 100644 (file)
@@ -1974,6 +1974,7 @@ major_finish_collection (const char *reason, size_t old_next_pin_slot, gboolean
        time_major_fragment_creation += TV_ELAPSED (atv, btv);
 
        binary_protocol_sweep_begin (GENERATION_OLD, !major_collector.sweeps_lazily);
+       sgen_memgov_major_pre_sweep ();
 
        TV_GETTIME (atv);
        time_major_free_bigobjs += TV_ELAPSED (btv, atv);
@@ -2154,12 +2155,12 @@ major_finish_concurrent_collection (gboolean forced)
  * LOCKING: The GC lock MUST be held.
  */
 void
-sgen_ensure_free_space (size_t size)
+sgen_ensure_free_space (size_t size, int generation)
 {
        int generation_to_collect = -1;
        const char *reason = NULL;
 
-       if (size > SGEN_MAX_SMALL_OBJ_SIZE) {
+       if (generation == GENERATION_OLD) {
                if (sgen_need_major_collection (size)) {
                        reason = "LOS overflow";
                        generation_to_collect = GENERATION_OLD;
index afd5ba5dce858c2721c9a7e53d6113d2205b9c83..4b2f895d890badc5f42157ebe4009f57211ad1b4 100644 (file)
@@ -802,7 +802,7 @@ enum {
 void sgen_pin_object (GCObject *object, SgenGrayQueue *queue);
 void sgen_set_pinned_from_failed_allocation (mword objsize);
 
-void sgen_ensure_free_space (size_t size);
+void sgen_ensure_free_space (size_t size, int generation);
 void sgen_gc_collect (int generation);
 void sgen_perform_collection (size_t requested_size, int generation_to_collect, const char *reason, gboolean wait_to_finish);
 
index 8cc92e34553f5008105bcc16fdc80232c1cb595c..a89ec99fe353517580f0695f6d45e68859a18101 100644 (file)
@@ -380,7 +380,7 @@ sgen_los_alloc_large_inner (GCVTable vtable, size_t size)
        los_segment_index += size + sizeof (LOSObject);
        g_assert (los_segment_index <= LOS_SEGMENT_SIZE);
 #else
-       sgen_ensure_free_space (size);
+       sgen_ensure_free_space (size, GENERATION_OLD);
 
 #ifdef USE_MALLOC
        obj = malloc (size + sizeof (LOSObject));
index 929d86031fee406233d691cde0c4933781f1e9ad..7aaaa0221e1d900931d9f052314379a3a00271e5 100644 (file)
@@ -1401,8 +1401,8 @@ bitcount (mword d)
        int count = 0;
 
 #ifdef __GNUC__
-       if (sizeof (mword) == sizeof (unsigned long))
-               count += __builtin_popcountl (d);
+       if (sizeof (mword) == 8)
+               count += __builtin_popcountll (d);
        else
                count += __builtin_popcount (d);
 #else
index ce34f7f4a67a7d304ff038e674c01aa38651e0c5..611ae5c118f4d66b7e1eb982fd4d32048e78a20b 100644 (file)
@@ -56,6 +56,9 @@ static gboolean debug_print_allowance = FALSE;
 /* use this to tune when to do a major/minor collection */
 static mword major_collection_trigger_size;
 
+static mword major_pre_sweep_heap_size;
+static mword major_start_heap_size;
+
 static mword last_major_num_sections = 0;
 static mword last_los_memory_usage = 0;
 
@@ -73,6 +76,7 @@ static void
 sgen_memgov_calculate_minor_collection_allowance (void)
 {
        size_t new_major, new_heap_size, allowance_target, allowance;
+       size_t decrease;
 
        if (!need_calculate_minor_collection_allowance)
                return;
@@ -90,6 +94,16 @@ sgen_memgov_calculate_minor_collection_allowance (void)
 
        allowance = MAX (allowance_target, MIN_MINOR_COLLECTION_ALLOWANCE);
 
+       /*
+        * For the concurrent collector, we decrease the allowance relative to the memory
+        * growth during the M&S phase, survival rate of the collection and the allowance
+        * ratio.
+        */
+       decrease = (major_pre_sweep_heap_size - major_start_heap_size) * ((float)new_heap_size / major_pre_sweep_heap_size) * (SGEN_DEFAULT_ALLOWANCE_HEAP_SIZE_RATIO + 1);
+       if (decrease > allowance)
+               decrease = allowance;
+       allowance -= decrease;
+
        if (new_heap_size + allowance > soft_heap_limit) {
                if (new_heap_size > soft_heap_limit)
                        allowance = MIN_MINOR_COLLECTION_ALLOWANCE;
@@ -129,13 +143,14 @@ sgen_need_major_collection (mword space_needed)
                if (heap_size <= major_collection_trigger_size)
                        return FALSE; 
 
-               /* We allow the heap to grow an additional third of the allowance during a concurrent collection */
-               if ((heap_size - major_collection_trigger_size) >
-                               (major_collection_trigger_size
-                               * (SGEN_DEFAULT_ALLOWANCE_HEAP_SIZE_RATIO / (SGEN_DEFAULT_ALLOWANCE_HEAP_SIZE_RATIO + 1))
-                               * SGEN_DEFAULT_CONCURRENT_HEAP_ALLOWANCE_RATIO)) {
+               /*
+                * The more the heap grows, the more we need to decrease the allowance above,
+                * in order to have similar trigger sizes as the synchronous collector.
+                * If the heap grows so much that we would need to have a negative allowance,
+                * we force the finishing of the collection, to avoid increased memory usage.
+                */
+               if ((heap_size - major_start_heap_size) > major_start_heap_size * SGEN_DEFAULT_ALLOWANCE_HEAP_SIZE_RATIO)
                        return TRUE;
-               }
                return FALSE;
        }
 
@@ -163,13 +178,25 @@ sgen_memgov_minor_collection_end (void)
 {
 }
 
+void
+sgen_memgov_major_pre_sweep (void)
+{
+       if (sgen_concurrent_collection_in_progress ()) {
+               major_pre_sweep_heap_size = get_heap_size ();
+       } else {
+               /* We decrease the allowance only in the concurrent case */
+               major_pre_sweep_heap_size = major_start_heap_size;
+       }
+}
+
 void
 sgen_memgov_major_collection_start (void)
 {
        need_calculate_minor_collection_allowance = TRUE;
+       major_start_heap_size = get_heap_size ();
 
        if (debug_print_allowance) {
-               SGEN_LOG (0, "Starting collection with heap size %ld bytes", (long)get_heap_size ());
+               SGEN_LOG (0, "Starting collection with heap size %ld bytes", (long)major_start_heap_size);
        }
 }
 
index 0115ec6e0605e2755c4b28dc8c020b89f8ea9466..669b59734e99200ffadae2dc540a7b8137f6349c 100644 (file)
@@ -33,6 +33,7 @@ gboolean sgen_memgov_try_alloc_space (mword size, int space);
 void sgen_memgov_minor_collection_start (void);
 void sgen_memgov_minor_collection_end (void);
 
+void sgen_memgov_major_pre_sweep (void);
 void sgen_memgov_major_collection_start (void);
 void sgen_memgov_major_collection_end (gboolean forced);
 
index 6aec66bdc099a083525f98a8a184598133e0947a..169a9e24c31e9c65ee75b0595c5d4d226bad6ded 100644 (file)
@@ -1,7 +1,6 @@
 SUBDIRS = assemblyresolve gc-descriptors
 
-check-local: assemblyresolve/test/asm.dll testjit test-generic-sharing test-type-load test-cattr-type-load test-reflection-load-with-context test_platform     \
-                test-console-output test-messages test-env-options test-unhandled-exception-2 test-appdomain-unload test-process-stress rm-empty-logs
+check-local: assemblyresolve/test/asm.dll testjit test-generic-sharing test-type-load test-cattr-type-load test-reflection-load-with-context test_platform test-process-exit test-console-output test-messages test-env-options test-unhandled-exception-2 test-appdomain-unload rm-empty-logs
 check-full: test-sgen check-local
 check-parallel: compile-tests check-full
 
@@ -1409,14 +1408,6 @@ test-console-output: console-output.exe
        @diff -w console-output.exe.stdout $(srcdir)/console-output.exe.stdout.expected \
                && diff -w console-output.exe.stderr $(srcdir)/console-output.exe.stderr.expected
 
-PROCESS_STRESS_TESTS=  \
-               process-stress-1.exe    \
-               process-stress-2.exe    \
-               process-stress-3.exe
-
-test-process-stress: $(PROCESS_STRESS_TESTS) test-runner.exe
-       $(RUNTIME) ./test-runner.exe --testsuite-name $@ $(PROCESS_STRESS_TESTS)
-
 coreclr-gcstress:
        $(MAKE) -C $(mono_build_root)/acceptance-tests coreclr-gcstress
 
index cb2fc0983757332593bf06f99e62f07cbdb0ed50..97279d2fb6ddbd9e2dabf09dbb61ee5af68a174e 100644 (file)
@@ -339,6 +339,16 @@ public class Tests : LoadMissing {
                return 2;
        }
 
+       public static int test_0_reflection_on_field_with_missing_custom_attr () {
+               var t = typeof (BadOverridesDriver).Assembly.GetType ("FieldWithMissingCustomAttribute");
+               try {
+                       Console.WriteLine (t.GetFields ()[0].CustomAttributes);
+                       return 1;
+               } catch (FileNotFoundException) {
+                       return 0;
+               }
+               return 2;
+       }
 
        public static int Main () {
                return TestDriver.RunTests (typeof (Tests));
index 3f2da10c57a8f6d507acc718faf8cfb4cb179605..1ae933d277bc598f764b08c4a6f4cf3796d09daf 100644 (file)
 {\r
   .ver 0:0:0:0\r
 }\r
+.assembly extern notFoundAssembly\r
+{\r
+  .ver 0:0:0:0\r
+}\r
 \r
 .assembly 'load-missing'\r
 {\r
        .field  public class [t]Missing BrokenField\r
     .field  public static int32 WorkingField\r
 }\r
+\r
+.class public auto ansi beforefieldinit FieldWithMissingCustomAttribute\r
+{\r
+    .field     public object f\r
+    .custom    instance void class [notFoundAssembly]SomeAttribute::'.ctor'() = (01 00 00 00 ) // ....\r
+}\r
diff --git a/mono/tests/process-stress-1.cs b/mono/tests/process-stress-1.cs
deleted file mode 100644 (file)
index 97d3569..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-
-using System;
-using System.Diagnostics;
-using System.Threading;
-using System.Threading.Tasks;
-
-class Driver
-{
-       static void Main ()
-       {
-               for (int i = 0; i < 1000; ++i) {
-                       ProcessStartInfo psi = new ProcessStartInfo () {
-                               FileName = "echo",
-                               Arguments = "hello 1>/dev/null",
-                       };
-
-                       Process p = Process.Start (psi);
-
-                       ManualResetEvent mre = new ManualResetEvent (false);
-
-                       Task t = Task.Run (() => {
-                               mre.Set ();
-                               if (!p.WaitForExit (1000))
-                                       Environment.Exit (1);
-                       });
-
-                       if (!mre.WaitOne (1000))
-                               Environment.Exit (2);
-                       if (!p.WaitForExit (1000))
-                               Environment.Exit (3);
-
-                       if (!t.Wait (1000))
-                               Environment.Exit (4);
-               }
-       }
-}
diff --git a/mono/tests/process-stress-2.cs b/mono/tests/process-stress-2.cs
deleted file mode 100644 (file)
index d31e23a..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-
-using System;
-using System.Diagnostics;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-
-class Driver
-{
-       static void Main ()
-       {
-               Action<Process>[] tests = new Action<Process> [] {
-                       new Action<Process> (Test1),
-                       new Action<Process> (Test2),
-               };
-
-               ProcessStartInfo psi = new ProcessStartInfo () {
-                       FileName = "echo",
-                       Arguments = "hello",
-                       UseShellExecute = false,
-                       RedirectStandardOutput = true,
-               };
-
-               foreach (Action<Process> test in tests) {
-                       for (int i = 0; i < 500; ++i) {
-                               test (new Process () { StartInfo = psi });
-                       }
-               }
-       }
-
-       static void Test1 (Process p)
-       {
-               StringBuilder sb = new StringBuilder ();
-               ManualResetEvent mre_exit = new ManualResetEvent (false);
-               ManualResetEvent mre_output = new ManualResetEvent (false);
-
-               p.EnableRaisingEvents = true;
-               p.Exited += (s, a) => mre_exit.Set ();
-
-               p.Start ();
-
-               p.OutputDataReceived += (s, a) => {
-                       if (a.Data == null) {
-                               mre_output.Set ();
-                               return;
-                       }
-                       sb.Append (a.Data);
-               };
-
-               p.BeginOutputReadLine ();
-
-               if (!mre_exit.WaitOne (1000))
-                       Environment.Exit (1);
-               if (!mre_output.WaitOne (1000))
-                       Environment.Exit (2);
-
-               if (sb.ToString () != "hello") {
-                       Console.WriteLine ("process output = '{0}'", sb.ToString ());
-                       Environment.Exit (3);
-               }
-       }
-
-       static void Test2 (Process p)
-       {
-               StringBuilder sb = new StringBuilder ();
-               ManualResetEvent mre_output = new ManualResetEvent (false);
-
-               p.Start ();
-
-               p.OutputDataReceived += (s, a) => {
-                       if (a.Data == null) {
-                               mre_output.Set ();
-                               return;
-                       }
-
-                       sb.Append (a.Data);
-               };
-
-               p.BeginOutputReadLine ();
-
-               if (!p.WaitForExit (1000))
-                       Environment.Exit (4);
-               if (!mre_output.WaitOne (1000))
-                       Environment.Exit (5);
-
-               if (sb.ToString () != "hello") {
-                       Console.WriteLine ("process output = '{0}'", sb.ToString ());
-                       Environment.Exit (6);
-               }
-       }
-}
diff --git a/mono/tests/process-stress-3.cs b/mono/tests/process-stress-3.cs
deleted file mode 100644 (file)
index 7b45a3e..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-
-using System;
-using System.Diagnostics;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-
-class Driver
-{
-       static void Main ()
-       {
-               Action<Process>[] tests = new Action<Process> [] {
-                       new Action<Process> (Test1),
-                       new Action<Process> (Test2),
-               };
-
-               ProcessStartInfo psi = new ProcessStartInfo () {
-                       FileName = "find",
-                       Arguments = "/ -maxdepth 4",
-                       UseShellExecute = false,
-                       RedirectStandardOutput = true,
-                       RedirectStandardError = true,
-               };
-
-               foreach (Action<Process> test in tests) {
-                       for (int i = 0; i < 200; ++i) {
-                               test (new Process () { StartInfo = psi });
-                       }
-               }
-       }
-
-       static void Test1 (Process p)
-       {
-               ManualResetEvent mre_exit = new ManualResetEvent (false);
-               ManualResetEvent mre_output = new ManualResetEvent (false);
-               ManualResetEvent mre_error = new ManualResetEvent (false);
-
-               p.EnableRaisingEvents = true;
-               p.Exited += (s, a) => mre_exit.Set ();
-
-               p.Start ();
-
-               p.OutputDataReceived += (s, a) => {
-                       if (a.Data == null) {
-                               mre_output.Set ();
-                               return;
-                       }
-               };
-
-               p.ErrorDataReceived += (s, a) => {
-                       if (a.Data == null) {
-                               mre_error.Set ();
-                               return;
-                       }
-               };
-
-               p.BeginOutputReadLine ();
-               p.BeginErrorReadLine ();
-
-               if (!mre_exit.WaitOne (10000))
-                       Environment.Exit (1);
-               if (!mre_output.WaitOne (1000))
-                       Environment.Exit (2);
-               if (!mre_error.WaitOne (1000))
-                       Environment.Exit (3);
-       }
-
-       static void Test2 (Process p)
-       {
-               ManualResetEvent mre_output = new ManualResetEvent (false);
-               ManualResetEvent mre_error = new ManualResetEvent (false);
-
-               p.Start ();
-
-               p.OutputDataReceived += (s, a) => {
-                       if (a.Data == null) {
-                               mre_output.Set ();
-                               return;
-                       }
-               };
-
-               p.ErrorDataReceived += (s, a) => {
-                       if (a.Data == null) {
-                               mre_error.Set ();
-                               return;
-                       }
-               };
-
-               p.BeginOutputReadLine ();
-               p.BeginErrorReadLine ();
-
-               if (!p.WaitForExit (10000))
-                       Environment.Exit (4);
-               if (!mre_output.WaitOne (1000))
-                       Environment.Exit (5);
-               if (!mre_error.WaitOne (1000))
-                       Environment.Exit (6);
-       }
-}