diff --git a/README.md b/README.md index 609b9fa466..b061956eee 100644 --- a/README.md +++ b/README.md @@ -494,16 +494,12 @@ Directory Roadmap * `dis/` - CIL executable Disassembler - * `cli/` - Common code for the JIT and the interpreter. - * `io-layer/` - The I/O layer and system abstraction for emulating the .NET IO model. * `cil/` - Common Intermediate Representation, XML definition of the CIL bytecodes. - * `interp/` - Interpreter for CLI executables (obsolete). - * `arch/` - Architecture specific portions. * `man/` - Manual pages for the various Mono commands and programs. diff --git a/acinclude.m4 b/acinclude.m4 index 5216cd14a5..bbc2781eab 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -26,7 +26,7 @@ i?86-*-linux*|i?86-apple-darwin*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-li |amd64-*-freebsd*|i?86-*-freebsd*|ia64-*-freebsd*|arm*-*-linux*|sparc*-*-linux*|mips*-*-linux*|x86_64-apple-darwin*|aarch64*) pic_options='-fPIC' ;; -?86-pc-cygwin*|i?86-pc-cygwin*) +?86-pc-cygwin*|i?86-pc-cygwin*|i?86-pc-mingw32*) pic_options='-DDLL_EXPORT' ;; i?86-apple-darwin*|arm-apple-darwin*) diff --git a/config.h.in b/config.h.in index b8c09f6b4a..9072b2ec17 100644 --- a/config.h.in +++ b/config.h.in @@ -335,6 +335,9 @@ /* Define to 1 if you have the `getresuid' function. */ #undef HAVE_GETRESUID +/* Define to 1 if you have the `getrlimit' function. */ +#undef HAVE_GETRLIMIT + /* Define to 1 if you have the `getrusage' function. */ #undef HAVE_GETRUSAGE @@ -761,6 +764,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_SYS_POLL_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_RESOURCE_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SDT_H diff --git a/configure.REMOVED.git-id b/configure.REMOVED.git-id index 5526f189a3..b7e7022d42 100644 --- a/configure.REMOVED.git-id +++ b/configure.REMOVED.git-id @@ -1 +1 @@ -f98bd1e8bf7b203688329a408624ecaaf8192c9a \ No newline at end of file +03ca165ce83cc7c3a8c992c897eb02312b51e7b8 \ No newline at end of file diff --git a/configure.ac.REMOVED.git-id b/configure.ac.REMOVED.git-id index c4a1fd294d..48ed412c52 100644 --- a/configure.ac.REMOVED.git-id +++ b/configure.ac.REMOVED.git-id @@ -1 +1 @@ -6792b0c1cb1e40049a4610645db04eb603741561 \ No newline at end of file +5d9961ae1eab15d979b37b7a90e6507b7a79f51b \ No newline at end of file diff --git a/data/Makefile.am b/data/Makefile.am index 71cdc650fb..daf6f38a79 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -26,17 +26,8 @@ else SGENPCFILE= endif -if JIT_SUPPORTED -if INTERP_SUPPORTED -pkgconfig_DATA= mono.pc mono-2.pc mint.pc dotnet.pc dotnet35.pc wcf.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc system.web.extensions_1.0.pc \ - system.web.extensions.design_1.0.pc system.web.mvc.pc system.web.mvc2.pc system.web.mvc3.pc aspnetwebstack.pc reactive.pc xbuild12.pc $(SGENPCFILE) -else pkgconfig_DATA= mono.pc mono-2.pc dotnet.pc dotnet35.pc wcf.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc system.web.extensions_1.0.pc \ system.web.extensions.design_1.0.pc system.web.mvc.pc system.web.mvc2.pc system.web.mvc3.pc aspnetwebstack.pc reactive.pc xbuild12.pc $(SGENPCFILE) -endif -else -pkgconfig_DATA= mint.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc -endif DISTCLEANFILES= mono-2.pc mono.pc mint.pc dotnet.pc dotnet35.pc wcf.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc system.web.extensions_1.0.pc \ system.web.extensions.design_1.0.pc system.web.mvc.pc system.web.mvc2.pc system.web.mvc3.pc aspnetwebstack.pc reactive.pc $(SGENPCFILE) mono-sgen-gdb.py diff --git a/data/Makefile.in b/data/Makefile.in index 75be628ba0..49241d7b66 100644 --- a/data/Makefile.in +++ b/data/Makefile.in @@ -447,13 +447,9 @@ EXTRA_DIST = \ pkgconfigdir = $(libdir)/pkgconfig @SUPPORT_SGEN_FALSE@SGENPCFILE = @SUPPORT_SGEN_TRUE@SGENPCFILE = monosgen-2.pc -@INTERP_SUPPORTED_FALSE@@JIT_SUPPORTED_TRUE@pkgconfig_DATA = mono.pc mono-2.pc dotnet.pc dotnet35.pc wcf.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc system.web.extensions_1.0.pc \ -@INTERP_SUPPORTED_FALSE@@JIT_SUPPORTED_TRUE@ system.web.extensions.design_1.0.pc system.web.mvc.pc system.web.mvc2.pc system.web.mvc3.pc aspnetwebstack.pc reactive.pc xbuild12.pc $(SGENPCFILE) +pkgconfig_DATA = mono.pc mono-2.pc dotnet.pc dotnet35.pc wcf.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc system.web.extensions_1.0.pc \ + system.web.extensions.design_1.0.pc system.web.mvc.pc system.web.mvc2.pc system.web.mvc3.pc aspnetwebstack.pc reactive.pc xbuild12.pc $(SGENPCFILE) -@INTERP_SUPPORTED_TRUE@@JIT_SUPPORTED_TRUE@pkgconfig_DATA = mono.pc mono-2.pc mint.pc dotnet.pc dotnet35.pc wcf.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc system.web.extensions_1.0.pc \ -@INTERP_SUPPORTED_TRUE@@JIT_SUPPORTED_TRUE@ system.web.extensions.design_1.0.pc system.web.mvc.pc system.web.mvc2.pc system.web.mvc3.pc aspnetwebstack.pc reactive.pc xbuild12.pc $(SGENPCFILE) - -@JIT_SUPPORTED_FALSE@pkgconfig_DATA = mint.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc DISTCLEANFILES = mono-2.pc mono.pc mint.pc dotnet.pc dotnet35.pc wcf.pc mono-nunit.pc mono-cairo.pc mono-options.pc cecil.pc monodoc.pc mono-lineeditor.pc system.web.extensions_1.0.pc \ system.web.extensions.design_1.0.pc system.web.mvc.pc system.web.mvc2.pc system.web.mvc3.pc aspnetwebstack.pc reactive.pc $(SGENPCFILE) mono-sgen-gdb.py diff --git a/data/config.in b/data/config.in index 51cac3f0b4..b7601766e9 100644 --- a/data/config.in +++ b/data/config.in @@ -10,7 +10,7 @@ - + diff --git a/docs/deploy/mono-api-class.html b/docs/deploy/mono-api-class.html index 287cba06d0..8ae3defebf 100644 --- a/docs/deploy/mono-api-class.html +++ b/docs/deploy/mono-api-class.html @@ -125,7 +125,7 @@ mono_class_from_name_case (MonoImage *image, const char* name_space, const char

Parameters -

image:
The MonoImage where the type is looked up in
name_space:
the type namespace
name:
the type short name.
+
image:
The MonoImage where the type is looked up in
name_space:
the type namespace
name:
the type short name.
deprecated:
use the _checked variant
Remarks

Obtains a MonoClass with a given namespace and a given name which @@ -332,7 +332,7 @@ mono_class_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *c

Parameters -

image:
the image where the class resides
type_token:
the token for the class
context:
the generic context used to evaluate generic instantiations in
+
image:
the image where the class resides
type_token:
the token for the class
context:
the generic context used to evaluate generic instantiations in
deprecated:
Functions that expose MonoGenericContext are going away in mono 4.0
Returns
the MonoClass that represents type_token in image
diff --git a/eglib/acinclude.m4 b/eglib/acinclude.m4 index 5216cd14a5..bbc2781eab 100644 --- a/eglib/acinclude.m4 +++ b/eglib/acinclude.m4 @@ -26,7 +26,7 @@ i?86-*-linux*|i?86-apple-darwin*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-li |amd64-*-freebsd*|i?86-*-freebsd*|ia64-*-freebsd*|arm*-*-linux*|sparc*-*-linux*|mips*-*-linux*|x86_64-apple-darwin*|aarch64*) pic_options='-fPIC' ;; -?86-pc-cygwin*|i?86-pc-cygwin*) +?86-pc-cygwin*|i?86-pc-cygwin*|i?86-pc-mingw32*) pic_options='-DDLL_EXPORT' ;; i?86-apple-darwin*|arm-apple-darwin*) diff --git a/eglib/config.h.in b/eglib/config.h.in index 50b2eb2421..bfaf5ef218 100644 --- a/eglib/config.h.in +++ b/eglib/config.h.in @@ -12,6 +12,9 @@ /* Define to 1 if you have the `getpwuid_r' function. */ #undef HAVE_GETPWUID_R +/* Define to 1 if you have the `getrlimit' function. */ +#undef HAVE_GETRLIMIT + /* Define if you have the iconv() function and it works. */ #undef HAVE_ICONV @@ -60,6 +63,9 @@ /* Define to 1 if you have the `strtok_r' function. */ #undef HAVE_STRTOK_R +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_RESOURCE_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SELECT_H diff --git a/eglib/configure.REMOVED.git-id b/eglib/configure.REMOVED.git-id index 7c814b9dcb..27c8e4e8e6 100644 --- a/eglib/configure.REMOVED.git-id +++ b/eglib/configure.REMOVED.git-id @@ -1 +1 @@ -8efa2ac8877cc4d116d3625738612cdba7e474a4 \ No newline at end of file +f63e8c4f995b49470fb7c4bd1f34dac0e85ad20c \ No newline at end of file diff --git a/eglib/configure.ac b/eglib/configure.ac index 1ff6c42ff2..5281419c00 100644 --- a/eglib/configure.ac +++ b/eglib/configure.ac @@ -135,6 +135,7 @@ AC_CHECK_SIZEOF(void *) AC_CHECK_SIZEOF(long) AC_CHECK_SIZEOF(long long) AC_CHECK_FUNCS(strlcpy stpcpy strtok_r rewinddir vasprintf) +AC_CHECK_FUNCS(getrlimit) # # Mono currently supports 10.6, but strndup is not available prior to 10.7; avoiding @@ -179,7 +180,7 @@ if test "x$have_iso_varargs" = "xyes"; then fi AC_SUBST(G_HAVE_ISO_VARARGS) -AC_CHECK_HEADERS(getopt.h sys/select.h sys/time.h sys/wait.h pwd.h langinfo.h iconv.h localcharset.h sys/types.h) +AC_CHECK_HEADERS(getopt.h sys/select.h sys/time.h sys/wait.h pwd.h langinfo.h iconv.h localcharset.h sys/types.h sys/resource.h) AC_CHECK_HEADER(alloca.h, [HAVE_ALLOCA_H=1], [HAVE_ALLOCA_H=0]) AC_SUBST(HAVE_ALLOCA_H) diff --git a/eglib/src/glib.h b/eglib/src/glib.h index 533c84116c..d23e32a534 100644 --- a/eglib/src/glib.h +++ b/eglib/src/glib.h @@ -176,7 +176,6 @@ typedef struct _GMemChunk GMemChunk; /* * Misc. */ -#define g_atexit(func) ((void) atexit (func)) const gchar * g_getenv(const gchar *variable); gboolean g_setenv(const gchar *variable, const gchar *value, gboolean overwrite); diff --git a/eglib/src/goutput.c b/eglib/src/goutput.c index 1dc8bd6faf..9756b67a47 100644 --- a/eglib/src/goutput.c +++ b/eglib/src/goutput.c @@ -176,7 +176,7 @@ default_stderr_handler (const gchar *message) } -#elif MONOTOUCH +#elif defined(HOST_IOS) #include static int diff --git a/eglib/src/gspawn.c b/eglib/src/gspawn.c index 836e6f2aa9..449a724be9 100644 --- a/eglib/src/gspawn.c +++ b/eglib/src/gspawn.c @@ -53,6 +53,10 @@ #include #endif +#ifdef HAVE_SYS_RESOURCE_H +# include +#endif + #ifdef G_OS_WIN32 #include #include @@ -213,6 +217,23 @@ write_all (int fd, const void *vbuf, size_t n) return nwritten; } +#ifndef G_OS_WIN32 +static int +g_getdtablesize (void) +{ +#ifdef HAVE_GETRLIMIT + struct rlimit limit; + int res; + + res = getrlimit (RLIMIT_NOFILE, &limit); + g_assert (res == 0); + return limit.rlim_cur; +#else + return getdtablesize (); +#endif +} +#endif + gboolean g_spawn_command_line_sync (const gchar *command_line, gchar **standard_output, @@ -256,7 +277,7 @@ g_spawn_command_line_sync (const gchar *command_line, close (stderr_pipe [0]); dup2 (stderr_pipe [1], STDERR_FILENO); } - for (i = getdtablesize () - 1; i >= 3; i--) + for (i = g_getdtablesize () - 1; i >= 3; i--) close (i); /* G_SPAWN_SEARCH_PATH is always enabled for g_spawn_command_line_sync */ @@ -417,7 +438,7 @@ g_spawn_async_with_pipes (const gchar *working_directory, } if ((flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN) != 0) { - for (i = getdtablesize () - 1; i >= 3; i--) + for (i = g_getdtablesize () - 1; i >= 3; i--) close (i); } diff --git a/eglib/winconfig.h b/eglib/winconfig.h index fdab3ddae6..04e8d4075c 100755 --- a/eglib/winconfig.h +++ b/eglib/winconfig.h @@ -1,6 +1,10 @@ /* config.h. Generated by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ +#ifndef _MSC_VER +#include "cygconfig.h" +#else + /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 @@ -74,3 +78,4 @@ #define VERSION "0.1" #define HAVE_STRTOK_R 1 +#endif diff --git a/libgc/acinclude.m4 b/libgc/acinclude.m4 index 5216cd14a5..bbc2781eab 100644 --- a/libgc/acinclude.m4 +++ b/libgc/acinclude.m4 @@ -26,7 +26,7 @@ i?86-*-linux*|i?86-apple-darwin*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-li |amd64-*-freebsd*|i?86-*-freebsd*|ia64-*-freebsd*|arm*-*-linux*|sparc*-*-linux*|mips*-*-linux*|x86_64-apple-darwin*|aarch64*) pic_options='-fPIC' ;; -?86-pc-cygwin*|i?86-pc-cygwin*) +?86-pc-cygwin*|i?86-pc-cygwin*|i?86-pc-mingw32*) pic_options='-DDLL_EXPORT' ;; i?86-apple-darwin*|arm-apple-darwin*) diff --git a/libgc/configure.REMOVED.git-id b/libgc/configure.REMOVED.git-id index 5501c4807f..3a004f6aeb 100644 --- a/libgc/configure.REMOVED.git-id +++ b/libgc/configure.REMOVED.git-id @@ -1 +1 @@ -8f066765940517df1ea0554208196aab32b6b19b \ No newline at end of file +2f526024d2da61894c7ed648a1207722cbb90688 \ No newline at end of file diff --git a/man/mono.1 b/man/mono.1 index 3d4bd54e98..784c078d38 100644 --- a/man/mono.1 +++ b/man/mono.1 @@ -1075,19 +1075,10 @@ first generation (of two). A larger nursery will usually speed up the program but will obviously use more memory. The default nursery size 4 MB. .TP -\fBmajor=\fIcollector\fR -Specifies which major collector to use. Options are `marksweep' for -the Mark&Sweep collector, `marksweep-conc' for concurrent Mark&Sweep, -`marksweep-par' for parallel Mark&Sweep, `marksweep-fixed' for -Mark&Sweep with a fixed heap, and `marksweep-fixed-par' for parallel -Mark&Sweep with a fixed heap. The Mark&Sweep collector is the default. -.TP -\fBmajor-heap-size=\fIsize\fR -Sets the size of the major heap (not including the large object space) -for the fixed-heap Mark&Sweep collector (i.e. `marksweep-fixed' and -`marksweep-fixed-par'). The size is in bytes, with optional suffixes -`k', `m' and `g' to specify kilo-, mega- and gigabytes, respectively. -The default is 512 megabytes. +\fBmajor=\fIcollector\fR Specifies which major collector to use. +Options are `marksweep' for the Mark&Sweep collector, and +`marksweep-conc' for concurrent Mark&Sweep. The non-concurrent +Mark&Sweep collector is the default. .TP \fBsoft-heap-limit=\fIsize\fR Once the heap size gets larger than this size, ignore what the default @@ -1266,6 +1257,11 @@ work, Mono needs to be compiled with the BINARY_PROTOCOL define on sgen-gc.c. You can then use this command to explore the output .nf sgen-grep-binprot 0x1234 0x5678 < file +.TP +\fBnursery-canaries\fR +If set, objects allocated in the nursery are suffixed with a canary (guard) +word, which is checked on each minor collection. Can be used to detect/debug +heap corruption issues. .fi .ne .RE diff --git a/mcs/Makefile b/mcs/Makefile index af4495e919..9bcf32ea2f 100644 --- a/mcs/Makefile +++ b/mcs/Makefile @@ -12,6 +12,7 @@ monotouch_SUBDIRS := build class monotouch_runtime_SUBDIRS := build class xammac_SUBDIRS := build class mobile_SUBDIRS := build class +mobile_static_SUBDIRS := build class net_3_5_SUBDIRS := build class tools/xbuild net_4_0_SUBDIRS := build class net_4_5_SUBDIRS := build mcs class nunit24 ilasm tools tests errors docs @@ -114,6 +115,7 @@ $(_boot_:%=profile-do--monotouch--%): profile-do--monotouch--%: $(_boot_:%=profile-do--monotouch_runtime--%): profile-do--monotouch_runtime--%: profile-do--build--% $(_boot_:%=profile-do--xammac--%): profile-do--xammac--%: profile-do--build--% $(_boot_:%=profile-do--mobile--%): profile-do--mobile--%: profile-do--build--% +$(_boot_:%=profile-do--mobile_static--%): profile-do--mobile_static--%: profile-do--build--% $(_boot_:%=profile-do--net_2_0--%): profile-do--net_2_0--%: profile-do--build--% $(_boot_:%=profile-do--build--%): profile-do--build--%: profile-do--basic--% diff --git a/mcs/build/common/Consts.cs b/mcs/build/common/Consts.cs index b01a325a1c..29b45d2162 100644 --- a/mcs/build/common/Consts.cs +++ b/mcs/build/common/Consts.cs @@ -34,7 +34,7 @@ static class Consts // Use these assembly version constants to make code more maintainable. // - public const string MonoVersion = "3.10.0.0"; + public const string MonoVersion = "3.12.0.0"; public const string MonoCompany = "Mono development team"; public const string MonoProduct = "Mono Common Language Infrastructure"; public const string MonoCopyright = "(c) Various Mono authors"; diff --git a/mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng.Rnc/RncParser.jay b/mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng.Rnc/RncParser.jay index df3157f022..625df5ca15 100644 --- a/mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng.Rnc/RncParser.jay +++ b/mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng.Rnc/RncParser.jay @@ -107,7 +107,7 @@ namespace Commons.Xml.Relaxng.Rnc public RelaxngPattern Parse (TextReader source, string baseUri, string defaultNamespace) { - this.defaultNamespace = defaultNamespace; + this.defaultNamespace = defaultNamespace ?? string.Empty; if (defaultNamespace != null && defaultNamespace.Length != 0) nsmgr.AddNamespace (String.Empty, defaultNamespace); try { diff --git a/mcs/class/Commons.Xml.Relaxng/Test/NvdlValidatingReaderTests.cs b/mcs/class/Commons.Xml.Relaxng/Test/NvdlValidatingReaderTests.cs index e7d600c5ea..8f0ae73cf6 100644 --- a/mcs/class/Commons.Xml.Relaxng/Test/NvdlValidatingReaderTests.cs +++ b/mcs/class/Commons.Xml.Relaxng/Test/NvdlValidatingReaderTests.cs @@ -13,7 +13,7 @@ using System.Xml; using Commons.Xml.Nvdl; using NUnit.Framework; -namespace MonoTests.Commons.Xml.Nvdl +namespace MonoTests.Commons.Xml.Relaxng { [TestFixture] public class NvdlValidatingReaderTests diff --git a/mcs/class/Commons.Xml.Relaxng/Test/RncTests.cs b/mcs/class/Commons.Xml.Relaxng/Test/RncTests.cs index d25fcb1e1c..fb7ac65e9c 100644 --- a/mcs/class/Commons.Xml.Relaxng/Test/RncTests.cs +++ b/mcs/class/Commons.Xml.Relaxng/Test/RncTests.cs @@ -95,5 +95,19 @@ start = mine"; r.Close (); } } + + [Test] + public void SimpleDefaultNamespace () + { + var g = RncParser.ParseRnc (new StringReader ("element e { empty }")); + var x = XmlReader.Create (new StringReader ("")); + var r = new RelaxngValidatingReader (x, g); + try { + while (!r.EOF) + r.Read (); + } finally { + r.Close (); + } + } } } diff --git a/mcs/class/Facades/System.Runtime.InteropServices/TypeForwarders.cs b/mcs/class/Facades/System.Runtime.InteropServices/TypeForwarders.cs index 060d929226..3fb4b16a43 100644 --- a/mcs/class/Facades/System.Runtime.InteropServices/TypeForwarders.cs +++ b/mcs/class/Facades/System.Runtime.InteropServices/TypeForwarders.cs @@ -40,6 +40,7 @@ [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.COMException))] [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.ComMemberType))] [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.ComSourceInterfacesAttribute))] +[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.ComInterfaceType))] [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.ComTypes.IStream))] [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.ComTypes.STATSTG))] [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.CriticalHandle))] diff --git a/mcs/class/Makefile b/mcs/class/Makefile index 47cf334888..8ca914dca5 100644 --- a/mcs/class/Makefile +++ b/mcs/class/Makefile @@ -106,7 +106,7 @@ net_2_0_only_dirs := \ pcl_facade_dirs := Facades -mobile_dirs := \ +mobile_common_dirs := \ corlib \ System \ System.Core \ @@ -134,19 +134,27 @@ mobile_dirs := \ System.Net \ System.Windows \ System.Xml.Serialization \ - $(pcl_facade_dirs) - -monodroid_dirs := \ - Mono.CompilerServices.SymbolWriter \ Mono.CSharp \ Microsoft.CSharp \ + $(pcl_facade_dirs) + +mobile_static_dirs := \ + $(mobile_common_dirs) \ + Mono.Dynamic.Interpreter + +mobile_dynamic_dirs := \ + $(mobile_common_dirs) \ + Mono.CompilerServices.SymbolWriter \ System.Net.Http xammac_dirs := \ - Mono.CompilerServices.SymbolWriter \ - Mono.CSharp \ - Microsoft.CSharp \ - System.Net.Http + $(mobile_dynamic_dirs) + +monodroid_dirs := \ + $(mobile_dynamic_dirs) + +monotouch_dirs := \ + $(mobile_static_dirs) monotouch_runtime_dirs := \ corlib \ @@ -155,11 +163,6 @@ monotouch_runtime_dirs := \ System.XML \ Mono.CSharp -monotouch_dirs := \ - Mono.CSharp \ - Microsoft.CSharp \ - Mono.Dynamic.Interpreter - net_4_0_dirs := \ System.Numerics \ Microsoft.CSharp \ @@ -229,12 +232,12 @@ xbuild_4_0_dirs := \ Microsoft.Build net_2_0_SUBDIRS := $(net_2_0_dirs) $(net_2_0_only_dirs) $(xbuild_2_0_dirs) aot-compiler -monodroid_SUBDIRS := $(mobile_dirs) $(monodroid_dirs) -monotouch_SUBDIRS := $(mobile_dirs) $(monotouch_dirs) +monodroid_SUBDIRS := $(monodroid_dirs) +monotouch_SUBDIRS := $(monotouch_dirs) monotouch_runtime_SUBDIRS := $(monotouch_runtime_dirs) -mobile_static_SUBDIRS := $(mobile_dirs) -mobile_SUBDIRS := $(mobile_dirs) -xammac_SUBDIRS := $(mobile_dirs) $(xammac_dirs) +mobile_static_SUBDIRS := $(mobile_static_dirs) +mobile_SUBDIRS := $(mobile_dynamic_dirs) +xammac_SUBDIRS := $(xammac_dirs) net_3_5_SUBDIRS := $(xbuild_2_0_dirs) net_4_0_SUBDIRS := $(net_2_0_dirs) $(net_4_0_dirs) $(net_4_0_only_dirs) $(xbuild_4_0_dirs) net_4_5_SUBDIRS := $(net_2_0_dirs) $(net_4_0_dirs) $(net_4_5_dirs) $(xbuild_4_0_dirs) aot-compiler @@ -242,7 +245,7 @@ xbuild_12_SUBDIRS := $(xbuild_4_0_dirs) include ../build/rules.make -SUBDIRS = $(net_2_0_dirs) $(net_2_0_only_dirs) $(mobile_dirs) $(monotouch_dirs) $(net_4_0_dirs) $(net_4_0_only_dirs) $(net_4_5_dirs) +SUBDIRS = $(net_2_0_dirs) $(net_2_0_only_dirs) $(mobile_static_dirs) $(mobile_dynamic_dirs) $(monotouch_dirs) $(monodroid_dirs) $(xammac_dirs) $(net_4_0_dirs) $(net_4_0_only_dirs) $(net_4_5_dirs) DIST_ONLY_SUBDIRS = dlr aot-compiler $(xbuild_4_0_dirs) diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Button.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Button.cs index dc640e836c..e04f399716 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Button.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Button.cs @@ -175,7 +175,7 @@ namespace System.Windows.Forms { Rectangle text_rectangle; Rectangle image_rectangle; - ThemeEngine.Current.CalculateButtonTextAndImageLayout (this, out text_rectangle, out image_rectangle); + ThemeEngine.Current.CalculateButtonTextAndImageLayout (pevent.Graphics, this, out text_rectangle, out image_rectangle); // Draw our button if (this.FlatStyle == FlatStyle.Standard) diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ListView.cs.REMOVED.git-id b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ListView.cs.REMOVED.git-id index 2e108650fb..63c1e16c50 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ListView.cs.REMOVED.git-id +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ListView.cs.REMOVED.git-id @@ -1 +1 @@ -f7075e8ef8f7cfbc0c67a85dbedc54b114523b38 \ No newline at end of file +3af4684710ade1ef9420d2e56c7319fc0e32c4cd \ No newline at end of file diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TextRenderer.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TextRenderer.cs index 6f3be9db10..bda5da96f7 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TextRenderer.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/TextRenderer.cs @@ -258,11 +258,19 @@ namespace System.Windows.Forms StringFormat sf = FlagsToStringFormat (flags); Size retval; - + + int proposedWidth; + if (proposedSize.Width == 0) + proposedWidth = Int32.MaxValue; + else { + proposedWidth = proposedSize.Width; + if ((flags & TextFormatFlags.NoPadding) == 0) + proposedWidth -= 9; + } if (dc is Graphics) - retval = (dc as Graphics).MeasureString (text, font, proposedSize.Width == 0 ? Int32.MaxValue : proposedSize.Width, sf).ToSize (); + retval = (dc as Graphics).MeasureString (text, font, proposedWidth, sf).ToSize (); else - retval = TextRenderer.MeasureString (text, font, proposedSize.Width == 0 ? Int32.MaxValue : proposedSize.Width, sf).ToSize (); + retval = TextRenderer.MeasureString (text, font, proposedWidth, sf).ToSize (); if (retval.Width > 0 && (flags & TextFormatFlags.NoPadding) == 0) retval.Width += 9; diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Theme.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Theme.cs index 18ee3dd811..b8cc63b7e8 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Theme.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Theme.cs @@ -698,7 +698,7 @@ namespace System.Windows.Forms #region Button public abstract Size CalculateButtonAutoSize (Button button); - public abstract void CalculateButtonTextAndImageLayout (ButtonBase b, out Rectangle textRectangle, out Rectangle imageRectangle); + public abstract void CalculateButtonTextAndImageLayout (Graphics g, ButtonBase b, out Rectangle textRectangle, out Rectangle imageRectangle); public abstract void DrawButton (Graphics g, Button b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle); public abstract void DrawFlatButton (Graphics g, ButtonBase b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle); public abstract void DrawPopupButton (Graphics g, Button b, Rectangle textBounds, Rectangle imageBounds, Rectangle clipRectangle); diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeWin32Classic.cs.REMOVED.git-id b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeWin32Classic.cs.REMOVED.git-id index 79ebd4d684..ce116c1bef 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeWin32Classic.cs.REMOVED.git-id +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/ThemeWin32Classic.cs.REMOVED.git-id @@ -1 +1 @@ -522dec40ec616af384bc431f1c9406aabdaec3fb \ No newline at end of file +29921942b4eddbcd9cdbc0b9c29b4e12a60804a8 \ No newline at end of file diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs.REMOVED.git-id b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs.REMOVED.git-id index 538b273725..17b63f9b27 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs.REMOVED.git-id +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs.REMOVED.git-id @@ -1 +1 @@ -1f3af25846450af900f33b95ed551929392ee807 \ No newline at end of file +657a42457c9f222751c977278db272df8f1f1caf \ No newline at end of file diff --git a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConsoleLogger.cs b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConsoleLogger.cs index 5fb7d21899..0d776b9fbb 100644 --- a/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConsoleLogger.cs +++ b/mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConsoleLogger.cs @@ -1018,13 +1018,27 @@ namespace Microsoft.Build.BuildEngine if (!StartHandlerHasExecuted) return; - if (EventArgs is ProjectStartedEventArgs) - ConsoleLogger.ProjectFinishedHandler (Sender, finished_args as ProjectFinishedEventArgs); - else if (EventArgs is TargetStartedEventArgs) - ConsoleLogger.TargetFinishedHandler (Sender, finished_args as TargetFinishedEventArgs); - else if (EventArgs is TaskStartedEventArgs) - ConsoleLogger.TaskFinishedHandler (Sender, finished_args as TaskFinishedEventArgs); - else if (!(EventArgs is BuildStartedEventArgs)) + if (EventArgs is ProjectStartedEventArgs) { + var pfa = finished_args as ProjectFinishedEventArgs; + // FIXME: BuildFinishedHandlerActual sends us BuildFinishedEventArgs via PopEvent + if (pfa == null) + return; + + ConsoleLogger.ProjectFinishedHandler (Sender, pfa); + } else if (EventArgs is TargetStartedEventArgs) { + var fa = finished_args as TargetFinishedEventArgs; + // FIXME: BuildFinishedHandlerActual sends us BuildFinishedEventArgs via PopEvent + if (fa == null) + return; + + ConsoleLogger.TargetFinishedHandler (Sender, fa); + } else if (EventArgs is TaskStartedEventArgs) { + // FIXME: BuildFinishedHandlerActual sends us BuildFinishedEventArgs via PopEvent + if (!(finished_args is TaskFinishedEventArgs)) + return; + + ConsoleLogger.TaskFinishedHandler (Sender, (TaskFinishedEventArgs) finished_args); + } else if (!(EventArgs is BuildStartedEventArgs)) throw new InvalidOperationException ("Unexpected event on the stack, type: " + EventArgs.GetType ()); } } diff --git a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolTask.cs b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolTask.cs index ded4b425c6..572c75c1bf 100644 --- a/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolTask.cs +++ b/mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolTask.cs @@ -1,12 +1,14 @@ // // ToolTask.cs: Base class for command line tool tasks. // -// Author: +// Authors: // Marek Sieradzki (marek.sieradzki@gmail.com) // Ankit Jain (jankit@novell.com) +// Marek Safar (marek.safar@gmail.com) // // (C) 2005 Marek Sieradzki // Copyright 2009 Novell, Inc (http://www.novell.com) +// Copyright 2014 Xamarin Inc // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -90,12 +92,45 @@ namespace Microsoft.Build.Utilities return true; } + string CreateToolPath () + { + string tp; + if (string.IsNullOrEmpty (ToolPath)) { + tp = GenerateFullPathToTool (); + if (string.IsNullOrEmpty (tp)) + return null; + + // + // GenerateFullPathToTool can return path including tool name + // + if (string.IsNullOrEmpty (ToolExe)) + return tp; + + tp = Path.GetDirectoryName (tp); + } else { + tp = ToolPath; + } + + var path = Path.Combine (tp, ToolExe); + if (!File.Exists (path)) { + if (Log != null) + Log.LogError ("Tool executable '{0}' could not be found", path); + return null; + } + + return path; + } + public override bool Execute () { if (SkipTaskExecution ()) return true; - exitCode = ExecuteTool (GenerateFullPathToTool (), GenerateResponseFileCommands (), + var tool_path = CreateToolPath (); + if (tool_path == null) + return false; + + exitCode = ExecuteTool (tool_path, GenerateResponseFileCommands (), GenerateCommandLineCommands ()); // HandleTaskExecutionErrors is called only if exitCode != 0 @@ -289,14 +324,14 @@ namespace Microsoft.Build.Utilities protected virtual string GenerateCommandLineCommands () { - return null; + return ""; } protected abstract string GenerateFullPathToTool (); protected virtual string GenerateResponseFileCommands () { - return null; + return ""; } protected virtual string GetResponseFileSwitch (string responseFilePath) diff --git a/mcs/class/Microsoft.Build.Utilities/Test/Microsoft.Build.Utilities/ToolTaskTest.cs b/mcs/class/Microsoft.Build.Utilities/Test/Microsoft.Build.Utilities/ToolTaskTest.cs index ec1e34768b..7c2a3843b6 100644 --- a/mcs/class/Microsoft.Build.Utilities/Test/Microsoft.Build.Utilities/ToolTaskTest.cs +++ b/mcs/class/Microsoft.Build.Utilities/Test/Microsoft.Build.Utilities/ToolTaskTest.cs @@ -26,6 +26,7 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using System; +using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -424,6 +425,53 @@ namespace MonoTests.Microsoft.Build.Utilities { Assert.AreEqual (a.ToolPath, "Bar", "#5"); a.ToolPath = ""; Assert.AreEqual (a.ToolPath, "", "#6"); + + a.Execute (); + } + + [Test] + public void Execute_1 () + { + var t = new TestExecuteToolTask (); + t.OnExecuteTool = delegate { Assert.Fail ("#1"); }; + t.BuildEngine = new MockBuildEngine (); + Assert.IsFalse (t.Execute (), "result"); + } + + [Test] + public void Execute_2 () + { + var t = new TestExecuteToolTask (); + t.BuildEngine = new MockBuildEngine (); + t.ToolPath = Directory.GetCurrentDirectory (); + t.ToolExe = "Makefile"; + + t.OnExecuteTool = (pathToTool, responseFileCommands, commandLineCommands) => { + Assert.AreEqual (Path.Combine (Directory.GetCurrentDirectory (), "Makefile"), pathToTool, "#1"); + Assert.AreEqual ("", responseFileCommands, "#2"); + Assert.AreEqual ("", commandLineCommands, "#3"); + + }; + + Assert.IsTrue (t.Execute (), "result"); + } + + [Test] + public void Execute_3 () + { + var t = new TestExecuteToolTask (); + t.FullPathToTool = "fpt"; + t.BuildEngine = new MockBuildEngine (); + t.ToolExe = "Makefile.mk"; + + t.OnExecuteTool = (pathToTool, responseFileCommands, commandLineCommands) => { + Assert.AreEqual ("Makefile.mk", pathToTool, "#1"); + Assert.AreEqual ("", responseFileCommands, "#2"); + Assert.AreEqual ("", commandLineCommands, "#3"); + + }; + + Assert.IsFalse (t.Execute (), "result"); } } @@ -548,9 +596,86 @@ namespace MonoTests.Microsoft.Build.Utilities { } protected override string GenerateFullPathToTool () + { + return ""; + } + } + + class MockBuildEngine : IBuildEngine + { + public int ColumnNumberOfTaskNode { + get { + return 0; + } + } + + public bool ContinueOnError { + get { + throw new NotImplementedException (); + } + } + + public int LineNumberOfTaskNode { + get { + return 0; + } + } + + public string ProjectFileOfTaskNode { + get { + return "ProjectFileOfTaskNode"; + } + } + + public bool BuildProjectFile (string projectFileName, string[] targetNames, IDictionary globalProperties, IDictionary targetOutputs) { throw new NotImplementedException (); } + + public void LogCustomEvent (CustomBuildEventArgs e) + { + } + + public void LogErrorEvent (BuildErrorEventArgs e) + { + Console.WriteLine (e.Message); + } + + public void LogMessageEvent (BuildMessageEventArgs e) + { + } + + public void LogWarningEvent (BuildWarningEventArgs e) + { + } + } + + class TestExecuteToolTask : ToolTask + { + public Action OnExecuteTool; + public string FullPathToTool; + + protected override string ToolName { + get { return "TestTool.exe"; } + } + + protected override bool CallHostObjectToExecute () + { + return base.CallHostObjectToExecute (); + } + + protected override string GenerateFullPathToTool () + { + return FullPathToTool; + } + + protected override int ExecuteTool (string pathToTool, string responseFileCommands, string commandLineCommands) + { + if (OnExecuteTool != null) + OnExecuteTool (pathToTool, responseFileCommands, commandLineCommands); + + return 0; + } } } diff --git a/mcs/class/Mono.CSharp/Makefile b/mcs/class/Mono.CSharp/Makefile index 85b86e0f46..35ee0a302b 100644 --- a/mcs/class/Mono.CSharp/Makefile +++ b/mcs/class/Mono.CSharp/Makefile @@ -6,7 +6,9 @@ LIBRARY = Mono.CSharp.dll LIB_MCS_FLAGS = -r:System.Core.dll -r:System.Xml.dll -r:System.dll -ifeq (monotouch, $(PROFILE)) +MOBILE_STATIC := $(filter mobile_static monotouch, $(PROFILE)) + +ifdef MOBILE_STATIC LIB_MCS_FLAGS += -d:IOS_REFLECTION endif diff --git a/mcs/class/Mono.CSharp/mobile_static_Mono.CSharp.dll.sources b/mcs/class/Mono.CSharp/mobile_static_Mono.CSharp.dll.sources new file mode 100644 index 0000000000..6e4c34213b --- /dev/null +++ b/mcs/class/Mono.CSharp/mobile_static_Mono.CSharp.dll.sources @@ -0,0 +1,13 @@ +#include Mono.CSharp.dll.sources +../corlib/System.Reflection.Emit/AssemblyBuilderAccess.cs +../corlib/System.Reflection.Emit/FlowControl.cs +../corlib/System.Reflection.Emit/OpCode.cs +../corlib/System.Reflection.Emit/OpCodeNames.cs +../corlib/System.Reflection.Emit/OpCodes.cs +../corlib/System.Reflection.Emit/OpCodeType.cs +../corlib/System.Reflection.Emit/OperandType.cs +../corlib/System.Reflection.Emit/PEFileKinds.cs +../corlib/System.Reflection.Emit/Label.cs +../corlib/System.Reflection.Emit/MethodToken.cs +../corlib/System.Reflection.Emit/StackBehaviour.cs +monotouch.cs \ No newline at end of file diff --git a/mcs/class/Mono.CSharp/monotouch_Mono.CSharp.dll.sources b/mcs/class/Mono.CSharp/monotouch_Mono.CSharp.dll.sources index 6e4c34213b..6a71501e34 100644 --- a/mcs/class/Mono.CSharp/monotouch_Mono.CSharp.dll.sources +++ b/mcs/class/Mono.CSharp/monotouch_Mono.CSharp.dll.sources @@ -1,13 +1,2 @@ -#include Mono.CSharp.dll.sources -../corlib/System.Reflection.Emit/AssemblyBuilderAccess.cs -../corlib/System.Reflection.Emit/FlowControl.cs -../corlib/System.Reflection.Emit/OpCode.cs -../corlib/System.Reflection.Emit/OpCodeNames.cs -../corlib/System.Reflection.Emit/OpCodes.cs -../corlib/System.Reflection.Emit/OpCodeType.cs -../corlib/System.Reflection.Emit/OperandType.cs -../corlib/System.Reflection.Emit/PEFileKinds.cs -../corlib/System.Reflection.Emit/Label.cs -../corlib/System.Reflection.Emit/MethodToken.cs -../corlib/System.Reflection.Emit/StackBehaviour.cs -monotouch.cs \ No newline at end of file +#include mobile_static_Mono.CSharp.dll.sources +monotouch.cs diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs index 6865df9adb..f06932c802 100644 --- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs +++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds.cs @@ -41,7 +41,9 @@ using System.ComponentModel; using System.Diagnostics; using System.Net.Sockets; using System.Globalization; +using System.Security; using System.Text; +using System.Runtime.InteropServices; namespace Mono.Data.Tds.Protocol { @@ -1468,7 +1470,7 @@ namespace Mono.Data.Tds.Protocol t3.Domain = this.connectionParms.DefaultDomain; t3.Host = this.connectionParms.Hostname; t3.Username = this.connectionParms.User; - t3.Password = this.connectionParms.Password; + t3.Password = GetPlainPassword(this.connectionParms.Password); Comm.StartPacket (TdsPacketType.SspAuth); // 0x11 Comm.Append (t3.GetBytes ()); @@ -1919,6 +1921,20 @@ namespace Mono.Data.Tds.Protocol comm.Skip(4); } + public static string GetPlainPassword(SecureString secPass) + { + IntPtr plainString = IntPtr.Zero; + try + { + plainString = Marshal.SecureStringToGlobalAllocUnicode(secPass); + return Marshal.PtrToStringUni(plainString); + } + finally + { + Marshal.ZeroFreeGlobalAllocUnicode(plainString); + } + } + #endregion // Private Methods #if NET_2_0 diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds42.cs b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds42.cs index fdca83087b..fb517d013d 100644 --- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds42.cs +++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds42.cs @@ -29,6 +29,7 @@ // using System; +using System.Security; namespace Mono.Data.Tds.Protocol { public sealed class Tds42 : Tds @@ -77,7 +78,7 @@ namespace Mono.Data.Tds.Protocol { Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30)); // password (offset 62 0x3e) - tmp = Comm.Append (connectionParameters.Password, 30, pad); + tmp = Comm.Append (GetPlainPassword(connectionParameters.Password), 30, pad); Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30)); // hostproc (offset 93 0x5d) @@ -145,7 +146,7 @@ namespace Mono.Data.Tds.Protocol { // remote passwords Comm.Append (empty, 2, pad); - tmp = Comm.Append (connectionParameters.Password, 253, pad); + tmp = Comm.Append (GetPlainPassword(connectionParameters.Password), 253, pad); Comm.Append ((byte) (tmp.Length < 253 ? tmp.Length + 2 : 253 + 2)); // tds version diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds50.cs b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds50.cs index 0d0e86c023..88219125df 100644 --- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds50.cs +++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds50.cs @@ -31,6 +31,7 @@ using Mono.Data.Tds; using System; using System.Text; +using System.Security; namespace Mono.Data.Tds.Protocol { @@ -118,7 +119,7 @@ namespace Mono.Data.Tds.Protocol // password (offset 62 0x3e) // 62-92 - tmp = Comm.Append (connectionParameters.Password, 30, pad); + tmp = Comm.Append (GetPlainPassword(connectionParameters.Password), 30, pad); Comm.Append ((byte) (tmp.Length < 30 ? tmp.Length : 30)); // hostproc (offset 93 0x5d) @@ -187,7 +188,7 @@ namespace Mono.Data.Tds.Protocol // remote passwords // 202-457 Comm.Append (empty, 2, pad); - tmp = Comm.Append (connectionParameters.Password, 253, pad); + tmp = Comm.Append (GetPlainPassword(connectionParameters.Password), 253, pad); Comm.Append ((byte) (tmp.Length < 253 ? tmp.Length + 2 : 253 + 2)); // tds version diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs index c67b6e8c3b..2f4fef03e1 100644 --- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs +++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/Tds70.cs @@ -37,6 +37,7 @@ using System; using System.Globalization; using System.Text; +using System.Security; using Mono.Security.Protocol.Ntlm; @@ -392,11 +393,12 @@ namespace Mono.Data.Tds.Protocol return IsConnected; } - private static string EncryptPassword (string pass) + private static string EncryptPassword (SecureString secPass) { int xormask = 0x5a5a; - int len = pass.Length; + int len = secPass.Length; char[] chars = new char[len]; + string pass = GetPlainPassword(secPass); for (int i = 0; i < len; ++i) { int c = ((int) (pass[i])) ^ xormask; @@ -487,6 +489,19 @@ namespace Mono.Data.Tds.Protocol Comm.Append ((byte) 0x00); // no param meta data name Comm.Append ((byte) 0x00); // no status flags + + // Convert BigNVarChar values larger than 4000 chars to nvarchar(max) + // Need to do this here so WritePreparedParameterInfo emit the + // correct data type + foreach (TdsMetaParameter param2 in parameters) { + var colType = param2.GetMetaType (); + + if (colType == TdsColumnType.BigNVarChar) { + int size = param2.GetActualSize (); + if ((size >> 1) > 4000) + param2.Size = -1; + } + } // Write sql as a parameter value - UCS2 TdsMetaParameter param = new TdsMetaParameter ("sql", diff --git a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsConnectionParameters.cs b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsConnectionParameters.cs index 19f676077d..e3b83aa257 100644 --- a/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsConnectionParameters.cs +++ b/mcs/class/Mono.Data.Tds/Mono.Data.Tds.Protocol/TdsConnectionParameters.cs @@ -31,6 +31,7 @@ // using System; +using System.Security; namespace Mono.Data.Tds.Protocol { @@ -42,7 +43,8 @@ namespace Mono.Data.Tds.Protocol public string Hostname; public string Language; public string LibraryName; - public string Password; + public SecureString Password; + public bool PasswordSet; public string ProgName; public string User; public bool DomainLogin; @@ -62,7 +64,8 @@ namespace Mono.Data.Tds.Protocol Hostname = System.Net.Dns.GetHostName(); Language = String.Empty; LibraryName = "Mono"; - Password = String.Empty; + Password = new SecureString(); + PasswordSet = false; ProgName = "Mono"; User = String.Empty; DomainLogin = false; diff --git a/mcs/class/Mono.Data.Tds/Test/bug-4786.cs b/mcs/class/Mono.Data.Tds/Test/bug-4786.cs index e8436a7dec..91f8a06fc1 100644 --- a/mcs/class/Mono.Data.Tds/Test/bug-4786.cs +++ b/mcs/class/Mono.Data.Tds/Test/bug-4786.cs @@ -27,11 +27,11 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -namespace bug4786test +namespace MonoTests.Mono.Data.Tds { using NUnit.Framework; - using Mono.Data.Tds.Protocol; + using global::Mono.Data.Tds.Protocol; using System; using System.Net; using System.Net.Sockets; diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs index 14bf701f46..753f3910f8 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs @@ -155,11 +155,12 @@ namespace Mono.Debugger.Soft [Flags] enum InvokeFlags { - NONE = 0x0, - DISABLE_BREAKPOINTS = 0x1, - SINGLE_THREADED = 0x2, - OUT_THIS = 0x4, - OUT_ARGS = 0x8, + NONE = 0, + DISABLE_BREAKPOINTS = 1, + SINGLE_THREADED = 2, + OUT_THIS = 4, + OUT_ARGS = 8, + VIRTUAL = 16, } enum ElementType { @@ -416,7 +417,7 @@ namespace Mono.Debugger.Soft * with newer runtimes, and vice versa. */ internal const int MAJOR_VERSION = 2; - internal const int MINOR_VERSION = 35; + internal const int MINOR_VERSION = 38; enum WPSuspendPolicy { NONE = 0, @@ -584,7 +585,8 @@ namespace Mono.Debugger.Soft enum CmdStackFrame { GET_VALUES = 1, GET_THIS = 2, - SET_VALUES = 3 + SET_VALUES = 3, + GET_DOMAIN = 4, } enum CmdArrayRef { @@ -2377,6 +2379,10 @@ namespace Mono.Debugger.Soft SendReceive (CommandSet.STACK_FRAME, (int)CmdStackFrame.SET_VALUES, new PacketWriter ().WriteId (thread_id).WriteId (id).WriteInt (len).WriteInts (pos).WriteValues (values)); } + internal long StackFrame_GetDomain (long thread_id, long id) { + return SendReceive (CommandSet.STACK_FRAME, (int)CmdStackFrame.GET_DOMAIN, new PacketWriter ().WriteId (thread_id).WriteId (id)).ReadId (); + } + /* * ARRAYS */ diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/InvokeOptions.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/InvokeOptions.cs index 5ca987ec69..99dc87fa80 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/InvokeOptions.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/InvokeOptions.cs @@ -22,6 +22,11 @@ namespace Mono.Debugger.Soft /* * Return the values of out arguments */ - ReturnOutArgs = 8 + ReturnOutArgs = 8, + /* + * Do a virtual invoke + * Since protocol version 2.37 + */ + Virtual = 16 } } diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs index d83e3a1a48..e65f62fc94 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs @@ -307,6 +307,8 @@ namespace Mono.Debugger.Soft f |= InvokeFlags.OUT_THIS; if ((options & InvokeOptions.ReturnOutArgs) != 0) f |= InvokeFlags.OUT_ARGS; + if ((options & InvokeOptions.Virtual) != 0) + f |= InvokeFlags.VIRTUAL; InvokeAsyncResult r = new InvokeAsyncResult { AsyncState = state, AsyncWaitHandle = new ManualResetEvent (false), VM = vm, Thread = thread, Callback = callback }; thread.InvalidateFrames (); diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StackFrame.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StackFrame.cs index 7a6a34fa53..8549a93700 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StackFrame.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StackFrame.cs @@ -7,6 +7,7 @@ namespace Mono.Debugger.Soft public class StackFrame : Mirror { ThreadMirror thread; + AppDomainMirror domain; MethodMirror method; int il_offset; Location location; @@ -32,6 +33,16 @@ namespace Mono.Debugger.Soft } } + public AppDomainMirror Domain { + get { + vm.CheckProtocolVersion (2, 38); + if (domain == null) + domain = vm.GetDomain (vm.conn.StackFrame_GetDomain (thread.Id, Id)); + + return domain; + } + } + public MethodMirror Method { get { return method; diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs index 3c9b2877c2..f75951b8bc 100644 --- a/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs +++ b/mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs @@ -22,6 +22,10 @@ public class TestsBase static string base_static_s = "C"; #pragma warning restore 0414 #pragma warning restore 0169 + + public virtual string virtual_method () { + return "V1"; + } } public enum AnEnum { @@ -1365,6 +1369,10 @@ public class Tests : TestsBase, ITest2 j = 5; set_ip_2 (); } + + public override string virtual_method () { + return "V2"; + } } class TypeLoadClass { diff --git a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs index 9a671202a8..d7aaacd338 100644 --- a/mcs/class/Mono.Debugger.Soft/Test/dtest.cs +++ b/mcs/class/Mono.Debugger.Soft/Test/dtest.cs @@ -2137,6 +2137,11 @@ public class DebuggerTests v = this_obj.InvokeMethod (e.Thread, m, null); AssertValue (42, v); + // virtual call + m = t.BaseType.GetMethod ("virtual_method"); + v = this_obj.InvokeMethod (e.Thread, m, null, InvokeOptions.Virtual); + AssertValue ("V2", v); + #if NET_4_5 // instance m = t.GetMethod ("invoke_pass_ref"); @@ -2864,8 +2869,10 @@ public class DebuggerTests var frames = e.Thread.GetFrames (); Assert.AreEqual ("invoke_in_domain", frames [0].Method.Name); + Assert.AreEqual (domain, frames [0].Domain); Assert.AreEqual ("invoke", frames [1].Method.Name); Assert.AreEqual ("domains", frames [2].Method.Name); + Assert.AreEqual (vm.RootDomain, frames [2].Domain); // Test breakpoints on already JITted methods in other domains m = entry_point.DeclaringType.GetMethod ("invoke_in_domain_2"); diff --git a/mcs/class/Mono.Dynamic.Interpreter/Makefile b/mcs/class/Mono.Dynamic.Interpreter/Makefile index 7677761182..bbb733bf69 100644 --- a/mcs/class/Mono.Dynamic.Interpreter/Makefile +++ b/mcs/class/Mono.Dynamic.Interpreter/Makefile @@ -9,7 +9,9 @@ LIB_MCS_FLAGS = -r:System.dll -r:System.Core.dll \ -d:MONO_INTERPRETER \ -delaysign -keyfile:../mono.pub -ifeq (monotouch, $(subst _runtime,,$(PROFILE))) +MOBILE_STATIC := $(filter mobile_static monotouch monotouch_runtime, $(PROFILE)) + +ifdef MOBILE_STATIC mono_dynamic_interpreter_deps = $(the_libdir_base)plaincore/System.Core.dll LIB_MCS_FLAGS += -lib:$(the_libdir_base)plaincore endif @@ -21,4 +23,4 @@ $(the_libdir_base)Mono.Dynamic.Interpreter.dll: $(mono_dynamic_interpreter_deps) $(the_libdir_base)plaincore/System.Core.dll: (cd ../System.Core; $(MAKE) $@) -.NOTPARALLEL: $(the_libdir_base)plaincore/System.Core.dll \ No newline at end of file +.NOTPARALLEL: $(the_libdir_base)plaincore/System.Core.dll diff --git a/mcs/class/Mono.Options/Test/Mono.Options/OptionContextTest.cs b/mcs/class/Mono.Options/Test/Mono.Options/OptionContextTest.cs index 8eb61b2c93..ec3fb02270 100644 --- a/mcs/class/Mono.Options/Test/Mono.Options/OptionContextTest.cs +++ b/mcs/class/Mono.Options/Test/Mono.Options/OptionContextTest.cs @@ -39,7 +39,7 @@ using NUnit.Framework; #if NDESK_OPTIONS namespace Tests.NDesk.Options #else -namespace Tests.Mono.Options +namespace MonoTests.Mono.Options #endif { [TestFixture] diff --git a/mcs/class/Mono.Options/Test/Mono.Options/OptionSetTest.cs b/mcs/class/Mono.Options/Test/Mono.Options/OptionSetTest.cs index 086c6d9c8c..688297a0f6 100644 --- a/mcs/class/Mono.Options/Test/Mono.Options/OptionSetTest.cs +++ b/mcs/class/Mono.Options/Test/Mono.Options/OptionSetTest.cs @@ -46,7 +46,7 @@ using NUnit.Framework; #if NDESK_OPTIONS namespace Tests.NDesk.Options #else -namespace Tests.Mono.Options +namespace MonoTests.Mono.Options #endif { class FooConverter : TypeConverter { diff --git a/mcs/class/Mono.Options/Test/Mono.Options/OptionTest.cs b/mcs/class/Mono.Options/Test/Mono.Options/OptionTest.cs index 5242609162..fad1b48478 100644 --- a/mcs/class/Mono.Options/Test/Mono.Options/OptionTest.cs +++ b/mcs/class/Mono.Options/Test/Mono.Options/OptionTest.cs @@ -39,7 +39,7 @@ using NUnit.Framework; #if NDESK_OPTIONS namespace Tests.NDesk.Options #else -namespace Tests.Mono.Options +namespace MonoTests.Mono.Options #endif { class DefaultOption : Option { diff --git a/mcs/class/Mono.Options/Test/Mono.Options/Utils.cs b/mcs/class/Mono.Options/Test/Mono.Options/Utils.cs index e5439aae4c..074478e3e2 100644 --- a/mcs/class/Mono.Options/Test/Mono.Options/Utils.cs +++ b/mcs/class/Mono.Options/Test/Mono.Options/Utils.cs @@ -31,7 +31,7 @@ using System; #if NDESK_OPTIONS namespace Tests.NDesk.Options #else -namespace Tests.Mono.Options +namespace MonoTests.Mono.Options #endif { static class Utils { diff --git a/mcs/class/Mono.Security/Mono.Security.Cryptography/KeyPairPersistence.cs b/mcs/class/Mono.Security/Mono.Security.Cryptography/KeyPairPersistence.cs index f07db9ec10..14f8c73a8a 100644 --- a/mcs/class/Mono.Security/Mono.Security.Cryptography/KeyPairPersistence.cs +++ b/mcs/class/Mono.Security/Mono.Security.Cryptography/KeyPairPersistence.cs @@ -221,15 +221,13 @@ namespace Mono.Security.Cryptography { string msg = Locale.GetText ("Could not create user key store '{0}'."); throw new CryptographicException (String.Format (msg, _userPath), e); } - - if (!ProtectUser (_userPath)) { - string msg = Locale.GetText ("Could not secure user key store '{0}'."); - throw new IOException (String.Format (msg, _userPath)); - } - _userPathExists = true; } } + if (!IsUserProtected (_userPath) && !ProtectUser (_userPath)) { + string msg = Locale.GetText ("Could not secure user key store '{0}'."); + throw new IOException (String.Format (msg, _userPath)); + } } // is it properly protected ? if (!IsUserProtected (_userPath)) { @@ -258,15 +256,13 @@ namespace Mono.Security.Cryptography { string msg = Locale.GetText ("Could not create machine key store '{0}'."); throw new CryptographicException (String.Format (msg, _machinePath), e); } - - if (!ProtectMachine (_machinePath)) { - string msg = Locale.GetText ("Could not secure machine key store '{0}'."); - throw new IOException (String.Format (msg, _machinePath)); - } - _machinePathExists = true; } } + if (!IsMachineProtected (_machinePath) && !ProtectMachine (_machinePath)) { + string msg = Locale.GetText ("Could not secure machine key store '{0}'."); + throw new IOException (String.Format (msg, _machinePath)); + } } // is it properly protected ? if (!IsMachineProtected (_machinePath)) { diff --git a/mcs/class/Mono.Security/Mono.Security.X509/X509Store.cs b/mcs/class/Mono.Security/Mono.Security.X509/X509Store.cs index c4bb4b99af..d3671c0bf9 100644 --- a/mcs/class/Mono.Security/Mono.Security.X509/X509Store.cs +++ b/mcs/class/Mono.Security/Mono.Security.X509/X509Store.cs @@ -97,10 +97,26 @@ namespace Mono.Security.X509 { // methods public void Clear () + { + /* + * Both _certificates and _crls extend CollectionBase, whose Clear() method calls OnClear() and + * OnClearComplete(), which should be overridden in derivative classes. So we should not worry about + * other threads that might be holding references to _certificates or _crls. They should be smart enough + * to handle this gracefully. And if not, it's their own fault. + */ + ClearCertificates (); + ClearCrls (); + } + + void ClearCertificates() { if (_certificates != null) _certificates.Clear (); _certificates = null; + } + + void ClearCrls () + { if (_crls != null) _crls.Clear (); _crls = null; @@ -117,6 +133,7 @@ namespace Mono.Security.X509 { fs.Write (data, 0, data.Length); fs.Close (); } + ClearCertificates (); // We have modified the store on disk. So forget the old state. } #if !NET_2_1 // Try to save privateKey if available.. @@ -141,6 +158,7 @@ namespace Mono.Security.X509 { byte[] data = crl.RawData; fs.Write (data, 0, data.Length); } + ClearCrls (); // We have modified the store on disk. So forget the old state. } } @@ -149,6 +167,7 @@ namespace Mono.Security.X509 { string filename = Path.Combine (_storePath, GetUniqueName (certificate)); if (File.Exists (filename)) { File.Delete (filename); + ClearCertificates (); // We have modified the store on disk. So forget the old state. } } @@ -157,6 +176,7 @@ namespace Mono.Security.X509 { string filename = Path.Combine (_storePath, GetUniqueName (crl)); if (File.Exists (filename)) { File.Delete (filename); + ClearCrls (); // We have modified the store on disk. So forget the old state. } } @@ -236,8 +256,13 @@ namespace Mono.Security.X509 { cspParams.Flags = CspProviderFlags.UseMachineKeyStore; KeyPairPersistence kpp = new KeyPairPersistence (cspParams); - if (!kpp.Load ()) + try { + if (!kpp.Load ()) + return cert; + } + catch { return cert; + } if (cert.RSA != null) cert.RSA = new RSACryptoServiceProvider (cspParams); diff --git a/mcs/class/System.ComponentModel.Composition.4.5/Makefile b/mcs/class/System.ComponentModel.Composition.4.5/Makefile index 4fe0fee915..b71beeab45 100644 --- a/mcs/class/System.ComponentModel.Composition.4.5/Makefile +++ b/mcs/class/System.ComponentModel.Composition.4.5/Makefile @@ -12,7 +12,7 @@ CLEAN_FILES += $(STRING_MESSAGES) EXTRA_DISTFILES = \ src/ComponentModel/Strings.resx -VALID_PROFILE := $(filter net_4_0 net_4_5 monotouch monodroid xammac mobile_static, $(PROFILE)) +VALID_PROFILE := $(filter net_4_0 net_4_5 monotouch monodroid xammac mobile mobile_static, $(PROFILE)) ifndef VALID_PROFILE LIBRARY_NAME = dummy-System.ComponentModel.Composition.dll NO_INSTALL = yes diff --git a/mcs/class/System.ComponentModel.DataAnnotations/Makefile b/mcs/class/System.ComponentModel.DataAnnotations/Makefile index 713754ccdb..3d9ff9e258 100644 --- a/mcs/class/System.ComponentModel.DataAnnotations/Makefile +++ b/mcs/class/System.ComponentModel.DataAnnotations/Makefile @@ -18,7 +18,7 @@ endif TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) # This is a .NET 3.5+ assembly -VALID_PROFILE := $(filter net_2_0 net_4_0 net_4_5 monotouch monodroid xammac mobile_static, $(PROFILE)) +VALID_PROFILE := $(filter net_2_0 net_4_0 net_4_5 monotouch monodroid xammac mobile mobile_static, $(PROFILE)) ifndef VALID_PROFILE LIBRARY_NAME = dummy-System.ComponentModel.DataAnnotations.dll NO_INSTALL = yes diff --git a/mcs/class/System.ComponentModel.DataAnnotations/mobile_System.ComponentModel.DataAnnotations.dll.sources b/mcs/class/System.ComponentModel.DataAnnotations/mobile_System.ComponentModel.DataAnnotations.dll.sources new file mode 100644 index 0000000000..3de14f5e0a --- /dev/null +++ b/mcs/class/System.ComponentModel.DataAnnotations/mobile_System.ComponentModel.DataAnnotations.dll.sources @@ -0,0 +1 @@ +#include net_4_5_System.ComponentModel.DataAnnotations.dll.sources diff --git a/mcs/class/System.Core/Makefile b/mcs/class/System.Core/Makefile index c8836d3125..f8cc33c7e8 100644 --- a/mcs/class/System.Core/Makefile +++ b/mcs/class/System.Core/Makefile @@ -10,17 +10,16 @@ ifneq (2.1, $(FRAMEWORK_VERSION)) LIB_MCS_FLAGS += -d:NET_3_5 -nowarn:1720 endif -ifeq (monodroid, $(PROFILE)) -LIB_MCS_FLAGS += -d:FEATURE_CORE_DLR,FEATURE_REFEMIT,ANDROID -endif +MOBILE_DYNAMIC := $(filter monodroid xammac mobile, $(PROFILE)) +MOBILE_STATIC := $(filter mobile_static monotouch monotouch_runtime, $(PROFILE)) -ifeq (xammac, $(PROFILE)) +ifdef MOBILE_DYNAMIC LIB_MCS_FLAGS += -d:FEATURE_CORE_DLR,FEATURE_REFEMIT endif system_core_plain_libdir = $(the_libdir_base)plaincore -ifeq (monotouch, $(subst _runtime,,$(PROFILE))) +ifdef MOBILE_STATIC extra_test_flags := -exclude:NotWorkingInterpreter system_core_library_deps = $(the_libdir_base)Mono.Dynamic.Interpreter.dll $(system_core_plain_libdir)/System.Core.dll LIB_MCS_FLAGS += -d:FEATURE_CORE_DLR @@ -72,4 +71,4 @@ ifneq ($(PROFILE),basic) csproj-local: $(MAKE) csproj-local intermediate=plaincore/ endif -endif \ No newline at end of file +endif diff --git a/mcs/class/System.Core/System/TimeZoneInfo.AdjustmentRule.cs b/mcs/class/System.Core/System/TimeZoneInfo.AdjustmentRule.cs index 637d0c400d..37f21464dc 100644 --- a/mcs/class/System.Core/System/TimeZoneInfo.AdjustmentRule.cs +++ b/mcs/class/System.Core/System/TimeZoneInfo.AdjustmentRule.cs @@ -24,13 +24,16 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if (INSIDE_CORLIB && NET_4_0) || (!INSIDE_CORLIB && (NET_3_5 && !NET_4_0 && !MOBILE)) +#if INSIDE_CORLIB || (NET_3_5 && !NET_4_0 && !MOBILE) using System.Runtime.CompilerServices; using System.Runtime.Serialization; namespace System { - public sealed partial class TimeZoneInfo { +#if NET_4_0 || !INSIDE_CORLIB + public +#endif + sealed partial class TimeZoneInfo { [SerializableAttribute] #if MOBILE [TypeForwardedFrom (Consts.AssemblySystem_Core)] diff --git a/mcs/class/System.Core/System/TimeZoneInfo.Android.cs b/mcs/class/System.Core/System/TimeZoneInfo.Android.cs index 63502e555f..6794524f5f 100644 --- a/mcs/class/System.Core/System/TimeZoneInfo.Android.cs +++ b/mcs/class/System.Core/System/TimeZoneInfo.Android.cs @@ -453,29 +453,29 @@ namespace System { : db.GetAvailableIds (); } - static TimeZoneInfo _GetTimeZone (string name) + static TimeZoneInfo _GetTimeZone (string id, string name) { if (db == null) return null; byte[] buffer = db.GetTimeZoneData (name); if (buffer == null) return null; - return TimeZoneInfo.ParseTZBuffer (name, buffer, buffer.Length); + return TimeZoneInfo.ParseTZBuffer (id, buffer, buffer.Length); } - internal static TimeZoneInfo GetTimeZone (string id) + internal static TimeZoneInfo GetTimeZone (string id, string name) { - if (id != null) { - if (id == "GMT" || id == "UTC") - return new TimeZoneInfo (id, TimeSpan.FromSeconds (0), id, id, id, null, true); - if (id.StartsWith ("GMT")) + if (name != null) { + if (name == "GMT" || name == "UTC") + return new TimeZoneInfo (id, TimeSpan.FromSeconds (0), id, name, name, null, disableDaylightSavingTime:true); + if (name.StartsWith ("GMT")) return new TimeZoneInfo (id, - TimeSpan.FromSeconds (ParseNumericZone (id)), - id, id, id, null, true); + TimeSpan.FromSeconds (ParseNumericZone (name)), + id, name, name, null, disableDaylightSavingTime:true); } try { - return _GetTimeZone (id); + return _GetTimeZone (id, name); } catch (Exception) { return null; } @@ -533,12 +533,13 @@ namespace System { static readonly object _lock = new object (); static TimeZoneInfo defaultZone; - internal static TimeZoneInfo Default { + internal static TimeZoneInfo Local { get { lock (_lock) { if (defaultZone != null) return defaultZone; - return defaultZone = GetTimeZone (GetDefaultTimeZoneName ()); + var id = GetDefaultTimeZoneName (); + return defaultZone = GetTimeZone (id, id); } } } @@ -553,7 +554,10 @@ namespace System { { IntPtr value = IntPtr.Zero; int n = 0; - string defaultTimeZone; + string defaultTimeZone = Environment.GetEnvironmentVariable ("__XA_OVERRIDE_TIMEZONE_ID__"); + + if (!string.IsNullOrEmpty (defaultTimeZone)) + return defaultTimeZone; // Used by the tests if (Environment.GetEnvironmentVariable ("__XA_USE_JAVA_DEFAULT_TIMEZONE_ID__") == null) @@ -576,16 +580,20 @@ namespace System { #if SELF_TEST /* * Compile: - * mcs /out:tzi.exe /unsafe "/d:INSIDE_CORLIB;MONODROID;NET_4_0;LIBC;SELF_TEST" System/TimeZone*.cs ../../build/common/Consts.cs ../Mono.Options/Mono.Options/Options.cs + * mcs /debug+ /out:tzi.exe /unsafe "/d:INSIDE_CORLIB;MONODROID;NET_4_0;LIBC;SELF_TEST" ../corlib/System/AndroidPlatform.cs System/TimeZone*.cs ../../build/common/Consts.cs ../Mono.Options/Mono.Options/Options.cs * Prep: * mkdir -p usr/share/zoneinfo + * mkdir -p misc/zoneinfo/zoneinfo * android_root=`adb shell echo '$ANDROID_ROOT' | tr -d "\r"` + * android_data=`adb shell echo '$ANDROID_DATA' | tr -d "\r"` * adb pull $android_root/usr/share/zoneinfo usr/share/zoneinfo + * adb pull $android_data/misc/zoneinfo/tzdata misc/zoneinfo * Run: - * ANDROID_ROOT=`pwd` mono tzi.exe + * __XA_OVERRIDE_TIMEZONE_ID__=America/New_York ANDROID_ROOT=`pwd` ANDROID_DATA=`pwd` mono --debug tzi.exe --offset=1969-01-01 */ static void Main (string[] args) { + DateTime? offset = null; Func c = () => GetDefaultTimeZoneDB (); Mono.Options.OptionSet p = null; p = new Mono.Options.OptionSet () { @@ -595,6 +603,10 @@ namespace System { { "Z=", "Create ZoneInfoDB from {DIR}.", v => { c = () => new ZoneInfoDB (v); } }, + { "offset=", "Show timezone info offset for DateTime {OFFSET}.", v => { + offset = DateTime.Parse (v); + Console.WriteLine ("Using DateTime Offset: {0}", offset); + } }, { "help", "Show this message and exit", v => { p.WriteOptionDescriptions (Console.Out); Environment.Exit (0); @@ -606,9 +618,13 @@ namespace System { foreach (var id in GetAvailableIds ()) { Console.Write ("name={0,-40}", id); try { - TimeZoneInfo zone = _GetTimeZone (id); - if (zone != null) - Console.Write (" {0}", zone); + TimeZoneInfo zone = _GetTimeZone (id, id); + if (zone != null) { + Console.Write (" {0,-40}", zone); + if (offset.HasValue) { + Console.Write ("From Offset: {0}", zone.GetUtcOffset (offset.Value)); + } + } else { Console.Write (" ERROR:null"); } diff --git a/mcs/class/System.Core/System/TimeZoneInfo.Serialization.cs b/mcs/class/System.Core/System/TimeZoneInfo.Serialization.cs index 22aa38c5fa..3a7da39ec7 100644 --- a/mcs/class/System.Core/System/TimeZoneInfo.Serialization.cs +++ b/mcs/class/System.Core/System/TimeZoneInfo.Serialization.cs @@ -24,7 +24,7 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if (INSIDE_CORLIB && NET_4_0) || (!INSIDE_CORLIB && (NET_3_5 && !NET_4_0 && !MOBILE)) +#if INSIDE_CORLIB || (NET_3_5 && !NET_4_0 && !MOBILE) using System.Collections.Generic; using System.Globalization; @@ -33,7 +33,10 @@ using System.Text; namespace System { - public partial class TimeZoneInfo +#if NET_4_0 || !INSIDE_CORLIB + public +#endif + partial class TimeZoneInfo { public static TimeZoneInfo FromSerializedString (string source) { diff --git a/mcs/class/System.Core/System/TimeZoneInfo.TransitionTime.cs b/mcs/class/System.Core/System/TimeZoneInfo.TransitionTime.cs index d57df150f0..719bb9d51f 100644 --- a/mcs/class/System.Core/System/TimeZoneInfo.TransitionTime.cs +++ b/mcs/class/System.Core/System/TimeZoneInfo.TransitionTime.cs @@ -24,14 +24,17 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if (INSIDE_CORLIB && NET_4_0) || (!INSIDE_CORLIB && (NET_3_5 && !NET_4_0 && !MOBILE)) +#if INSIDE_CORLIB || (NET_3_5 && !NET_4_0 && !MOBILE) using System.Runtime.CompilerServices; using System.Runtime.Serialization; namespace System { - public sealed partial class TimeZoneInfo +#if NET_4_0 || !INSIDE_CORLIB + public +#endif + sealed partial class TimeZoneInfo { [SerializableAttribute] #if MOBILE diff --git a/mcs/class/System.Core/System/TimeZoneInfo.cs b/mcs/class/System.Core/System/TimeZoneInfo.cs index aead18c764..15298e6650 100644 --- a/mcs/class/System.Core/System/TimeZoneInfo.cs +++ b/mcs/class/System.Core/System/TimeZoneInfo.cs @@ -35,7 +35,7 @@ using System.Threading; [assembly:TypeForwardedTo (typeof(TimeZoneInfo))] -#elif (INSIDE_CORLIB && NET_4_0) || (!INSIDE_CORLIB && (NET_3_5 && !NET_4_0 && !MOBILE)) +#elif INSIDE_CORLIB || (NET_3_5 && !NET_4_0 && !MOBILE) using System.Collections.Generic; using System.Collections.ObjectModel; @@ -57,7 +57,10 @@ namespace System [TypeForwardedFrom (Consts.AssemblySystemCore_3_5)] #endif [SerializableAttribute] - public sealed partial class TimeZoneInfo : IEquatable, ISerializable, IDeserializationCallback +#if NET_4_0 || !INSIDE_CORLIB + public +#endif + sealed partial class TimeZoneInfo : IEquatable, ISerializable, IDeserializationCallback { TimeSpan baseUtcOffset; public TimeSpan BaseUtcOffset { @@ -100,15 +103,31 @@ namespace System } } + /* + TimeZone transitions are stored when there is a change on the base offset. + */ + private List> transitions; + static TimeZoneInfo CreateLocal () { #if MONODROID - return AndroidTimeZones.Default; + return AndroidTimeZones.Local; #elif MONOTOUCH using (Stream stream = GetMonoTouchData (null)) { return BuildFromStream ("Local", stream); } #elif LIBC + var tz = Environment.GetEnvironmentVariable ("TZ"); + if (tz != null) { + if (tz == String.Empty) + return Utc; + try { + return FindSystemTimeZoneByFileName (tz, Path.Combine (TimeZoneDirectory, tz)); + } catch { + return Utc; + } + } + try { return FindSystemTimeZoneByFileName ("Local", "/etc/localtime"); } catch { @@ -332,8 +351,7 @@ namespace System if (dateTime.Kind == DateTimeKind.Utc) return dateTime; - //FIXME: do not rely on DateTime implementation ! - return DateTime.SpecifyKind (dateTime.ToUniversalTime (), DateTimeKind.Utc); + return ConvertTimeToUtc (dateTime, TimeZoneInfo.Local); } public static DateTime ConvertTimeToUtc (DateTime dateTime, TimeZoneInfo sourceTimeZone) @@ -350,15 +368,9 @@ namespace System if (sourceTimeZone.IsInvalidTime (dateTime)) throw new ArgumentException ("dateTime parameter is an invalid time"); - if (dateTime.Kind == DateTimeKind.Utc && sourceTimeZone == TimeZoneInfo.Utc) - return dateTime; - if (dateTime.Kind == DateTimeKind.Utc) return dateTime; - if (dateTime.Kind == DateTimeKind.Local) - return ConvertTimeToUtc (dateTime); - if (sourceTimeZone.IsAmbiguousTime (dateTime) || !sourceTimeZone.IsDaylightSavingTime (dateTime)) return DateTime.SpecifyKind (dateTime - sourceTimeZone.BaseUtcOffset, DateTimeKind.Utc); else { @@ -414,12 +426,6 @@ namespace System return FromRegistryKey(id, key); } #endif -#if MONODROID - var timeZoneInfo = AndroidTimeZones.GetTimeZone (id); - if (timeZoneInfo == null) - throw new TimeZoneNotFoundException (); - return timeZoneInfo; -#else // Local requires special logic that already exists in the Local property (bug #326) if (id == "Local") return Local; @@ -427,12 +433,16 @@ namespace System using (Stream stream = GetMonoTouchData (id)) { return BuildFromStream (id, stream); } +#elif MONODROID + var timeZoneInfo = AndroidTimeZones.GetTimeZone (id, id); + if (timeZoneInfo == null) + throw new TimeZoneNotFoundException (); + return timeZoneInfo; #elif LIBC string filepath = Path.Combine (TimeZoneDirectory, id); return FindSystemTimeZoneByFileName (id, filepath); #else throw new NotImplementedException (); -#endif #endif } @@ -644,7 +654,7 @@ namespace System #endif #if MONODROID foreach (string id in AndroidTimeZones.GetAvailableIds ()) { - var tz = AndroidTimeZones.GetTimeZone (id); + var tz = AndroidTimeZones.GetTimeZone (id, id); if (tz != null) systemTimeZones.Add (tz); } @@ -684,13 +694,8 @@ namespace System public TimeSpan GetUtcOffset (DateTime dateTime) { - if (IsDaylightSavingTime (dateTime)) { - AdjustmentRule rule = GetApplicableRule (dateTime); - if (rule != null) - return BaseUtcOffset + rule.DaylightDelta; - } - - return BaseUtcOffset; + bool isDST; + return GetUtcOffset (dateTime, out isDST); } public TimeSpan GetUtcOffset (DateTimeOffset dateTimeOffset) @@ -698,6 +703,82 @@ namespace System throw new NotImplementedException (); } + private TimeSpan GetUtcOffset (DateTime dateTime, out bool isDST) + { + isDST = false; + + TimeZoneInfo tz = this; + if (dateTime.Kind == DateTimeKind.Utc) + tz = TimeZoneInfo.Utc; + + if (dateTime.Kind == DateTimeKind.Local) + tz = TimeZoneInfo.Local; + + bool isTzDst; + var tzOffset = GetUtcOffset (dateTime, tz, out isTzDst); + + if (tz == this) { + isDST = isTzDst; + return tzOffset; + } + + var utcTicks = dateTime.Ticks - tzOffset.Ticks; + if (utcTicks < 0 || utcTicks > DateTime.MaxValue.Ticks) + return BaseUtcOffset; + + var utcDateTime = new DateTime (utcTicks, DateTimeKind.Utc); + + return GetUtcOffset (utcDateTime, this, out isDST); + } + + private static TimeSpan GetUtcOffset (DateTime dateTime, TimeZoneInfo tz, out bool isDST) + { + if (dateTime.Kind == DateTimeKind.Local && tz != TimeZoneInfo.Local) + throw new Exception (); + + isDST = false; + + if (tz == TimeZoneInfo.Utc) + return TimeSpan.Zero; + + TimeSpan offset; + if (tz.TryGetTransitionOffset(dateTime, out offset, out isDST)) + return offset; + + if (dateTime.Kind == DateTimeKind.Utc) { + var utcRule = tz.GetApplicableRule (dateTime); + if (utcRule != null && tz.IsInDST (utcRule, dateTime)) { + isDST = true; + return tz.BaseUtcOffset + utcRule.DaylightDelta; + } + + return tz.BaseUtcOffset; + } + + var stdTicks = dateTime.Ticks - tz.BaseUtcOffset.Ticks; + if (stdTicks < 0 || stdTicks > DateTime.MaxValue.Ticks) + return tz.BaseUtcOffset; + + var stdUtcDateTime = new DateTime (stdTicks, DateTimeKind.Utc); + var tzRule = tz.GetApplicableRule (stdUtcDateTime); + + DateTime dstUtcDateTime = DateTime.MinValue; + if (tzRule != null) { + var dstTicks = stdUtcDateTime.Ticks - tzRule.DaylightDelta.Ticks; + if (dstTicks < 0 || dstTicks > DateTime.MaxValue.Ticks) + return tz.BaseUtcOffset; + + dstUtcDateTime = new DateTime (dstTicks, DateTimeKind.Utc); + } + + if (tzRule != null && tz.IsInDST (tzRule, stdUtcDateTime) && tz.IsInDST (tzRule, dstUtcDateTime)) { + isDST = true; + return tz.BaseUtcOffset + tzRule.DaylightDelta; + } + + return tz.BaseUtcOffset; + } + public bool HasSameRules (TimeZoneInfo other) { if (other == null) @@ -752,6 +833,16 @@ namespace System throw new NotImplementedException (); } + private bool IsInDST (AdjustmentRule rule, DateTime dateTime) + { + // Check whether we're in the dateTime year's DST period + if (IsInDSTForYear (rule, dateTime, dateTime.Year)) + return true; + + // We might be in the dateTime previous year's DST period + return IsInDSTForYear (rule, dateTime, dateTime.Year - 1); + } + bool IsInDSTForYear (AdjustmentRule rule, DateTime dateTime, int year) { DateTime DST_start = TransitionPoint (rule.DaylightTransitionStart, year); @@ -774,25 +865,11 @@ namespace System if (!SupportsDaylightSavingTime) return false; - - //FIXME: do not rely on DateTime implementation ! - if ((dateTime.Kind == DateTimeKind.Local || dateTime.Kind == DateTimeKind.Unspecified) && this == TimeZoneInfo.Local) - return dateTime.IsDaylightSavingTime (); - - //FIXME: do not rely on DateTime implementation ! - if (dateTime.Kind == DateTimeKind.Local && this != TimeZoneInfo.Utc) - return IsDaylightSavingTime (DateTime.SpecifyKind (dateTime.ToUniversalTime (), DateTimeKind.Utc)); - - AdjustmentRule rule = GetApplicableRule (dateTime.Date); - if (rule == null) - return false; - // Check whether we're in the dateTime year's DST period - if (IsInDSTForYear (rule, dateTime, dateTime.Year)) - return true; + bool isDst; + GetUtcOffset (dateTime, out isDst); - // We might be in the dateTime previous year's DST period - return IsInDSTForYear (rule, dateTime, dateTime.Year - 1); + return isDst; } public bool IsDaylightSavingTime (DateTimeOffset dateTimeOffset) @@ -969,6 +1046,40 @@ namespace System return null; } + private bool TryGetTransitionOffset (DateTime dateTime, out TimeSpan offset,out bool isDst) + { + offset = BaseUtcOffset; + isDst = false; + + if (transitions == null) + return false; + + //Transitions are always in standard time + DateTime date = dateTime; + + if (dateTime.Kind == DateTimeKind.Local && this != TimeZoneInfo.Local) + date = date.ToUniversalTime () + BaseUtcOffset; + + if (dateTime.Kind == DateTimeKind.Utc && this != TimeZoneInfo.Utc) + date = date + BaseUtcOffset; + + for (var i = transitions.Count - 1; i >= 0; i--) { + var pair = transitions [i]; + DateTime ttime = pair.Key; + TimeType ttype = pair.Value; + + if (ttime > date) + continue; + + offset = new TimeSpan (0, 0, ttype.Offset); + isDst = ttype.IsDst; + + return true; + } + + return false; + } + private static DateTime TransitionPoint (TransitionTime transition, int year) { if (transition.IsFixedDateRule) @@ -1059,6 +1170,7 @@ namespace System bool dst_observed = false; DateTime dst_start = DateTime.MinValue; List adjustmentRules = new List (); + bool storeTransition = false; for (int i = 0; i < transitions.Count; i++) { var pair = transitions [i]; @@ -1069,6 +1181,8 @@ namespace System standardDisplayName = ttype.Name; daylightDisplayName = null; baseUtcOffset = new TimeSpan (0, 0, ttype.Offset); + if (adjustmentRules.Count > 0) // We ignore AdjustmentRules but store transitions. + storeTransition = true; adjustmentRules = new List (); dst_observed = false; } @@ -1110,16 +1224,22 @@ namespace System } } - if (adjustmentRules.Count == 0) { + TimeZoneInfo tz; + if (adjustmentRules.Count == 0 && !storeTransition) { TimeType t = (TimeType)time_types [0]; if (standardDisplayName == null) { standardDisplayName = t.Name; baseUtcOffset = new TimeSpan (0, 0, t.Offset); } - return CreateCustomTimeZone (id, baseUtcOffset, id, standardDisplayName); + tz = CreateCustomTimeZone (id, baseUtcOffset, id, standardDisplayName); } else { - return CreateCustomTimeZone (id, baseUtcOffset, id, standardDisplayName, daylightDisplayName, ValidateRules (adjustmentRules).ToArray ()); + tz = CreateCustomTimeZone (id, baseUtcOffset, id, standardDisplayName, daylightDisplayName, ValidateRules (adjustmentRules).ToArray ()); } + + if (storeTransition) + tz.transitions = transitions; + + return tz; } static Dictionary ParseAbbreviations (byte [] buffer, int index, int count) diff --git a/mcs/class/System.Core/Test/System.Threading/ReaderWriterLockSlimTest.cs b/mcs/class/System.Core/Test/System.Threading/ReaderWriterLockSlimTest.cs index aef9fffbb5..8e2c317450 100644 --- a/mcs/class/System.Core/Test/System.Threading/ReaderWriterLockSlimTest.cs +++ b/mcs/class/System.Core/Test/System.Threading/ReaderWriterLockSlimTest.cs @@ -401,9 +401,14 @@ namespace MonoTests.System.Threading { var v = new ReaderWriterLockSlim (); int local = 10; + int ready_count = 0; + int entered_count = 0; + const int thread_count = 10; - var r = from i in Enumerable.Range (1, 10) select new Thread (() => { + var r = from i in Enumerable.Range (1, thread_count) select new Thread (() => { + Interlocked.Increment (ref ready_count); v.EnterReadLock (); + Interlocked.Increment (ref entered_count); Assert.AreEqual (11, local); }); @@ -415,12 +420,16 @@ namespace MonoTests.System.Threading t.Start (); } - Thread.Sleep (200); + while (ready_count != thread_count) + Thread.Sleep (10); + + /* Extra up to 2s of sleep to ensure all threads got the chance to enter the lock */ + for (int i = 0; i < 200 && v.WaitingReadCount != thread_count; ++i) + Thread.Sleep (10); local = 11; - // FIXME: Don't rely on Thread.Sleep (200) Assert.AreEqual (0, v.WaitingWriteCount, "in waiting write"); - Assert.AreEqual (10, v.WaitingReadCount, "in waiting read"); + Assert.AreEqual (thread_count, v.WaitingReadCount, "in waiting read"); Assert.AreEqual (0, v.WaitingUpgradeCount, "in waiting upgrade"); v.ExitWriteLock (); diff --git a/mcs/class/System.Core/Test/System/TimeZoneInfoTest.cs b/mcs/class/System.Core/Test/System/TimeZoneInfoTest.cs index f6ea66e98c..c3972e747c 100644 --- a/mcs/class/System.Core/Test/System/TimeZoneInfoTest.cs +++ b/mcs/class/System.Core/Test/System/TimeZoneInfoTest.cs @@ -232,7 +232,7 @@ namespace MonoTests.System DateTime afterDST = new DateTime (2007, 10, 28, 2, 0, 0, DateTimeKind.Unspecified); Assert.IsFalse (london.IsDaylightSavingTime (beforeDST), "Just before DST"); Assert.IsTrue (london.IsDaylightSavingTime (startDST), "the first seconds of DST"); - Assert.IsTrue (london.IsDaylightSavingTime (endDST), "The last seconds of DST"); + Assert.IsFalse (london.IsDaylightSavingTime (endDST), "The last seconds of DST"); Assert.IsFalse (london.IsDaylightSavingTime (afterDST), "Just after DST"); } @@ -804,6 +804,143 @@ namespace MonoTests.System Assert.IsTrue (london.Equals (deserialized)); } } + + [TestFixture] + public class MultipleDaylightSavingTimeTests { + private TimeZoneInfo cairo; + private DateTime dst1Start; + private DateTime dst1End; + private DateTime dst2Start; + private DateTime dst2End; + + private TimeSpan baseUtcOffset; + private TimeSpan dstUtcOffset; + private TimeSpan dstOffset; + + [SetUp] + public void CreateTimeZones () + { + /* + From 1/1/2014 12:00:00 AM to 6/30/2014 12:00:00 AM + Delta: 01:00:00 + Begins at 12:00 AM on 16 May + Ends at 1:00 AM on 29 June + From 7/1/2014 12:00:00 AM to 12/31/2014 12:00:00 AM + Delta: 01:00:00 + Begins at 12:00 AM on 29 July + Ends at 12:00 AM on 26 September + */ + dst1Start = new DateTime (2014, 5, 16); + dst1End = new DateTime (2014, 6, 29); + dst2Start = new DateTime (2014, 7, 29); + dst2End = new DateTime (2014, 9, 26); + + baseUtcOffset = new TimeSpan (2, 0, 0); + dstUtcOffset = new TimeSpan (3, 0, 0); + dstOffset = dstUtcOffset - baseUtcOffset; + + var rule1 = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule ( + new DateTime (2014, 1, 1), new DateTime (2014, 6, 30), dstOffset, + CreateFixedDateRule (dst1Start), CreateFixedDateRule (dst1End)); + + var rule2 = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule ( + new DateTime (2014, 7, 1), new DateTime (2014, 12, 31), dstOffset, + CreateFixedDateRule (dst2Start), CreateFixedDateRule (dst2End)); + + cairo = TimeZoneInfo.CreateCustomTimeZone ("Africa/Cairo", baseUtcOffset, "Africa/Cairo", "EET", "EEST", + new [] {rule1, rule2}); + } + + private static TimeZoneInfo.TransitionTime CreateFixedDateRule (DateTime dateTime) + { + var time = new DateTime (dateTime.Ticks - dateTime.Date.Ticks); + return TimeZoneInfo.TransitionTime.CreateFixedDateRule (time, dateTime.Month, dateTime.Day); + } + + [Test] + public void GetUtcOffset_FromUTC () + { + var d = dst1Start.Add (-baseUtcOffset); + d = DateTime.SpecifyKind (d, DateTimeKind.Utc); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0,-1)))); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d)); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0, 1)))); + + d = dst1End.Add (-baseUtcOffset-dstOffset); + d = DateTime.SpecifyKind (d, DateTimeKind.Utc); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0,-1)))); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d)); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0, 1)))); + + d = dst2Start.Add (-baseUtcOffset); + d = DateTime.SpecifyKind (d, DateTimeKind.Utc); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0,-1)))); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d)); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0, 1)))); + + d = dst2End.Add (-baseUtcOffset-dstOffset); + d = DateTime.SpecifyKind (d, DateTimeKind.Utc); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0,-1)))); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d)); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0, 1)))); + } + + [Test] + public void GetUtcOffset_FromLocal () + { + var d = dst1Start.Add (-baseUtcOffset); + d = DateTime.SpecifyKind (d, DateTimeKind.Utc); + d = d.ToLocalTime (); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0,-1)))); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d)); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0, 1)))); + + d = dst1End.Add (-baseUtcOffset-dstOffset); + d = DateTime.SpecifyKind (d, DateTimeKind.Utc); + d = d.ToLocalTime (); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0,-1)))); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d)); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0, 1)))); + + d = dst2Start.Add (-baseUtcOffset); + d = DateTime.SpecifyKind (d, DateTimeKind.Utc); + d = d.ToLocalTime (); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0,-1)))); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d)); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0, 1)))); + + d = dst2End.Add (-baseUtcOffset-dstOffset); + d = DateTime.SpecifyKind (d, DateTimeKind.Utc); + d = d.ToLocalTime (); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0,-1)))); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d)); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0, 1)))); + } + + [Test] + public void GetUtcOffset_FromUnspecified () + { + var d = dst1Start.Add (dstOffset); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0,-1)))); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d)); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0, 1)))); + + d = dst1End.Add (-dstOffset); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0,-1)))); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d)); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0, 1)))); + + d = dst2Start.Add (dstOffset); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0,-1)))); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d)); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0, 1)))); + + d = dst2End.Add (-dstOffset); + Assert.AreEqual(dstUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0,-1)))); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d)); + Assert.AreEqual(baseUtcOffset, cairo.GetUtcOffset (d.Add (new TimeSpan(0,0,0, 1)))); + } + } } } #endif diff --git a/mcs/class/System.Core/mobile_System.Core.dll.sources b/mcs/class/System.Core/mobile_System.Core.dll.sources index dee2534a29..5cd8ddf660 100644 --- a/mcs/class/System.Core/mobile_System.Core.dll.sources +++ b/mcs/class/System.Core/mobile_System.Core.dll.sources @@ -1,109 +1,4 @@ -Assembly/AssemblyInfo.cs -System/Actions.cs -System/Funcs.cs -System/InvalidTimeZoneException.cs -System/TimeZoneInfo.AdjustmentRule.cs -System/TimeZoneInfo.cs -System/TimeZoneInfo.Serialization.cs -System/TimeZoneInfo.TransitionTime.cs -System/TimeZoneNotFoundException.cs -System/Util.cs -System.Runtime.CompilerServices/DynamicAttribute.cs -System.Runtime.CompilerServices/ExecutionScope.cs -System.Runtime.CompilerServices/ExtensionAttribute.cs -System.Runtime.CompilerServices/IStrongBox.cs -System.Runtime.CompilerServices/StrongBox_T.cs -System.Linq/Check.cs -System.Linq/Enumerable.cs -System.Linq/QueryableEnumerable.cs -System.Linq/QueryableTransformer.cs -System.Linq/Grouping.cs -System.Linq/IGrouping.cs -System.Linq/IOrderedQueryable.cs -System.Linq/IOrderedQueryable_T.cs -System.Linq/IOrderedEnumerable_T.cs -System.Linq/IQueryable.cs -System.Linq/IQueryable_T.cs -System.Linq/Lookup.cs -System.Linq/ILookup_T.cs -System.Linq/OrderedEnumerable.cs -System.Linq/OrderedSequence.cs -System.Linq/Queryable.cs -System.Linq/QuickSort.cs -System.Linq/SortContext.cs -System.Linq/SortDirection.cs -System.Linq/SortSequenceContext.cs -System.Linq/IQueryProvider.cs -System.Collections.Generic/HashSet.cs -System.Security.Cryptography/Aes.cs -System.Threading/LockRecursionPolicy.cs -System.Threading/ReaderWriterLockSlim.cs -System.Threading/ThreadLockState.cs -System.Threading/ReaderWriterLockSlimExtensions.cs -System.Linq.Parallel.QueryNodes/QueryBaseNode.cs -System.Linq.Parallel.QueryNodes/QueryCastNode.cs -System.Linq.Parallel.QueryNodes/QueryChildNode.cs -System.Linq.Parallel.QueryNodes/QueryConcatNode.cs -System.Linq.Parallel.QueryNodes/QueryDefaultEmptyNode.cs -System.Linq.Parallel.QueryNodes/QueryGroupByNode.cs -System.Linq.Parallel.QueryNodes/QueryHeadWorkerNode.cs -System.Linq.Parallel.QueryNodes/QueryJoinNode.cs -System.Linq.Parallel.QueryNodes/QueryMuxNode.cs -System.Linq.Parallel.QueryNodes/QueryOptionNode.cs -System.Linq.Parallel.QueryNodes/QueryOrderByNode.cs -System.Linq.Parallel.QueryNodes/QueryOrderGuardNode.cs -System.Linq.Parallel.QueryNodes/QueryOrderedStreamNode.cs -System.Linq.Parallel.QueryNodes/QueryReverseNode.cs -System.Linq.Parallel.QueryNodes/QuerySelectManyNode.cs -System.Linq.Parallel.QueryNodes/QuerySelectNode.cs -System.Linq.Parallel.QueryNodes/QuerySetNode.cs -System.Linq.Parallel.QueryNodes/QueryStartNode.cs -System.Linq.Parallel.QueryNodes/QueryStreamNode.cs -System.Linq.Parallel.QueryNodes/QueryWhereNode.cs -System.Linq.Parallel.QueryNodes/QueryZipNode.cs -System.Linq.Parallel.QueryNodes/SetInclusion.cs -System.Linq.Parallel.QueryNodes/WrapHelper.cs -System.Linq.Parallel/AggregationList.cs -System.Linq.Parallel/ConcurrentGrouping.cs -System.Linq.Parallel/ConcurrentLookup.cs -System.Linq.Parallel/INodeVisitor.cs -System.Linq.Parallel/IVisitableNode.cs -System.Linq.Parallel/OrderingEnumerator.cs -System.Linq.Parallel/ParallelExecuter.cs -System.Linq.Parallel/ParallelPartitioner.cs -System.Linq.Parallel/ParallelQueryEnumerator.cs -System.Linq.Parallel/ParallelQuickSort.cs -System.Linq.Parallel/QueryCheckerVisitor.cs -System.Linq.Parallel/QueryIsOrderedVisitor.cs -System.Linq.Parallel/QueryOptions.cs -System.Linq.Parallel/RangeList.cs -System.Linq.Parallel/RepeatList.cs -System.Linq.Parallel/ReverseList.cs -System.Linq.Parallel/StripPartitioner.cs -System.Linq.Parallel/TemporaryArea.cs -System.Linq/EnumerableExecutor.cs -System.Linq/EnumerableExecutor_T.cs -System.Linq/EnumerableQuery.cs -System.Linq/EnumerableQuery_T.cs -System.Linq/OrderedParallelQuery.cs -System.Linq/ParallelEnumerable.cs -System.Linq/ParallelExecutionMode.cs -System.Linq/ParallelMergeOptions.cs -System.Linq/ParallelQuery.cs -System.IO.MemoryMappedFiles/MemoryMappedFile.cs -System.IO.MemoryMappedFiles/MemoryMappedFileAccess.cs -System.IO.MemoryMappedFiles/MemoryMappedFileOptions.cs -System.IO.MemoryMappedFiles/MemoryMappedFileRights.cs -System.IO.MemoryMappedFiles/MemoryMappedFileSecurity.cs -System.IO.MemoryMappedFiles/MemoryMappedViewStream.cs -System.IO.MemoryMappedFiles/MemoryMappedViewAccessor.cs -Microsoft.Win32.SafeHandles/SafeMemoryMappedFileHandle.cs -Microsoft.Win32.SafeHandles/SafeMemoryMappedViewHandle.cs -System.IO/HandleInheritability.cs -System.Threading.Tasks/TaskExtensions.cs -System.Linq.Expressions/Extensions.cs -System.Linq.Expressions/ExpressionTransformer.cs -../dlr/Runtime/Microsoft.Scripting.Core/Ast/DynamicExpression.cs -../dlr/Runtime/Microsoft.Scripting.Core/Compiler/Closure.cs -System.Linq.Expressions/DynamicExpressionVisitor.cs +#include mobile_common_System.Core.dll.sources + +#include dynamic_System.Core.dll.sources diff --git a/mcs/class/System.Core/mobile_common_System.Core.dll.sources b/mcs/class/System.Core/mobile_common_System.Core.dll.sources new file mode 100644 index 0000000000..10e8623125 --- /dev/null +++ b/mcs/class/System.Core/mobile_common_System.Core.dll.sources @@ -0,0 +1,108 @@ +Assembly/AssemblyInfo.cs +System/Actions.cs +System/Funcs.cs +System/InvalidTimeZoneException.cs +System/TimeZoneInfo.AdjustmentRule.cs +System/TimeZoneInfo.cs +System/TimeZoneInfo.Serialization.cs +System/TimeZoneInfo.TransitionTime.cs +System/TimeZoneNotFoundException.cs +System/Util.cs +System.Runtime.CompilerServices/DynamicAttribute.cs +System.Runtime.CompilerServices/ExecutionScope.cs +System.Runtime.CompilerServices/ExtensionAttribute.cs +System.Runtime.CompilerServices/IStrongBox.cs +System.Runtime.CompilerServices/StrongBox_T.cs +System.Linq/Check.cs +System.Linq/Enumerable.cs +System.Linq/QueryableEnumerable.cs +System.Linq/QueryableTransformer.cs +System.Linq/Grouping.cs +System.Linq/IGrouping.cs +System.Linq/IOrderedQueryable.cs +System.Linq/IOrderedQueryable_T.cs +System.Linq/IOrderedEnumerable_T.cs +System.Linq/IQueryable.cs +System.Linq/IQueryable_T.cs +System.Linq/Lookup.cs +System.Linq/ILookup_T.cs +System.Linq/OrderedEnumerable.cs +System.Linq/OrderedSequence.cs +System.Linq/Queryable.cs +System.Linq/QuickSort.cs +System.Linq/SortContext.cs +System.Linq/SortDirection.cs +System.Linq/SortSequenceContext.cs +System.Linq/IQueryProvider.cs +System.Collections.Generic/HashSet.cs +System.Security.Cryptography/Aes.cs +System.Threading/LockRecursionPolicy.cs +System.Threading/ReaderWriterLockSlim.cs +System.Threading/ThreadLockState.cs +System.Threading/ReaderWriterLockSlimExtensions.cs +System.Linq.Parallel.QueryNodes/QueryBaseNode.cs +System.Linq.Parallel.QueryNodes/QueryCastNode.cs +System.Linq.Parallel.QueryNodes/QueryChildNode.cs +System.Linq.Parallel.QueryNodes/QueryConcatNode.cs +System.Linq.Parallel.QueryNodes/QueryDefaultEmptyNode.cs +System.Linq.Parallel.QueryNodes/QueryGroupByNode.cs +System.Linq.Parallel.QueryNodes/QueryHeadWorkerNode.cs +System.Linq.Parallel.QueryNodes/QueryJoinNode.cs +System.Linq.Parallel.QueryNodes/QueryMuxNode.cs +System.Linq.Parallel.QueryNodes/QueryOptionNode.cs +System.Linq.Parallel.QueryNodes/QueryOrderByNode.cs +System.Linq.Parallel.QueryNodes/QueryOrderGuardNode.cs +System.Linq.Parallel.QueryNodes/QueryOrderedStreamNode.cs +System.Linq.Parallel.QueryNodes/QueryReverseNode.cs +System.Linq.Parallel.QueryNodes/QuerySelectManyNode.cs +System.Linq.Parallel.QueryNodes/QuerySelectNode.cs +System.Linq.Parallel.QueryNodes/QuerySetNode.cs +System.Linq.Parallel.QueryNodes/QueryStartNode.cs +System.Linq.Parallel.QueryNodes/QueryStreamNode.cs +System.Linq.Parallel.QueryNodes/QueryWhereNode.cs +System.Linq.Parallel.QueryNodes/QueryZipNode.cs +System.Linq.Parallel.QueryNodes/SetInclusion.cs +System.Linq.Parallel.QueryNodes/WrapHelper.cs +System.Linq.Parallel/AggregationList.cs +System.Linq.Parallel/ConcurrentGrouping.cs +System.Linq.Parallel/ConcurrentLookup.cs +System.Linq.Parallel/INodeVisitor.cs +System.Linq.Parallel/IVisitableNode.cs +System.Linq.Parallel/OrderingEnumerator.cs +System.Linq.Parallel/ParallelExecuter.cs +System.Linq.Parallel/ParallelPartitioner.cs +System.Linq.Parallel/ParallelQueryEnumerator.cs +System.Linq.Parallel/ParallelQuickSort.cs +System.Linq.Parallel/QueryCheckerVisitor.cs +System.Linq.Parallel/QueryIsOrderedVisitor.cs +System.Linq.Parallel/QueryOptions.cs +System.Linq.Parallel/RangeList.cs +System.Linq.Parallel/RepeatList.cs +System.Linq.Parallel/ReverseList.cs +System.Linq.Parallel/StripPartitioner.cs +System.Linq.Parallel/TemporaryArea.cs +System.Linq/EnumerableExecutor.cs +System.Linq/EnumerableExecutor_T.cs +System.Linq/EnumerableQuery.cs +System.Linq/EnumerableQuery_T.cs +System.Linq/OrderedParallelQuery.cs +System.Linq/ParallelEnumerable.cs +System.Linq/ParallelExecutionMode.cs +System.Linq/ParallelMergeOptions.cs +System.Linq/ParallelQuery.cs +System.IO.MemoryMappedFiles/MemoryMappedFile.cs +System.IO.MemoryMappedFiles/MemoryMappedFileAccess.cs +System.IO.MemoryMappedFiles/MemoryMappedFileOptions.cs +System.IO.MemoryMappedFiles/MemoryMappedFileRights.cs +System.IO.MemoryMappedFiles/MemoryMappedFileSecurity.cs +System.IO.MemoryMappedFiles/MemoryMappedViewStream.cs +System.IO.MemoryMappedFiles/MemoryMappedViewAccessor.cs +Microsoft.Win32.SafeHandles/SafeMemoryMappedFileHandle.cs +Microsoft.Win32.SafeHandles/SafeMemoryMappedViewHandle.cs +System.IO/HandleInheritability.cs +System.Threading.Tasks/TaskExtensions.cs +System.Linq.Expressions/Extensions.cs +System.Linq.Expressions/ExpressionTransformer.cs +../dlr/Runtime/Microsoft.Scripting.Core/Ast/DynamicExpression.cs +../dlr/Runtime/Microsoft.Scripting.Core/Compiler/Closure.cs +System.Linq.Expressions/DynamicExpressionVisitor.cs diff --git a/mcs/class/System.Core/mobile_static_System.Core.dll.sources b/mcs/class/System.Core/mobile_static_System.Core.dll.sources new file mode 100644 index 0000000000..6da190e254 --- /dev/null +++ b/mcs/class/System.Core/mobile_static_System.Core.dll.sources @@ -0,0 +1,2 @@ +#include mobile_common_System.Core.dll.sources +#include interpreter_System.Core.dll.sources diff --git a/mcs/class/System.Core/monodroid_System.Core.dll.sources b/mcs/class/System.Core/monodroid_System.Core.dll.sources index c681f5a1f8..7228e910c4 100644 --- a/mcs/class/System.Core/monodroid_System.Core.dll.sources +++ b/mcs/class/System.Core/monodroid_System.Core.dll.sources @@ -1,4 +1,4 @@ -#include mobile_System.Core.dll.sources +#include mobile_common_System.Core.dll.sources #include dynamic_System.Core.dll.sources diff --git a/mcs/class/System.Core/monotouch_System.Core.dll.sources b/mcs/class/System.Core/monotouch_System.Core.dll.sources index fad05a08f1..1296c8186d 100644 --- a/mcs/class/System.Core/monotouch_System.Core.dll.sources +++ b/mcs/class/System.Core/monotouch_System.Core.dll.sources @@ -1,3 +1,3 @@ -#include mobile_System.Core.dll.sources +#include mobile_common_System.Core.dll.sources #include interpreter_System.Core.dll.sources System/TimeZoneInfo.MonoTouch.cs diff --git a/mcs/class/System.Core/xammac_System.Core.dll.sources b/mcs/class/System.Core/xammac_System.Core.dll.sources index 6ede304927..5cd8ddf660 100644 --- a/mcs/class/System.Core/xammac_System.Core.dll.sources +++ b/mcs/class/System.Core/xammac_System.Core.dll.sources @@ -1,4 +1,4 @@ -#include mobile_System.Core.dll.sources +#include mobile_common_System.Core.dll.sources #include dynamic_System.Core.dll.sources diff --git a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs index b6c229efb5..acef0f9047 100644 --- a/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs +++ b/mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs @@ -830,9 +830,12 @@ namespace DbLinq.Data.Linq } } - private static MethodInfo _WhereMethod = typeof(Queryable).GetMethods().First(m => m.Name == "Where"); + private static MethodInfo _WhereMethod; internal object GetOtherTableQuery(Expression predicate, ParameterExpression parameter, Type otherTableType, IQueryable otherTable) { + if (_WhereMethod == null) + System.Threading.Interlocked.CompareExchange (ref _WhereMethod, typeof(Queryable).GetMethods().First(m => m.Name == "Where"), null); + //predicate: other.EmployeeID== "WARTH" Expression lambdaPredicate = Expression.Lambda(predicate, parameter); //lambdaPredicate: other=>other.EmployeeID== "WARTH" diff --git a/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciCalls.cs b/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciCalls.cs index 3e1ce93078..e6125bf5c9 100644 --- a/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciCalls.cs +++ b/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciCalls.cs @@ -95,7 +95,7 @@ namespace System.Data.OracleClient.Oci IntPtr valuep, int value_sz, [MarshalAs (UnmanagedType.U2)] OciDataType dty, - ref short indp, + IntPtr indp, IntPtr alenp, IntPtr rcodep, uint maxarr_len, @@ -111,7 +111,7 @@ namespace System.Data.OracleClient.Oci ref IntPtr valuep, int value_sz, [MarshalAs (UnmanagedType.U2)] OciDataType dty, - ref short indp, + IntPtr indp, IntPtr alenp, IntPtr rcodep, uint maxarr_len, @@ -127,7 +127,7 @@ namespace System.Data.OracleClient.Oci byte[] valuep, int value_sz, [MarshalAs (UnmanagedType.U2)] OciDataType dty, - ref short indp, + IntPtr indp, IntPtr alenp, IntPtr rcodep, uint maxarr_len, @@ -142,7 +142,7 @@ namespace System.Data.OracleClient.Oci IntPtr valuep, int value_sz, [MarshalAs (UnmanagedType.U2)] OciDataType dty, - ref short indp, + IntPtr indp, IntPtr alenp, IntPtr rcodep, uint maxarr_len, @@ -157,7 +157,7 @@ namespace System.Data.OracleClient.Oci byte[] valuep, int value_sz, [MarshalAs (UnmanagedType.U2)] OciDataType dty, - ref short indp, + IntPtr indp, IntPtr alenp, IntPtr rcodep, uint maxarr_len, @@ -172,7 +172,7 @@ namespace System.Data.OracleClient.Oci ref IntPtr valuep, int value_sz, [MarshalAs (UnmanagedType.U2)] OciDataType dty, - ref short indp, + IntPtr indp, IntPtr alenp, IntPtr rcodep, uint maxarr_len, @@ -193,8 +193,8 @@ namespace System.Data.OracleClient.Oci IntPtr valuep, int value_sz, [MarshalAs (UnmanagedType.U4)] OciDataType dty, - ref short indp, - ref short rlenp, + IntPtr indp, + IntPtr rlenp, IntPtr rcodep, uint mode); @@ -206,8 +206,8 @@ namespace System.Data.OracleClient.Oci ref IntPtr valuep, int value_sz, [MarshalAs (UnmanagedType.U4)] OciDataType dty, - ref short indp, - ref short rlenp, + IntPtr indp, + IntPtr rlenp, IntPtr rcodep, uint mode); @@ -547,7 +547,7 @@ namespace System.Data.OracleClient.Oci IntPtr valuep, int value_sz, OciDataType dty, - ref short indp, + IntPtr indp, IntPtr alenp, IntPtr rcodep, uint maxarr_len, @@ -558,7 +558,7 @@ namespace System.Data.OracleClient.Oci Trace.WriteLineIf(traceOci, "OCIBindByName", "OCI"); #endif return OciNativeCalls.OCIBindByName (stmtp, out bindpp, errhp, placeholder, placeh_len, valuep, - value_sz, dty, ref indp, alenp, rcodep, maxarr_len, curelp, mode); + value_sz, dty, indp, alenp, rcodep, maxarr_len, curelp, mode); } internal static int OCIBindByNameRef (IntPtr stmtp, @@ -569,7 +569,7 @@ namespace System.Data.OracleClient.Oci ref IntPtr valuep, int value_sz, OciDataType dty, - ref short indp, + IntPtr indp, IntPtr alenp, IntPtr rcodep, uint maxarr_len, @@ -580,7 +580,7 @@ namespace System.Data.OracleClient.Oci Trace.WriteLineIf(traceOci, "OCIBindByName", "OCI"); #endif return OciNativeCalls.OCIBindByNameRef (stmtp, out bindpp, errhp, placeholder, placeh_len, ref valuep, - value_sz, dty, ref indp, alenp, rcodep, maxarr_len, curelp, mode); + value_sz, dty, indp, alenp, rcodep, maxarr_len, curelp, mode); } internal static int OCIBindByNameBytes (IntPtr stmtp, @@ -591,7 +591,7 @@ namespace System.Data.OracleClient.Oci byte[] valuep, int value_sz, [MarshalAs (UnmanagedType.U2)] OciDataType dty, - ref short indp, + IntPtr indp, IntPtr alenp, IntPtr rcodep, uint maxarr_len, @@ -602,7 +602,7 @@ namespace System.Data.OracleClient.Oci Trace.WriteLineIf(traceOci, "OCIBindByName", "OCI"); #endif return OciNativeCalls.OCIBindByNameBytes (stmtp, out bindpp, errhp, placeholder, placeh_len, valuep, - value_sz, dty, ref indp, alenp, rcodep, maxarr_len, curelp, mode); + value_sz, dty, indp, alenp, rcodep, maxarr_len, curelp, mode); } internal static int OCIBindByPos (IntPtr stmtp, @@ -612,7 +612,7 @@ namespace System.Data.OracleClient.Oci IntPtr valuep, int value_sz, [MarshalAs (UnmanagedType.U2)] OciDataType dty, - ref short indp, + IntPtr indp, IntPtr alenp, IntPtr rcodep, uint maxarr_len, @@ -623,7 +623,7 @@ namespace System.Data.OracleClient.Oci Trace.WriteLineIf(traceOci, "OCIBindByPos", "OCI"); #endif return OciNativeCalls.OCIBindByPos (stmtp, out bindpp, errhp, position, valuep, - value_sz, dty, ref indp, alenp, rcodep, maxarr_len, curelp, mode); + value_sz, dty, indp, alenp, rcodep, maxarr_len, curelp, mode); } internal static int OCIBindByPosRef (IntPtr stmtp, @@ -633,7 +633,7 @@ namespace System.Data.OracleClient.Oci ref IntPtr valuep, int value_sz, [MarshalAs (UnmanagedType.U2)] OciDataType dty, - ref short indp, + IntPtr indp, IntPtr alenp, IntPtr rcodep, uint maxarr_len, @@ -644,7 +644,7 @@ namespace System.Data.OracleClient.Oci Trace.WriteLineIf(traceOci, "OCIBindByPos", "OCI"); #endif return OciNativeCalls.OCIBindByPosRef (stmtp, out bindpp, errhp, position, ref valuep, - value_sz, dty, ref indp, alenp, rcodep, maxarr_len, curelp, mode); + value_sz, dty, indp, alenp, rcodep, maxarr_len, curelp, mode); } internal static int OCIBindByPosBytes (IntPtr stmtp, @@ -654,7 +654,7 @@ namespace System.Data.OracleClient.Oci byte[] valuep, int value_sz, [MarshalAs (UnmanagedType.U2)] OciDataType dty, - ref short indp, + IntPtr indp, IntPtr alenp, IntPtr rcodep, uint maxarr_len, @@ -665,7 +665,7 @@ namespace System.Data.OracleClient.Oci Trace.WriteLineIf(traceOci, "OCIBindByPos", "OCI"); #endif return OciNativeCalls.OCIBindByPosBytes (stmtp, out bindpp, errhp, position, valuep, - value_sz, dty, ref indp, alenp, rcodep, maxarr_len, curelp, mode); + value_sz, dty, indp, alenp, rcodep, maxarr_len, curelp, mode); } [DllImport ("oci")] @@ -723,8 +723,8 @@ namespace System.Data.OracleClient.Oci IntPtr valuep, int value_sz, OciDataType dty, - ref short indp, - ref short rlenp, + IntPtr indp, + IntPtr rlenp, IntPtr rcodep, uint mode) { @@ -732,7 +732,7 @@ namespace System.Data.OracleClient.Oci Trace.WriteLineIf(traceOci, "OCIDefineByPos", "OCI"); #endif return OciNativeCalls.OCIDefineByPos (stmtp, out defnpp, errhp, position, valuep, - value_sz, dty, ref indp, ref rlenp, rcodep, mode); + value_sz, dty, indp, rlenp, rcodep, mode); } internal static int OCIDefineByPosPtr (IntPtr stmtp, @@ -742,8 +742,8 @@ namespace System.Data.OracleClient.Oci ref IntPtr valuep, int value_sz, OciDataType dty, - ref short indp, - ref short rlenp, + IntPtr indp, + IntPtr rlenp, IntPtr rcodep, uint mode) { @@ -751,7 +751,7 @@ namespace System.Data.OracleClient.Oci Trace.WriteLineIf(traceOci, "OCIDefineByPosPtr", "OCI"); #endif return OciNativeCalls.OCIDefineByPosPtr (stmtp, out defnpp, errhp, position, ref valuep, - value_sz, dty, ref indp, ref rlenp, rcodep, mode); + value_sz, dty, indp, rlenp, rcodep, mode); } internal static int OCIDescriptorFree (IntPtr hndlp, diff --git a/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciDefineHandle.cs b/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciDefineHandle.cs index baf90c1865..9f46f98509 100644 --- a/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciDefineHandle.cs +++ b/mcs/class/System.Data.OracleClient/System.Data.OracleClient.Oci/OciDefineHandle.cs @@ -32,16 +32,16 @@ namespace System.Data.OracleClient.Oci //IntPtr handle; IntPtr value; - short indicator; + IntPtr indicator; //OracleType type; OciDataType ociType; OciDataType definedType; int definedSize; - short rlenp = 0; + IntPtr rlenp; //short precision; short scale; Type fieldType; - //string name; + string name; // Oracle defines the LONG VARCHAR and LONG VARRAW to have a size of 2 to the 31 power - 5 // see DefineLongVarChar and DefineLongVarRaw @@ -70,11 +70,13 @@ namespace System.Data.OracleClient.Oci { OciParameterDescriptor parameter = ((OciStatementHandle) Parent).GetParameter (position); - //name = parameter.GetName (); + name = parameter.GetName (); definedType = parameter.GetDataType (); definedSize = parameter.GetDataSize (); //precision = parameter.GetPrecision (); scale = parameter.GetScale (); + rlenp = OciCalls.AllocateClear (sizeof(short)); + indicator = OciCalls.AllocateClear (sizeof(short)); Define (position, connection); @@ -103,7 +105,7 @@ namespace System.Data.OracleClient.Oci } internal bool IsNull { - get { return (indicator == -1); } + get { return (Indicator == -1); } } internal short Scale { @@ -111,7 +113,13 @@ namespace System.Data.OracleClient.Oci } internal short Size { - get { return rlenp; } + get { return(Marshal.ReadInt16(rlenp)); } + set { Marshal.WriteInt16(rlenp, value); } + } + + internal short Indicator { + get { return(Marshal.ReadInt16(indicator)); } + set { Marshal.WriteInt16(indicator, value); } } internal IntPtr Value { @@ -192,8 +200,8 @@ namespace System.Data.OracleClient.Oci ref value, definedSize, ociType, - ref indicator, - ref rlenp, + indicator, + rlenp, IntPtr.Zero, 0); @@ -222,8 +230,8 @@ namespace System.Data.OracleClient.Oci value, definedSize, ociType, - ref indicator, - ref rlenp, + indicator, + rlenp, IntPtr.Zero, 0); @@ -261,11 +269,11 @@ namespace System.Data.OracleClient.Oci value, definedSize, ociType, - ref indicator, - ref rlenp, + indicator, + rlenp, IntPtr.Zero, 0); - rlenp = (short) definedSize; + Size = (short) definedSize; if (status != 0) { OciErrorInfo info = ErrorHandle.HandleError (); @@ -291,8 +299,8 @@ namespace System.Data.OracleClient.Oci value, maxByteCount, ociType, - ref indicator, - ref rlenp, + indicator, + rlenp, IntPtr.Zero, 0); OciErrorHandle.ThrowExceptionIfError (ErrorHandle, status); @@ -312,10 +320,10 @@ namespace System.Data.OracleClient.Oci ErrorHandle, position + 1, value, - definedSize * 2, + definedSize, ociType, - ref indicator, - ref rlenp, + indicator, + rlenp, IntPtr.Zero, 0); @@ -357,8 +365,8 @@ namespace System.Data.OracleClient.Oci ref value, definedSize, ociType, - ref indicator, - ref rlenp, + indicator, + rlenp, IntPtr.Zero, 0); @@ -386,8 +394,8 @@ namespace System.Data.OracleClient.Oci value, definedSize, ociType, - ref indicator, - ref rlenp, + indicator, + rlenp, IntPtr.Zero, 0); if (status != 0) { @@ -415,8 +423,8 @@ namespace System.Data.OracleClient.Oci value, definedSize, ociType, - ref indicator, - ref rlenp, + indicator, + rlenp, IntPtr.Zero, 0); if (status != 0) { @@ -459,8 +467,8 @@ namespace System.Data.OracleClient.Oci ref value, definedSize, ociType, - ref indicator, - ref rlenp, + indicator, + rlenp, IntPtr.Zero, 0); @@ -487,6 +495,8 @@ namespace System.Data.OracleClient.Oci } disposed = true; } finally { + Marshal.FreeHGlobal (indicator); + Marshal.FreeHGlobal (rlenp); base.Dispose (disposing); value = IntPtr.Zero; } diff --git a/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs b/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs index 6f11d970f0..ef5eb27020 100644 --- a/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs +++ b/mcs/class/System.Data.OracleClient/System.Data.OracleClient/OracleParameter.cs @@ -37,12 +37,13 @@ using System.Text; namespace System.Data.OracleClient { [TypeConverter (typeof(OracleParameter.OracleParameterConverter))] - public sealed class OracleParameter : + public sealed class OracleParameter : #if NET_2_0 - DbParameter, IDbDataParameter, ICloneable + DbParameter, IDbDataParameter, ICloneable, #else - MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable + MarshalByRefObject, IDbDataParameter, IDataParameter, ICloneable, #endif + IDisposable { #region Fields @@ -66,6 +67,7 @@ namespace System.Data.OracleClient object value = DBNull.Value; OciLobLocator lobLocator; // only if Blob or Clob IntPtr bindOutValue = IntPtr.Zero; + IntPtr indicator = IntPtr.Zero; OciDateTimeDescriptor dateTimeDesc; IntPtr cursor = IntPtr.Zero; @@ -77,7 +79,6 @@ namespace System.Data.OracleClient bool useRef; OciDataType bindType; - short indicator; int bindSize; bool sizeManuallySet; @@ -104,6 +105,7 @@ namespace System.Data.OracleClient this.value = value.value; this.lobLocator = value.lobLocator; this.oracleTypeSet = value.oracleTypeSet; + this.indicator = OciCalls.AllocateClear (sizeof(short)); } public OracleParameter () @@ -119,6 +121,7 @@ namespace System.Data.OracleClient this.srcVersion = DataRowVersion.Current; this.value = null; this.oracleTypeSet = false; + this.indicator = OciCalls.AllocateClear (sizeof(short)); } public OracleParameter (string name, object value) @@ -129,6 +132,7 @@ namespace System.Data.OracleClient srcColumn = string.Empty; SourceVersion = DataRowVersion.Current; InferOracleType (value); + this.indicator = OciCalls.AllocateClear (sizeof(short)); #if NET_2_0 // Find the OciType before inferring for the size if (value != null && value != DBNull.Value) { @@ -173,6 +177,7 @@ namespace System.Data.OracleClient OracleType = oracleType; SourceColumn = sourceColumn; SourceVersion = sourceVersion; + this.indicator = OciCalls.AllocateClear (sizeof(short)); } #endif @@ -199,6 +204,12 @@ namespace System.Data.OracleClient OracleType = oracleType; SourceColumn = srcColumn; SourceVersion = srcVersion; + this.indicator = OciCalls.AllocateClear (sizeof(short)); + } + + ~OracleParameter () + { + Dispose(false); } #endregion // Constructors @@ -210,6 +221,11 @@ namespace System.Data.OracleClient set { container = value; } } + internal short Indicator { + get { return (Marshal.ReadInt16(indicator)); } + set { Marshal.WriteInt16(indicator, value); } + } + #if !NET_2_0 [Browsable (false)] [RefreshProperties (RefreshProperties.All)] @@ -453,7 +469,6 @@ namespace System.Data.OracleClient } if (isnull == true && direction == ParameterDirection.Input) { - indicator = 0; bindType = OciDataType.VarChar2; bindSize = 0; } else { @@ -465,7 +480,6 @@ namespace System.Data.OracleClient case OciDataType.CharZ: case OciDataType.OciString: bindType = OciDataType.String; - indicator = 0; svalue = "\0"; // convert value from managed type to type to marshal if (direction == ParameterDirection.Input || @@ -558,7 +572,7 @@ namespace System.Data.OracleClient dt = DateTime.MinValue; sDate = ""; if (isnull) - indicator = -1; + Indicator = -1; else if (v is String) { sDate = (string) v; dt = DateTime.Parse (sDate); @@ -594,7 +608,7 @@ namespace System.Data.OracleClient case OciDataType.Float: case OciDataType.Number: bindType = OciDataType.String; - indicator = 0; + Indicator = 0; svalue = "\0"; // convert value from managed type to type to marshal if (direction == ParameterDirection.Input || @@ -638,7 +652,7 @@ namespace System.Data.OracleClient bindSize = Size + 5; // 4 bytes prepended for length, bytes, 1 byte NUL character - indicator = 0; + Indicator = 0; svalue = "\0"; // convert value from managed type to type to marshal if (direction == ParameterDirection.Input || @@ -758,7 +772,7 @@ namespace System.Data.OracleClient case OciDataType.VarRaw: bindType = OciDataType.VarRaw; bindSize = Size + 2; // include 2 bytes prepended to hold the length - indicator = 0; + Indicator = 0; bytes = new byte [bindSize]; if (direction == ParameterDirection.Input || direction == ParameterDirection.InputOutput) { @@ -784,7 +798,7 @@ namespace System.Data.OracleClient case OciDataType.LongVarRaw: bindType = OciDataType.LongVarRaw; bindSize = Size + 4; // include 4 bytes prepended to hold the length - indicator = 0; + Indicator = 0; bytes = new byte [bindSize]; if (direction == ParameterDirection.Input || direction == ParameterDirection.InputOutput) { @@ -854,7 +868,7 @@ namespace System.Data.OracleClient ref bindValue, bindSize, bindType, - ref indicator, + indicator, IntPtr.Zero, IntPtr.Zero, 0, @@ -870,7 +884,7 @@ namespace System.Data.OracleClient ref bindValue, bindSize, bindType, - ref indicator, + indicator, IntPtr.Zero, IntPtr.Zero, 0, @@ -887,7 +901,7 @@ namespace System.Data.OracleClient ref cursor, bindSize, bindType, - ref indicator, + indicator, IntPtr.Zero, IntPtr.Zero, 0, @@ -903,7 +917,7 @@ namespace System.Data.OracleClient bytes, bindSize, bindType, - ref indicator, + indicator, IntPtr.Zero, IntPtr.Zero, 0, @@ -919,7 +933,7 @@ namespace System.Data.OracleClient bindValue, bindSize, bindType, - ref indicator, + indicator, IntPtr.Zero, IntPtr.Zero, 0, @@ -1251,7 +1265,7 @@ namespace System.Data.OracleClient // used to update the parameter value // for Output, the output of InputOutput, and Return parameters value = DBNull.Value; - if (indicator == -1) + if (Indicator == -1) return; int rsize = 0; @@ -1453,6 +1467,22 @@ namespace System.Data.OracleClient return buffer; } + public void Dispose () + { + Dispose (true); + } + + void Dispose (bool disposing) + { + if (disposing) { + GC.SuppressFinalize(this); + } + if (indicator != IntPtr.Zero) { + Marshal.FreeHGlobal (indicator); + indicator = IntPtr.Zero; + } + } + #endregion // Methods internal sealed class OracleParameterConverter : ExpandableObjectConverter diff --git a/mcs/class/System.Data.Services.Client/mobile_System.Data.Services.Client.dll.sources b/mcs/class/System.Data.Services.Client/mobile_System.Data.Services.Client.dll.sources index 5ad9459d88..37dc2990c8 100644 --- a/mcs/class/System.Data.Services.Client/mobile_System.Data.Services.Client.dll.sources +++ b/mcs/class/System.Data.Services.Client/mobile_System.Data.Services.Client.dll.sources @@ -1,2 +1 @@ -#include System.Data.Services.Client.dll.sources -./Client/AssemblyAttributes.cs +#include net_4_5_System.Data.Services.Client.dll.sources diff --git a/mcs/class/System.Data.Services/Test/ChangeInterceptorAttributeTests.cs b/mcs/class/System.Data.Services/Test/ChangeInterceptorAttributeTests.cs index d8d0e157a8..3cc769d05e 100644 --- a/mcs/class/System.Data.Services/Test/ChangeInterceptorAttributeTests.cs +++ b/mcs/class/System.Data.Services/Test/ChangeInterceptorAttributeTests.cs @@ -26,9 +26,11 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Data.Services; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class ChangeInterceptorAttributeTests { [Test] @@ -45,4 +47,4 @@ namespace System.Data.Services.Tests { Assert.AreEqual ("setName", ci.EntitySetName); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data.Services/Test/DataServiceExceptionTests.cs b/mcs/class/System.Data.Services/Test/DataServiceExceptionTests.cs index 6058fc3e38..5f9758a44c 100644 --- a/mcs/class/System.Data.Services/Test/DataServiceExceptionTests.cs +++ b/mcs/class/System.Data.Services/Test/DataServiceExceptionTests.cs @@ -26,9 +26,11 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Data.Services; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class DataServiceExceptionTests { [Test] @@ -68,4 +70,4 @@ namespace System.Data.Services.Tests { Assert.AreEqual (inner, ex.InnerException); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data.Services/Test/DataServiceTests.cs b/mcs/class/System.Data.Services/Test/DataServiceTests.cs index 58b6785959..2bcc6a9dd7 100644 --- a/mcs/class/System.Data.Services/Test/DataServiceTests.cs +++ b/mcs/class/System.Data.Services/Test/DataServiceTests.cs @@ -26,9 +26,11 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Data.Services; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class DataServiceTests { [Test] @@ -79,4 +81,4 @@ namespace System.Data.Services.Tests { this.OnStartProcessingRequest (args); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data.Services/Test/ETagAttributeTests.cs b/mcs/class/System.Data.Services/Test/ETagAttributeTests.cs index 8b40de6c5b..706e02c699 100644 --- a/mcs/class/System.Data.Services/Test/ETagAttributeTests.cs +++ b/mcs/class/System.Data.Services/Test/ETagAttributeTests.cs @@ -26,10 +26,12 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Data.Services; using System.Linq; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class ETagAttributeTests { [Test] @@ -63,4 +65,4 @@ namespace System.Data.Services.Tests { Assert.AreEqual ("bar", e.PropertyNames[1]); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data.Services/Test/ExpandSegmentCollectionTests.cs b/mcs/class/System.Data.Services/Test/ExpandSegmentCollectionTests.cs index e0eb629d5b..cd5e9a1d31 100644 --- a/mcs/class/System.Data.Services/Test/ExpandSegmentCollectionTests.cs +++ b/mcs/class/System.Data.Services/Test/ExpandSegmentCollectionTests.cs @@ -26,10 +26,11 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System.Data.Services; using System.Linq.Expressions; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class ExpandSegmentCollectionTests { [Test] @@ -101,4 +102,4 @@ namespace System.Data.Services.Tests { Assert.IsFalse (esc.HasFilter); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data.Services/Test/ExpandSegmentTests.cs b/mcs/class/System.Data.Services/Test/ExpandSegmentTests.cs index f64faa8fad..ce6712c94e 100644 --- a/mcs/class/System.Data.Services/Test/ExpandSegmentTests.cs +++ b/mcs/class/System.Data.Services/Test/ExpandSegmentTests.cs @@ -26,10 +26,12 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Data.Services; using System.Linq.Expressions; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class ExpandSegmentTests { [Test] @@ -84,4 +86,4 @@ namespace System.Data.Services.Tests { { new ExpandSegment ("first", null), new ExpandSegment ("second", null), new ExpandSegment ("third", null) })); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data.Services/Test/IgnorePropertiesAttributeTests.cs b/mcs/class/System.Data.Services/Test/IgnorePropertiesAttributeTests.cs index 04c17e3d3c..090b3bf64b 100644 --- a/mcs/class/System.Data.Services/Test/IgnorePropertiesAttributeTests.cs +++ b/mcs/class/System.Data.Services/Test/IgnorePropertiesAttributeTests.cs @@ -26,10 +26,12 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Data.Services; using System.Linq; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class IgnorePropertiesAttributeTests { [Test] @@ -63,4 +65,4 @@ namespace System.Data.Services.Tests { Assert.AreEqual ("bar", e.PropertyNames[1]); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data.Services/Test/MimeTypeAttributeTests.cs b/mcs/class/System.Data.Services/Test/MimeTypeAttributeTests.cs index 6b5533ffa5..824cab9fcb 100644 --- a/mcs/class/System.Data.Services/Test/MimeTypeAttributeTests.cs +++ b/mcs/class/System.Data.Services/Test/MimeTypeAttributeTests.cs @@ -26,9 +26,10 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System.Data.Services; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class MimeTypeAttributeTests { [Test] @@ -39,4 +40,4 @@ namespace System.Data.Services.Tests { Assert.AreEqual ("type", mt.MimeType); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data.Services/Test/QueryInterceptorAttributeTests.cs b/mcs/class/System.Data.Services/Test/QueryInterceptorAttributeTests.cs index b483fbe1cd..e4b0147ccc 100644 --- a/mcs/class/System.Data.Services/Test/QueryInterceptorAttributeTests.cs +++ b/mcs/class/System.Data.Services/Test/QueryInterceptorAttributeTests.cs @@ -26,9 +26,11 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; +using System.Data.Services; using NUnit.Framework; -namespace System.Data.Services.Tests { +namespace MonoTests.System.Data.Services { [TestFixture] public class QueryInterceptorAttributeTests { [Test] @@ -45,4 +47,4 @@ namespace System.Data.Services.Tests { new QueryInterceptorAttribute (null); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data/System.Data.Common/DbEnumerator.cs b/mcs/class/System.Data/System.Data.Common/DbEnumerator.cs index 2a6c0da488..7cad139dc3 100644 --- a/mcs/class/System.Data/System.Data.Common/DbEnumerator.cs +++ b/mcs/class/System.Data/System.Data.Common/DbEnumerator.cs @@ -43,7 +43,6 @@ namespace System.Data.Common { readonly IDataReader reader; readonly bool closeReader; readonly SchemaInfo [] schema; - readonly object [] values; #endregion // Fields @@ -58,7 +57,6 @@ namespace System.Data.Common { { this.reader = reader; this.closeReader = closeReader; - this.values = new object [reader.FieldCount]; this.schema = LoadSchema (reader); } @@ -67,8 +65,13 @@ namespace System.Data.Common { #region Properties public object Current { - get { + get { + // DbDataRecordImpl does not do copy of the array + // and MoveNext would overwrite any previously filled data + var values = new object [reader.FieldCount]; reader.GetValues (values); + + // TODO: Should not allocate on every property call return new DbDataRecordImpl (schema, values); } } diff --git a/mcs/class/System.Data/System.Data.SqlClient/SqlConnection.cs b/mcs/class/System.Data/System.Data.SqlClient/SqlConnection.cs index 8712eca6cf..e1fa878c4c 100644 --- a/mcs/class/System.Data/System.Data.SqlClient/SqlConnection.cs +++ b/mcs/class/System.Data/System.Data.SqlClient/SqlConnection.cs @@ -56,6 +56,7 @@ using System.Xml; #if NET_2_0 using System.Collections.Generic; #endif +using System.Security; namespace System.Data.SqlClient { @@ -93,6 +94,9 @@ namespace System.Data.SqlClient // The connection string that identifies this connection string connectionString; + // The connection credentials + SqlCredential credentials; + // The transaction object for the current transaction SqlTransaction transaction; @@ -133,6 +137,12 @@ namespace System.Data.SqlClient ConnectionString = connectionString; } + public SqlConnection (string connectionString, SqlCredential cred) + { + ConnectionString = connectionString; + Credentials = cred; + } + #endregion // Constructors #region Properties @@ -155,6 +165,15 @@ namespace System.Data.SqlClient } } + public SqlCredential Credentials { + get { + return credentials; + } + set { + credentials = value; + } + } + #if !NET_2_0 [DataSysDescription ("Current connection timeout value, 'Connect Timeout=X' in the ConnectionString.")] #endif @@ -563,6 +582,16 @@ namespace System.Data.SqlClient if (!tds.IsConnected) { try { + if (Credentials != null) { + if (parms.User != String.Empty) + throw new ArgumentException("UserID already specified"); + if (parms.PasswordSet) + throw new ArgumentException("Password already specified"); + if (parms.DomainLogin != false) + throw new ArgumentException("Cannot use credentials with DomainLogin"); + parms.User = Credentials.UserId; + parms.Password = Credentials.Password; + } tds.Connect (parms); } catch { if (pooling) @@ -879,7 +908,10 @@ namespace System.Data.SqlClient break; case "password" : case "pwd" : - parms.Password = value; + parms.Password = new SecureString(); + foreach (char c in value) + parms.Password.AppendChar(c); + parms.PasswordSet = true; break; case "persistsecurityinfo" : case "persist security info" : diff --git a/mcs/class/System.Data/System.Data.SqlClient/SqlCredential.cs b/mcs/class/System.Data/System.Data.SqlClient/SqlCredential.cs new file mode 100644 index 0000000000..5b15b48cb6 --- /dev/null +++ b/mcs/class/System.Data/System.Data.SqlClient/SqlCredential.cs @@ -0,0 +1,76 @@ +// +// System.Data.SqlClient.SqlCredential.cs +// +// Author: +// Neale Ferguson (neale@sinenomine.net) +// +// Copyright (C) Neale Ferguson, 2014 +// + +// +// 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. +// + +using System; +using System.Data; +using System.Runtime.InteropServices; +using System.Security; + +namespace System.Data.SqlClient { + /// + /// Describes an error from a SQL database. + /// + [Serializable] + public sealed class SqlCredential + { + #region Fields + + string uid = ""; + SecureString pwd = null; + + #endregion // Fields + + #region Constructors + + public SqlCredential (string user, SecureString password) + { + if (user == null) + throw new ArgumentNullException("UserID"); + if (password == null) + throw new ArgumentNullException("Password"); + this.uid = user; + this.pwd = password; + } + + #endregion // Constructors + + #region Properties + + public string UserId { + get { return uid; } + } + + public SecureString Password { + get { return pwd; } + } + + #endregion + } +} diff --git a/mcs/class/System.Data/System.Data.dll.sources b/mcs/class/System.Data/System.Data.dll.sources index aeae903dbc..5ec88803ea 100644 --- a/mcs/class/System.Data/System.Data.dll.sources +++ b/mcs/class/System.Data/System.Data.dll.sources @@ -289,6 +289,7 @@ System.Data.SqlClient/SqlCommand.cs System.Data.SqlClient/SqlCommandBuilder.cs System.Data.SqlClient/SqlConnection.cs System.Data.SqlClient/SqlConnectionStringBuilder.cs +System.Data.SqlClient/SqlCredential.cs System.Data.SqlClient/SqlDataAdapter.cs System.Data.SqlClient/SqlDataReader.cs System.Data.SqlClient/SqlDataSourceConverter.cs diff --git a/mcs/class/System.Data/System.Data/DataRow.cs b/mcs/class/System.Data/System.Data/DataRow.cs index 4207d16f87..2d0df625f3 100644 --- a/mcs/class/System.Data/System.Data/DataRow.cs +++ b/mcs/class/System.Data/System.Data/DataRow.cs @@ -118,11 +118,11 @@ namespace System.Data { /// public bool HasErrors { get { - if (RowError != string.Empty) + if (!string.IsNullOrEmpty (RowError)) return true; foreach (String columnError in ColumnErrors) { - if (columnError != null && columnError != string.Empty) + if (!string.IsNullOrEmpty (columnError)) return true; } return false; @@ -509,7 +509,7 @@ namespace System.Data { /// public string RowError { get { return rowError; } - set { rowError = value; } + set { rowError = value ?? string.Empty; } } internal int IndexFromVersion (DataRowVersion version) diff --git a/mcs/class/System.Data/Test/System.Data.Common/DbDataReaderMock.cs b/mcs/class/System.Data/Test/System.Data.Common/DbDataReaderMock.cs index 5d561b44dd..2957cd73de 100644 --- a/mcs/class/System.Data/Test/System.Data.Common/DbDataReaderMock.cs +++ b/mcs/class/System.Data/Test/System.Data.Common/DbDataReaderMock.cs @@ -31,7 +31,7 @@ using System.Data; using System.Data.Common; using System.IO; -namespace Test.System.Data.Common +namespace MonoTests.System.Data.Common { internal class DbDataReaderMock : DbDataReader { diff --git a/mcs/class/System.Data/Test/System.Data.Common/DbDataReaderTest.cs b/mcs/class/System.Data/Test/System.Data.Common/DbDataReaderTest.cs index 0a7235f1b9..20d5c1ab0b 100644 --- a/mcs/class/System.Data/Test/System.Data.Common/DbDataReaderTest.cs +++ b/mcs/class/System.Data/Test/System.Data.Common/DbDataReaderTest.cs @@ -32,7 +32,7 @@ using System.Data; using System.Data.Common; using System.IO; -namespace Test.System.Data.Common +namespace MonoTests.System.Data.Common { [TestFixture] public class DbDataReaderTest diff --git a/mcs/class/System.Data/Test/System.Data/BinarySerializationTest.cs b/mcs/class/System.Data/Test/System.Data/BinarySerializationTest.cs index 5eae92a396..efbe64a1a4 100644 --- a/mcs/class/System.Data/Test/System.Data/BinarySerializationTest.cs +++ b/mcs/class/System.Data/Test/System.Data/BinarySerializationTest.cs @@ -12,6 +12,8 @@ using System.Threading; using NUnit.Framework; +namespace MonoTests.System.Data +{ [TestFixture] public class BinarySerializationTest { @@ -751,3 +753,4 @@ public class BinarySerializationTest } #endif +} diff --git a/mcs/class/System.Data/Test/System.Data/ConstraintExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/ConstraintExceptionTest.cs index c98a03c5aa..fe575137ea 100644 --- a/mcs/class/System.Data/Test/System.Data/ConstraintExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/ConstraintExceptionTest.cs @@ -33,7 +33,7 @@ using System.IO; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class ConstraintExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/DBConcurrencyExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/DBConcurrencyExceptionTest.cs index bfae78d6e6..35e876ff51 100644 --- a/mcs/class/System.Data/Test/System.Data/DBConcurrencyExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/DBConcurrencyExceptionTest.cs @@ -31,7 +31,7 @@ using System.Data; using NUnit.Framework; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DBConcurrencyExceptionTest diff --git a/mcs/class/System.Data/Test/System.Data/DataRowTest2.cs b/mcs/class/System.Data/Test/System.Data/DataRowTest2.cs index 4dc0d77495..e3e7aac285 100644 --- a/mcs/class/System.Data/Test/System.Data/DataRowTest2.cs +++ b/mcs/class/System.Data/Test/System.Data/DataRowTest2.cs @@ -739,6 +739,21 @@ namespace MonoTests.System.Data Assert.AreEqual(true , dr.HasErrors , "DRW48"); } + [Test] public void HasErrorsWithNullError() + { + DataTable dt = new DataTable("myTable"); + DataRow dr = dt.NewRow(); + + // HasErrors (default) + Assert.AreEqual(false, dr.HasErrors, "DRW47.2"); + + dr.RowError = null; + + // HasErrors (set/get) + Assert.AreEqual(string.Empty , dr.RowError , "DRW48.2"); + Assert.AreEqual(false , dr.HasErrors , "DRW49.2"); + } + [Test] public void HasVersion_ByDataRowVersion() { DataTable t = new DataTable("atable"); diff --git a/mcs/class/System.Data/Test/System.Data/DataSetTest2.cs.REMOVED.git-id b/mcs/class/System.Data/Test/System.Data/DataSetTest2.cs.REMOVED.git-id index 446009d44b..6d68582e8a 100644 --- a/mcs/class/System.Data/Test/System.Data/DataSetTest2.cs.REMOVED.git-id +++ b/mcs/class/System.Data/Test/System.Data/DataSetTest2.cs.REMOVED.git-id @@ -1 +1 @@ -27df0f589849c36eb477a933314db4f1f253993c \ No newline at end of file +6e338558389714f5748b4d8369ab873ffd258984 \ No newline at end of file diff --git a/mcs/class/System.Data/Test/System.Data/DataTableCollectionTest2.cs b/mcs/class/System.Data/Test/System.Data/DataTableCollectionTest2.cs index 9229265648..053825e350 100644 --- a/mcs/class/System.Data/Test/System.Data/DataTableCollectionTest2.cs +++ b/mcs/class/System.Data/Test/System.Data/DataTableCollectionTest2.cs @@ -28,10 +28,12 @@ using NUnit.Framework; using System; +using System.Collections; +using System.ComponentModel; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DataTableCollectionTest2 { @@ -143,7 +145,7 @@ namespace MonoTests_System.Data { counter = 0; DataSet ds = new DataSet(); - ds.Tables.CollectionChanged+=new System.ComponentModel.CollectionChangeEventHandler(Tables_CollectionChanged); + ds.Tables.CollectionChanged+=new CollectionChangeEventHandler(Tables_CollectionChanged); ds.Tables.Add(); ds.Tables.Add(); Assert.AreEqual(2, counter, "DTC15"); @@ -153,7 +155,7 @@ namespace MonoTests_System.Data Assert.AreEqual(4, counter, "DTC16"); } - private void Tables_CollectionChanged(object sender, System.ComponentModel.CollectionChangeEventArgs e) + private void Tables_CollectionChanged(object sender, CollectionChangeEventArgs e) { counter++; } @@ -163,7 +165,7 @@ namespace MonoTests_System.Data { counter = 0; DataSet ds = new DataSet(); - ds.Tables.CollectionChanging+=new System.ComponentModel.CollectionChangeEventHandler(Tables_CollectionChanging); + ds.Tables.CollectionChanging+=new CollectionChangeEventHandler(Tables_CollectionChanging); ds.Tables.Add(); ds.Tables.Add(); Assert.AreEqual(2, counter, "DTC17"); @@ -173,7 +175,7 @@ namespace MonoTests_System.Data Assert.AreEqual(4, counter, "DTC18"); } - private void Tables_CollectionChanging(object sender, System.ComponentModel.CollectionChangeEventArgs e) + private void Tables_CollectionChanging(object sender, CollectionChangeEventArgs e) { counter++; } @@ -233,7 +235,7 @@ namespace MonoTests_System.Data ds.Tables.Add(); int count=0; - System.Collections.IEnumerator myEnumerator = ds.Tables.GetEnumerator(); + IEnumerator myEnumerator = ds.Tables.GetEnumerator(); while (myEnumerator.MoveNext()) { diff --git a/mcs/class/System.Data/Test/System.Data/DataTableTest2.cs b/mcs/class/System.Data/Test/System.Data/DataTableTest2.cs index 331875ac88..bed6e55e50 100644 --- a/mcs/class/System.Data/Test/System.Data/DataTableTest2.cs +++ b/mcs/class/System.Data/Test/System.Data/DataTableTest2.cs @@ -36,7 +36,7 @@ using MonoTests.System.Data.Utils; using NUnit.Framework; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DataTableTest2 diff --git a/mcs/class/System.Data/Test/System.Data/DataTableTest3.cs b/mcs/class/System.Data/Test/System.Data/DataTableTest3.cs index 6fc2d64b20..c706778c67 100644 --- a/mcs/class/System.Data/Test/System.Data/DataTableTest3.cs +++ b/mcs/class/System.Data/Test/System.Data/DataTableTest3.cs @@ -31,7 +31,7 @@ using System.Xml; using NUnit.Framework; -namespace Monotests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DataTableTest3 diff --git a/mcs/class/System.Data/Test/System.Data/DataTableTest4.cs b/mcs/class/System.Data/Test/System.Data/DataTableTest4.cs index 2cdd5af913..c7cb3a35e8 100644 --- a/mcs/class/System.Data/Test/System.Data/DataTableTest4.cs +++ b/mcs/class/System.Data/Test/System.Data/DataTableTest4.cs @@ -31,7 +31,7 @@ using System.IO; using System.Xml; using NUnit.Framework; -namespace Monotests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DataTableTest4 @@ -1600,7 +1600,7 @@ namespace Monotests_System.Data DataSet ds = new DataSet (); DataTable table = new DataTable ("ParentTable"); XmlReadMode mode = XmlReadMode.Auto; - table.Columns.Add (new DataColumn ("id", System.Type.GetType ("System.Int32"))); + table.Columns.Add (new DataColumn ("id", Type.GetType ("System.Int32"))); ds.Tables.Add (table); using (FileStream stream = new FileStream (tempFile, FileMode.Open)) { @@ -1638,7 +1638,7 @@ namespace Monotests_System.Data using (FileStream stream = new FileStream (tempFile, FileMode.Open)) { DataSet ds = new DataSet (); DataTable table = new DataTable ("Table1"); - table.Columns.Add (new DataColumn ("id", System.Type.GetType ("System.Int32"))); + table.Columns.Add (new DataColumn ("id", Type.GetType ("System.Int32"))); ds.Tables.Add (table); try { @@ -1852,7 +1852,7 @@ namespace Monotests_System.Data DataTable table = new DataTable ("DummyTable"); //define the table schame partially with a column name which does not match with any //table columns in the diffgram - table.Columns.Add (new DataColumn ("WrongColumnName", System.Type.GetType ("System.String"))); + table.Columns.Add (new DataColumn ("WrongColumnName", Type.GetType ("System.String"))); XmlReadMode mode = XmlReadMode.Auto; @@ -2013,8 +2013,8 @@ namespace Monotests_System.Data Assert.AreEqual ("NewDataSet", table.DataSet.DataSetName, "#2"); Assert.AreEqual (2, table.Columns.Count, "#3"); Assert.AreEqual (2, table.Rows.Count, "#4"); - Assert.AreEqual (typeof (System.Int32), table.Columns [0].DataType, "#5"); - Assert.AreEqual (typeof (System.String), table.Columns [1].DataType, "#6"); + Assert.AreEqual (typeof (Int32), table.Columns [0].DataType, "#5"); + Assert.AreEqual (typeof (String), table.Columns [1].DataType, "#6"); Assert.AreEqual (1, table.Constraints.Count, "#7"); Assert.AreEqual (typeof (UniqueConstraint), table.Constraints [0].GetType (), "#8"); Assert.AreEqual (1, table.ChildRelations.Count, "#9"); @@ -2027,9 +2027,9 @@ namespace Monotests_System.Data Assert.AreEqual ("NewDataSet", table1.DataSet.DataSetName, "#14"); Assert.AreEqual (3, table1.Columns.Count, "#15"); Assert.AreEqual (4, table1.Rows.Count, "#16"); - Assert.AreEqual (typeof (System.Int32), table1.Columns [0].DataType, "#17"); - Assert.AreEqual (typeof (System.String), table1.Columns [1].DataType, "#18"); - Assert.AreEqual (typeof (System.Int32), table1.Columns [2].DataType, "#19"); + Assert.AreEqual (typeof (Int32), table1.Columns [0].DataType, "#17"); + Assert.AreEqual (typeof (String), table1.Columns [1].DataType, "#18"); + Assert.AreEqual (typeof (Int32), table1.Columns [2].DataType, "#19"); Assert.AreEqual (2, table1.Constraints.Count, "#20"); Assert.AreEqual (typeof (UniqueConstraint), table1.Constraints [0].GetType (), "#21"); Assert.AreEqual (typeof (ForeignKeyConstraint), table1.Constraints [1].GetType (), "#22"); @@ -2045,8 +2045,8 @@ namespace Monotests_System.Data Assert.AreEqual ("NewDataSet", table1.DataSet.DataSetName, "#29"); Assert.AreEqual (2, table1.Columns.Count, "#30"); Assert.AreEqual (8, table1.Rows.Count, "#31"); - Assert.AreEqual (typeof (System.Int32), table1.Columns [0].DataType, "#32"); - Assert.AreEqual (typeof (System.String), table1.Columns [1].DataType, "#33"); + Assert.AreEqual (typeof (Int32), table1.Columns [0].DataType, "#32"); + Assert.AreEqual (typeof (String), table1.Columns [1].DataType, "#33"); Assert.AreEqual (1, table1.Constraints.Count, "#34"); Assert.AreEqual (typeof (ForeignKeyConstraint), table1.Constraints [0].GetType (), "#35"); Assert.AreEqual (1, table1.ParentRelations.Count, "#36"); diff --git a/mcs/class/System.Data/Test/System.Data/DataTableTest5.cs b/mcs/class/System.Data/Test/System.Data/DataTableTest5.cs index 3bcbf75889..0cacc8ea9e 100644 --- a/mcs/class/System.Data/Test/System.Data/DataTableTest5.cs +++ b/mcs/class/System.Data/Test/System.Data/DataTableTest5.cs @@ -34,7 +34,7 @@ using System.Xml.Serialization; using NUnit.Framework; -namespace Monotests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DataTableTest5 diff --git a/mcs/class/System.Data/Test/System.Data/DataViewTest2.cs b/mcs/class/System.Data/Test/System.Data/DataViewTest2.cs index f6c6b3f9a8..58ca232fb5 100644 --- a/mcs/class/System.Data/Test/System.Data/DataViewTest2.cs +++ b/mcs/class/System.Data/Test/System.Data/DataViewTest2.cs @@ -28,12 +28,13 @@ using NUnit.Framework; using System; -using System.IO; +using System.Collections; using System.ComponentModel; +using System.IO; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DataViewTest2 { @@ -41,7 +42,7 @@ namespace MonoTests_System.Data class EventProperties //hold the event properties to be checked { - public System.ComponentModel.ListChangedType lstType ; + public ListChangedType lstType ; public int NewIndex; public int OldIndex; } @@ -508,7 +509,7 @@ namespace MonoTests_System.Data //create the dataview for the table DataView dv = new DataView(dt); - System.Collections.IEnumerator ienm = null; + IEnumerator ienm = null; // GetEnumerator != null ienm = dv.GetEnumerator(); @@ -549,7 +550,7 @@ namespace MonoTests_System.Data DataView dv = new DataView(dt); //add event handler - dv.ListChanged +=new System.ComponentModel.ListChangedEventHandler(dv_ListChanged); + dv.ListChanged +=new ListChangedEventHandler(dv_ListChanged); // ----- Change Value --------- evProp = null; @@ -557,7 +558,7 @@ namespace MonoTests_System.Data dv[1]["String1"] = "something"; Assert.AreEqual(true , evProp!=null , "DV58"); // change value - ListChangedType - Assert.AreEqual(System.ComponentModel.ListChangedType.ItemChanged, evProp.lstType , "DV59"); + Assert.AreEqual(ListChangedType.ItemChanged, evProp.lstType , "DV59"); // change value - NewIndex Assert.AreEqual(1, evProp.NewIndex, "DV60"); // change value - OldIndex @@ -569,7 +570,7 @@ namespace MonoTests_System.Data dv.AddNew(); Assert.AreEqual(true , evProp!=null , "DV62"); // Add New - ListChangedType - Assert.AreEqual(System.ComponentModel.ListChangedType.ItemAdded , evProp.lstType , "DV63"); + Assert.AreEqual(ListChangedType.ItemAdded , evProp.lstType , "DV63"); // Add New - NewIndex Assert.AreEqual(6, evProp.NewIndex, "DV64"); // Add New - OldIndex @@ -581,7 +582,7 @@ namespace MonoTests_System.Data dv.Sort = "ParentId Desc"; Assert.AreEqual(true , evProp!=null , "DV66"); // sort - ListChangedType - Assert.AreEqual(System.ComponentModel.ListChangedType.Reset , evProp.lstType , "DV67"); + Assert.AreEqual(ListChangedType.Reset , evProp.lstType , "DV67"); // sort - NewIndex Assert.AreEqual(-1, evProp.NewIndex, "DV68"); // sort - OldIndex @@ -627,12 +628,12 @@ namespace MonoTests_System.Data Assert.AreEqual(true , evProp != null , "DV168"); // Clear DataTable - should emit ListChangedType.Reset - Assert.AreEqual(System.ComponentModel.ListChangedType.Reset , evProp.lstType , "DV169"); + Assert.AreEqual(ListChangedType.Reset , evProp.lstType , "DV169"); // Clear DataTable - should clear view count Assert.AreEqual(0, dt.DefaultView.Count , "DV169"); } - private void dv_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e) + private void dv_ListChanged(object sender, ListChangedEventArgs e) { evProp = new EventProperties(); evProp.lstType = e.ListChangedType; @@ -646,7 +647,7 @@ namespace MonoTests_System.Data // this test also check DataView.Count property DataRowView[] drvResult = null; - System.Collections.ArrayList al = new System.Collections.ArrayList(); + ArrayList al = new ArrayList(); //create the source datatable DataTable dt = DataProvider.CreateChildDataTable(); @@ -763,7 +764,7 @@ namespace MonoTests_System.Data */ //DataRowView[] drvResult = null; - System.Collections.ArrayList al = new System.Collections.ArrayList(); + ArrayList al = new ArrayList(); DataTable dt = DataProvider.CreateParentDataTable(); @@ -821,7 +822,7 @@ namespace MonoTests_System.Data private DataRow[] GetResultRows(DataTable dt,DataRowState State) { //get expected rows - System.Collections.ArrayList al = new System.Collections.ArrayList(); + ArrayList al = new ArrayList(); DataRowVersion drVer = DataRowVersion.Current; //From MSDN - The row the default version for the current DataRowState. diff --git a/mcs/class/System.Data/Test/System.Data/DeletedRowInaccessibleExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/DeletedRowInaccessibleExceptionTest.cs index 89fdeb547b..be2810330f 100644 --- a/mcs/class/System.Data/Test/System.Data/DeletedRowInaccessibleExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/DeletedRowInaccessibleExceptionTest.cs @@ -33,7 +33,7 @@ using System.IO; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DeletedRowInaccessibleExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/DuplicateNameExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/DuplicateNameExceptionTest.cs index c26a71db1e..77cf583fc8 100644 --- a/mcs/class/System.Data/Test/System.Data/DuplicateNameExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/DuplicateNameExceptionTest.cs @@ -33,7 +33,7 @@ using System.IO; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class DuplicateNameExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/EvaluateExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/EvaluateExceptionTest.cs index dd6fe52c91..a9c41f0c2a 100644 --- a/mcs/class/System.Data/Test/System.Data/EvaluateExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/EvaluateExceptionTest.cs @@ -33,7 +33,7 @@ using System.IO; using System.Data; //using GHTUtils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class EvaluateExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/ForeignKeyConstraintTest2.cs b/mcs/class/System.Data/Test/System.Data/ForeignKeyConstraintTest2.cs index c0ed174c96..591fef23f0 100644 --- a/mcs/class/System.Data/Test/System.Data/ForeignKeyConstraintTest2.cs +++ b/mcs/class/System.Data/Test/System.Data/ForeignKeyConstraintTest2.cs @@ -31,7 +31,7 @@ using System; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class ForeignKeyConstraintTest2 { diff --git a/mcs/class/System.Data/Test/System.Data/InRowChangingEventExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/InRowChangingEventExceptionTest.cs index 08dd7f08c6..549076cbb3 100644 --- a/mcs/class/System.Data/Test/System.Data/InRowChangingEventExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/InRowChangingEventExceptionTest.cs @@ -33,7 +33,7 @@ using System.IO; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class InRowChangingEventExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/InvalidConstraintExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/InvalidConstraintExceptionTest.cs index 1aacff1ee9..04c19bfc75 100644 --- a/mcs/class/System.Data/Test/System.Data/InvalidConstraintExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/InvalidConstraintExceptionTest.cs @@ -33,7 +33,7 @@ using System.IO; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class InvalidConstraintExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/MissingPrimaryKeyExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/MissingPrimaryKeyExceptionTest.cs index 75791b325b..14404f2b35 100644 --- a/mcs/class/System.Data/Test/System.Data/MissingPrimaryKeyExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/MissingPrimaryKeyExceptionTest.cs @@ -32,7 +32,7 @@ using System.Data; using NUnit.Framework; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] class MissingPrimaryKeyExceptionTest @@ -57,4 +57,4 @@ namespace MonoTests_System.Data tbl.Rows.Contains("Something"); } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data/Test/System.Data/NoNullAllowedExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/NoNullAllowedExceptionTest.cs index 5b1506a857..45a5c5f3f7 100644 --- a/mcs/class/System.Data/Test/System.Data/NoNullAllowedExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/NoNullAllowedExceptionTest.cs @@ -33,7 +33,7 @@ using System.IO; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class NoNullAllowedExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/ReadOnlyExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/ReadOnlyExceptionTest.cs index 4969ea0a93..dd16e85714 100644 --- a/mcs/class/System.Data/Test/System.Data/ReadOnlyExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/ReadOnlyExceptionTest.cs @@ -33,7 +33,7 @@ using System.IO; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class ReadOnlyExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/RowNotInTableExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/RowNotInTableExceptionTest.cs index 349bdb8ae8..edade03835 100644 --- a/mcs/class/System.Data/Test/System.Data/RowNotInTableExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/RowNotInTableExceptionTest.cs @@ -31,7 +31,7 @@ using System; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class RowNotInTableExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/SyntaxErrorExceptionTest.cs b/mcs/class/System.Data/Test/System.Data/SyntaxErrorExceptionTest.cs index 875be98389..e1e2b08e24 100644 --- a/mcs/class/System.Data/Test/System.Data/SyntaxErrorExceptionTest.cs +++ b/mcs/class/System.Data/Test/System.Data/SyntaxErrorExceptionTest.cs @@ -32,7 +32,7 @@ using System.Text; using System.IO; using System.Data; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class SyntaxErrorExceptionTest { diff --git a/mcs/class/System.Data/Test/System.Data/TrailingSpaceTest.cs b/mcs/class/System.Data/Test/System.Data/TrailingSpaceTest.cs index 788cc5a390..8c6d6a0d86 100644 --- a/mcs/class/System.Data/Test/System.Data/TrailingSpaceTest.cs +++ b/mcs/class/System.Data/Test/System.Data/TrailingSpaceTest.cs @@ -2,7 +2,7 @@ using NUnit.Framework; using System; using System.Data; -namespace Monotests_Mono.Data.SqlExpressions +namespace MonoTests.System.Data { [TestFixture] public class ComparisonTest { @@ -10,7 +10,7 @@ namespace Monotests_Mono.Data.SqlExpressions [Test] public void TestStringTrailingSpaceHandling () { // test for bug 79695 - does not ignore certain trailing whitespace chars when comparing strings - System.Data.DataTable dataTable = new System.Data.DataTable ("Person"); + DataTable dataTable = new DataTable ("Person"); dataTable.Columns.Add ("Name", typeof (string)); dataTable.Rows.Add (new object[] {"Mike "}); DataRow[] selectedRows = dataTable.Select ("Name = 'Mike'"); diff --git a/mcs/class/System.Data/Test/System.Data/UniqueConstraintTest2.cs b/mcs/class/System.Data/Test/System.Data/UniqueConstraintTest2.cs index a21d94f188..4e0224430c 100644 --- a/mcs/class/System.Data/Test/System.Data/UniqueConstraintTest2.cs +++ b/mcs/class/System.Data/Test/System.Data/UniqueConstraintTest2.cs @@ -31,7 +31,7 @@ using System; using System.Data; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class UniqueConstraintTest2 { diff --git a/mcs/class/System.Data/Test/System.Data/VersionNotFoundException.cs b/mcs/class/System.Data/Test/System.Data/VersionNotFoundException.cs index 8c2e7a9f7f..235e30890a 100644 --- a/mcs/class/System.Data/Test/System.Data/VersionNotFoundException.cs +++ b/mcs/class/System.Data/Test/System.Data/VersionNotFoundException.cs @@ -32,7 +32,7 @@ using System.Data; using NUnit.Framework; using MonoTests.System.Data.Utils; -namespace MonoTests_System.Data +namespace MonoTests.System.Data { [TestFixture] class VersionNotFoundExceptionTest @@ -73,4 +73,4 @@ namespace MonoTests_System.Data object obj = drParent[0,DataRowVersion.Original]; } } -} \ No newline at end of file +} diff --git a/mcs/class/System.Data/Test/System.Data/XmlDataLoaderTest.cs b/mcs/class/System.Data/Test/System.Data/XmlDataLoaderTest.cs index dee7e6e378..2e0fe01830 100644 --- a/mcs/class/System.Data/Test/System.Data/XmlDataLoaderTest.cs +++ b/mcs/class/System.Data/Test/System.Data/XmlDataLoaderTest.cs @@ -32,7 +32,7 @@ using System.Xml; using NUnit.Framework; -namespace Monotests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class XmlDataLoaderTest @@ -74,7 +74,7 @@ namespace Monotests_System.Data DataSet ds = new DataSet ("Set"); DataTable dt = new DataTable ("Test"); dt.Columns.Add ("CustName", typeof (String)); - dt.Columns.Add ("Type", typeof (System.Type)); + dt.Columns.Add ("Type", typeof (Type)); ds.Tables.Add (dt); return ds; } diff --git a/mcs/class/System.Data/Test/System.Data/XmlDataReaderTest.cs b/mcs/class/System.Data/Test/System.Data/XmlDataReaderTest.cs index 546db60bfb..9bff68d0b9 100644 --- a/mcs/class/System.Data/Test/System.Data/XmlDataReaderTest.cs +++ b/mcs/class/System.Data/Test/System.Data/XmlDataReaderTest.cs @@ -33,7 +33,7 @@ using System.Xml.Serialization; using System.Xml.Schema; using NUnit.Framework; -namespace Monotests_System.Data +namespace MonoTests.System.Data { [TestFixture] public class XmlDataReaderTest @@ -103,7 +103,7 @@ namespace Monotests_System.Data StringReader sr = new StringReader (xml); XmlTextReader xr = new XmlTextReader (sr); DataTable tbl = new DataTable("CustomTypesTable"); - tbl.Columns.Add("Dummy", typeof(System.UInt32)); + tbl.Columns.Add("Dummy", typeof(UInt32)); tbl.Columns.Add("FuncXml", typeof(CustomTypeXml)); DataSet ds = new DataSet("CustomTypesData"); diff --git a/mcs/class/System.Data/mobile_System.Data.dll.sources b/mcs/class/System.Data/mobile_System.Data.dll.sources index b1174b8361..5a5ed877c5 100644 --- a/mcs/class/System.Data/mobile_System.Data.dll.sources +++ b/mcs/class/System.Data/mobile_System.Data.dll.sources @@ -225,6 +225,7 @@ System.Data.SqlClient/SqlCommand.cs System.Data.SqlClient/SqlCommandBuilder.cs System.Data.SqlClient/SqlConnection.cs System.Data.SqlClient/SqlConnectionStringBuilder.cs +System.Data.SqlClient/SqlCredential.cs System.Data.SqlClient/SqlDataAdapter.cs System.Data.SqlClient/SqlDataReader.cs System.Data.SqlClient/SqlDataSourceConverter.cs diff --git a/mcs/class/System.Drawing/Assembly/AssemblyInfo.cs b/mcs/class/System.Drawing/Assembly/AssemblyInfo.cs index 115adf5d92..c036603b98 100644 --- a/mcs/class/System.Drawing/Assembly/AssemblyInfo.cs +++ b/mcs/class/System.Drawing/Assembly/AssemblyInfo.cs @@ -56,7 +56,9 @@ using System.Runtime.InteropServices; [assembly: CLSCompliant (true)] [assembly: AssemblyDelaySign (true)] +#if !MOBILE [assembly: AssemblyKeyFile("../msfinal.pub")] +#endif [assembly: AssemblyFileVersion (Consts.FxFileVersion)] [assembly: CompilationRelaxations (CompilationRelaxations.NoStringInterning)] diff --git a/mcs/class/System.Drawing/System.Drawing.Design/UITypeEditor.cs b/mcs/class/System.Drawing/System.Drawing.Design/UITypeEditor.cs index 1f53a32fa9..76c66c3fcc 100644 --- a/mcs/class/System.Drawing/System.Drawing.Design/UITypeEditor.cs +++ b/mcs/class/System.Drawing/System.Drawing.Design/UITypeEditor.cs @@ -48,7 +48,9 @@ namespace System.Drawing.Design editors [typeof (IList)] = "System.ComponentModel.Design.CollectionEditor, " + Consts.AssemblySystem_Design; editors [typeof (ICollection)] = "System.ComponentModel.Design.CollectionEditor, " + Consts.AssemblySystem_Design; editors [typeof (string[])] = "System.Windows.Forms.Design.StringArrayEditor, " + Consts.AssemblySystem_Design; +#if !MOBILE TypeDescriptor.AddEditorTable (typeof (UITypeEditor), editors); +#endif } public UITypeEditor() diff --git a/mcs/class/System.IdentityModel/System.IdentityModel.Tokens/BootstrapContext.cs b/mcs/class/System.IdentityModel/System.IdentityModel.Tokens/BootstrapContext.cs new file mode 100644 index 0000000000..5e9f589c29 --- /dev/null +++ b/mcs/class/System.IdentityModel/System.IdentityModel.Tokens/BootstrapContext.cs @@ -0,0 +1,117 @@ +// +// BootstrapContext.cs +// +// Author: +// Robert J. van der Boon (rjvdboon@gmail.com) +// +// Copyright (C) 2014 Robert J. van der Boon +// +// 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. +// +#if NET_4_5 +using System; +using System.IO; +using System.Runtime.Serialization; +using System.Text; +using System.Xml; + +namespace System.IdentityModel.Tokens { + [Serializable] + public class BootstrapContext : ISerializable { + /// Gets the string that was used to initialize the context. + public string Token { get; private set; } + /// Gets the array that was used to initialize the context. + public byte [] TokenBytes { get; private set; } + /// Gets the security token that was used to initialize the context. + public SecurityToken SecurityToken { get; private set; } + /// Gets the token handler that was used to initialize the context. + public SecurityTokenHandler SecurityTokenHandler { get; private set; } + + /// Initializes a new instance of the class by using the specified string. + public BootstrapContext (string token) + { + if (token == null) + throw new ArgumentNullException ("token"); + Token = token; + } + + /// Initializes a new instance of the class by using the specified array. + public BootstrapContext (byte [] token) + { + if (token == null) + throw new ArgumentNullException ("token"); + TokenBytes = token; + } + + /// Initializes a new instance of the class by using the specified security token and token handler. + public BootstrapContext (SecurityToken token, SecurityTokenHandler handler) + { + if (token == null) + throw new ArgumentNullException ("token"); + if (handler == null) + throw new ArgumentNullException ("handler"); + SecurityToken = token; + SecurityTokenHandler = handler; + } + + /// Initializes a new instance of the class from a stream. + protected BootstrapContext (SerializationInfo info, StreamingContext context) + { + if (info == null) + throw new ArgumentNullException ("info"); + char type = info.GetChar ("K"); + switch (type) { + case 'S': + Token = info.GetString ("T"); + break; + case 'B': + TokenBytes = (byte [])info.GetValue ("T", typeof (byte [])); + break; + case 'T': + Token = Encoding.UTF8.GetString (Convert.FromBase64String (info.GetString ("T"))); + break; + } + } + + /// Populates the with data needed to serialize the current object. + public void GetObjectData (SerializationInfo info, StreamingContext context) + { + if (info == null) + throw new ArgumentNullException ("info"); + if (Token != null) { + info.AddValue ("K", 'S'); + info.AddValue ("T", Token); + } else if (TokenBytes != null) { + info.AddValue ("K", 'B'); + info.AddValue ("T", TokenBytes); + } else if (SecurityToken != null && SecurityTokenHandler != null) { + info.AddValue ("K", 'T'); + using (var ms = new MemoryStream ()) + using (var streamWriter = new StreamWriter (ms, new UTF8Encoding (false))) + using (var writer = XmlWriter.Create (streamWriter, new XmlWriterSettings { OmitXmlDeclaration = true })) { + SecurityTokenHandler.WriteToken (writer, SecurityToken); + writer.Flush (); + info.AddValue ("T", Convert.ToBase64String (ms.ToArray ())); + } + } + } + } +} +#endif diff --git a/mcs/class/System.IdentityModel/System.IdentityModel.dll.sources b/mcs/class/System.IdentityModel/System.IdentityModel.dll.sources index 32942efdb5..2c86355259 100755 --- a/mcs/class/System.IdentityModel/System.IdentityModel.dll.sources +++ b/mcs/class/System.IdentityModel/System.IdentityModel.dll.sources @@ -54,6 +54,7 @@ System.IdentityModel.Tokens/AudienceRestriction.cs System.IdentityModel.Tokens/AuthenticationContext.cs System.IdentityModel.Tokens/AuthenticationInformation.cs System.IdentityModel.Tokens/BinaryKeyIdentifierClause.cs +System.IdentityModel.Tokens/BootstrapContext.cs System.IdentityModel.Tokens/EncryptedKeyIdentifierClause.cs System.IdentityModel.Tokens/EncryptingCredentials.cs System.IdentityModel.Tokens/GenericXmlSecurityToken.cs diff --git a/mcs/class/System.IdentityModel/System.IdentityModel_test.dll.sources b/mcs/class/System.IdentityModel/System.IdentityModel_test.dll.sources index 86d286ce11..2fcb687a3a 100644 --- a/mcs/class/System.IdentityModel/System.IdentityModel_test.dll.sources +++ b/mcs/class/System.IdentityModel/System.IdentityModel_test.dll.sources @@ -12,6 +12,7 @@ System.IdentityModel.Selectors/SecurityTokenResolverTest.cs System.IdentityModel.Selectors/TestEvaluationContext.cs System.IdentityModel.Selectors/X509SecurityTokenAuthenticatorTest.cs System.IdentityModel.Selectors/X509SecurityTokenProviderTest.cs +System.IdentityModel.Tokens/BootstrapContextTest.cs System.IdentityModel.Tokens/EncryptedKeyIdentifierClauseTest.cs System.IdentityModel.Tokens/InMemorySymmetricSecurityKeyTest.cs System.IdentityModel.Tokens/LocalIdKeyIdentifierClauseTest.cs diff --git a/mcs/class/System.IdentityModel/Test/System.IdentityModel.Tokens/BootstrapContextTest.cs b/mcs/class/System.IdentityModel/Test/System.IdentityModel.Tokens/BootstrapContextTest.cs new file mode 100644 index 0000000000..1d5090748c --- /dev/null +++ b/mcs/class/System.IdentityModel/Test/System.IdentityModel.Tokens/BootstrapContextTest.cs @@ -0,0 +1,251 @@ +// +// BootstrapContextTest.cs - NUnit Test Cases for System.IdentityModel.Tokens.BootstrapContext +// + +#if NET_4_5 +using System; +using System.IO; +using System.IdentityModel.Tokens; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters.Binary; +using System.Text; +using System.Xml; +using NUnit.Framework; + +namespace MonoTests.System.IdentityModel.Tokens.net_4_5 { + [TestFixture] + public class BootstrapContextTest { + // The following byte arrays are the serialized bytes as emitted on Microsoft .Net 4.5. + private static readonly byte [] SerializedBootstrapContextByteArray = new byte [] { 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x57, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2C, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x34, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x30, 0x2C, 0x20, 0x43, 0x75, 0x6C, 0x74, 0x75, 0x72, 0x65, 0x3D, 0x6E, 0x65, 0x75, 0x74, 0x72, 0x61, 0x6C, 0x2C, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x4B, 0x65, 0x79, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x3D, 0x62, 0x37, 0x37, 0x61, 0x35, 0x63, 0x35, 0x36, 0x31, 0x39, 0x33, 0x34, 0x65, 0x30, 0x38, 0x39, 0x05, 0x01, 0x00, 0x00, 0x00, 0x2C, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2E, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x73, 0x2E, 0x42, 0x6F, 0x6F, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x78, 0x74, 0x02, 0x00, 0x00, 0x00, 0x01, 0x4B, 0x01, 0x54, 0x00, 0x07, 0x03, 0x02, 0x02, 0x00, 0x00, 0x00, 0x42, 0x09, 0x03, 0x00, 0x00, 0x00, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x0B }; + private static readonly byte [] SerializedBootstrapContextString = new byte [] { 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x57, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2C, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x34, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x30, 0x2C, 0x20, 0x43, 0x75, 0x6C, 0x74, 0x75, 0x72, 0x65, 0x3D, 0x6E, 0x65, 0x75, 0x74, 0x72, 0x61, 0x6C, 0x2C, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x4B, 0x65, 0x79, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x3D, 0x62, 0x37, 0x37, 0x61, 0x35, 0x63, 0x35, 0x36, 0x31, 0x39, 0x33, 0x34, 0x65, 0x30, 0x38, 0x39, 0x05, 0x01, 0x00, 0x00, 0x00, 0x2C, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2E, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x73, 0x2E, 0x42, 0x6F, 0x6F, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x78, 0x74, 0x02, 0x00, 0x00, 0x00, 0x01, 0x4B, 0x01, 0x54, 0x00, 0x01, 0x03, 0x02, 0x00, 0x00, 0x00, 0x53, 0x06, 0x03, 0x00, 0x00, 0x00, 0x05, 0x74, 0x6F, 0x6B, 0x65, 0x6E, 0x0B }; + + // Put in some non-ascii/latin1 characters to test the encoding scheme + // \u018E == Latin capital letter Reversed E + private const string user = "us\u018Er"; + // \u00BD == Vulgar Fraction one half + private const string password = "pass\u00BDword"; + private static readonly string SerializedBootstrapContextSecurityTokenString = ""; + private static readonly byte [] SerializedBootstrapContextSecurityToken = new byte [] { 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x02, 0x00, 0x00, 0x00, 0x57, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2C, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6F, 0x6E, 0x3D, 0x34, 0x2E, 0x30, 0x2E, 0x30, 0x2E, 0x30, 0x2C, 0x20, 0x43, 0x75, 0x6C, 0x74, 0x75, 0x72, 0x65, 0x3D, 0x6E, 0x65, 0x75, 0x74, 0x72, 0x61, 0x6C, 0x2C, 0x20, 0x50, 0x75, 0x62, 0x6C, 0x69, 0x63, 0x4B, 0x65, 0x79, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x3D, 0x62, 0x37, 0x37, 0x61, 0x35, 0x63, 0x35, 0x36, 0x31, 0x39, 0x33, 0x34, 0x65, 0x30, 0x38, 0x39, 0x05, 0x01, 0x00, 0x00, 0x00, 0x2C, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x2E, 0x49, 0x64, 0x65, 0x6E, 0x74, 0x69, 0x74, 0x79, 0x4D, 0x6F, 0x64, 0x65, 0x6C, 0x2E, 0x54, 0x6F, 0x6B, 0x65, 0x6E, 0x73, 0x2E, 0x42, 0x6F, 0x6F, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x43, 0x6F, 0x6E, 0x74, 0x65, 0x78, 0x74, 0x02, 0x00, 0x00, 0x00, 0x01, 0x4B, 0x01, 0x54, 0x00, 0x01, 0x03, 0x02, 0x00, 0x00, 0x00, 0x54, 0x06, 0x03, 0x00, 0x00, 0x00, 0x98, 0x01, 0x50, 0x46, 0x56, 0x7A, 0x5A, 0x58, 0x4A, 0x4F, 0x59, 0x57, 0x31, 0x6C, 0x55, 0x32, 0x56, 0x6A, 0x64, 0x58, 0x4A, 0x70, 0x64, 0x48, 0x6C, 0x55, 0x62, 0x32, 0x74, 0x6C, 0x62, 0x69, 0x42, 0x4A, 0x5A, 0x44, 0x30, 0x69, 0x64, 0x58, 0x56, 0x70, 0x5A, 0x43, 0x30, 0x35, 0x4D, 0x6A, 0x64, 0x6A, 0x4D, 0x47, 0x49, 0x35, 0x4F, 0x43, 0x31, 0x69, 0x59, 0x54, 0x45, 0x34, 0x4C, 0x54, 0x51, 0x35, 0x5A, 0x44, 0x49, 0x74, 0x59, 0x54, 0x59, 0x31, 0x4D, 0x79, 0x30, 0x7A, 0x4D, 0x44, 0x5A, 0x6B, 0x4E, 0x6A, 0x42, 0x6D, 0x4F, 0x44, 0x55, 0x33, 0x4E, 0x54, 0x45, 0x74, 0x4D, 0x79, 0x49, 0x67, 0x56, 0x58, 0x4E, 0x6C, 0x63, 0x6D, 0x35, 0x68, 0x62, 0x57, 0x55, 0x39, 0x49, 0x6E, 0x56, 0x7A, 0x78, 0x6F, 0x35, 0x79, 0x49, 0x69, 0x42, 0x51, 0x59, 0x58, 0x4E, 0x7A, 0x64, 0x32, 0x39, 0x79, 0x5A, 0x44, 0x30, 0x69, 0x63, 0x47, 0x46, 0x7A, 0x63, 0x38, 0x4B, 0x39, 0x64, 0x32, 0x39, 0x79, 0x5A, 0x43, 0x49, 0x76, 0x50, 0x67, 0x3D, 0x3D, 0x0B }; + + [Test] + public void Ctor_StringToken_Works () + { + BootstrapContext bootstrapContext = new BootstrapContext ("token"); + + Assert.AreEqual ("token", bootstrapContext.Token, "#1"); + Assert.IsNull (bootstrapContext.TokenBytes, "#2"); + Assert.IsNull (bootstrapContext.SecurityToken, "#3"); + Assert.IsNull (bootstrapContext.SecurityTokenHandler, "#4"); + } + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void Ctor_StringToken_NullToken_Throws () + { + BootstrapContext bootstrapContext = new BootstrapContext ((string)null); + Assert.Fail ("Should have thrown"); + } + + [Test] + public void Serialize_StringToken_Works () + { + BootstrapContext bootstrapContext = new BootstrapContext ("token"); + BinaryFormatter binaryFormatter = new BinaryFormatter (); + using (var s = new MemoryStream ()) { + binaryFormatter.Serialize (s, bootstrapContext); + s.Position = 0; + BootstrapContext bootstrapContext2 = binaryFormatter.Deserialize (s) as BootstrapContext; + Assert.IsNotNull (bootstrapContext2, "#1"); + Assert.AreEqual (bootstrapContext.Token, bootstrapContext2.Token, "#2"); + Assert.AreEqual (bootstrapContext.TokenBytes, bootstrapContext2.TokenBytes, "#3"); + Assert.AreEqual (bootstrapContext.SecurityToken, bootstrapContext2.SecurityToken, "#4"); + Assert.AreEqual (bootstrapContext.SecurityTokenHandler, bootstrapContext2.SecurityTokenHandler, "#5"); + } + } + + [Test] + public void Deserialize_StringToken_Works () + { + BinaryFormatter binaryFormatter = new BinaryFormatter (); + using (var s = new MemoryStream (SerializedBootstrapContextString)) { + BootstrapContext bootstrapContext = binaryFormatter.Deserialize (s) as BootstrapContext; + Assert.IsNotNull (bootstrapContext, "#1"); + Assert.AreEqual ("token", bootstrapContext.Token, "#2"); + Assert.IsNull (bootstrapContext.TokenBytes, "#3"); + Assert.IsNull (bootstrapContext.SecurityToken, "#4"); + Assert.IsNull (bootstrapContext.SecurityTokenHandler, "#5"); + } + } + + [Test] + public void Ctor_ByteArrayToken_Works () + { + BootstrapContext bootstrapContext = new BootstrapContext (new byte [] { 0x01 }); + + Assert.IsNotNull (bootstrapContext.TokenBytes, "#1"); + Assert.AreEqual (1, bootstrapContext.TokenBytes.Length, "#2"); + Assert.AreEqual (1, bootstrapContext.TokenBytes [0], "#3"); + Assert.IsNull (bootstrapContext.Token, "#4"); + Assert.IsNull (bootstrapContext.SecurityToken, "#5"); + Assert.IsNull (bootstrapContext.SecurityTokenHandler, "#6"); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void Ctor_ByteArrayToken_NullToken_Throws () + { + BootstrapContext bootstrapContext = new BootstrapContext ((byte [])null); + Assert.Fail ("Should have thrown"); + } + + [Test] + public void Serialize_ByteArrayToken_Works () + { + BootstrapContext bootstrapContext = new BootstrapContext (new byte [] { 0x1 }); + BinaryFormatter binaryFormatter = new BinaryFormatter (); + using (var s = new MemoryStream ()) { + binaryFormatter.Serialize (s, bootstrapContext); + s.Position = 0; + BootstrapContext bootstrapContext2 = binaryFormatter.Deserialize (s) as BootstrapContext; + Assert.IsNotNull (bootstrapContext2, "#1"); + Assert.AreEqual (bootstrapContext.Token, bootstrapContext2.Token, "#2"); + Assert.AreEqual (bootstrapContext.TokenBytes, bootstrapContext2.TokenBytes, "#3"); + Assert.AreEqual (bootstrapContext.SecurityToken, bootstrapContext2.SecurityToken, "#4"); + Assert.AreEqual (bootstrapContext.SecurityTokenHandler, bootstrapContext2.SecurityTokenHandler, "#5"); + } + } + + [Test] + public void Deserialize_ByteArrayToken_Works () + { + BinaryFormatter binaryFormatter = new BinaryFormatter (); + using (var s = new MemoryStream (SerializedBootstrapContextByteArray)) { + BootstrapContext bootstrapContext = binaryFormatter.Deserialize (s) as BootstrapContext; + Assert.IsNotNull (bootstrapContext, "#1"); + Assert.IsNotNull (bootstrapContext.TokenBytes, "#2"); + Assert.AreEqual (1, bootstrapContext.TokenBytes.Length, "#3"); + Assert.AreEqual (1, bootstrapContext.TokenBytes [0], "#4"); + Assert.IsNull (bootstrapContext.Token, "#5"); + Assert.IsNull (bootstrapContext.SecurityToken, "#6"); + Assert.IsNull (bootstrapContext.SecurityTokenHandler, "#7"); + } + } + + [Test] + public void Ctor_SecurityToken_Works () + { + var securityToken = new UserNameSecurityToken (user, password); + var securityTokenHandler = new SimpleSecurityTokenHandler (); + BootstrapContext bootstrapContext = new BootstrapContext (securityToken, securityTokenHandler); + + Assert.IsNotNull (bootstrapContext.SecurityToken, "#1"); + Assert.AreEqual (user, securityToken.UserName, "#2"); + Assert.AreEqual (password, securityToken.Password, "#3"); + Assert.AreEqual (securityTokenHandler, bootstrapContext.SecurityTokenHandler, "#4"); + + Assert.IsNull (bootstrapContext.Token, "#5"); + Assert.IsNull (bootstrapContext.TokenBytes, "#6"); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void Ctor_SecurityToken_NullToken_Throws () + { + BootstrapContext bootstrapContext = new BootstrapContext (null, new SimpleSecurityTokenHandler ()); + Assert.Fail ("Should have thrown"); + } + + [Test] + [ExpectedException (typeof (ArgumentNullException))] + public void Ctor_SecurityToken_NullHandler_Throws () + { + BootstrapContext bootstrapContext = new BootstrapContext (new UserNameSecurityToken ("user", "password"), null); + Assert.Fail ("Should have thrown"); + } + + [Test] + public void Serialize_SecurityTokenAndHandler_Works () + { + var securityToken = new UserNameSecurityToken (user, password, "uuid-927c0b98-ba18-49d2-a653-306d60f85751-3"); + var securityTokenHandler = new SimpleSecurityTokenHandler (); + BootstrapContext bootstrapContext = new BootstrapContext (securityToken, securityTokenHandler); + + BinaryFormatter binaryFormatter = new BinaryFormatter (); + using (var s = new MemoryStream ()) { + binaryFormatter.Serialize (s, bootstrapContext); + s.Position = 0; + BootstrapContext bootstrapContext2 = binaryFormatter.Deserialize (s) as BootstrapContext; + Assert.IsNotNull (bootstrapContext2, "#1"); + // Deserialize does not restore the SecurityToken, but restores into the Token. + Assert.IsNotNull (bootstrapContext2.Token, "#3"); + // We replace ' /' by '/' to accomodate the xml writer differences between mono and .net + Assert.AreEqual (SerializedBootstrapContextSecurityTokenString.Replace (" /", "/"), bootstrapContext2.Token.Replace (" /", "/"), "#2"); + Assert.AreEqual (bootstrapContext.TokenBytes, bootstrapContext2.TokenBytes, "#3"); + Assert.IsNull (bootstrapContext2.SecurityToken, "#4"); + Assert.IsNull (bootstrapContext2.SecurityTokenHandler, "#5"); + } + } + + [Test] + public void Deserialize_SecurityTokenAndHandler_Works () + { + BinaryFormatter binaryFormatter = new BinaryFormatter (); + using (var s = new MemoryStream (SerializedBootstrapContextSecurityToken)) { + BootstrapContext bootstrapContext = binaryFormatter.Deserialize (s) as BootstrapContext; + Assert.IsNotNull (bootstrapContext, "#1"); + Assert.AreEqual (SerializedBootstrapContextSecurityTokenString, bootstrapContext.Token, "#2"); + Assert.IsNull (bootstrapContext.SecurityToken, "#3"); + Assert.IsNull (bootstrapContext.SecurityTokenHandler, "#4"); + Assert.IsNull (bootstrapContext.TokenBytes, "#5"); + } + } + + private static void DumpAsText (byte [] data) + { + Console.WriteLine ("{0}", Encoding.ASCII.GetString (data)); + } + + private static void Dump (byte [] data) + { + var sb = new StringBuilder (); + sb.Append ("new byte[] { "); + bool first = true; + foreach (byte b in data) { + if (!first) + sb.Append (", "); + else + first = false; + sb.AppendFormat ("0x{0:X2}", b); + } + sb.Append (" };"); + Console.WriteLine (sb.ToString ()); + } + + private class SimpleSecurityTokenHandler : SecurityTokenHandler { + public override string [] GetTokenTypeIdentifiers () + { + throw new NotImplementedException (); + } + + public override Type TokenType { + get { return typeof (UserNameSecurityToken); } + } + + public override bool CanWriteToken { + get { return true; } + } + + public override void WriteToken (XmlWriter writer, SecurityToken token) + { + UserNameSecurityToken unst = token as UserNameSecurityToken; + if (unst == null) + throw new ArgumentException ("Token must be of type UserNameSecurityToken", "token"); + writer.WriteStartElement ("UserNameSecurityToken"); + writer.WriteAttributeString ("Id", unst.Id); + writer.WriteAttributeString ("Username", unst.UserName); + writer.WriteAttributeString ("Password", unst.Password); + writer.WriteEndElement (); + } + } + } +} +#endif diff --git a/mcs/class/System.Management/System.Management/ManagementObjectSearcher.cs b/mcs/class/System.Management/System.Management/ManagementObjectSearcher.cs index 90ed57e3dc..f79d9662bc 100644 --- a/mcs/class/System.Management/System.Management/ManagementObjectSearcher.cs +++ b/mcs/class/System.Management/System.Management/ManagementObjectSearcher.cs @@ -26,28 +26,28 @@ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // - using System.ComponentModel; namespace System.Management { - [MonoTODO ("System.Management is not implemented")] [ToolboxItem (false)] public class ManagementObjectSearcher : Component { + ObjectQuery mQueryObject; + public ManagementObjectSearcher () { - throw new NotImplementedException (); + mQueryObject = new ObjectQuery (); } public ManagementObjectSearcher (ObjectQuery query) { - throw new NotImplementedException (); + mQueryObject = (ObjectQuery)query.Clone (); } public ManagementObjectSearcher (string queryString) { - throw new NotImplementedException (); + mQueryObject = new ObjectQuery (queryString); } public ManagementObjectSearcher (ManagementScope scope, ObjectQuery query) @@ -81,10 +81,10 @@ namespace System.Management public ObjectQuery Query { get { - throw new NotImplementedException (); + return mQueryObject; } set { - throw new NotImplementedException (); + mQueryObject = value; } } diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentDispositionHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentDispositionHeaderValue.cs index 0e28b72838..f80e50e414 100644 --- a/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentDispositionHeaderValue.cs +++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentDispositionHeaderValue.cs @@ -120,9 +120,17 @@ namespace System.Net.Http.Headers public string Name { get { - return FindParameter ("name"); + var value = FindParameter ("name"); + + if (value == null) + return null; + + return DecodeValue (value, false); } set { + if (value != null) + value = EncodeBase64Value (value); + SetValue ("name", value); } } @@ -249,6 +257,11 @@ namespace System.Net.Http.Headers continue; } + if (!Lexer.IsValidCharacter (ch) || ch == '*' || ch == '?' || ch == '%') { + sb.Append (Uri.HexEscape (ch)); + continue; + } + sb.Append (ch); } diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentRangeHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentRangeHeaderValue.cs index 118d65085f..1bea52b76e 100644 --- a/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentRangeHeaderValue.cs +++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/ContentRangeHeaderValue.cs @@ -170,7 +170,7 @@ namespace System.Net.Http.Headers } else { value.From = nvalue; - t = lexer.Scan (); + t = lexer.Scan (recognizeDash: true); if (t != Token.Type.SeparatorDash) return false; diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs index 5717ddd67d..4f1137a8cc 100644 --- a/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs +++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs @@ -96,6 +96,7 @@ namespace System.Net.Http.Headers HeaderInfo.CreateSingle ("Authorization", AuthenticationHeaderValue.TryParse, HttpHeaderKind.Request), HeaderInfo.CreateSingle ("Cache-Control", CacheControlHeaderValue.TryParse, HttpHeaderKind.Request | HttpHeaderKind.Response), HeaderInfo.CreateMulti ("Connection", CollectionParser.TryParse, HttpHeaderKind.Request | HttpHeaderKind.Response), + HeaderInfo.CreateSingle ("Content-Disposition", ContentDispositionHeaderValue.TryParse, HttpHeaderKind.Content), HeaderInfo.CreateMulti ("Content-Encoding", CollectionParser.TryParse, HttpHeaderKind.Content), HeaderInfo.CreateMulti ("Content-Language", CollectionParser.TryParse, HttpHeaderKind.Content), HeaderInfo.CreateSingle ("Content-Length", Parser.Long.TryParse, HttpHeaderKind.Content), diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/Lexer.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/Lexer.cs index 5bd7d093ac..1865d876a5 100644 --- a/mcs/class/System.Net.Http/System.Net.Http.Headers/Lexer.cs +++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/Lexer.cs @@ -193,13 +193,18 @@ namespace System.Net.Http.Headers // for (; i < input.Length; ++i) { char s = input[i]; - if (s > last_token_char || !token_chars[s]) + if (!IsValidCharacter (s)) return false; } return i > 0; } + public static bool IsValidCharacter (char input) + { + return input <= last_token_char && token_chars[input]; + } + public void EatChar () { ++pos; @@ -247,7 +252,7 @@ namespace System.Net.Http.Headers return false; } - public Token Scan () + public Token Scan (bool recognizeDash = false) { int start = pos; if (s == null) @@ -279,8 +284,12 @@ namespace System.Net.Http.Headers ttype = Token.Type.SeparatorSlash; break; case '-': - ttype = Token.Type.SeparatorDash; - break; + if (recognizeDash) { + ttype = Token.Type.SeparatorDash; + break; + } + + goto default; case ',': ttype = Token.Type.SeparatorComma; break; diff --git a/mcs/class/System.Net.Http/System.Net.Http.Headers/RangeHeaderValue.cs b/mcs/class/System.Net.Http/System.Net.Http.Headers/RangeHeaderValue.cs index ad8e7e2b4f..36e9c80615 100644 --- a/mcs/class/System.Net.Http/System.Net.Http.Headers/RangeHeaderValue.cs +++ b/mcs/class/System.Net.Http/System.Net.Http.Headers/RangeHeaderValue.cs @@ -127,7 +127,7 @@ namespace System.Net.Http.Headers int number; token_read = false; - t = lexer.Scan (); + t = lexer.Scan (recognizeDash: true); switch (t.Kind) { case Token.Type.SeparatorDash: t = lexer.Scan (); @@ -144,7 +144,7 @@ namespace System.Net.Http.Headers switch (values.Length) { case 1: - t = lexer.Scan (); + t = lexer.Scan (recognizeDash: true); from = number; switch (t.Kind) { case Token.Type.SeparatorDash: diff --git a/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs b/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs index 865a8062b7..b4de2a029c 100644 --- a/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs +++ b/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs @@ -50,7 +50,6 @@ namespace System.Net.Http bool useProxy; ClientCertificateOption certificate; bool sentRequest; - HttpWebRequest wrequest; string connectionGroupName; bool disposed; @@ -221,12 +220,9 @@ namespace System.Net.Http protected override void Dispose (bool disposing) { - if (disposing) { - if (wrequest != null) { - wrequest.ServicePoint.CloseConnectionGroup (wrequest.ConnectionGroupName); - Volatile.Write (ref wrequest, null); - } + if (disposing && !disposed) { Volatile.Write (ref disposed, true); + ServicePointManager.CloseConnectionGroup (connectionGroupName); } base.Dispose (disposing); @@ -317,7 +313,7 @@ namespace System.Net.Http throw new ObjectDisposedException (GetType ().ToString ()); Volatile.Write (ref sentRequest, true); - wrequest = CreateWebRequest (request); + var wrequest = CreateWebRequest (request); if (request.Content != null) { var headers = wrequest.Headers; diff --git a/mcs/class/System.Net.Http/Test/System.Net.Http.Headers/ContentDispositionHeaderValueTest.cs b/mcs/class/System.Net.Http/Test/System.Net.Http.Headers/ContentDispositionHeaderValueTest.cs index b9c8a7796e..dfa4c5a128 100644 --- a/mcs/class/System.Net.Http/Test/System.Net.Http.Headers/ContentDispositionHeaderValueTest.cs +++ b/mcs/class/System.Net.Http/Test/System.Net.Http.Headers/ContentDispositionHeaderValueTest.cs @@ -237,6 +237,36 @@ namespace MonoTests.System.Net.Http.Headers value.FileNameStar = "č"; Assert.AreEqual ("č", value.FileNameStar, "#11"); Assert.AreEqual (new NameValueHeaderValue ("filename*", "utf-8''%C4%8D"), value.Parameters.First (), "#12"); + + value.FileNameStar = "@x*\\%?.txt"; + Assert.AreEqual ("@x*\\%?.txt", value.FileNameStar, "#21"); + Assert.AreEqual (new NameValueHeaderValue ("filename*", "utf-8''%40x%2A%5C%25%3F.txt"), value.Parameters.First (), "#22"); + } + + [Test] + public void Properties_Name () + { + var value = new ContentDispositionHeaderValue ("a"); + + value.Name = "aa"; + Assert.AreEqual ("aa", value.Name, "#1"); + Assert.AreEqual (new NameValueHeaderValue ("name", "aa"), value.Parameters.First (), "#2"); + + value.Name = "č"; + Assert.AreEqual ("č", value.Name, "#11"); + Assert.AreEqual (new NameValueHeaderValue ("name", "\"=?utf-8?B?xI0=?=\""), value.Parameters.First (), "#12"); + + value.Name = "(@)"; + Assert.AreEqual ("\"(@)\"", value.Name, "#21"); + Assert.AreEqual (new NameValueHeaderValue ("name", "\"(@)\""), value.Parameters.First (), "#22"); + + value.Name = "\"č\""; + Assert.AreEqual ("č", value.Name, "#31"); + Assert.AreEqual (new NameValueHeaderValue ("name", "\"=?utf-8?B?xI0=?=\""), value.Parameters.First (), "#32"); + + value.Name = "\"quoted\""; + Assert.AreEqual ("\"quoted\"", value.Name, "#41"); + Assert.AreEqual (new NameValueHeaderValue ("name", "\"quoted\""), value.Parameters.First (), "#42"); } [Test] diff --git a/mcs/class/System.Net.Http/Test/System.Net.Http.Headers/MediaTypeHeaderValueTest.cs b/mcs/class/System.Net.Http/Test/System.Net.Http.Headers/MediaTypeHeaderValueTest.cs index afbf8274b9..c4b882467a 100644 --- a/mcs/class/System.Net.Http/Test/System.Net.Http.Headers/MediaTypeHeaderValueTest.cs +++ b/mcs/class/System.Net.Http/Test/System.Net.Http.Headers/MediaTypeHeaderValueTest.cs @@ -31,6 +31,7 @@ using System.Collections; using System.Collections.Generic; using NUnit.Framework; using System.Net.Http.Headers; +using System.Linq; namespace MonoTests.System.Net.Http.Headers { @@ -81,6 +82,13 @@ namespace MonoTests.System.Net.Http.Headers Assert.AreEqual ("mu/m", res.MediaType, "#2"); Assert.AreEqual ("jj'", res.CharSet, "#2b"); Assert.AreEqual ("mu/m; CHarset=jj'", res.ToString (), "#2c"); + + res = MediaTypeHeaderValue.Parse ("multipart/form-data; boundary=----Wk"); + Assert.AreEqual ("multipart/form-data", res.MediaType, "#3"); + Assert.IsNull (res.CharSet, "#3b"); + Assert.AreEqual (1, res.Parameters.Count, "#3c"); + Assert.AreEqual (new NameValueHeaderValue ("boundary", "----Wk"), res.Parameters.First (), "#3d"); + Assert.AreEqual ("multipart/form-data; boundary=----Wk", res.ToString (), "#3e"); } [Test] diff --git a/mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs b/mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs index be0c47c5cc..5d7cd12490 100644 --- a/mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs +++ b/mcs/class/System.Net.Http/Test/System.Net.Http/StreamContentTest.cs @@ -222,6 +222,7 @@ namespace MonoTests.System.Net.Http Assert.AreEqual (330, scm.Headers.ContentLength, "#2"); headers.Allow.Add ("a1"); + headers.ContentDisposition = new ContentDispositionHeaderValue ("cd1"); headers.ContentEncoding.Add ("ce1"); headers.ContentLanguage.Add ("cl1"); headers.ContentLength = 23; @@ -234,6 +235,12 @@ namespace MonoTests.System.Net.Http headers.Add ("allow", "a2"); + try { + headers.Add ("content-disposition", "cd2"); + Assert.Fail ("content-disposition"); + } catch (FormatException) { + } + headers.Add ("content-encoding", "ce3"); headers.Add ("content-language", "cl2"); @@ -307,6 +314,7 @@ namespace MonoTests.System.Net.Http Assert.AreEqual (new MediaTypeHeaderValue ("multipart/*"), headers.ContentType); Assert.AreEqual (new DateTimeOffset (DateTime.Today), headers.Expires); Assert.AreEqual (new DateTimeOffset (DateTime.Today), headers.LastModified); + Assert.AreEqual (new ContentDispositionHeaderValue ("cd1"), headers.ContentDisposition); } [Test] diff --git a/mcs/class/System.Numerics/System.Numerics/BigInteger.cs b/mcs/class/System.Numerics/System.Numerics/BigInteger.cs index 329f91eed1..93fb7b939e 100644 --- a/mcs/class/System.Numerics/System.Numerics/BigInteger.cs +++ b/mcs/class/System.Numerics/System.Numerics/BigInteger.cs @@ -1,10 +1,12 @@ // // System.Numerics.BigInteger // -// Rodrigo Kumpera (rkumpera@novell.com) - +// Authors: +// Rodrigo Kumpera (rkumpera@novell.com) +// Marek Safar // // Copyright (C) 2010 Novell, Inc (http://www.novell.com) +// Copyright (C) 2014 Xamarin Inc (http://www.xamarin.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -68,7 +70,6 @@ namespace System.Numerics { readonly uint[] data; readonly short sign; - static readonly uint[] ZERO = new uint [1]; static readonly uint[] ONE = new uint [1] { 1 }; BigInteger (short sign, uint[] data) @@ -81,7 +82,7 @@ namespace System.Numerics { { if (value == 0) { sign = 0; - data = ZERO; + data = null; } else if (value > 0) { sign = 1; data = new uint[] { (uint) value }; @@ -96,7 +97,7 @@ namespace System.Numerics { { if (value == 0) { sign = 0; - data = ZERO; + data = null; } else { sign = 1; data = new uint [1] { value }; @@ -107,7 +108,7 @@ namespace System.Numerics { { if (value == 0) { sign = 0; - data = ZERO; + data = null; } else if (value > 0) { sign = 1; uint low = (uint)value; @@ -135,7 +136,7 @@ namespace System.Numerics { { if (value == 0) { sign = 0; - data = ZERO; + data = null; } else { sign = 1; uint low = (uint)value; @@ -180,7 +181,7 @@ namespace System.Numerics { int exponent = Exponent (bytes); if (exponent == 0) { sign = 0; - data = ZERO; + data = null; return; } @@ -217,7 +218,7 @@ namespace System.Numerics { if (size == 0) { sign = 0; - data = ZERO; + data = null; return; } @@ -241,7 +242,7 @@ namespace System.Numerics { if (len == 0 || (len == 1 && value [0] == 0)) { sign = 0; - data = ZERO; + data = null; return; } @@ -254,7 +255,7 @@ namespace System.Numerics { while (value [len - 1] == 0) { if (--len == 0) { sign = 0; - data = ZERO; + data = null; return; } } @@ -456,12 +457,12 @@ namespace System.Numerics { } public static BigInteger Zero { - get { return new BigInteger (0, ZERO); } + get { return new BigInteger (0); } } public static explicit operator int (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return 0; if (value.data.Length > 1) throw new OverflowException (); @@ -483,7 +484,7 @@ namespace System.Numerics { [CLSCompliantAttribute (false)] public static explicit operator uint (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return 0; if (value.data.Length > 1 || value.sign == -1) throw new OverflowException (); @@ -527,7 +528,7 @@ namespace System.Numerics { public static explicit operator long (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return 0; if (value.data.Length > 2) @@ -569,7 +570,7 @@ namespace System.Numerics { [CLSCompliantAttribute (false)] public static explicit operator ulong (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return 0; if (value.data.Length > 2 || value.sign == -1) throw new OverflowException (); @@ -584,9 +585,10 @@ namespace System.Numerics { public static explicit operator double (BigInteger value) { - switch (value.data.Length) { - case 0: + if (value.data == null) return 0.0; + + switch (value.data.Length) { case 1: return BuildDouble (value.sign, value.data [0], 0); case 2: @@ -613,7 +615,7 @@ namespace System.Numerics { public static explicit operator decimal (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return Decimal.Zero; uint[] data = value.data; @@ -703,7 +705,7 @@ namespace System.Numerics { int r = CoreCompare (left.data, right.data); if (r == 0) - return new BigInteger (0, ZERO); + return Zero; if (r > 0) //left > right return new BigInteger (left.sign, CoreSub (left.data, right.data)); @@ -722,7 +724,7 @@ namespace System.Numerics { int r = CoreCompare (left.data, right.data); if (r == 0) - return new BigInteger (0, ZERO); + return Zero; if (r > 0) //left > right return new BigInteger (left.sign, CoreSub (left.data, right.data)); @@ -736,7 +738,7 @@ namespace System.Numerics { public static BigInteger operator* (BigInteger left, BigInteger right) { if (left.sign == 0 || right.sign == 0) - return new BigInteger (0, ZERO); + return Zero; if (left.data [0] == 1 && left.data.Length == 1) { if (left.sign == 1) @@ -797,7 +799,7 @@ namespace System.Numerics { int i; for (i = quotient.Length - 1; i >= 0 && quotient [i] == 0; --i) ; if (i == -1) - return new BigInteger (0, ZERO); + return Zero; if (i < quotient.Length - 1) quotient = Resize (quotient, i + 1); @@ -820,7 +822,7 @@ namespace System.Numerics { int i; for (i = remainder_value.Length - 1; i >= 0 && remainder_value [i] == 0; --i) ; if (i == -1) - return new BigInteger (0, ZERO); + return Zero; if (i < remainder_value.Length - 1) remainder_value = Resize (remainder_value, i + 1); @@ -829,7 +831,7 @@ namespace System.Numerics { public static BigInteger operator- (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return value; return new BigInteger ((short)-value.sign, value.data); } @@ -841,14 +843,14 @@ namespace System.Numerics { public static BigInteger operator++ (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return One; short sign = value.sign; uint[] data = value.data; if (data.Length == 1) { if (sign == -1 && data [0] == 1) - return new BigInteger (0, ZERO); + return Zero; if (sign == 0) return new BigInteger (1, ONE); } @@ -863,14 +865,14 @@ namespace System.Numerics { public static BigInteger operator-- (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return MinusOne; short sign = value.sign; uint[] data = value.data; if (data.Length == 1) { if (sign == 1 && data [0] == 1) - return new BigInteger (0, ZERO); + return Zero; if (sign == 0) return new BigInteger (-1, ONE); } @@ -935,7 +937,7 @@ namespace System.Numerics { for (i = result.Length - 1; i >= 0 && result [i] == 0; --i) ; if (i == -1) - return new BigInteger (0, ZERO); + return Zero; if (i < result.Length - 1) result = Resize (result, i + 1); @@ -995,7 +997,7 @@ namespace System.Numerics { for (i = result.Length - 1; i >= 0 && result [i] == 0; --i) ; if (i == -1) - return new BigInteger (0, ZERO); + return Zero; if (i < result.Length - 1) result = Resize (result, i + 1); @@ -1055,7 +1057,7 @@ namespace System.Numerics { for (i = result.Length - 1; i >= 0 && result [i] == 0; --i) ; if (i == -1) - return new BigInteger (0, ZERO); + return Zero; if (i < result.Length - 1) result = Resize (result, i + 1); @@ -1065,7 +1067,7 @@ namespace System.Numerics { public static BigInteger operator~ (BigInteger value) { - if (value.sign == 0) + if (value.data == null) return new BigInteger (-1, ONE); uint[] data = value.data; @@ -1099,7 +1101,7 @@ namespace System.Numerics { for (i = result.Length - 1; i >= 0 && result [i] == 0; --i) ; if (i == -1) - return new BigInteger (0, ZERO); + return Zero; if (i < result.Length - 1) result = Resize (result, i + 1); @@ -1121,7 +1123,7 @@ namespace System.Numerics { public static BigInteger operator<< (BigInteger value, int shift) { - if (shift == 0 || value.sign == 0) + if (shift == 0 || value.data == null) return value; if (shift < 0) return value >> -shift; @@ -1177,7 +1179,7 @@ namespace System.Numerics { if (size <= 0) { if (sign == 1) - return new BigInteger (0, ZERO); + return Zero; return new BigInteger (-1, ONE); } @@ -2142,7 +2144,7 @@ namespace System.Numerics { int i; for (i = remainder_value.Length - 1; i >= 0 && remainder_value [i] == 0; --i) ; if (i == -1) { - remainder = new BigInteger (0, ZERO); + remainder = Zero; } else { if (i < remainder_value.Length - 1) remainder_value = Resize (remainder_value, i + 1); @@ -2151,7 +2153,7 @@ namespace System.Numerics { for (i = quotient.Length - 1; i >= 0 && quotient [i] == 0; --i) ; if (i == -1) - return new BigInteger (0, ZERO); + return Zero; if (i < quotient.Length - 1) quotient = Resize (quotient, i + 1); @@ -2264,7 +2266,7 @@ namespace System.Numerics { if (baseValue == 0.0d || baseValue == Double.PositiveInfinity) return value.IsOne ? 0 : double.NaN; - if (value.sign == 0) + if (value.data == null) return double.NegativeInfinity; int length = value.data.Length - 1; diff --git a/mcs/class/System.Numerics/Test/System.Numerics/BigIntegerTest.cs b/mcs/class/System.Numerics/Test/System.Numerics/BigIntegerTest.cs index 817d13e40c..e9b81a71cd 100644 --- a/mcs/class/System.Numerics/Test/System.Numerics/BigIntegerTest.cs +++ b/mcs/class/System.Numerics/Test/System.Numerics/BigIntegerTest.cs @@ -70,6 +70,7 @@ namespace MonoTests.System.Numerics NfiUser.PercentNegativePattern = 2; NfiUser.PercentPositivePattern = 2; NfiUser.PercentSymbol = "%%%"; + NfiUser.NumberDecimalSeparator = "."; } [Test] @@ -625,10 +626,12 @@ namespace MonoTests.System.Numerics Assert.IsTrue (new BigInteger (1).IsOne, "#7"); Assert.IsTrue (new BigInteger (32).IsPowerOfTwo, "#8"); Assert.IsTrue (new BigInteger (0).IsZero, "#9"); + Assert.IsTrue (new BigInteger ().IsZero, "#9b"); Assert.AreEqual (0, new BigInteger (0).Sign, "#10"); Assert.AreEqual (-1, new BigInteger (-99999).Sign, "#11"); Assert.IsFalse (new BigInteger (0).IsPowerOfTwo, "#12"); + Assert.IsFalse (new BigInteger ().IsPowerOfTwo, "#12b"); Assert.IsFalse (new BigInteger (-16).IsPowerOfTwo, "#13"); Assert.IsTrue (new BigInteger (1).IsPowerOfTwo, "#14"); } @@ -647,6 +650,7 @@ namespace MonoTests.System.Numerics Assert.AreEqual ("0000000005", new BigInteger (5).ToString ("d10"), "#2"); Assert.AreEqual ("0A8", new BigInteger (168).ToString ("X"), "#3"); Assert.AreEqual ("0", new BigInteger (0).ToString ("X"), "#4"); + Assert.AreEqual ("0", new BigInteger ().ToString ("X"), "#4b"); Assert.AreEqual ("1", new BigInteger (1).ToString ("X"), "#5"); Assert.AreEqual ("0A", new BigInteger (10).ToString ("X"), "#6"); Assert.AreEqual ("F6", new BigInteger (-10).ToString ("X"), "#7"); @@ -750,6 +754,7 @@ namespace MonoTests.System.Numerics Assert.AreEqual (new byte[] { 0x7F }, new BigInteger (0x7F).ToByteArray (), "#10"); Assert.AreEqual (new byte[] { 0x45, 0xCC, 0xD0 }, new BigInteger (-0x2F33BB).ToByteArray (), "#11"); Assert.AreEqual (new byte[] { 0 }, new BigInteger (0).ToByteArray (), "#12"); + Assert.AreEqual (new byte[] { 0 }, new BigInteger ().ToByteArray (), "#13"); } [Test] @@ -886,6 +891,14 @@ namespace MonoTests.System.Numerics Assert.AreEqual (-1m, (decimal)new BigInteger (-1), "#6"); Assert.AreEqual (9999999999999999999999999999m, (decimal)new BigInteger (9999999999999999999999999999m), "#7"); + Assert.AreEqual (0m, (decimal)new BigInteger (), "#8"); + } + + [SetCulture ("pt-BR")] + [Test] + public void Parse_pt_BR () + { + Parse (); } [Test] @@ -938,7 +951,8 @@ namespace MonoTests.System.Numerics Assert.AreEqual (-23, (int)BigInteger.Parse(" -23 ", NumberStyles.AllowLeadingSign | NumberStyles.AllowLeadingWhite | NumberStyles.AllowTrailingWhite), "#19"); Assert.AreEqual (300000, (int)BigInteger.Parse("3E5", NumberStyles.AllowExponent), "#20"); - Assert.AreEqual (250, (int)BigInteger.Parse("2"+Nfi.NumberDecimalSeparator+"5E2", NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint), "#21");//2.5E2 = 250 + var dsep = NumberFormatInfo.CurrentInfo.NumberDecimalSeparator; + Assert.AreEqual (250, (int)BigInteger.Parse("2" + dsep + "5E2", NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint), "#21");//2.5E2 = 250 Assert.AreEqual (25, (int)BigInteger.Parse("2500E-2", NumberStyles.AllowExponent), "#22"); Assert.AreEqual ("136236974127783066520110477975349088954559032721408", BigInteger.Parse("136236974127783066520110477975349088954559032721408", NumberStyles.None).ToString(), "#23"); @@ -951,7 +965,7 @@ namespace MonoTests.System.Numerics } try { - Int32.Parse ("2.09E1", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent); + Int32.Parse ("2" + dsep + "09E1", NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent); Assert.Fail ("#26"); } catch (OverflowException) { } @@ -1276,6 +1290,9 @@ namespace MonoTests.System.Numerics a = new BigInteger (); Assert.AreEqual (BigInteger.Zero.GetHashCode (), a.GetHashCode (), "#15"); + + a = new BigInteger (); + Assert.AreEqual (BigInteger.Zero, a, "#16"); } [Test] diff --git a/mcs/class/System.Reactive.Core/Makefile b/mcs/class/System.Reactive.Core/Makefile index 3f74f8bf98..624018c109 100644 --- a/mcs/class/System.Reactive.Core/Makefile +++ b/mcs/class/System.Reactive.Core/Makefile @@ -35,7 +35,7 @@ TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) EXTRA_DISTFILES = more_build_args $(RESX_RESOURCES:.resources=.resx) $(PREBUILT) -VALID_PROFILE := $(filter monotouch monodroid xammac net_4_0 net_4_5, $(PROFILE)) +VALID_PROFILE := $(filter monotouch monodroid xammac mobile mobile_static net_4_0 net_4_5, $(PROFILE)) ifndef VALID_PROFILE LIBRARY_NAME = dummy-System.System.Reactive.Core.dll NO_SIGN_ASSEMBLY = yes diff --git a/mcs/class/System.Reactive.Debugger/Makefile b/mcs/class/System.Reactive.Debugger/Makefile index c603f89a68..3e30821245 100644 --- a/mcs/class/System.Reactive.Debugger/Makefile +++ b/mcs/class/System.Reactive.Debugger/Makefile @@ -24,7 +24,7 @@ TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) EXTRA_DISTFILES = more_build_args -VALID_PROFILE := $(filter monotouch monodroid xammac net_4_0 net_4_5, $(PROFILE)) +VALID_PROFILE := $(filter monotouch monodroid xammac mobile mobile_static net_4_0 net_4_5, $(PROFILE)) ifndef VALID_PROFILE LIBRARY_NAME = dummy-System.System.Reactive.Debugger.dll NO_SIGN_ASSEMBLY = yes diff --git a/mcs/class/System.Reactive.Experimental/Makefile b/mcs/class/System.Reactive.Experimental/Makefile index 234a63b12d..834240accc 100644 --- a/mcs/class/System.Reactive.Experimental/Makefile +++ b/mcs/class/System.Reactive.Experimental/Makefile @@ -24,7 +24,7 @@ TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) EXTRA_DISTFILES = more_build_args -VALID_PROFILE := $(filter monotouch monodroid xammac net_4_0 net_4_5, $(PROFILE)) +VALID_PROFILE := $(filter monotouch monodroid xammac mobile mobile_static net_4_0 net_4_5, $(PROFILE)) ifndef VALID_PROFILE LIBRARY_NAME = dummy-System.System.Reactive.Experimental.dll NO_SIGN_ASSEMBLY = yes diff --git a/mcs/class/System.Reactive.Interfaces/Makefile b/mcs/class/System.Reactive.Interfaces/Makefile index acee40d296..fae4663497 100644 --- a/mcs/class/System.Reactive.Interfaces/Makefile +++ b/mcs/class/System.Reactive.Interfaces/Makefile @@ -21,7 +21,7 @@ TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) EXTRA_DISTFILES = more_build_args -VALID_PROFILE := $(filter monotouch monodroid xammac net_4_0 net_4_5, $(PROFILE)) +VALID_PROFILE := $(filter monotouch monodroid xammac mobile mobile_static net_4_0 net_4_5, $(PROFILE)) ifndef VALID_PROFILE LIBRARY_NAME = dummy-System.System.Reactive.Interfaces.dll NO_SIGN_ASSEMBLY = yes diff --git a/mcs/class/System.Reactive.Linq/Makefile b/mcs/class/System.Reactive.Linq/Makefile index 18a3360daf..3906cfc6ad 100644 --- a/mcs/class/System.Reactive.Linq/Makefile +++ b/mcs/class/System.Reactive.Linq/Makefile @@ -36,7 +36,7 @@ TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) EXTRA_DISTFILES = more_build_args $(RESX_RESOURCES:.resources=.resx) $(PREBUILT) -VALID_PROFILE := $(filter monotouch monodroid xammac net_4_0 net_4_5, $(PROFILE)) +VALID_PROFILE := $(filter monotouch monodroid xammac mobile mobile_static net_4_0 net_4_5, $(PROFILE)) ifndef VALID_PROFILE LIBRARY_NAME = dummy-System.System.Reactive.Linq.dll NO_SIGN_ASSEMBLY = yes diff --git a/mcs/class/System.Reactive.PlatformServices/Makefile b/mcs/class/System.Reactive.PlatformServices/Makefile index 187dd7702f..6fccc274c4 100644 --- a/mcs/class/System.Reactive.PlatformServices/Makefile +++ b/mcs/class/System.Reactive.PlatformServices/Makefile @@ -42,7 +42,7 @@ TEST_MCS_FLAGS = $(LIB_MCS_FLAGS) -r:Mono.Reactive.Tests.dll EXTRA_DISTFILES = more_build_args $(RESX_RESOURCES:.resources=.resx) $(PREBUILT) -VALID_PROFILE := $(filter monotouch monodroid xammac net_4_0 net_4_5, $(PROFILE)) +VALID_PROFILE := $(filter monotouch monodroid xammac mobile mobile_static net_4_0 net_4_5, $(PROFILE)) ifndef VALID_PROFILE LIBRARY_NAME = dummy-System.System.Reactive.PlatformServices.dll NO_SIGN_ASSEMBLY = yes diff --git a/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/DataContractJsonSerializer.cs b/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/DataContractJsonSerializer.cs index 295161932b..8ae0ce5735 100644 --- a/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/DataContractJsonSerializer.cs +++ b/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/DataContractJsonSerializer.cs @@ -84,7 +84,17 @@ namespace System.Runtime.Serialization.Json throw new ArgumentOutOfRangeException ("maxItemsInObjectGraph"); this.type = type; - known_types = new ReadOnlyCollection (knownTypes != null ? knownTypes.ToArray () : Type.EmptyTypes); + + var knownTypesFromAttributes = new List (); + + foreach (var attr in type.GetCustomAttributes (typeof (KnownTypeAttribute), false)) + knownTypesFromAttributes.Add ((attr as KnownTypeAttribute).Type); + + if (knownTypes != null) + knownTypesFromAttributes.AddRange (knownTypes); + + known_types = new ReadOnlyCollection (knownTypesFromAttributes); + root = rootName; max_items = maxItemsInObjectGraph; ignore_extension = ignoreExtensionDataObject; @@ -134,8 +144,6 @@ namespace System.Runtime.Serialization.Json public bool IgnoreExtensionDataObject { get { return ignore_extension; } } - - [MonoTODO] public ReadOnlyCollection KnownTypes { get { return known_types; } } diff --git a/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonSerializationReader.cs b/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonSerializationReader.cs index 8f8fe7171f..d0f84d0f93 100644 --- a/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonSerializationReader.cs +++ b/mcs/class/System.ServiceModel.Web/System.Runtime.Serialization.Json/JsonSerializationReader.cs @@ -182,8 +182,18 @@ namespace System.Runtime.Serialization.Json if (ct != null) { return DeserializeGenericCollection (type, ct, instance); } else { - TypeMap map = GetTypeMap (type); - return map.Deserialize (this, instance); + string typeHint = reader.GetAttribute ("__type"); + if (typeHint != null) { + // this might be a derived & known type. We allow it when it's both. + Type exactType = GetRuntimeType (typeHint, type); + if (exactType == null) + throw SerializationError (String.Format ("Cannot load type '{0}'", typeHint)); + TypeMap map = GetTypeMap (exactType); + return map.Deserialize (this, instance); + } else { // no type hint + TypeMap map = GetTypeMap (type); + return map.Deserialize (this, instance); + } } } else @@ -198,24 +208,22 @@ namespace System.Runtime.Serialization.Json } - Type GetRuntimeType (string name) + Type GetRuntimeType (string name, Type baseType) { - name = ToRuntimeTypeName (name); + string properName = ToRuntimeTypeName (name); + + if (baseType != null && baseType.FullName.Equals (properName)) + return baseType; + if (serializer.KnownTypes != null) foreach (Type t in serializer.KnownTypes) - if (t.FullName == name) + if (t.FullName.Equals (properName)) return t; - var ret = root_type.Assembly.GetType (name, false) ?? Type.GetType (name, false); - if (ret != null) - return ret; - // We probably have to iterate all the existing - // assemblies that are loaded in current domain. - foreach (var ass in AppDomain.CurrentDomain.GetAssemblies ()) { - ret = ass.GetType (name, false); - if (ret != null) - return ret; - } + if (baseType != null) + foreach (var attr in baseType.GetCustomAttributes (typeof (KnownTypeAttribute), false)) + if ((attr as KnownTypeAttribute).Type.FullName.Equals (properName)) + return (attr as KnownTypeAttribute).Type; return null; } @@ -230,7 +238,7 @@ namespace System.Runtime.Serialization.Json case "object": string runtimeType = reader.GetAttribute ("__type"); if (runtimeType != null) { - Type t = GetRuntimeType (runtimeType); + Type t = GetRuntimeType (runtimeType, null); if (t == null) throw SerializationError (String.Format ("Cannot load type '{0}'", runtimeType)); return ReadObject (t); @@ -264,7 +272,7 @@ namespace System.Runtime.Serialization.Json if (double.TryParse (v, NumberStyles.None, CultureInfo.InvariantCulture, out dbl)) return dbl; decimal dec; - if (decimal.TryParse (v, NumberStyles.None, CultureInfo.InvariantCulture, out dec)) + if (decimal.TryParse (v, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out dec)) return dec; throw SerializationError (String.Format ("Invalid JSON input: {0}", v)); default: diff --git a/mcs/class/System.ServiceModel.Web/System.ServiceModel.Syndication/Rss20ItemFormatter.cs b/mcs/class/System.ServiceModel.Web/System.ServiceModel.Syndication/Rss20ItemFormatter.cs index cd4c1ffccd..cd586fa05c 100644 --- a/mcs/class/System.ServiceModel.Web/System.ServiceModel.Syndication/Rss20ItemFormatter.cs +++ b/mcs/class/System.ServiceModel.Web/System.ServiceModel.Syndication/Rss20ItemFormatter.cs @@ -203,10 +203,9 @@ namespace System.ServiceModel.Syndication Item.Links.Add (l); continue; case "guid": + Item.Id = reader.ReadElementContentAsString (); if (reader.GetAttribute ("isPermaLink") == "true") - Item.AddPermalink (CreateUri (reader.ReadElementContentAsString ())); - else - Item.Id = reader.ReadElementContentAsString (); + Item.AddPermalink (CreateUri (Item.Id)); continue; case "pubDate": Item.PublishDate = FromRFC822DateString (reader.ReadElementContentAsString ()); diff --git a/mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs b/mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs index 68d9fb6a08..8a11d70baf 100644 --- a/mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs +++ b/mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/DataContractJsonSerializerTest.cs @@ -1191,6 +1191,15 @@ namespace MonoTests.System.Runtime.Serialization.Json return ser.ReadObject (xr); } + public T Deserialize(string json) + { + var bytes = Encoding.Unicode.GetBytes (json); + using (MemoryStream stream = new MemoryStream (bytes)) { + var serializer = new DataContractJsonSerializer (typeof(T)); + return (T)serializer.ReadObject (stream); + } + } + [Test] public void IsStartObject () { @@ -1819,6 +1828,50 @@ namespace MonoTests.System.Runtime.Serialization.Json serializer.WriteObject (stream, o); } + // properly deserialize object with a polymorphic property (known derived type) + [Test] + public void Bug23058() + { + string serializedObj = @"{""PolymorphicProperty"":{""__type"":""KnownDerivedType:#MonoTests.System.Runtime.Serialization.Json"",""BaseTypeProperty"":""Base"",""DerivedProperty"":""Derived 1""},""Name"":""Parent2""}"; + ParentType deserializedObj = Deserialize (serializedObj); + + Assert.AreEqual (deserializedObj.PolymorphicProperty.GetType ().FullName, "MonoTests.System.Runtime.Serialization.Json.KnownDerivedType"); + Assert.AreEqual (deserializedObj.PolymorphicProperty.BaseTypeProperty, "Base"); + Assert.AreEqual ((deserializedObj.PolymorphicProperty as KnownDerivedType).DerivedProperty, "Derived 1"); + Assert.AreEqual (deserializedObj.Name, "Parent2"); + } + + // properly deserialize object with a polymorphic property (base type with __type hint) + [Test] + public void DeserializeBaseTypePropHint() + { + string serializedObj = @"{""PolymorphicProperty"":{""__type"":""BaseType:#MonoTests.System.Runtime.Serialization.Json"",""BaseTypeProperty"":""Base""},""Name"":""Parent2""}"; + ParentType deserializedObj = Deserialize (serializedObj); + + Assert.AreEqual (deserializedObj.PolymorphicProperty.GetType ().FullName, "MonoTests.System.Runtime.Serialization.Json.BaseType"); + Assert.AreEqual (deserializedObj.PolymorphicProperty.BaseTypeProperty, "Base"); + } + + // properly deserialize object with a polymorphic property (base type with __type hint) + [Test] + public void DeserializeBaseTypePropNoHint() + { + string serializedObj = @"{""PolymorphicProperty"":{""BaseTypeProperty"":""Base""},""Name"":""Parent2""}"; + ParentType deserializedObj = Deserialize (serializedObj); + + Assert.AreEqual (deserializedObj.PolymorphicProperty.GetType ().FullName, "MonoTests.System.Runtime.Serialization.Json.BaseType"); + Assert.AreEqual (deserializedObj.PolymorphicProperty.BaseTypeProperty, "Base"); + } + + // properly fail deserializing object with a polymorphic property (unknown derived type) + [ExpectedException (typeof (SerializationException))] + [Test] + public void FailDeserializingUnknownTypeProp() + { + string serializedObj = @"{""PolymorphicProperty"":{""__type"":""UnknownDerivedType:#MonoTests.System.Runtime.Serialization.Json"",""BaseTypeProperty"":""Base"",""DerivedProperty"":""Derived 1""},""Name"":""Parent2""}"; + ParentType deserializedObj = Deserialize (serializedObj); + } + #endregion } @@ -2037,6 +2090,42 @@ namespace MonoTests.System.Runtime.Serialization.Json public long CodedServerTimeUTC { get; set; } public DateTime ServerTimeUTC { get; set; } } + + #region polymorphism test helper classes + + [DataContract] + [KnownType (typeof (KnownDerivedType))] + public class ParentType + { + [DataMember] + public string Name { get; set; } + + [DataMember] + public BaseType PolymorphicProperty { get; set; } + } + + [DataContract] + public class BaseType + { + [DataMember] + public string BaseTypeProperty { get; set; } + } + + [DataContract] + public class KnownDerivedType : BaseType + { + [DataMemberAttribute] + public string DerivedProperty { get; set; } + } + + [DataContract] + public class UnknownDerivedType : BaseType + { + [DataMember] + public string DerivedProperty { get; set; } + } + + #endregion } [DataContract] diff --git a/mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/JsonReaderTest.cs b/mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/JsonReaderTest.cs index 0ca6f2fb05..de884aeac9 100644 --- a/mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/JsonReaderTest.cs +++ b/mcs/class/System.ServiceModel.Web/Test/System.Runtime.Serialization.Json/JsonReaderTest.cs @@ -855,5 +855,16 @@ namespace MonoTests.System.Runtime.Serialization.Json r.ReadStartElement (); r.Read (); } + + [Test] + public void ReadNumberAsObject () + { + const double testValue = 42.42D; + var serializer = new DataContractJsonSerializer (typeof (object)); + var serializedStream = GetInput (testValue.ToString (CultureInfo.InvariantCulture)); + var deserializedValue = serializer.ReadObject (serializedStream); + Assert.AreEqual (typeof (decimal), deserializedValue.GetType ()); + Assert.AreEqual (testValue, (decimal) deserializedValue); + } } } diff --git a/mcs/class/System.ServiceModel.Web/Test/System.ServiceModel.Syndication/Rss20ItemFormatterTest.cs b/mcs/class/System.ServiceModel.Web/Test/System.ServiceModel.Syndication/Rss20ItemFormatterTest.cs index 3b83d230cb..d0ea17ff6a 100644 --- a/mcs/class/System.ServiceModel.Web/Test/System.ServiceModel.Syndication/Rss20ItemFormatterTest.cs +++ b/mcs/class/System.ServiceModel.Web/Test/System.ServiceModel.Syndication/Rss20ItemFormatterTest.cs @@ -351,6 +351,24 @@ namespace MonoTests.System.ServiceModel.Syndication { Assert.IsNull (((IXmlSerializable) new Rss20ItemFormatter ()).GetSchema ()); } + + [Test] + public void ReadFromGuidPermaLink () + { + const string xml1 = "urn:myid"; + using (XmlReader r = CreateReader (xml1)) { + var rss = new Rss20ItemFormatter (); + rss.ReadFrom (r); + Assert.AreEqual ("urn:myid", rss.Item.Id); + } + + const string xml2 = "urn:myid"; + using (XmlReader r = CreateReader (xml2)) { + var rss = new Rss20ItemFormatter (); + rss.ReadFrom (r); + Assert.AreEqual ("urn:myid", rss.Item.Id); + } + } } } #endif \ No newline at end of file diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescription.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescription.cs index 6c0c3366f7..805053196d 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescription.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescription.cs @@ -234,6 +234,9 @@ namespace System.ServiceModel.Description foreach (var fd in od.Faults) o.FaultContractInfos.Add (new FaultContractInfo (fd.Action, fd.DetailType)); + o.BeginMethod = od.BeginMethod; + o.EndMethod = od.EndMethod; + // FIXME: at initialization time it does not seem to // fill default formatter. It should be filled after // applying all behaviors. (Tthat causes regression, so diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescriptionGenerator.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescriptionGenerator.cs index 929a450d22..a7665b8cab 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescriptionGenerator.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Description/ContractDescriptionGenerator.cs @@ -237,7 +237,6 @@ namespace System.ServiceModel.Description for (int i = 0; i < contractMethods.Length; ++i) { - MethodInfo mi = contractMethods [i]; OperationContractAttribute oca = GetOperationContractAttribute (mi); if (oca == null) @@ -253,7 +252,7 @@ namespace System.ServiceModel.Description if (GetOperationContractAttribute (end) != null) throw new InvalidOperationException ("Async 'End' method must not have OperationContractAttribute. It is automatically treated as the EndMethod of the corresponding 'Begin' method."); } - OperationDescription od = GetOrCreateOperation (cd, mi, serviceMethods [i], oca, end != null ? end.ReturnType : null, isCallback, givenServiceType); + OperationDescription od = GetOrCreateOperation (cd, mi, serviceMethods [i], oca, end, isCallback, givenServiceType); if (end != null) od.EndMethod = end; } @@ -286,7 +285,7 @@ namespace System.ServiceModel.Description static OperationDescription GetOrCreateOperation ( ContractDescription cd, MethodInfo mi, MethodInfo serviceMethod, OperationContractAttribute oca, - Type asyncReturnType, + MethodInfo endMethod, bool isCallback, Type givenServiceType) { @@ -311,7 +310,8 @@ namespace System.ServiceModel.Description od.Messages.Add (GetMessage (od, mi, oca, true, isCallback, null)); if (!od.IsOneWay) { - var md = GetMessage (od, mi, oca, false, isCallback, asyncReturnType); + var asyncReturnType = endMethod != null ? endMethod.ReturnType : null; + var md = GetMessage (od, endMethod ?? mi, oca, false, isCallback, asyncReturnType); od.Messages.Add (md); var mpa = mi.ReturnParameter.GetCustomAttribute (true); if (mpa != null) { @@ -522,8 +522,12 @@ namespace System.ServiceModel.Description int index = 0; foreach (ParameterInfo pi in plist) { // AsyncCallback and state are extraneous. - if (oca.AsyncPattern && pi.Position == plist.Length - 2) - break; + if (oca.AsyncPattern) { + if (isRequest && pi.Position == plist.Length - 2) + break; + if (!isRequest && pi.Position == plist.Length - 1) + break; + } // They are ignored: // - out parameter in request diff --git a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/BaseMessagesFormatter.cs b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/BaseMessagesFormatter.cs index f512ea3755..db1c49650c 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/BaseMessagesFormatter.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/BaseMessagesFormatter.cs @@ -281,9 +281,10 @@ namespace System.ServiceModel.Dispatcher } else { int index = ParamsOffset (md.Body); - foreach (ParameterInfo pi in requestMethodParams) + foreach (ParameterInfo pi in replyMethodParams) { if (pi.IsOut || pi.ParameterType.IsByRef) parameters [pi.Position] = parts [index++]; + } return HasReturnValue (md.Body) ? parts [0] : null; } } diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/ClientBase.cs b/mcs/class/System.ServiceModel/System.ServiceModel/ClientBase.cs index 702217017d..07952e04f1 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/ClientBase.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/ClientBase.cs @@ -389,7 +389,7 @@ namespace System.ServiceModel var od = cd.Operations.Find (methodName); if (od == null) throw new ArgumentException (String.Format ("Operation '{0}' not found in the service contract '{1}' in namespace '{2}'", methodName, cd.Name, cd.Namespace)); - return Inner.Process (od.SyncMethod, methodName, args); + return Inner.Process (od.SyncMethod, methodName, args, OperationContext.Current); } protected IAsyncResult BeginInvoke (string methodName, object [] args, AsyncCallback callback, object state) diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/ClientRealProxy.cs b/mcs/class/System.ServiceModel/System.ServiceModel/ClientRealProxy.cs index 1c94718b6b..41d75e98f9 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/ClientRealProxy.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/ClientRealProxy.cs @@ -108,8 +108,7 @@ namespace System.ServiceModel // sync invocation pl = new object [inmsg.MethodBase.GetParameters ().Length]; Array.Copy (inmsg.Args, pl, inmsg.ArgCount); - channel.Context = OperationContext.Current; - ret = channel.Process (inmsg.MethodBase, od.Name, pl); + ret = channel.Process (inmsg.MethodBase, od.Name, pl, OperationContext.Current); method = od.SyncMethod; } else if (inmsg.MethodBase.Equals (od.BeginMethod)) { // async invocation diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs b/mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs index 6d073e3d57..043b2ab7af 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/ClientRuntimeChannel.cs @@ -46,9 +46,7 @@ namespace System.ServiceModel.MonoInternal { ContractDescription Contract { get; } - OperationContext Context { set; } - - object Process (MethodBase method, string operationName, object [] parameters); + object Process (MethodBase method, string operationName, object [] parameters, OperationContext context); IAsyncResult BeginProcess (MethodBase method, string operationName, object [] parameters, AsyncCallback callback, object asyncState); @@ -69,12 +67,11 @@ namespace System.ServiceModel.MonoInternal TimeSpan default_open_timeout, default_close_timeout; IChannel channel; IChannelFactory factory; - OperationContext context; #region delegates readonly ProcessDelegate _processDelegate; - delegate object ProcessDelegate (MethodBase method, string operationName, object [] parameters); + delegate object ProcessDelegate (MethodBase method, string operationName, bool isAsync, ref object [] parameters, OperationContext context); readonly RequestDelegate requestDelegate; @@ -149,10 +146,6 @@ namespace System.ServiceModel.MonoInternal get { return channel as IDuplexChannel; } } - public OperationContext Context { - set { context = value; } - } - #region IClientChannel bool did_interactive_initialization; @@ -445,42 +438,48 @@ namespace System.ServiceModel.MonoInternal public IAsyncResult BeginProcess (MethodBase method, string operationName, object [] parameters, AsyncCallback callback, object asyncState) { - if (context != null) - throw new InvalidOperationException ("another operation is in progress"); - context = OperationContext.Current; - - try { - return _processDelegate.BeginInvoke (method, operationName, parameters, callback, asyncState); - } catch { - context = null; - throw; - } + var p = parameters; + var retval = _processDelegate.BeginInvoke (method, operationName, true, ref p, OperationContext.Current, callback, asyncState); + if (p != parameters) + throw new InvalidOperationException (); + return retval; } public object EndProcess (MethodBase method, string operationName, object [] parameters, IAsyncResult result) { - try { - if (result == null) - throw new ArgumentNullException ("result"); - if (parameters == null) - throw new ArgumentNullException ("parameters"); - // FIXME: the method arguments should be verified to be - // identical to the arguments in the corresponding begin method. - return _processDelegate.EndInvoke (result); - } finally { - context = null; - } + if (result == null) + throw new ArgumentNullException ("result"); + if (parameters == null) + throw new ArgumentNullException ("parameters"); + + object[] p = parameters; + var retval = _processDelegate.EndInvoke (ref p, result); + if (p == parameters) + return retval; + + if (p.Length != parameters.Length) + throw new InvalidOperationException (); + Array.Copy (p, parameters, p.Length); + return retval; } - public object Process (MethodBase method, string operationName, object [] parameters) + public object Process (MethodBase method, string operationName, object [] parameters, OperationContext context) + { + var p = parameters; + var retval = Process (method, operationName, false, ref p, context); + if (p != parameters) + throw new InvalidOperationException (); + return retval; + } + + object Process (MethodBase method, string operationName, bool isAsync, ref object [] parameters, OperationContext context) { var previousContext = OperationContext.Current; try { // Inherit the context from the calling thread - if (this.context != null) - OperationContext.Current = this.context; + OperationContext.Current = context; - return DoProcess (method, operationName, parameters); + return DoProcess (method, operationName, isAsync, ref parameters, context); } catch (Exception ex) { throw; } finally { @@ -489,7 +488,7 @@ namespace System.ServiceModel.MonoInternal } } - object DoProcess (MethodBase method, string operationName, object [] parameters) + object DoProcess (MethodBase method, string operationName, bool isAsync, ref object [] parameters, OperationContext context) { if (AllowInitializationUI) DisplayInitializationUI (); @@ -499,9 +498,9 @@ namespace System.ServiceModel.MonoInternal Open (); if (!od.IsOneWay) - return Request (od, parameters); + return Request (od, isAsync, ref parameters, context); else { - Output (od, parameters); + Output (od, parameters, context); return null; } } @@ -519,17 +518,17 @@ namespace System.ServiceModel.MonoInternal return od; } - void Output (OperationDescription od, object [] parameters) + void Output (OperationDescription od, object [] parameters, OperationContext context) { ClientOperation op = runtime.Operations [od.Name]; - Send (CreateRequest (op, parameters), OperationTimeout); + Send (CreateRequest (op, parameters, context), OperationTimeout); } - object Request (OperationDescription od, object [] parameters) + object Request (OperationDescription od, bool isAsync, ref object [] parameters, OperationContext context) { ClientOperation op = runtime.Operations [od.Name]; object [] inspections = new object [runtime.MessageInspectors.Count]; - Message req = CreateRequest (op, parameters); + Message req = CreateRequest (op, parameters, context); for (int i = 0; i < inspections.Length; i++) inspections [i] = runtime.MessageInspectors [i].BeforeSendRequest (ref req, this); @@ -566,10 +565,15 @@ namespace System.ServiceModel.MonoInternal for (int i = 0; i < inspections.Length; i++) runtime.MessageInspectors [i].AfterReceiveReply (ref res, inspections [i]); - if (op.DeserializeReply) - return op.Formatter.DeserializeReply (res, parameters); - else + if (!op.DeserializeReply) return res; + + if (isAsync && od.EndMethod != null) { + var endParams = od.EndMethod.GetParameters (); + parameters = new object [endParams.Length - 1]; + } + + return op.Formatter.DeserializeReply (res, parameters); } #region Message-based Request() and Send() @@ -621,7 +625,7 @@ namespace System.ServiceModel.MonoInternal } #endregion - Message CreateRequest (ClientOperation op, object [] parameters) + Message CreateRequest (ClientOperation op, object [] parameters, OperationContext context) { MessageVersion version = message_version; if (version == null) diff --git a/mcs/class/System.ServiceModel/System.ServiceModel/ServiceRuntimeChannel.cs b/mcs/class/System.ServiceModel/System.ServiceModel/ServiceRuntimeChannel.cs index 0fe0d47b3d..7bc5482362 100644 --- a/mcs/class/System.ServiceModel/System.ServiceModel/ServiceRuntimeChannel.cs +++ b/mcs/class/System.ServiceModel/System.ServiceModel/ServiceRuntimeChannel.cs @@ -114,9 +114,9 @@ namespace System.ServiceModel.MonoInternal return client.EndProcess (method, operationName, parameters, result); } - public object Process (MethodBase method, string operationName, object [] parameters) + public object Process (MethodBase method, string operationName, object [] parameters, OperationContext context) { - return client.Process (method, operationName, parameters); + return client.Process (method, operationName, parameters, context); } } diff --git a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/CommunicationObjectSyncTest.cs b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/CommunicationObjectSyncTest.cs index 1650bead02..798a77915f 100644 --- a/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/CommunicationObjectSyncTest.cs +++ b/mcs/class/System.ServiceModel/Test/System.ServiceModel.Channels/CommunicationObjectSyncTest.cs @@ -35,7 +35,7 @@ using System.ServiceModel.Channels; using Microsoft.VisualStudio.TestTools.UnitTesting; using Mono.Moonlight.UnitTesting; -namespace MoonTest.ServiceModel { +namespace MonoTests.System.ServiceModel.Channels { [TestClass] public class CommunicationObjectSyncTest { diff --git a/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceBaseTest.cs b/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceBaseTest.cs index 7a3c014f7c..ec6a3a236b 100644 --- a/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceBaseTest.cs +++ b/mcs/class/System.ServiceProcess/Test/System.ServiceProcess/ServiceBaseTest.cs @@ -27,10 +27,11 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System.ComponentModel; using System.ServiceProcess; using NUnit.Framework; -namespace Test +namespace MonoTests.System.ServiceProcess { [TestFixture] public class ServiceBaseTest @@ -84,7 +85,7 @@ namespace Test /// /// Required designer variable. /// - private System.ComponentModel.IContainer components = null; + private IContainer components = null; /// /// Clean up any resources being used. @@ -107,7 +108,7 @@ namespace Test /// private void InitializeComponent() { - components = new System.ComponentModel.Container(); + components = new Container(); this.ServiceName = "ServiceFoo"; } diff --git a/mcs/class/System.Web.Abstractions/System.Web/HttpRequestBase.cs b/mcs/class/System.Web.Abstractions/System.Web/HttpRequestBase.cs index 3a4c58e951..3a31754b94 100644 --- a/mcs/class/System.Web.Abstractions/System.Web/HttpRequestBase.cs +++ b/mcs/class/System.Web.Abstractions/System.Web/HttpRequestBase.cs @@ -136,6 +136,9 @@ namespace System.Web public virtual int TotalBytes { get { NotImplemented (); return 0; } } +#if NET_4_5 + public virtual ReadEntityBodyMode ReadEntityBodyMode { get { NotImplemented(); return ReadEntityBodyMode.Classic; } } +#endif public virtual Uri Url { get { NotImplemented (); return null; } } public virtual Uri UrlReferrer { get { NotImplemented (); return null; } } @@ -148,6 +151,12 @@ namespace System.Web public virtual string [] UserLanguages { get { NotImplemented (); return null; } } +#if NET_4_5 + public virtual void Abort () + { + NotImplemented(); + } +#endif public virtual byte [] BinaryRead (int count) { diff --git a/mcs/class/System.Web.Abstractions/System.Web/HttpRequestWrapper.cs b/mcs/class/System.Web.Abstractions/System.Web/HttpRequestWrapper.cs index 41969c6468..dc5098a3be 100644 --- a/mcs/class/System.Web.Abstractions/System.Web/HttpRequestWrapper.cs +++ b/mcs/class/System.Web.Abstractions/System.Web/HttpRequestWrapper.cs @@ -232,6 +232,13 @@ namespace System.Web get { return w.UserLanguages; } } +#if NET_4_5 + public void Abort () + { + w.WorkerRequest.CloseConnection(); + } +#endif + public override byte [] BinaryRead (int count) { return w.BinaryRead (count); diff --git a/mcs/class/System.Web.Abstractions/System.Web/HttpResponseBase.cs b/mcs/class/System.Web.Abstractions/System.Web/HttpResponseBase.cs index 0a3aa6694d..921ace9ea8 100644 --- a/mcs/class/System.Web.Abstractions/System.Web/HttpResponseBase.cs +++ b/mcs/class/System.Web.Abstractions/System.Web/HttpResponseBase.cs @@ -105,6 +105,10 @@ namespace System.Web public virtual bool SuppressContent { get { NotImplemented (); return false; } set { NotImplemented (); } } +#if NET_4_5 + public virtual bool SuppressFormsAuthenticationRedirect { get { NotImplemented (); return false; } set { NotImplemented (); } } +#endif + public virtual bool TrySkipIisCustomErrors { get { NotImplemented (); return false; } set { NotImplemented (); } } diff --git a/mcs/class/System.Web.Abstractions/System.Web/HttpResponseWrapper.cs b/mcs/class/System.Web.Abstractions/System.Web/HttpResponseWrapper.cs index eed3415cd1..1d9c207817 100644 --- a/mcs/class/System.Web.Abstractions/System.Web/HttpResponseWrapper.cs +++ b/mcs/class/System.Web.Abstractions/System.Web/HttpResponseWrapper.cs @@ -169,6 +169,13 @@ namespace System.Web set { w.SuppressContent = value; } } +#if NET_4_5 + public override bool SuppressFormsAuthenticationRedirect { + get { return w.SuppressFormsAuthenticationRedirect; } + set { w.SuppressFormsAuthenticationRedirect = value; } + } +#endif + public override bool TrySkipIisCustomErrors { get { return w.TrySkipIisCustomErrors; } set { w.TrySkipIisCustomErrors = value; } diff --git a/mcs/class/System.Web.Extensions/System.Web.Script.Services/LogicalTypeInfo.cs b/mcs/class/System.Web.Extensions/System.Web.Script.Services/LogicalTypeInfo.cs index 5f8defbff8..a9b6fc0171 100644 --- a/mcs/class/System.Web.Extensions/System.Web.Script.Services/LogicalTypeInfo.cs +++ b/mcs/class/System.Web.Extensions/System.Web.Script.Services/LogicalTypeInfo.cs @@ -411,7 +411,7 @@ if (typeof({0}) === 'undefined') {{", className); var ret = new Dictionary (); for (int i = nvc.Count - 1; i >= 0; i--) - ret.Add (nvc.GetKey (i), JavaScriptSerializer.DefaultSerializer.DeserializeObjectInternal (nvc.Get (i))); + ret.Add (nvc.GetKey (i), nvc.Get (i)); return ret; } diff --git a/mcs/class/System.Web/System.Web.Configuration_2.0/WebConfigurationManager.cs b/mcs/class/System.Web/System.Web.Configuration_2.0/WebConfigurationManager.cs index 14bcf13a6e..75fd8723e7 100644 --- a/mcs/class/System.Web/System.Web.Configuration_2.0/WebConfigurationManager.cs +++ b/mcs/class/System.Web/System.Web.Configuration_2.0/WebConfigurationManager.cs @@ -67,6 +67,7 @@ namespace System.Web.Configuration { static readonly char[] pathTrimChars = { '/' }; static readonly object suppressAppReloadLock = new object (); static readonly object saveLocationsCacheLock = new object (); + static readonly object getSectionLock = new object (); // See comment for the cacheLock field at top of System.Web.Caching/Cache.cs static readonly ReaderWriterLockSlim sectionCacheLock; @@ -517,7 +518,10 @@ namespace System.Web.Configuration { cachePath = path; } - ConfigurationSection section = c.GetSection (sectionName); + ConfigurationSection section; + lock (getSectionLock) { + section = c.GetSection (sectionName); + } if (section == null) return null; @@ -529,7 +533,7 @@ namespace System.Web.Configuration { value = collection; } #else - object value = SettingsMappingManager.MapSection (get_runtime_object.Invoke (section, new object [0])); + object value = SettingsMappingManager.MapSection (section.GetRuntimeObject ()); #endif if (cachePath != null) cacheKey = baseCacheKey ^ cachePath.GetHashCode (); @@ -677,7 +681,9 @@ namespace System.Web.Configuration { configurations.Remove (GetCurrentPath (ctx)); } +#if TARGET_J2EE readonly static MethodInfo get_runtime_object = typeof (ConfigurationSection).GetMethod ("GetRuntimeObject", BindingFlags.NonPublic | BindingFlags.Instance); +#endif public static object GetWebApplicationSection (string sectionName) { diff --git a/mcs/class/System.Web/System.Web.Hosting/HostingEnvironment.cs b/mcs/class/System.Web/System.Web.Hosting/HostingEnvironment.cs index f585531194..a2b87e029c 100644 --- a/mcs/class/System.Web/System.Web.Hosting/HostingEnvironment.cs +++ b/mcs/class/System.Web/System.Web.Hosting/HostingEnvironment.cs @@ -160,7 +160,9 @@ namespace System.Web.Hosting { { if (obj == null) throw new ArgumentNullException ("obj"); - Host.RegisterObject (obj, false); + + if (Host != null) + Host.RegisterObject (obj, false); } public static void RegisterVirtualPathProvider (VirtualPathProvider virtualPathProvider) @@ -200,7 +202,9 @@ namespace System.Web.Hosting { { if (obj == null) throw new ArgumentNullException ("obj"); - Host.UnregisterObject (obj); + + if (Host != null) + Host.UnregisterObject (obj); } } } diff --git a/mcs/class/System.Web/System.Web.Security/FormsAuthenticationModule.cs b/mcs/class/System.Web/System.Web.Security/FormsAuthenticationModule.cs index cab57fea2f..54f07294e2 100644 --- a/mcs/class/System.Web/System.Web.Security/FormsAuthenticationModule.cs +++ b/mcs/class/System.Web/System.Web.Security/FormsAuthenticationModule.cs @@ -180,6 +180,11 @@ namespace System.Web.Security if (context.Response.StatusCode != 401 || context.Request.QueryString ["ReturnUrl"] != null) return; +#if NET_4_5 + if (context.Response.StatusCode == 401 && context.Response.SuppressFormsAuthenticationRedirect) + return; +#endif + string loginPage; InitConfig (context); #if NET_2_0 diff --git a/mcs/class/System.Web/System.Web.Security/MembershipUser.cs b/mcs/class/System.Web/System.Web.Security/MembershipUser.cs index b2bae459a5..13a7319cba 100644 --- a/mcs/class/System.Web/System.Web.Security/MembershipUser.cs +++ b/mcs/class/System.Web/System.Web.Security/MembershipUser.cs @@ -94,7 +94,7 @@ namespace System.Web.Security internal void UpdateUser () { - MembershipUser newUser = Provider.GetUser (name, false); + MembershipUser newUser = Provider.GetUser (UserName, false); UpdateSelf (newUser); } diff --git a/mcs/class/System.Web/System.Web/HttpApplication.cs b/mcs/class/System.Web/System.Web/HttpApplication.cs index efa4432011..da393081d5 100644 --- a/mcs/class/System.Web/System.Web/HttpApplication.cs +++ b/mcs/class/System.Web/System.Web/HttpApplication.cs @@ -230,6 +230,10 @@ namespace System.Web } } catch (Exception e) { initialization_exception = e; + Console.Error.WriteLine("Exception while initOnce: "+e.ToString()); + // Once initialization_exception != null, we always respond with this exception + // You have to restart the HttpApplication to "unlock" it + Console.Error.WriteLine("Please restart your app to unlock it"); } finally { if (mustNullContext) context = null; @@ -1549,6 +1553,7 @@ namespace System.Web if (initialization_exception != null) { Exception e = initialization_exception; HttpException exc = HttpException.NewWithCode (String.Empty, e, WebEventCodes.RuntimeErrorRequestAbort); + context.Response.StatusCode = 500; FinalErrorWrite (context.Response, exc.GetHtmlErrorMessage ()); PipelineDone (); return; diff --git a/mcs/class/System.Web/System.Web/HttpResponse.cs b/mcs/class/System.Web/System.Web/HttpResponse.cs index 65718e5cd9..4bd3380a8f 100644 --- a/mcs/class/System.Web/System.Web/HttpResponse.cs +++ b/mcs/class/System.Web/System.Web/HttpResponse.cs @@ -400,6 +400,13 @@ namespace System.Web set; } +#if NET_4_5 + public bool SuppressFormsAuthenticationRedirect { + get; + set; + } +#endif + public bool TrySkipIisCustomErrors { get; set; diff --git a/mcs/class/System.Web/System.Web/HttpUtility.cs b/mcs/class/System.Web/System.Web/HttpUtility.cs index bb821a573c..7189276746 100644 --- a/mcs/class/System.Web/System.Web/HttpUtility.cs +++ b/mcs/class/System.Web/System.Web/HttpUtility.cs @@ -56,7 +56,7 @@ namespace System.Web { StringBuilder sb = new StringBuilder (); string [] keys = AllKeys; for (int i = 0; i < count; i++) { - sb.AppendFormat ("{0}={1}&", keys [i], this [keys [i]]); + sb.AppendFormat ("{0}={1}&", keys [i], UrlEncode (this [keys [i]])); } if (sb.Length > 0) sb.Length--; diff --git a/mcs/class/System.Web/System.Web/MimeTypes.cs b/mcs/class/System.Web/System.Web/MimeTypes.cs index 8b7bfcadf7..673507d1cf 100644 --- a/mcs/class/System.Web/System.Web/MimeTypes.cs +++ b/mcs/class/System.Web/System.Web/MimeTypes.cs @@ -233,6 +233,7 @@ namespace System.Web mimeTypes.Add ("la", "audio/nspaudio"); mimeTypes.Add ("lam", "audio/x-liveaudio"); mimeTypes.Add ("latex", "application/x-latex"); + mimeTypes.Add ("less", "text/css"); mimeTypes.Add ("list", "text/plain"); mimeTypes.Add ("lma", "audio/nspaudio"); mimeTypes.Add ("log", "text/plain"); @@ -529,7 +530,7 @@ namespace System.Web mimeTypes.Add ("wmls", "text/vnd.wap.wmlscript"); mimeTypes.Add ("wml", "text/vnd.wap.wml"); mimeTypes.Add ("wmp", "video/x-ms-wmp"); - mimeTypes.Add ("woff", "application/x-woff"); + mimeTypes.Add ("woff", "application/font-woff"); mimeTypes.Add ("word", "application/msword"); mimeTypes.Add ("wp5", "application/wordperfect"); mimeTypes.Add ("wp6", "application/wordperfect"); diff --git a/mcs/class/System.Web/System.Web/ReadEntityBodyMode.cs b/mcs/class/System.Web/System.Web/ReadEntityBodyMode.cs new file mode 100644 index 0000000000..a97c3cf5f1 --- /dev/null +++ b/mcs/class/System.Web/System.Web/ReadEntityBodyMode.cs @@ -0,0 +1,34 @@ +// +// ReadEntityBodyMode.cs +// +// Author: Martin Thwaites (github@my2cents.co.uk) +// +// Copyright (C) 2014 Martin Thwaites +// +// 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. + +namespace System.Web { + public enum ReadEntityBodyMode { + None, + Classic, + Bufferless, + Buffered, + } +} diff --git a/mcs/class/System.Web/Test/System.Web.Hosting/HostingEnvironmentTest.cs b/mcs/class/System.Web/Test/System.Web.Hosting/HostingEnvironmentTest.cs index eb3aa2a3e0..2f039d0289 100644 --- a/mcs/class/System.Web/Test/System.Web.Hosting/HostingEnvironmentTest.cs +++ b/mcs/class/System.Web/Test/System.Web.Hosting/HostingEnvironmentTest.cs @@ -35,6 +35,10 @@ using System.Web.UI; using MonoTests.SystemWeb.Framework; namespace MonoTests.System.Web.Hosting { + public class MyRegisteredObject : IRegisteredObject { + public void Stop(bool immediate) {} + } + [TestFixture] public class HostingEnvironmentTest { [Test] @@ -105,6 +109,15 @@ namespace MonoTests.System.Web.Hosting { { Assert.IsNull (HostingEnvironment.MapPath ("hola")); } + + [Test] + public void RegisterAndUnregisterObject () + { + var registered = new MyRegisteredObject (); + + HostingEnvironment.RegisterObject (registered); + HostingEnvironment.UnregisterObject (registered); + } } } #endif diff --git a/mcs/class/System.Web/Test/System.Web/HttpUtilityTest.cs b/mcs/class/System.Web/Test/System.Web/HttpUtilityTest.cs index 4c7228dd6a..5ead217389 100644 --- a/mcs/class/System.Web/Test/System.Web/HttpUtilityTest.cs +++ b/mcs/class/System.Web/Test/System.Web/HttpUtilityTest.cs @@ -861,6 +861,15 @@ namespace MonoTests.System.Web { @" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ", }; + [Test] + public void ToStringEncoding () + { + var queryStringNameValues = HttpUtility.ParseQueryString(string.Empty); + queryStringNameValues.Add("ReturnUrl", @"http://localhost/login/authenticate?ReturnUrl=http://localhost/secured_area&__provider__=google"); + + var expected = "ReturnUrl=http%3a%2f%2flocalhost%2flogin%2fauthenticate%3fReturnUrl%3dhttp%3a%2f%2flocalhost%2fsecured_area%26__provider__%3dgoogle"; + Assert.AreEqual (expected, queryStringNameValues.ToString()); + } } } diff --git a/mcs/class/System.Web/net_4_5_System.Web.dll.sources b/mcs/class/System.Web/net_4_5_System.Web.dll.sources index a7957a0019..04c7cacd65 100644 --- a/mcs/class/System.Web/net_4_5_System.Web.dll.sources +++ b/mcs/class/System.Web/net_4_5_System.Web.dll.sources @@ -1,3 +1,5 @@ #include net_4_0_System.Web.dll.sources System.Web/MimeMapping.cs +System.Web/ReadEntityBodyMode.cs + diff --git a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AnnotationPathPointTest.cs b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AnnotationPathPointTest.cs index 1933373d27..a802e4b8c0 100644 --- a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AnnotationPathPointTest.cs +++ b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AnnotationPathPointTest.cs @@ -27,7 +27,7 @@ using System; using System.Windows.Forms.DataVisualization.Charting; using NUnit.Framework; -namespace ChartingTests +namespace MonoTests.System.Windows.Forms.DataVisualization.Charting { [TestFixture] public class AnnotationPathPointTest diff --git a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AnovaResultTest.cs b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AnovaResultTest.cs index 8a146d266b..ef1f648777 100644 --- a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AnovaResultTest.cs +++ b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AnovaResultTest.cs @@ -27,7 +27,7 @@ using System; using System.Windows.Forms.DataVisualization.Charting; using NUnit.Framework; -namespace ChartingTests +namespace MonoTests.System.Windows.Forms.DataVisualization.Charting { [TestFixture] public class AnovaResultTest diff --git a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/ArrowAnnotationTest.cs b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/ArrowAnnotationTest.cs index ccc5700501..9fced81aad 100644 --- a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/ArrowAnnotationTest.cs +++ b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/ArrowAnnotationTest.cs @@ -27,7 +27,7 @@ using System; using System.Windows.Forms.DataVisualization.Charting; using NUnit.Framework; -namespace ChartingTests +namespace MonoTests.System.Windows.Forms.DataVisualization.Charting { [TestFixture] public class ArrowAnnotationTest diff --git a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AxisScaleBreakStyleTest.cs b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AxisScaleBreakStyleTest.cs index e820427d52..3871898efd 100644 --- a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AxisScaleBreakStyleTest.cs +++ b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/AxisScaleBreakStyleTest.cs @@ -28,7 +28,7 @@ using System.Windows.Forms.DataVisualization.Charting; using NUnit.Framework; using System.Drawing; -namespace ChartingTests +namespace MonoTests.System.Windows.Forms.DataVisualization.Charting { [TestFixture] public class AxisScaleBreakStyleTest diff --git a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/ChartElementTest.cs b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/ChartElementTest.cs index c7053c6a7e..3afeffe423 100644 --- a/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/ChartElementTest.cs +++ b/mcs/class/System.Windows.Forms.DataVisualization/Test/System.Windows.Forms.DataVisualization.Charting/ChartElementTest.cs @@ -27,7 +27,7 @@ using System; using System.Windows.Forms.DataVisualization.Charting; using NUnit.Framework; -namespace ChartingTests +namespace MonoTests.System.Windows.Forms.DataVisualization.Charting { [TestFixture] public class ChartElementTest diff --git a/mcs/class/System.XML/Makefile b/mcs/class/System.XML/Makefile index c52a56468f..f44d93a6f0 100644 --- a/mcs/class/System.XML/Makefile +++ b/mcs/class/System.XML/Makefile @@ -13,7 +13,7 @@ ifdef USE_BOOT_COMPILE LIBRARY_COMPILE = $(BOOT_COMPILE) endif -PROFILE_ANY_MOBILE := $(filter monotouch monotouch_runtime monodroid xammac, $(PROFILE)) +PROFILE_ANY_MOBILE := $(filter monotouch monotouch_runtime monodroid xammac mobile mobile_static, $(PROFILE)) LIB_MCS_FLAGS = -r:$(corlib) -r:System.dll -nowarn:0618,0612,0642 ifeq (2.1, $(FRAMEWORK_VERSION)) @@ -127,4 +127,4 @@ ifneq ($(PROFILE),basic) csproj-local: $(MAKE) csproj-local intermediate=bare/ endif -endif \ No newline at end of file +endif diff --git a/mcs/class/System.XML/System.Xml.Serialization/SerializationCodeGenerator.cs.REMOVED.git-id b/mcs/class/System.XML/System.Xml.Serialization/SerializationCodeGenerator.cs.REMOVED.git-id index 1da27e7249..eea2078cbc 100644 --- a/mcs/class/System.XML/System.Xml.Serialization/SerializationCodeGenerator.cs.REMOVED.git-id +++ b/mcs/class/System.XML/System.Xml.Serialization/SerializationCodeGenerator.cs.REMOVED.git-id @@ -1 +1 @@ -0ac2cd5e0ba7d882e76c0a148eb6203b65602140 \ No newline at end of file +27848d10ea073aee33c40a78188d74462717de4f \ No newline at end of file diff --git a/mcs/class/System.XML/System.Xml.Serialization/TypeData.cs b/mcs/class/System.XML/System.Xml.Serialization/TypeData.cs index 861fcc11de..79c89c2567 100644 --- a/mcs/class/System.XML/System.Xml.Serialization/TypeData.cs +++ b/mcs/class/System.XML/System.Xml.Serialization/TypeData.cs @@ -255,7 +255,7 @@ namespace System.Xml.Serialization sb.Append (type.Name); } else { - if (full && type.Namespace.Length > 0) + if (full && !string.IsNullOrEmpty(type.Namespace)) sb.Append (type.Namespace).Append ('.'); sb.Append (type.Name); } diff --git a/mcs/class/System.XML/System.Xml.Serialization/XmlReflectionImporter.cs b/mcs/class/System.XML/System.Xml.Serialization/XmlReflectionImporter.cs index 14afa1d061..554d673251 100644 --- a/mcs/class/System.XML/System.Xml.Serialization/XmlReflectionImporter.cs +++ b/mcs/class/System.XML/System.Xml.Serialization/XmlReflectionImporter.cs @@ -516,7 +516,7 @@ namespace System.Xml.Serialization { elem.Form = att.Form; if (att.Form == XmlSchemaForm.Unqualified) elem.Namespace = string.Empty; - elem.IsNullable = att.IsNullable && CanBeNull (elem.TypeData); + elem.IsNullable = (!att.IsNullableSpecified || att.IsNullable) && CanBeNull (elem.TypeData); elem.NestingLevel = att.NestingLevel; if (isMultiArray) { diff --git a/mcs/class/System.XML/System.Xml.Serialization/XmlSerializationReaderInterpreter.cs b/mcs/class/System.XML/System.Xml.Serialization/XmlSerializationReaderInterpreter.cs index a90ae2bfb3..5d9e4b24f3 100644 --- a/mcs/class/System.XML/System.Xml.Serialization/XmlSerializationReaderInterpreter.cs +++ b/mcs/class/System.XML/System.Xml.Serialization/XmlSerializationReaderInterpreter.cs @@ -505,7 +505,7 @@ namespace System.Xml.Serialization XmlTypeMapMemberElement mem = (XmlTypeMapMemberElement) map.XmlTextCollector; XmlTypeMapElementInfo info = (XmlTypeMapElementInfo) mem.ElementInfo [0]; if (info.TypeData.Type == typeof (string)) - SetMemberValue (mem, ob, ReadString ((string) GetMemberValue (mem, ob, isValueList)), isValueList); + SetMemberValue (mem, ob, Reader.ReadString (), isValueList); else SetMemberValue (mem, ob, GetValueFromXmlString (Reader.ReadString(), info.TypeData, info.MappedType), isValueList); } @@ -585,6 +585,10 @@ namespace System.Xml.Serialization void SetMemberValue (XmlTypeMapMember member, object ob, object value, bool isValueList) { + var memberType = member.TypeData.Type; + if (value != null && !value.GetType().IsAssignableFrom (memberType)) + value = XmlSerializationWriterInterpreter.ImplicitConvert (value, memberType); + if (isValueList) ((object[])ob)[member.GlobalIndex] = value; else diff --git a/mcs/class/System.XML/System.Xml.Serialization/XmlSerializationWriterInterpreter.cs b/mcs/class/System.XML/System.Xml.Serialization/XmlSerializationWriterInterpreter.cs index 846848a39a..cf7985349e 100644 --- a/mcs/class/System.XML/System.Xml.Serialization/XmlSerializationWriterInterpreter.cs +++ b/mcs/class/System.XML/System.Xml.Serialization/XmlSerializationWriterInterpreter.cs @@ -120,6 +120,10 @@ namespace System.Xml.Serialization return; } + var obExpectedType = typeMap.TypeData.Type; + if (!ob.GetType().IsAssignableFrom (obExpectedType)) + ob = ImplicitConvert (ob, obExpectedType); + XmlTypeMapping map = typeMap.GetRealTypeMap (ob.GetType()); if (map == null) @@ -355,20 +359,19 @@ namespace System.Xml.Serialization } } - object ImplicitConvert (object obj, Type type) + internal static object ImplicitConvert (object obj, Type type) { if (obj == null) return null; - for (Type t = type; t != typeof (object); t = t.BaseType) { - MethodInfo mi = t.GetMethod ("op_Implicit", new Type [] {t}); - if (mi != null && mi.ReturnType.IsAssignableFrom (obj.GetType ())) - return mi.Invoke (null, new object [] {obj}); - } for (Type t = obj.GetType (); t != typeof (object); t = t.BaseType) { MethodInfo mi = t.GetMethod ("op_Implicit", new Type [] {t}); if (mi != null && mi.ReturnType == type) return mi.Invoke (null, new object [] {obj}); + + mi = type.GetMethod ("op_Implicit", new Type [] {t}); + if (mi != null && mi.ReturnType == type) + return mi.Invoke (null, new object [] {obj}); } return obj; } diff --git a/mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapMember.cs b/mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapMember.cs index e023321ba4..df6d3361a4 100644 --- a/mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapMember.cs +++ b/mcs/class/System.XML/System.Xml.Serialization/XmlTypeMapMember.cs @@ -46,6 +46,7 @@ namespace System.Xml.Serialization TypeData _typeData; MemberInfo _member; MemberInfo _specifiedMember; + MethodInfo _shouldSerialize; object _defaultValue = System.DBNull.Value; string documentation; int _flags; @@ -118,8 +119,12 @@ namespace System.Xml.Serialization mems = type.GetMember (_name + "Specified", BindingFlags.Instance|BindingFlags.Public); if (mems.Length > 0) _specifiedMember = mems[0]; - if (_specifiedMember is PropertyInfo && !((PropertyInfo) _specifiedMember).CanWrite) + if (_specifiedMember is PropertyInfo && !((PropertyInfo) _specifiedMember).CanRead) _specifiedMember = null; + + var method = type.GetMethod ("ShouldSerialize" + _name, BindingFlags.Instance | BindingFlags.Public, null, Type.EmptyTypes, null); + if (method != null && method.ReturnType == typeof (bool) && !method.IsGenericMethod) + _shouldSerialize = method; } public TypeData TypeData @@ -167,7 +172,7 @@ namespace System.Xml.Serialization { // Used when reflecting a type if (_member == null) InitMember (type); - IsOptionalValueType = (_specifiedMember != null); + IsOptionalValueType = (_specifiedMember != null || _shouldSerialize != null); } public void CheckOptionalValueType (XmlReflectionMember[] members) @@ -182,26 +187,54 @@ namespace System.Xml.Serialization } } } - + + public bool HasSpecified { + get { return _specifiedMember != null; } + } + + public bool HasShouldSerialize { + get { return _shouldSerialize != null; } + } + public bool GetValueSpecified (object ob) { if (_specifiedGlobalIndex != -1) { object[] array = (object[])ob; return _specifiedGlobalIndex < array.Length && (bool) array [_specifiedGlobalIndex]; } - else if (_specifiedMember is PropertyInfo) - return (bool) ((PropertyInfo)_specifiedMember).GetValue (ob, null); - else - return (bool) ((FieldInfo)_specifiedMember).GetValue (ob); + bool specified = true; + + if (_specifiedMember != null) { + if (_specifiedMember is PropertyInfo) + specified = (bool)((PropertyInfo)_specifiedMember).GetValue (ob, null); + else + specified = (bool)((FieldInfo)_specifiedMember).GetValue (ob); + } + if (_shouldSerialize != null) + specified = specified && (bool)_shouldSerialize.Invoke (ob, new object [] {}); + + return specified; + } + + public bool IsValueSpecifiedSettable () { + if (_specifiedMember is PropertyInfo) + return ((PropertyInfo) _specifiedMember).CanWrite; + + if (_specifiedMember is FieldInfo) + return ((FieldInfo) _specifiedMember).IsInitOnly; + + return false; } public void SetValueSpecified (object ob, bool value) { if (_specifiedGlobalIndex != -1) ((object[])ob) [_specifiedGlobalIndex] = value; - else if (_specifiedMember is PropertyInfo) + else if (_specifiedMember is PropertyInfo) { + if (!((PropertyInfo) _specifiedMember).CanWrite) + return; ((PropertyInfo)_specifiedMember).SetValue (ob, value, null); - else + } else if (_specifiedMember is FieldInfo) ((FieldInfo)_specifiedMember).SetValue (ob, value); } diff --git a/mcs/class/System.XML/System.Xml/XmlTextReader.cs b/mcs/class/System.XML/System.Xml/XmlTextReader.cs index 63745fe303..eee0580d44 100644 --- a/mcs/class/System.XML/System.Xml/XmlTextReader.cs +++ b/mcs/class/System.XML/System.Xml/XmlTextReader.cs @@ -164,11 +164,6 @@ namespace Mono.Xml2 InitializeContext (url, context, fragment, fragType); } - Uri ResolveUri (string url) - { - return resolver == null ? null : resolver.ResolveUri (null, url); - } - Stream GetStreamFromUrl (string url, out string absoluteUriString) { #if NET_2_1 @@ -177,9 +172,13 @@ namespace Mono.Xml2 if (url.Length == 0) throw new ArgumentException ("url"); #endif - Uri uri = ResolveUri (url); + // + // This needs to work even if resolver is explicitly set to null + // + var res = resolver ?? new XmlUrlResolver (); + var uri = res.ResolveUri (null, url); absoluteUriString = uri != null ? uri.ToString () : String.Empty; - return resolver == null ? null : resolver.GetEntity (uri, null, typeof (Stream)) as Stream; + return res.GetEntity (uri, null, typeof (Stream)) as Stream; } #endregion @@ -717,7 +716,6 @@ namespace Mono.Xml2 if (valueCache != null) return valueCache; if (ValueBufferStart >= 0) { -//Console.WriteLine (NodeType + " / " + ValueBuffer.Length + " / " + ValueBufferStart + " / " + ValueBufferEnd); valueCache = Reader.valueBuffer.ToString (ValueBufferStart, ValueBufferEnd - ValueBufferStart); return valueCache; } @@ -1801,6 +1799,7 @@ namespace Mono.Xml2 value, false); ati.Value = value; + ati.ValueTokenStartIndex = ati.ValueTokenEndIndex = currentAttributeValue; attributeCount++; } diff --git a/mcs/class/System.XML/System.Xml/XmlTextReader2.cs b/mcs/class/System.XML/System.Xml/XmlTextReader2.cs index 2110bb62f1..52a7a9e687 100644 --- a/mcs/class/System.XML/System.Xml/XmlTextReader2.cs +++ b/mcs/class/System.XML/System.Xml/XmlTextReader2.cs @@ -254,6 +254,11 @@ namespace System.Xml get { return entity != null ? ReadState.Interactive : source.ReadState; } } +#if NET_4_0 + [MonoTODO] + public DtdProcessing DtdProcessing { get; set; } +#endif + #if !NET_4_5 public override XmlReaderSettings Settings { get { return base.Settings; } diff --git a/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTestClasses.cs b/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTestClasses.cs index 62b3698c83..872e6cbdf7 100644 --- a/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTestClasses.cs +++ b/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTestClasses.cs @@ -1117,5 +1117,83 @@ namespace MonoTests.System.Xml.TestClasses [XmlElement ("Extra", Order=1)] public string[] Extra; } + + public class SimpleObjectA + { + [XmlAttribute] + public string Text + { + get; set; + } + + public static implicit operator SimpleObjectA (SimpleObjectB o) + { + return new SimpleObjectA { Text = o.Text }; + } + + public static implicit operator SimpleObjectB (SimpleObjectA o) + { + return new SimpleObjectB { Text = o.Text }; + } + } + + public class SimpleObjectB + { + [XmlAttribute] + public string Text + { + get; set; + } + } + + public class ObjectWithElementRequiringImplicitCast + { + public ObjectWithElementRequiringImplicitCast () { } + public ObjectWithElementRequiringImplicitCast (string text) + { + Object = new SimpleObjectB { Text = text }; + } + + [XmlElement(Type = typeof (SimpleObjectA))] + public SimpleObjectB Object + { + get; set; + } + } + + public class ObjectWithNullableArrayItems + { + [XmlArrayItem ("Element", IsNullable = true)] + public List Elements; + } + + public class ObjectWithNonNullableArrayItems + { + [XmlArrayItem ("Element", IsNullable = false)] + public List Elements; + } + + public class ObjectWithNotSpecifiedNullableArrayItems + { + [XmlArrayItem ("Element")] + public List Elements; + } + + [Serializable] + public sealed class ClassWithDefaultTextNotNull + { + [XmlText] + public string Value; + + public const string DefaultValue = "NotNull"; + + public ClassWithDefaultTextNotNull (string v) { + Value = v; + } + + public ClassWithDefaultTextNotNull () { + Value = DefaultValue; + } + } } diff --git a/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTests.cs.REMOVED.git-id b/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTests.cs.REMOVED.git-id index 65c293ed9b..d7668fd685 100644 --- a/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTests.cs.REMOVED.git-id +++ b/mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializerTests.cs.REMOVED.git-id @@ -1 +1 @@ -6001f7f247689571d9181a9a36a4e1a33efbdf6a \ No newline at end of file +ef6ba78867fa3b99cb16bbe347f37608795cc92a \ No newline at end of file diff --git a/mcs/class/System.XML/Test/System.Xml/XmlResolverTest.cs b/mcs/class/System.XML/Test/System.Xml/XmlResolverTest.cs index fcdc34e7f7..80a46e5c99 100644 --- a/mcs/class/System.XML/Test/System.Xml/XmlResolverTest.cs +++ b/mcs/class/System.XML/Test/System.Xml/XmlResolverTest.cs @@ -33,7 +33,7 @@ using System.Xml; using NUnit.Framework; -namespace MonoTest.System.Xml { +namespace MonoTests.System.Xml { [TestFixture] public class XmlResolverTest { diff --git a/mcs/class/System.XML/Test/System.Xml/XmlSecureResolverCas.cs b/mcs/class/System.XML/Test/System.Xml/XmlSecureResolverCas.cs index 52de90d141..2e5316c1ff 100644 --- a/mcs/class/System.XML/Test/System.Xml/XmlSecureResolverCas.cs +++ b/mcs/class/System.XML/Test/System.Xml/XmlSecureResolverCas.cs @@ -38,7 +38,7 @@ using System.Security.Permissions; using System.Security.Policy; using System.Xml; -using MonoTestsXml; +using MonoTests.System.Xml; namespace MonoCasTests.System.Xml { @@ -85,4 +85,4 @@ namespace MonoCasTests.System.Xml { } } -#endif \ No newline at end of file +#endif diff --git a/mcs/class/System.XML/Test/System.Xml/XmlSecureResolverTests.cs b/mcs/class/System.XML/Test/System.Xml/XmlSecureResolverTests.cs index c97407de98..a2eaa8b106 100644 --- a/mcs/class/System.XML/Test/System.Xml/XmlSecureResolverTests.cs +++ b/mcs/class/System.XML/Test/System.Xml/XmlSecureResolverTests.cs @@ -20,7 +20,7 @@ using System.Security.Permissions; using System.Xml; using NUnit.Framework; -namespace MonoTestsXml +namespace MonoTests.System.Xml { [TestFixture] public class XmlSecureResolverTests diff --git a/mcs/class/System.XML/Test/System.Xml/XmlTextReaderTests.cs b/mcs/class/System.XML/Test/System.Xml/XmlTextReaderTests.cs index 7ecd83780a..d089892325 100644 --- a/mcs/class/System.XML/Test/System.Xml/XmlTextReaderTests.cs +++ b/mcs/class/System.XML/Test/System.Xml/XmlTextReaderTests.cs @@ -1382,5 +1382,56 @@ namespace MonoTests.System.Xml var xtr = new XmlTextReader (ms); xtr.Read (); } + + [Test] + public void XmlDeclarationReadAttributeValue () + { + const string input = ""; + var reader = new XmlTextReader (new StringReader (input)); + reader.WhitespaceHandling = WhitespaceHandling.All; + reader.Read (); + + Assert.AreEqual ("1.0", reader.GetAttribute ("version"), "#0"); + Assert.AreEqual ("utf-8", reader.GetAttribute ("encoding"), "#0-2"); + + Assert.IsTrue (reader.MoveToNextAttribute (), "#1"); + Assert.AreEqual ("1.0", reader.Value, "#1-1"); + Assert.IsTrue (reader.ReadAttributeValue (), "#2"); + Assert.AreEqual ("1.0", reader.Value, "#3"); + Assert.IsFalse (reader.ReadAttributeValue (), "#4"); + + Assert.IsTrue (reader.MoveToNextAttribute (), "#5"); + Assert.AreEqual ("utf-8", reader.Value, "#5-1"); + Assert.IsTrue (reader.ReadAttributeValue (), "#6"); + Assert.AreEqual ("utf-8", reader.Value, "#7"); + Assert.IsFalse (reader.ReadAttributeValue (), "#8"); + + Assert.IsFalse (reader.MoveToNextAttribute (), "#9"); + Assert.IsFalse (reader.ReadAttributeValue (), "#10"); + } + + [Test] + public void XmlDeclarationReadAttributeValue2 () + { + const string input = ""; + var reader = new XmlTextReader (new StringReader (input)); + reader.WhitespaceHandling = WhitespaceHandling.All; + reader.Read (); + Assert.IsTrue (reader.MoveToNextAttribute (), "#1a"); + Assert.IsTrue (reader.ReadAttributeValue (), "#1b"); + Assert.AreEqual (XmlNodeType.Text, reader.NodeType, "#1c"); + Assert.AreEqual ("1.0", reader.Value, "#1d"); + Assert.IsFalse (reader.ReadAttributeValue(), "#1e"); + + Assert.IsTrue (reader.MoveToNextAttribute(), "#2a"); + Assert.IsTrue (reader.ReadAttributeValue(), "#2b"); + Assert.AreEqual (XmlNodeType.Text, reader.NodeType, "#2c"); + Assert.AreEqual ("utf-8", reader.Value, "#2d"); + Assert.IsFalse (reader.ReadAttributeValue(), "#2e"); + + Assert.IsFalse (reader.MoveToNextAttribute(), "#3"); + Assert.IsFalse (reader.ReadAttributeValue(), "#4"); + Assert.AreEqual (XmlNodeType.Text, reader.NodeType, "#5"); + } } } diff --git a/mcs/class/System.Xaml/Makefile b/mcs/class/System.Xaml/Makefile index 17d1613291..5104e87b04 100644 --- a/mcs/class/System.Xaml/Makefile +++ b/mcs/class/System.Xaml/Makefile @@ -18,7 +18,7 @@ TEST_EXTRA_DISTFILES = \ Test/XmlFiles/*.xml \ Test/XmlFiles/*.xaml -VALID_PROFILE := $(filter 4 monodroid monotouch, $(FRAMEWORK_VERSION_MAJOR)) +VALID_PROFILE := $(filter 4 monodroid monotouch mobile mobile_static, $(FRAMEWORK_VERSION_MAJOR)) ifndef VALID_PROFILE LIBRARY_NAME = dummy-System.Xaml.dll NO_INSTALL = yes diff --git a/mcs/class/System.Xml.Linq/System.Xml.Linq/XComment.cs b/mcs/class/System.Xml.Linq/System.Xml.Linq/XComment.cs index edab3fb477..f7b5e7b6c6 100644 --- a/mcs/class/System.Xml.Linq/System.Xml.Linq/XComment.cs +++ b/mcs/class/System.Xml.Linq/System.Xml.Linq/XComment.cs @@ -25,6 +25,7 @@ // using System; +using System.Linq; using System.Xml; namespace System.Xml.Linq @@ -54,7 +55,9 @@ namespace System.Xml.Linq public override void WriteTo (XmlWriter writer) { - writer.WriteComment (value); + var v = value.Replace ("--", "- -"); + v = v.LastOrDefault () == '-' ? v.Substring (0, v.Length - 1) +"D;" : v; + writer.WriteComment (v); } } } diff --git a/mcs/class/System.Xml.Linq/System.Xml.Linq_test.dll.sources b/mcs/class/System.Xml.Linq/System.Xml.Linq_test.dll.sources index 77007ae238..693d4a2e29 100644 --- a/mcs/class/System.Xml.Linq/System.Xml.Linq_test.dll.sources +++ b/mcs/class/System.Xml.Linq/System.Xml.Linq_test.dll.sources @@ -1,5 +1,6 @@ System.Xml.Linq/ExtensionsTest.cs System.Xml.Linq/XAttributeTest.cs +System.Xml.Linq/XCommentTest.cs System.Xml.Linq/XDocumentTest.cs System.Xml.Linq/XElementTest.cs System.Xml.Linq/XNameTest.cs diff --git a/mcs/class/System.Xml.Linq/Test/System.Xml.Linq/XCommentTest.cs b/mcs/class/System.Xml.Linq/Test/System.Xml.Linq/XCommentTest.cs new file mode 100644 index 0000000000..b324bb68fc --- /dev/null +++ b/mcs/class/System.Xml.Linq/Test/System.Xml.Linq/XCommentTest.cs @@ -0,0 +1,66 @@ +// +// Authors: +// Atsushi Enomoto +// +// Copyright 2014 Xamarin Inc. (http://www.xamarin.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. +// + +using System; +using System.IO; +using System.Xml; +using System.Xml.Linq; +using System.Linq; + +using NUnit.Framework; + +namespace MonoTests.System.Xml.Linq +{ + [TestFixture] + public class XCommentTest + { + [Test] + public void EscapeSequentialDashes () + { + XComment c; + + c = new XComment ("<--foo-->"); + Assert.AreEqual ("<--foo-->", c.Value, "#1"); + // bug #23318 + // Unlike XmlWriter.WriteComment(), XComment.ToString() seems to accept "--" in the value. + Assert.AreEqual ("", c.ToString (), "#2"); + // make sure if it can be read... + XmlReader.Create (new StringReader (c.ToString ())).Read (); + + // The last '-' causes some glitch... + c = new XComment ("--foo--"); + Assert.AreEqual ("--foo--", c.Value, "#3"); + Assert.AreEqual ("", c.ToString (), "#4"); + XmlReader.Create (new StringReader (c.ToString ())).Read (); + + // What if "); + Assert.AreEqual ("", c.Value, "#5"); + Assert.AreEqual ("", c.ToString (), "#6"); + XmlReader.Create (new StringReader (c.ToString ())).Read (); + } + } +} diff --git a/mcs/class/System/Makefile b/mcs/class/System/Makefile index 50bc1fce7d..729aeaa9f3 100644 --- a/mcs/class/System/Makefile +++ b/mcs/class/System/Makefile @@ -24,14 +24,10 @@ TEST_MCS_FLAGS = -r:System.Drawing.dll -r:Mono.Security.dll -r:System.Data -r:Sy LIB_MCS_FLAGS = -nowarn:618 -d:CONFIGURATION_2_0 -unsafe $(RESOURCE_FILES:%=-resource:%) TEST_MCS_FLAGS += -r:System.Configuration -PROFILE_ANY_MOBILE := $(filter monotouch monotouch_runtime monodroid xammac, $(PROFILE)) -NOT_SL := $(filter net_2_0 net_4_0 net_4_5 monotouch_runtime mobile xammac, $(PROFILE)) +PROFILE_ANY_MOBILE := $(filter monotouch monotouch_runtime monodroid xammac mobile mobile_static, $(PROFILE)) ifeq (2.1, $(FRAMEWORK_VERSION)) LIB_MCS_FLAGS += -d:INSIDE_SYSTEM -ifeq (moonlight_raw, $(PROFILE)) -LIB_MCS_FLAGS += -d:SECURITY_DEP -endif endif ifeq (monotouch, $(subst _runtime,,$(PROFILE))) LIB_MCS_FLAGS += -d:SECURITY_DEP @@ -154,4 +150,4 @@ csproj-local: $(MAKE) csproj-local intermediate=bare/ $(MAKE) csproj-local intermediate=secxml/ endif -endif \ No newline at end of file +endif diff --git a/mcs/class/System/System.Collections.Concurrent/BlockingCollection.cs b/mcs/class/System/System.Collections.Concurrent/BlockingCollection.cs index 893cd8e3a4..395bc68e96 100644 --- a/mcs/class/System/System.Collections.Concurrent/BlockingCollection.cs +++ b/mcs/class/System/System.Collections.Concurrent/BlockingCollection.cs @@ -124,8 +124,12 @@ namespace System.Collections.Concurrent int cachedRemoveId = removeId; int itemsIn = cachedAddId - cachedRemoveId; + // Check our transaction id against completed stored one + if (isComplete.Value && cachedAddId >= completeId) + ThrowCompleteException (); + // If needed, we check and wait that the collection isn't full - if (upperBound != -1 && itemsIn > upperBound) { + if (upperBound != -1 && itemsIn >= upperBound) { if (millisecondsTimeout == 0) return false; @@ -144,10 +148,6 @@ namespace System.Collections.Concurrent continue; } - // Check our transaction id against completed stored one - if (isComplete.Value && cachedAddId >= completeId) - ThrowCompleteException (); - // Validate the steps we have been doing until now if (Interlocked.CompareExchange (ref addId, cachedAddId + 1, cachedAddId) != cachedAddId) continue; @@ -291,30 +291,28 @@ namespace System.Collections.Concurrent public static int AddToAny (BlockingCollection[] collections, T item) { - CheckArray (collections); - int index = 0; - foreach (var coll in collections) { - try { - coll.Add (item); - return index; - } catch {} - index++; - } - return -1; + return AddToAny (collections, item, CancellationToken.None); } public static int AddToAny (BlockingCollection[] collections, T item, CancellationToken cancellationToken) { CheckArray (collections); - int index = 0; - foreach (var coll in collections) { - try { - coll.Add (item, cancellationToken); - return index; - } catch {} - index++; + WaitHandle[] wait_table = null; + while (true) { + for (int i = 0; i < collections.Length; ++i) { + if (collections [i].TryAdd (item)) + return i; + } + cancellationToken.ThrowIfCancellationRequested (); + if (wait_table == null) { + wait_table = new WaitHandle [collections.Length + 1]; + for (int i = 0; i < collections.Length; ++i) + wait_table [i] = collections [i].mreAdd.WaitHandle; + wait_table [collections.Length] = cancellationToken.WaitHandle; + } + WaitHandle.WaitAny (wait_table); + cancellationToken.ThrowIfCancellationRequested (); } - return -1; } public static int TryAddToAny (BlockingCollection[] collections, T item) @@ -368,21 +366,7 @@ namespace System.Collections.Concurrent public static int TakeFromAny (BlockingCollection[] collections, out T item) { - item = default (T); - CheckArray (collections); - WaitHandle[] wait_table = null; - while (true) { - for (int i = 0; i < collections.Length; ++i) { - if (collections [i].TryTake (out item)) - return i; - } - if (wait_table == null) { - wait_table = new WaitHandle [collections.Length]; - for (int i = 0; i < collections.Length; ++i) - wait_table [i] = collections [i].mreRemove.WaitHandle; - } - WaitHandle.WaitAny (wait_table); - } + return TakeFromAny (collections, out item, CancellationToken.None); } public static int TakeFromAny (BlockingCollection[] collections, out T item, CancellationToken cancellationToken) diff --git a/mcs/class/System/System.Diagnostics/DiagnosticsConfigurationHandler.cs b/mcs/class/System/System.Diagnostics/DiagnosticsConfigurationHandler.cs index 149ad3bc5b..c3937530f6 100644 --- a/mcs/class/System/System.Diagnostics/DiagnosticsConfigurationHandler.cs +++ b/mcs/class/System/System.Diagnostics/DiagnosticsConfigurationHandler.cs @@ -94,6 +94,7 @@ namespace System.Diagnostics public DiagnosticsConfigurationHandler () { elementHandlers ["assert"] = new ElementHandler (AddAssertNode); + elementHandlers ["performanceCounters"] = new ElementHandler (AddPerformanceCountersNode); elementHandlers ["switches"] = new ElementHandler (AddSwitchesNode); elementHandlers ["trace"] = new ElementHandler (AddTraceNode); elementHandlers ["sources"] = new ElementHandler (AddSourcesNode); @@ -181,6 +182,25 @@ namespace System.Diagnostics ThrowUnrecognizedElement (node.ChildNodes[0]); } + private void AddPerformanceCountersNode (IDictionary d, XmlNode node) + { + XmlAttributeCollection c = node.Attributes; + string filemappingsize = GetAttribute (c, "filemappingsize", false, node); + ValidateInvalidAttributes (c, node); + if (filemappingsize != null) { + try { + d ["filemappingsize"] = int.Parse (filemappingsize); + } + catch (Exception e) { + throw new ConfigurationException ("The `filemappingsize' attribute must be an integral value.", + e, node); + } + } + + if (node.ChildNodes.Count > 0) + ThrowUnrecognizedElement (node.ChildNodes[0]); + } + // name and value attributes are required // Docs do not define "remove" or "clear" elements, but .NET recognizes // them diff --git a/mcs/class/System/System.Diagnostics/LocalFileEventLog.cs b/mcs/class/System/System.Diagnostics/LocalFileEventLog.cs index e5a34ff1a4..c013223d08 100644 --- a/mcs/class/System/System.Diagnostics/LocalFileEventLog.cs +++ b/mcs/class/System/System.Diagnostics/LocalFileEventLog.cs @@ -29,7 +29,7 @@ // using System; -using System.Collections; +using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; @@ -227,7 +227,7 @@ namespace System.Diagnostics DateFormat, CultureInfo.InvariantCulture); DateTime timeWritten = File.GetLastWriteTime (file); int stringNums = int.Parse (tr.ReadLine ().Substring (20)); - ArrayList replacementTemp = new ArrayList (); + var replacementTemp = new List (); StringBuilder sb = new StringBuilder (); while (replacementTemp.Count < stringNums) { char c = (char) tr.Read (); @@ -238,8 +238,7 @@ namespace System.Diagnostics sb.Append (c); } } - string [] replacementStrings = new string [replacementTemp.Count]; - replacementTemp.CopyTo (replacementStrings, 0); + string [] replacementStrings = replacementTemp.ToArray (); string message = FormatMessage (source, instanceID, replacementStrings); int eventID = EventLog.GetEventID (instanceID); diff --git a/mcs/class/System/System.Diagnostics/Process.cs b/mcs/class/System/System.Diagnostics/Process.cs index 795ebaaa80..0cf197af1d 100644 --- a/mcs/class/System/System.Diagnostics/Process.cs +++ b/mcs/class/System/System.Diagnostics/Process.cs @@ -39,7 +39,7 @@ using System.ComponentModel.Design; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Security.Permissions; -using System.Collections; +using System.Collections.Generic; using System.Security; using System.Threading; @@ -832,13 +832,13 @@ namespace System.Diagnostics { [MethodImplAttribute(MethodImplOptions.InternalCall)] private extern static int[] GetProcesses_internal(); - public static Process[] GetProcesses() + public static Process[] GetProcesses () { int [] pids = GetProcesses_internal (); if (pids == null) return new Process [0]; - ArrayList proclist = new ArrayList (pids.Length); + var proclist = new List (pids.Length); for (int i = 0; i < pids.Length; i++) { try { proclist.Add (GetProcessById (pids [i])); @@ -851,7 +851,7 @@ namespace System.Diagnostics { } } - return ((Process []) proclist.ToArray (typeof (Process))); + return proclist.ToArray (); } [MonoTODO ("There is no support for retrieving process information from a remote machine")] @@ -871,7 +871,7 @@ namespace System.Diagnostics { if (pids == null) return new Process [0]; - ArrayList proclist = new ArrayList (pids.Length); + var proclist = new List (pids.Length); for (int i = 0; i < pids.Length; i++) { try { Process p = GetProcessById (pids [i]); @@ -886,7 +886,7 @@ namespace System.Diagnostics { } } - return ((Process []) proclist.ToArray (typeof (Process))); + return proclist.ToArray (); } [MonoTODO] @@ -940,7 +940,7 @@ namespace System.Diagnostics { ref proc_info); } finally { if (proc_info.Password != IntPtr.Zero) - Marshal.FreeBSTR (proc_info.Password); + Marshal.ZeroFreeBSTR (proc_info.Password); proc_info.Password = IntPtr.Zero; } if (!ret) { @@ -1080,7 +1080,7 @@ namespace System.Diagnostics { ref proc_info); } finally { if (proc_info.Password != IntPtr.Zero) - Marshal.FreeBSTR (proc_info.Password); + Marshal.ZeroFreeBSTR (proc_info.Password); proc_info.Password = IntPtr.Zero; } if (!ret) { diff --git a/mcs/class/System/System.Diagnostics/SourceSwitch.cs b/mcs/class/System/System.Diagnostics/SourceSwitch.cs index d991271478..e9b29ca3b8 100644 --- a/mcs/class/System/System.Diagnostics/SourceSwitch.cs +++ b/mcs/class/System/System.Diagnostics/SourceSwitch.cs @@ -59,15 +59,11 @@ namespace System.Diagnostics { switch (eventType) { case TraceEventType.Critical: - return (Level & SourceLevels.Critical) != 0; case TraceEventType.Error: - return (Level & SourceLevels.Error) != 0; case TraceEventType.Warning: - return (Level & SourceLevels.Warning) != 0; case TraceEventType.Information: - return (Level & SourceLevels.Information) != 0; case TraceEventType.Verbose: - return (Level & SourceLevels.Verbose) != 0; + return (Level & (SourceLevels)eventType) != 0; case TraceEventType.Start: case TraceEventType.Stop: case TraceEventType.Suspend: @@ -78,6 +74,7 @@ namespace System.Diagnostics } } + protected override void OnValueChanged () { SwitchSetting = (int) Enum.Parse (typeof (SourceLevels), diff --git a/mcs/class/System/System.Diagnostics/Switch.cs b/mcs/class/System/System.Diagnostics/Switch.cs index 216cde7fa2..94d1f4d19f 100644 --- a/mcs/class/System/System.Diagnostics/Switch.cs +++ b/mcs/class/System/System.Diagnostics/Switch.cs @@ -64,8 +64,8 @@ namespace System.Diagnostics protected Switch(string displayName, string description) { - this.name = displayName; - this.description = description; + this.name = displayName ?? string.Empty; + this.description = description ?? string.Empty; } protected Switch(string displayName, string description, string defaultSwitchValue) diff --git a/mcs/class/System/System.Diagnostics/Win32EventLog.cs b/mcs/class/System/System.Diagnostics/Win32EventLog.cs index 40fe3a36b1..4002c3b7cd 100644 --- a/mcs/class/System/System.Diagnostics/Win32EventLog.cs +++ b/mcs/class/System/System.Diagnostics/Win32EventLog.cs @@ -28,7 +28,7 @@ // using System; -using System.Collections; +using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; @@ -177,12 +177,11 @@ namespace System.Diagnostics string [] sources = (string []) logKey.GetValue ("Sources"); if (sources != null) { - ArrayList temp = new ArrayList (); + var temp = new List (); for (int i = 0; i < sources.Length; i++) if (sources [i] != source) temp.Add (sources [i]); - string [] newSources = new string [temp.Count]; - temp.CopyTo (newSources, 0); + string [] newSources = temp.ToArray (); logKey.SetValue ("Sources", newSources); } } diff --git a/mcs/class/System/System.IO.Ports/SerialPort.cs b/mcs/class/System/System.IO.Ports/SerialPort.cs index 08a9a655b2..65189c5813 100644 --- a/mcs/class/System/System.IO.Ports/SerialPort.cs +++ b/mcs/class/System/System.IO.Ports/SerialPort.cs @@ -529,7 +529,7 @@ namespace System.IO.Ports // Probe for Linux-styled devices: /dev/ttyS* or /dev/ttyUSB* // foreach (string dev in ttys) { - if (dev.StartsWith("/dev/ttyS") || dev.StartsWith("/dev/ttyUSB")){ + if (dev.StartsWith("/dev/ttyS") || dev.StartsWith("/dev/ttyUSB") || dev.StartsWith("/dev/ttyACM")) { linux_style = true; break; } @@ -537,7 +537,7 @@ namespace System.IO.Ports foreach (string dev in ttys) { if (linux_style){ - if (dev.StartsWith("/dev/ttyS") || dev.StartsWith("/dev/ttyUSB")) + if (dev.StartsWith("/dev/ttyS") || dev.StartsWith("/dev/ttyUSB") || dev.StartsWith("/dev/ttyACM")) serial_ports.Add (dev); } else { if (dev != "/dev/tty" && dev.StartsWith ("/dev/tty") && !dev.StartsWith ("/dev/ttyC")) diff --git a/mcs/class/System/System.IO.Ports/SerialPortStream.cs b/mcs/class/System/System.IO.Ports/SerialPortStream.cs index dd4ac22f98..b9bac73066 100644 --- a/mcs/class/System/System.IO.Ports/SerialPortStream.cs +++ b/mcs/class/System/System.IO.Ports/SerialPortStream.cs @@ -211,7 +211,10 @@ namespace System.IO.Ports ~SerialPortStream () { - Dispose (false); + try { + Dispose (false); + } catch (IOException) { + } } void CheckDisposed () diff --git a/mcs/class/System/System.IO/DefaultWatcher.cs b/mcs/class/System/System.IO/DefaultWatcher.cs index 8988a6b970..d2d8b28d86 100644 --- a/mcs/class/System/System.IO/DefaultWatcher.cs +++ b/mcs/class/System/System.IO/DefaultWatcher.cs @@ -30,6 +30,7 @@ using System; using System.Collections; +using System.Collections.Generic; using System.IO; using System.Threading; @@ -240,12 +241,12 @@ namespace System.IO { return; /* Removed files */ - ArrayList removed = null; + List removed = null; foreach (string filename in data.Files.Keys) { FileData fd = (FileData) data.Files [filename]; if (fd.NotExists) { if (removed == null) - removed = new ArrayList (); + removed = new List (); removed.Add (filename); DispatchEvents (data.FSW, FileAction.Removed, filename); @@ -269,7 +270,7 @@ namespace System.IO { } catch { /* Deleted */ if (removed == null) - removed = new ArrayList (); + removed = new List (); removed.Add (filename); DispatchEvents (data.FSW, FileAction.Removed, filename); diff --git a/mcs/class/System/System.IO/FileSystemWatcher.cs b/mcs/class/System/System.IO/FileSystemWatcher.cs index 125f07805f..0d293e5318 100644 --- a/mcs/class/System/System.IO/FileSystemWatcher.cs +++ b/mcs/class/System/System.IO/FileSystemWatcher.cs @@ -183,7 +183,10 @@ namespace System.IO { internal SearchPattern2 Pattern { get { if (pattern == null) { - pattern = new SearchPattern2 (MangledFilter); + if (watcher.GetType () == typeof (KeventWatcher)) + pattern = new SearchPattern2 (MangledFilter, true); //assume we want to ignore case (OS X) + else + pattern = new SearchPattern2 (MangledFilter); } return pattern; } @@ -372,52 +375,60 @@ namespace System.IO { ErrorEvent, RenameEvent } - private void RaiseEvent (Delegate ev, EventArgs arg, EventType evtype) - { - if (ev == null) - return; - - if (synchronizingObject == null) { - switch (evtype) { - case EventType.RenameEvent: - ((RenamedEventHandler)ev).BeginInvoke (this, (RenamedEventArgs) arg, null, null); - break; - case EventType.ErrorEvent: - ((ErrorEventHandler)ev).BeginInvoke (this, (ErrorEventArgs) arg, null, null); - break; - case EventType.FileSystemEvent: - ((FileSystemEventHandler)ev).BeginInvoke (this, (FileSystemEventArgs) arg, null, null); - break; - } - return; - } - synchronizingObject.BeginInvoke (ev, new object [] {this, arg}); - } - protected void OnChanged (FileSystemEventArgs e) { - RaiseEvent (Changed, e, EventType.FileSystemEvent); + if (Changed == null) + return; + + if (synchronizingObject == null) + Changed (this, e); + else + synchronizingObject.BeginInvoke (Changed, new object[] { this, e }); } protected void OnCreated (FileSystemEventArgs e) { - RaiseEvent (Created, e, EventType.FileSystemEvent); + if (Created == null) + return; + + if (synchronizingObject == null) + Created (this, e); + else + synchronizingObject.BeginInvoke (Created, new object[] { this, e }); } protected void OnDeleted (FileSystemEventArgs e) { - RaiseEvent (Deleted, e, EventType.FileSystemEvent); + if (Deleted == null) + return; + + if (synchronizingObject == null) + Deleted (this, e); + else + synchronizingObject.BeginInvoke (Deleted, new object[] { this, e }); } - protected void OnError (ErrorEventArgs e) + internal void OnError (ErrorEventArgs e) { - RaiseEvent (Error, e, EventType.ErrorEvent); + if (Error == null) + return; + + if (synchronizingObject == null) + Error (this, e); + else + synchronizingObject.BeginInvoke (Error, new object[] { this, e }); } protected void OnRenamed (RenamedEventArgs e) { - RaiseEvent (Renamed, e, EventType.RenameEvent); + if (Renamed == null) + return; + + if (synchronizingObject == null) + Renamed (this, e); + else + synchronizingObject.BeginInvoke (Renamed, new object[] { this, e }); } public WaitForChangedResult WaitForChanged (WatcherChangeTypes changeType) diff --git a/mcs/class/System/System.IO/KeventWatcher.cs b/mcs/class/System/System.IO/KeventWatcher.cs index e673f99739..f3cc7dcc18 100644 --- a/mcs/class/System/System.IO/KeventWatcher.cs +++ b/mcs/class/System/System.IO/KeventWatcher.cs @@ -3,6 +3,8 @@ // // Authors: // Geoff Norton (gnorton@customerdna.com) +// Cody Russell (cody@xamarin.com) +// Alexis Christoforides (lexas@xamarin.com) // // (c) 2004 Geoff Norton // Copyright 2014 Xamarin Inc @@ -29,11 +31,13 @@ using System; using System.Collections; +using System.Collections.Generic; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Threading; +using System.Reflection; namespace System.IO { @@ -71,6 +75,7 @@ namespace System.IO { VM = -11 } + [Flags] enum FilterFlags : uint { ReadPoll = EventFlags.Flag0, ReadOutOfBand = EventFlags.Flag1, @@ -123,13 +128,14 @@ namespace System.IO { TimerNanoSeconds = 0x00000004, TimerAbsolute = 0x00000008, } - + + [StructLayout(LayoutKind.Sequential)] struct kevent : IDisposable { - public int ident; + public UIntPtr ident; public EventFilter filter; public EventFlags flags; public FilterFlags fflags; - public int data; + public IntPtr data; public IntPtr udata; public void Dispose () @@ -137,49 +143,471 @@ namespace System.IO { if (udata != IntPtr.Zero) Marshal.FreeHGlobal (udata); } + + } + [StructLayout(LayoutKind.Sequential)] struct timespec { - public int tv_sec; - public int tv_usec; + public IntPtr tv_sec; + public IntPtr tv_usec; } - class KeventFileData { - public FileSystemInfo fsi; - public DateTime LastAccessTime; - public DateTime LastWriteTime; + class PathData + { + public string Path; + public bool IsDirectory; + public int Fd; + } - public KeventFileData(FileSystemInfo fsi, DateTime LastAccessTime, DateTime LastWriteTime) { - this.fsi = fsi; - this.LastAccessTime = LastAccessTime; - this.LastWriteTime = LastWriteTime; + class KqueueMonitor : IDisposable + { + public int Connection + { + get { return conn; } } - } - class KeventData { - public FileSystemWatcher FSW; - public string Directory; - public string FileMask; - public bool IncludeSubdirs; - public bool Enabled; - public Hashtable DirEntries; - public kevent ev; - } + public KqueueMonitor (FileSystemWatcher fsw) + { + this.fsw = fsw; + this.conn = -1; + } + + public void Dispose () + { + CleanUp (); + } + + public void Start () + { + lock (stateLock) { + if (started) + return; + + conn = kqueue (); + + if (conn == -1) + throw new IOException (String.Format ( + "kqueue() error at init, error code = '{0}'", Marshal.GetLastWin32Error ())); + + thread = new Thread (() => DoMonitor ()); + thread.IsBackground = true; + thread.Start (); + + startedEvent.WaitOne (); + + if (failedInit) { + thread.Join (); + CleanUp (); + throw new IOException ("Monitor thread failed while initializing."); + } + else + started = true; + } + } + + public void Stop () + { + lock (stateLock) { + if (!started) + return; + + requestStop = true; + thread.Join (); + requestStop = false; + + CleanUp (); + started = false; + } + } + + void CleanUp () + { + if (conn != -1) + close (conn); + + conn = -1; + + foreach (int fd in fdsDict.Keys) + close (fd); + + fdsDict.Clear (); + pathsDict.Clear (); + } + + void DoMonitor () + { + Exception exc = null; + failedInit = false; + + try { + Setup (); + } catch (Exception e) { + failedInit = true; + exc = e; + } finally { + startedEvent.Set (); + } + + if (failedInit) { + fsw.OnError (new ErrorEventArgs (exc)); + return; + } + + try { + Monitor (); + } catch (Exception e) { + exc = e; + } finally { + if (!requestStop) { // failure + CleanUp (); + started = false; + } + if (exc != null) + fsw.OnError (new ErrorEventArgs (exc)); + } + } + + void Setup () + { + var initialFds = new List (); + + // GetFilenameFromFd() returns the *realpath* which can be different than fsw.FullPath because symlinks. + // If so, introduce a fixup step. + int fd = open (fsw.FullPath, O_EVTONLY, 0); + var resolvedFullPath = GetFilenameFromFd (fd); + close (fd); + + if (resolvedFullPath != fsw.FullPath) + fixupPath = resolvedFullPath; + else + fixupPath = null; + + Scan (fsw.FullPath, false, ref initialFds); + + var immediate_timeout = new timespec { tv_sec = (IntPtr)0, tv_usec = (IntPtr)0 }; + var eventBuffer = new kevent[0]; // we don't want to take any events from the queue at this point + var changes = CreateChangeList (ref initialFds); + + int numEvents = kevent (conn, changes, changes.Length, eventBuffer, eventBuffer.Length, ref immediate_timeout); + + if (numEvents == -1) { + var errMsg = String.Format ("kevent() error at initial event registration, error code = '{0}'", Marshal.GetLastWin32Error ()); + throw new IOException (errMsg); + } + } + + kevent[] CreateChangeList (ref List FdList) + { + if (FdList.Count == 0) + return emptyEventList; + + var changes = new List (); + foreach (int fd in FdList) { + var change = new kevent { + + ident = (UIntPtr)fd, + filter = EventFilter.Vnode, + flags = EventFlags.Add | EventFlags.Enable | EventFlags.Clear, + fflags = FilterFlags.VNodeDelete | FilterFlags.VNodeExtend | + FilterFlags.VNodeRename | FilterFlags.VNodeAttrib | + FilterFlags.VNodeLink | FilterFlags.VNodeRevoke | + FilterFlags.VNodeWrite, + data = IntPtr.Zero, + udata = IntPtr.Zero + }; + + changes.Add (change); + } + FdList.Clear (); + + return changes.ToArray (); + } + + void Monitor () + { + var timeout = new timespec { tv_sec = (IntPtr)0, tv_usec = (IntPtr)500000000 }; + var eventBuffer = new kevent[32]; + var newFds = new List (); + List removeQueue = new List (); + List rescanQueue = new List (); + + while (!requestStop) { + var changes = CreateChangeList (ref newFds); + + int numEvents = kevent (conn, changes, changes.Length, eventBuffer, eventBuffer.Length, ref timeout); + + if (numEvents == -1) { + var errMsg = String.Format ("kevent() error, error code = '{0}'", Marshal.GetLastWin32Error ()); + fsw.OnError (new ErrorEventArgs (new IOException (errMsg))); + } + + if (numEvents == 0) + continue; + + for (var i = 0; i < numEvents; i++) { + var kevt = eventBuffer [i]; + var pathData = fdsDict [(int)kevt.ident]; + + if ((kevt.flags & EventFlags.Error) == EventFlags.Error) { + var errMsg = String.Format ("kevent() error watching path '{0}', error code = '{1}'", pathData.Path, kevt.data); + fsw.OnError (new ErrorEventArgs (new IOException (errMsg))); + continue; + } + + if ((kevt.fflags & FilterFlags.VNodeDelete) == FilterFlags.VNodeDelete || (kevt.fflags & FilterFlags.VNodeRevoke) == FilterFlags.VNodeRevoke) + removeQueue.Add (pathData); + + else if ((kevt.fflags & FilterFlags.VNodeWrite) == FilterFlags.VNodeWrite) { + if (pathData.IsDirectory) + rescanQueue.Add (pathData.Path); + else + PostEvent (FileAction.Modified, pathData.Path); + } + + else if ((kevt.fflags & FilterFlags.VNodeRename) == FilterFlags.VNodeRename) { + var newFilename = GetFilenameFromFd (pathData.Fd); + + if (newFilename.StartsWith (fsw.FullPath)) + Rename (pathData, newFilename); + else //moved outside of our watched dir so stop watching + RemoveTree (pathData); + } + + else if ((kevt.fflags & FilterFlags.VNodeAttrib) == FilterFlags.VNodeAttrib || (kevt.fflags & FilterFlags.VNodeExtend) == FilterFlags.VNodeExtend) + PostEvent (FileAction.Modified, pathData.Path); + } + + removeQueue.ForEach (Remove); + removeQueue.Clear (); + + rescanQueue.ForEach (path => { + Scan (path, true, ref newFds); + }); + rescanQueue.Clear (); + } + } + + PathData Add (string path, bool postEvents, ref List fds) + { + PathData pathData; + pathsDict.TryGetValue (path, out pathData); + + if (pathData != null) + return pathData; + + var fd = open (path, O_EVTONLY, 0); + + if (fd == -1) { + fsw.OnError (new ErrorEventArgs (new IOException (String.Format ( + "open() error while attempting to process path '{0}', error code = '{1}'", path, Marshal.GetLastWin32Error ())))); + return null; + } + + try { + fds.Add (fd); + + var attrs = File.GetAttributes (path); + + pathData = new PathData { + Path = path, + Fd = fd, + IsDirectory = (attrs & FileAttributes.Directory) == FileAttributes.Directory + }; + + pathsDict.Add (path, pathData); + fdsDict.Add (fd, pathData); + + if (postEvents) + PostEvent (FileAction.Added, path); + + return pathData; + } catch (Exception e) { + close (fd); + fsw.OnError (new ErrorEventArgs (e)); + return null; + } + + } + + void Remove (PathData pathData) + { + fdsDict.Remove (pathData.Fd); + pathsDict.Remove (pathData.Path); + close (pathData.Fd); + PostEvent (FileAction.Removed, pathData.Path); + } + + void RemoveTree (PathData pathData) + { + var toRemove = new List (); + + toRemove.Add (pathData); + + if (pathData.IsDirectory) { + var prefix = pathData.Path + Path.DirectorySeparatorChar; + foreach (var path in pathsDict.Keys) + if (path.StartsWith (prefix)) { + toRemove.Add (pathsDict [path]); + } + } + toRemove.ForEach (Remove); + } + + void Rename (PathData pathData, string newRoot) + { + var toRename = new List (); + var oldRoot = pathData.Path; + + toRename.Add (pathData); + + if (pathData.IsDirectory) { + var prefix = oldRoot + Path.DirectorySeparatorChar; + foreach (var path in pathsDict.Keys) + if (path.StartsWith (prefix)) + toRename.Add (pathsDict [path]); + } + + toRename.ForEach ((pd) => { + var oldPath = pd.Path; + var newPath = newRoot + oldPath.Substring (oldRoot.Length); + pd.Path = newPath; + pathsDict.Remove (oldPath); + pathsDict.Add (newPath, pd); + }); + + PostEvent (FileAction.RenamedNewName, oldRoot, newRoot); + } + + void Scan (string path, bool postEvents, ref List fds) + { + if (requestStop) + return; + + var pathData = Add (path, postEvents, ref fds); + + if (pathData == null) + return; + + if (!pathData.IsDirectory) + return; + + var dirsToProcess = new List (); + dirsToProcess.Add (path); + + while (dirsToProcess.Count > 0) { + var tmp = dirsToProcess [0]; + dirsToProcess.RemoveAt (0); + + var info = new DirectoryInfo (tmp); + FileSystemInfo[] fsInfos = null; + try { + fsInfos = info.GetFileSystemInfos (); + + } catch (IOException) { + // this can happen if the directory has been deleted already. + // that's okay, just keep processing the other dirs. + fsInfos = new FileSystemInfo[0]; + } + + foreach (var fsi in fsInfos) { + if ((fsi.Attributes & FileAttributes.Directory) == FileAttributes.Directory && !fsw.IncludeSubdirectories) + continue; + + if ((fsi.Attributes & FileAttributes.Directory) != FileAttributes.Directory && !fsw.Pattern.IsMatch (fsi.FullName)) + continue; + + var currentPathData = Add (fsi.FullName, postEvents, ref fds); + + if (currentPathData != null && currentPathData.IsDirectory) + dirsToProcess.Add (fsi.FullName); + } + } + } + + void PostEvent (FileAction action, string path, string newPath = null) + { + RenamedEventArgs renamed = null; + + if (action == 0) + return; + + // only post events that match filter pattern. check both old and new paths for renames + if (!fsw.Pattern.IsMatch (path) && (newPath == null || !fsw.Pattern.IsMatch (newPath))) + return; + + if (action == FileAction.RenamedNewName) + renamed = new RenamedEventArgs (WatcherChangeTypes.Renamed, "", newPath, path); + + lock (fsw) { + fsw.DispatchEvents (action, path, ref renamed); + + if (fsw.Waiting) { + fsw.Waiting = false; + System.Threading.Monitor.PulseAll (fsw); + } + } + } + + private string GetFilenameFromFd (int fd) + { + var sb = new StringBuilder (__DARWIN_MAXPATHLEN); + + if (fcntl (fd, F_GETPATH, sb) != -1) { + if (fixupPath != null) + sb.Replace (fixupPath, fsw.FullPath, 0, fixupPath.Length); // see Setup() + return sb.ToString (); + } else { + fsw.OnError (new ErrorEventArgs (new IOException (String.Format ( + "fcntl() error while attempting to get path for fd '{0}', error code = '{1}'", fd, Marshal.GetLastWin32Error ())))); + return String.Empty; + } + } + + const int O_EVTONLY = 0x8000; + const int F_GETPATH = 50; + const int __DARWIN_MAXPATHLEN = 1024; + static readonly kevent[] emptyEventList = new System.IO.kevent[0]; + + FileSystemWatcher fsw; + int conn; + Thread thread; + volatile bool requestStop = false; + AutoResetEvent startedEvent = new AutoResetEvent (false); + bool started = false; + bool failedInit = false; + object stateLock = new object (); + + readonly Dictionary pathsDict = new Dictionary (); + readonly Dictionary fdsDict = new Dictionary (); + string fixupPath = null; + + [DllImport ("libc", EntryPoint="fcntl", CharSet=CharSet.Auto, SetLastError=true)] + static extern int fcntl (int file_names_by_descriptor, int cmd, StringBuilder sb); + + [DllImport ("libc")] + extern static int open (string path, int flags, int mode_t); + + [DllImport ("libc")] + extern static int close (int fd); + + [DllImport ("libc")] + extern static int kqueue (); + + [DllImport ("libc")] + extern static int kevent (int kq, [In]kevent[] ev, int nchanges, [Out]kevent[] evtlist, int nevents, [In] ref timespec time); + } class KeventWatcher : IFileWatcher { static bool failed; static KeventWatcher instance; - static Hashtable watches; - static Hashtable requests; - static Thread thread; - static int conn; - static bool stop; - + static Hashtable watches; // + private KeventWatcher () { } - + // Locked by caller public static bool GetInstance (out IFileWatcher watcher) { @@ -194,268 +622,47 @@ namespace System.IO { } watches = Hashtable.Synchronized (new Hashtable ()); - requests = Hashtable.Synchronized (new Hashtable ()); - conn = kqueue(); + var conn = kqueue(); if (conn == -1) { failed = true; watcher = null; return false; } + close (conn); instance = new KeventWatcher (); watcher = instance; return true; } - + public void StartDispatching (FileSystemWatcher fsw) { - KeventData data; - lock (this) { - if (thread == null) { - thread = new Thread (new ThreadStart (Monitor)); - thread.IsBackground = true; - thread.Start (); - } + KqueueMonitor monitor; - data = (KeventData) watches [fsw]; + if (watches.ContainsKey (fsw)) { + monitor = (KqueueMonitor)watches [fsw]; + } else { + monitor = new KqueueMonitor (fsw); + watches.Add (fsw, monitor); } - - if (data == null) { - data = new KeventData (); - data.FSW = fsw; - data.Directory = fsw.FullPath; - data.FileMask = fsw.MangledFilter; - data.IncludeSubdirs = fsw.IncludeSubdirectories; - - data.Enabled = true; - lock (this) { - StartMonitoringDirectory (data); - watches [fsw] = data; - stop = false; - } - } - } - - static void StartMonitoringDirectory (KeventData data) - { - DirectoryInfo dir = new DirectoryInfo (data.Directory); - if(data.DirEntries == null) { - data.DirEntries = new Hashtable(); - foreach (FileSystemInfo fsi in dir.GetFileSystemInfos() ) - data.DirEntries.Add(fsi.FullName, new KeventFileData(fsi, fsi.LastAccessTime, fsi.LastWriteTime)); - } - - int fd = open(data.Directory, 0, 0); - kevent ev = new kevent(); - ev.udata = IntPtr.Zero; - timespec nullts = new timespec(); - nullts.tv_sec = 0; - nullts.tv_usec = 0; - if (fd > 0) { - ev.ident = fd; - ev.filter = EventFilter.Vnode; - ev.flags = EventFlags.Add | EventFlags.Enable | EventFlags.OneShot; - ev.fflags = // 20 | 2 | 1 | 8; - FilterFlags.VNodeDelete | - FilterFlags.VNodeWrite | - FilterFlags.VNodeAttrib | - // The following two values are the equivalent of the original value "20", but we suspect the original author meant - // 0x20, we will review later with some test cases - FilterFlags.VNodeLink | - FilterFlags.VNodeExtend; - ev.data = 0; - ev.udata = Marshal.StringToHGlobalAuto (data.Directory); - kevent outev = new kevent(); - outev.udata = IntPtr.Zero; - kevent (conn, ref ev, 1, ref outev, 0, ref nullts); - data.ev = ev; - requests [fd] = data; - } - - if (!data.IncludeSubdirs) - return; - + + monitor.Start (); } public void StopDispatching (FileSystemWatcher fsw) { - KeventData data; - lock (this) { - data = (KeventData) watches [fsw]; - if (data == null) - return; - - StopMonitoringDirectory (data); - watches.Remove (fsw); - if (watches.Count == 0) - stop = true; - - if (!data.IncludeSubdirs) - return; - - } - } - - static void StopMonitoringDirectory (KeventData data) - { - close(data.ev.ident); - } - - void Monitor () - { - - while (!stop) { - kevent ev = new kevent(); - ev.udata = IntPtr.Zero; - kevent nullev = new kevent(); - nullev.udata = IntPtr.Zero; - timespec ts = new timespec(); - ts.tv_sec = 0; - ts.tv_usec = 0; - int haveEvents; - lock (this) { - haveEvents = kevent (conn, ref nullev, 0, ref ev, 1, ref ts); - } - - if (haveEvents > 0) { - // Restart monitoring - KeventData data = (KeventData) requests [ev.ident]; - StopMonitoringDirectory (data); - StartMonitoringDirectory (data); - ProcessEvent (ev); - } else { - System.Threading.Thread.Sleep (500); - } - } - - lock (this) { - thread = null; - stop = false; - } - } - - void ProcessEvent (kevent ev) - { - lock (this) { - KeventData data = (KeventData) requests [ev.ident]; - if (!data.Enabled) - return; - - FileSystemWatcher fsw; - string filename = ""; - - fsw = data.FSW; - FileAction fa = 0; - DirectoryInfo dir = new DirectoryInfo (data.Directory); - FileSystemInfo changedFsi = null; - - try { - foreach (FileSystemInfo fsi in dir.GetFileSystemInfos() ) - if (data.DirEntries.ContainsKey (fsi.FullName) && (fsi is FileInfo)) { - KeventFileData entry = (KeventFileData) data.DirEntries [fsi.FullName]; - if (entry.LastWriteTime != fsi.LastWriteTime) { - filename = fsi.Name; - fa = FileAction.Modified; - data.DirEntries [fsi.FullName] = new KeventFileData(fsi, fsi.LastAccessTime, fsi.LastWriteTime); - if (fsw.IncludeSubdirectories && fsi is DirectoryInfo) { - data.Directory = filename; - requests [ev.ident] = data; - ProcessEvent(ev); - } - changedFsi = fsi; - PostEvent(filename, fsw, fa, changedFsi); - } - } - } catch (Exception) { - // The file system infos were changed while we processed them - } - // Deleted - try { - bool deleteMatched = true; - while(deleteMatched) { - foreach (KeventFileData entry in data.DirEntries.Values) { - if (!File.Exists (entry.fsi.FullName) && !Directory.Exists (entry.fsi.FullName)) { - filename = entry.fsi.Name; - fa = FileAction.Removed; - data.DirEntries.Remove (entry.fsi.FullName); - changedFsi = entry.fsi; - PostEvent(filename, fsw, fa, changedFsi); - break; - } - } - deleteMatched = false; - } - } catch (Exception) { - // The file system infos were changed while we processed them - } - // Added - try { - foreach (FileSystemInfo fsi in dir.GetFileSystemInfos()) - if (!data.DirEntries.ContainsKey (fsi.FullName)) { - changedFsi = fsi; - filename = fsi.Name; - fa = FileAction.Added; - data.DirEntries [fsi.FullName] = new KeventFileData(fsi, fsi.LastAccessTime, fsi.LastWriteTime); - PostEvent(filename, fsw, fa, changedFsi); - } - } catch (Exception) { - // The file system infos were changed while we processed them - } - - - } - } - - private void PostEvent (string filename, FileSystemWatcher fsw, FileAction fa, FileSystemInfo changedFsi) { - RenamedEventArgs renamed = null; - if (fa == 0) + KqueueMonitor monitor = (KqueueMonitor)watches [fsw]; + if (monitor == null) return; + + monitor.Stop (); + } - if (fsw.IncludeSubdirectories && fa == FileAction.Added) { - if (changedFsi is DirectoryInfo) { - KeventData newdirdata = new KeventData (); - newdirdata.FSW = fsw; - newdirdata.Directory = changedFsi.FullName; - newdirdata.FileMask = fsw.MangledFilter; - newdirdata.IncludeSubdirs = fsw.IncludeSubdirectories; - - newdirdata.Enabled = true; - lock (this) { - StartMonitoringDirectory (newdirdata); - } - } - } - - if (!fsw.Pattern.IsMatch(filename, true)) - return; - - lock (fsw) { - if (changedFsi.FullName.StartsWith (fsw.FullPath, StringComparison.Ordinal)) { - if (fsw.FullPath.EndsWith ("/", StringComparison.Ordinal)) { - filename = changedFsi.FullName.Substring (fsw.FullPath.Length); - } else { - filename = changedFsi.FullName.Substring (fsw.FullPath.Length + 1); - } - } - fsw.DispatchEvents (fa, filename, ref renamed); - if (fsw.Waiting) { - fsw.Waiting = false; - System.Threading.Monitor.PulseAll (fsw); - } - } - } + [DllImport ("libc")] + extern static int close (int fd); [DllImport ("libc")] - extern static int open(string path, int flags, int mode_t); - - [DllImport ("libc")] - extern static int close(int fd); - - [DllImport ("libc")] - extern static int kqueue(); - - [DllImport ("libc")] - extern static int kevent(int kqueue, ref kevent ev, int nchanges, ref kevent evtlist, int nevents, ref timespec ts); + extern static int kqueue (); } } diff --git a/mcs/class/System/System.IO/SearchPattern.cs b/mcs/class/System/System.IO/SearchPattern.cs index 0fbab4e5e7..f302dffaaa 100644 --- a/mcs/class/System/System.IO/SearchPattern.cs +++ b/mcs/class/System/System.IO/SearchPattern.cs @@ -47,7 +47,7 @@ namespace System.IO { Compile (pattern); } - // OSX has a retarded case-insensitive yet case-aware filesystem + // OSX has a case-insensitive yet case-aware filesystem // so we need a overload in here for the Kqueue watcher public bool IsMatch (string text, bool ignorecase) { @@ -55,20 +55,17 @@ namespace System.IO { bool match = String.Compare (pattern, text, ignorecase) == 0; if (match) return true; - - // This is a special case for FSW. It needs to match e.g. subdir/file.txt - // when the pattern is "file.txt" - int idx = text.LastIndexOf ('/'); - if (idx == -1) - return false; - idx++; - if (idx == text.Length) - return false; - - return (String.Compare (pattern, text.Substring (idx), ignorecase) == 0); } + + // This is a special case for FSW. It needs to match e.g. subdir/file.txt + // when the pattern is "file.txt" + var fileName = Path.GetFileName (text); - return Match (ops, text, 0); + if (!hasWildcard) + return (String.Compare (pattern, fileName, ignorecase) == 0); + + + return Match (ops, fileName, 0); } public bool IsMatch (string text) diff --git a/mcs/class/System/System.Media/AudioDevice.cs b/mcs/class/System/System.Media/AudioDevice.cs index 628c04d8ed..a1d0896dba 100644 --- a/mcs/class/System/System.Media/AudioDevice.cs +++ b/mcs/class/System/System.Media/AudioDevice.cs @@ -200,6 +200,8 @@ namespace Mono.Audio { snd_pcm_hw_params_free (hw_param); if (handle != IntPtr.Zero) snd_pcm_close (handle); + sw_param = IntPtr.Zero; + hw_param = IntPtr.Zero; handle = IntPtr.Zero; } @@ -278,10 +280,14 @@ namespace Mono.Audio { Console.WriteLine ("failed to alloc Alsa sw param struct"); } - if (hw_param != IntPtr.Zero) + if (hw_param != IntPtr.Zero) { snd_pcm_hw_params_free (hw_param); // free hw params - if (sw_param != IntPtr.Zero) + hw_param = IntPtr.Zero; + } + if (sw_param != IntPtr.Zero) { snd_pcm_sw_params_free (sw_param); // free sw params + sw_param = IntPtr.Zero; + } return alsa_err == 0; } diff --git a/mcs/class/System/System.Net.Sockets/SocketAsyncEventArgs.cs b/mcs/class/System/System.Net.Sockets/SocketAsyncEventArgs.cs index a7eeb67d88..c7f6259172 100644 --- a/mcs/class/System/System.Net.Sockets/SocketAsyncEventArgs.cs +++ b/mcs/class/System/System.Net.Sockets/SocketAsyncEventArgs.cs @@ -260,6 +260,8 @@ namespace System.Net.Sockets curSocket.EndConnect (ares); } catch (SocketException se) { SocketError = se.SocketErrorCode; + } catch (ObjectDisposedException) { + SocketError = SocketError.OperationAborted; } finally { OnCompleted (this); } diff --git a/mcs/class/System/System.Net.Sockets/Socket_2_1.cs b/mcs/class/System/System.Net.Sockets/Socket_2_1.cs index b0295bef71..b44a061159 100644 --- a/mcs/class/System/System.Net.Sockets/Socket_2_1.cs +++ b/mcs/class/System/System.Net.Sockets/Socket_2_1.cs @@ -952,6 +952,14 @@ namespace System.Net.Sockets { #endif } +#if NET_4_5 + [MonoTODO ("Currently hardcoded to IPv4. Ideally, support v4/v6 dual-stack.")] + public Socket (SocketType socketType, ProtocolType protocolType) + : this (AddressFamily.InterNetwork, socketType, protocolType) + { + } +#endif + ~Socket () { Dispose (false); diff --git a/mcs/class/System/System.Net.WebSockets/ClientWebSocket.cs b/mcs/class/System/System.Net.WebSockets/ClientWebSocket.cs index bfa085885e..d7e999c46f 100644 --- a/mcs/class/System/System.Net.WebSockets/ClientWebSocket.cs +++ b/mcs/class/System/System.Net.WebSockets/ClientWebSocket.cs @@ -61,6 +61,7 @@ namespace System.Net.WebSockets const int HeaderMaxLength = 14; byte[] headerBuffer; byte[] sendBuffer; + long remaining; public ClientWebSocket () { @@ -226,32 +227,43 @@ namespace System.Net.WebSockets ValidateArraySegment (buffer); return Task.Run (() => { EnsureWebSocketState (WebSocketState.Open, WebSocketState.CloseSent); - // First read the two first bytes to know what we are doing next - connection.Read (req, headerBuffer, 0, 2); - var isLast = (headerBuffer[0] >> 7) > 0; - var isMasked = (headerBuffer[1] >> 7) > 0; - int mask = 0; - var type = WireToMessageType ((byte)(headerBuffer[0] & 0xF)); - long length = headerBuffer[1] & 0x7F; - int offset = 0; - if (length == 126) { - offset = 2; - connection.Read (req, headerBuffer, 2, offset); - length = (headerBuffer[2] << 8) | headerBuffer[3]; - } else if (length == 127) { - offset = 8; - connection.Read (req, headerBuffer, 2, offset); - length = 0; - for (int i = 2; i <= 9; i++) - length = (length << 8) | headerBuffer[i]; - } - if (isMasked) { - connection.Read (req, headerBuffer, 2 + offset, 4); - for (int i = 0; i < 4; i++) { - var pos = i + offset + 2; - mask = (mask << 8) | headerBuffer[pos]; + bool isLast; + WebSocketMessageType type; + long length; + + if (remaining == 0) { + // First read the two first bytes to know what we are doing next + connection.Read (req, headerBuffer, 0, 2); + isLast = (headerBuffer[0] >> 7) > 0; + var isMasked = (headerBuffer[1] >> 7) > 0; + int mask = 0; + type = WireToMessageType ((byte)(headerBuffer[0] & 0xF)); + length = headerBuffer[1] & 0x7F; + int offset = 0; + if (length == 126) { + offset = 2; + connection.Read (req, headerBuffer, 2, offset); + length = (headerBuffer[2] << 8) | headerBuffer[3]; + } else if (length == 127) { + offset = 8; + connection.Read (req, headerBuffer, 2, offset); + length = 0; + for (int i = 2; i <= 9; i++) + length = (length << 8) | headerBuffer[i]; } + + if (isMasked) { + connection.Read (req, headerBuffer, 2 + offset, 4); + for (int i = 0; i < 4; i++) { + var pos = i + offset + 2; + mask = (mask << 8) | headerBuffer[pos]; + } + } + } else { + isLast = (headerBuffer[0] >> 7) > 0; + type = WireToMessageType ((byte)(headerBuffer[0] & 0xF)); + length = remaining; } if (type == WebSocketMessageType.Close) { @@ -264,8 +276,9 @@ namespace System.Net.WebSockets } else { var readLength = (int)(buffer.Count < length ? buffer.Count : length); connection.Read (req, buffer.Array, buffer.Offset, readLength); + remaining = length - readLength; - return new WebSocketReceiveResult ((int)length, type, isLast); + return new WebSocketReceiveResult ((int)readLength, type, isLast && remaining == 0); } }); } diff --git a/mcs/class/System/System.Net/MacProxy.cs b/mcs/class/System/System.Net/MacProxy.cs index 45740306db..0b5d6a76e4 100644 --- a/mcs/class/System/System.Net/MacProxy.cs +++ b/mcs/class/System/System.Net/MacProxy.cs @@ -225,6 +225,14 @@ namespace System.Net } } + internal struct CFStreamClientContext { + public IntPtr Version; + public IntPtr Info; + public IntPtr Retain; + public IntPtr Release; + public IntPtr CopyDescription; + } + internal class CFString : CFObject { string str; @@ -361,6 +369,52 @@ namespace System.Net } } + internal class CFRunLoop : CFObject + { + [DllImport (CFObject.CoreFoundationLibrary)] + static extern void CFRunLoopAddSource (IntPtr rl, IntPtr source, IntPtr mode); + + [DllImport (CFObject.CoreFoundationLibrary)] + static extern void CFRunLoopRemoveSource (IntPtr rl, IntPtr source, IntPtr mode); + + [DllImport (CFObject.CoreFoundationLibrary)] + static extern int CFRunLoopRunInMode (IntPtr mode, double seconds, bool returnAfterSourceHandled); + + [DllImport (CFObject.CoreFoundationLibrary)] + static extern IntPtr CFRunLoopGetCurrent (); + + [DllImport (CFObject.CoreFoundationLibrary)] + static extern void CFRunLoopStop (IntPtr rl); + + public CFRunLoop (IntPtr handle, bool own): base (handle, own) + { + } + + public static CFRunLoop CurrentRunLoop { + get { return new CFRunLoop (CFRunLoopGetCurrent (), false); } + } + + public void AddSource (IntPtr source, CFString mode) + { + CFRunLoopAddSource (Handle, source, mode.Handle); + } + + public void RemoveSource (IntPtr source, CFString mode) + { + CFRunLoopRemoveSource (Handle, source, mode.Handle); + } + + public int RunInMode (CFString mode, double seconds, bool returnAfterSourceHandled) + { + return CFRunLoopRunInMode (mode.Handle, seconds, returnAfterSourceHandled); + } + + public void Stop () + { + CFRunLoopStop (Handle); + } + } + internal enum CFProxyType { None, AutoConfigurationUrl, @@ -615,6 +669,10 @@ namespace System.Net // CFArrayRef CFNetworkCopyProxiesForAutoConfigurationScript (CFStringRef proxyAutoConfigurationScript, CFURLRef targetURL, CFErrorRef* error); extern static IntPtr CFNetworkCopyProxiesForAutoConfigurationScriptSequential (IntPtr proxyAutoConfigurationScript, IntPtr targetURL, out IntPtr error); + [DllImport (CFNetworkLibrary)] + extern static IntPtr CFNetworkExecuteProxyAutoConfigurationURL (IntPtr proxyAutoConfigURL, IntPtr targetURL, CFProxyAutoConfigurationResultCallback cb, ref CFStreamClientContext clientContext); + + class GetProxyData : IDisposable { public IntPtr script; public IntPtr targetUri; @@ -737,6 +795,45 @@ namespace System.Net return proxies; } + + delegate void CFProxyAutoConfigurationResultCallback (IntPtr client, IntPtr proxyList, IntPtr error); + + public static CFProxy[] ExecuteProxyAutoConfigurationURL (IntPtr proxyAutoConfigURL, Uri targetURL) + { + CFUrl url = CFUrl.Create (targetURL.AbsoluteUri); + if (url == null) + return null; + + CFProxy[] proxies = null; + + var runLoop = CFRunLoop.CurrentRunLoop; + + // Callback that will be called after executing the configuration script + CFProxyAutoConfigurationResultCallback cb = delegate (IntPtr client, IntPtr proxyList, IntPtr error) { + if (proxyList != IntPtr.Zero) { + var array = new CFArray (proxyList, false); + proxies = new CFProxy [array.Count]; + for (int i = 0; i < proxies.Length; i++) { + CFDictionary dict = new CFDictionary (array[i], false); + proxies[i] = new CFProxy (dict); + } + array.Dispose (); + } + runLoop.Stop (); + }; + + var clientContext = new CFStreamClientContext (); + var loopSource = CFNetworkExecuteProxyAutoConfigurationURL (proxyAutoConfigURL, url.Handle, cb, ref clientContext); + + // Create a private mode + var mode = CFString.Create ("Mono.MacProxy"); + + runLoop.AddSource (loopSource, mode); + runLoop.RunInMode (mode, double.MaxValue, false); + runLoop.RemoveSource (loopSource, mode); + + return proxies; + } [DllImport (CFNetworkLibrary)] // CFArrayRef CFNetworkCopyProxiesForURL (CFURLRef url, CFDictionaryRef proxySettings); @@ -859,7 +956,18 @@ namespace System.Net static Uri GetProxyUriFromScript (IntPtr script, Uri targetUri, out NetworkCredential credentials) { CFProxy[] proxies = CFNetwork.GetProxiesForAutoConfigurationScript (script, targetUri); - + return SelectProxy (proxies, targetUri, out credentials); + } + + static Uri ExecuteProxyAutoConfigurationURL (IntPtr proxyAutoConfigURL, Uri targetUri, out NetworkCredential credentials) + { + CFProxy[] proxies = CFNetwork.ExecuteProxyAutoConfigurationURL (proxyAutoConfigURL, targetUri); + return SelectProxy (proxies, targetUri, out credentials); + } + + + static Uri SelectProxy (CFProxy[] proxies, Uri targetUri, out NetworkCredential credentials) + { if (proxies == null) { credentials = null; return targetUri; @@ -907,7 +1015,7 @@ namespace System.Net proxy = GetProxyUriFromScript (proxies[i].AutoConfigurationJavaScript, targetUri, out credentials); break; case CFProxyType.AutoConfigurationUrl: - // unsupported proxy type (requires fetching script from remote url) + proxy = ExecuteProxyAutoConfigurationURL (proxies[i].AutoConfigurationUrl, targetUri, out credentials); break; case CFProxyType.HTTPS: case CFProxyType.HTTP: diff --git a/mcs/class/System/System.Net/ServicePointManager.cs b/mcs/class/System/System.Net/ServicePointManager.cs index b6095b0890..dc7412d725 100644 --- a/mcs/class/System/System.Net/ServicePointManager.cs +++ b/mcs/class/System/System.Net/ServicePointManager.cs @@ -369,6 +369,15 @@ namespace System.Net return sp; } + + internal static void CloseConnectionGroup (string connectionGroupName) + { + lock (servicePoints) { + foreach (ServicePoint sp in servicePoints.Values) { + sp.CloseConnectionGroup (connectionGroupName); + } + } + } #if SECURITY_DEP internal class ChainValidationHelper { diff --git a/mcs/class/System/System.Net/WebClient.cs b/mcs/class/System/System.Net/WebClient.cs index ded7767114..38415f05c5 100644 --- a/mcs/class/System/System.Net/WebClient.cs +++ b/mcs/class/System/System.Net/WebClient.cs @@ -1972,20 +1972,17 @@ namespace System.Net if (fileName == null) throw new ArgumentNullException ("fileName"); - WebRequest request = null; try { SetBusy (); cts = new CancellationTokenSource (); - request = await SetupRequestAsync (address, method, true).ConfigureAwait (false); - var result = await UploadFileTaskAsyncCore (request, method, fileName, cts.Token).ConfigureAwait (false); + + var result = await UploadFileTaskAsyncCore (address, method, fileName, cts.Token).ConfigureAwait (false); OnUploadFileCompleted (new UploadFileCompletedEventArgs (result, null, false, null)); return result; } catch (WebException ex) { OnUploadFileCompleted (new UploadFileCompletedEventArgs (null, ex, false, null)); throw; } catch (OperationCanceledException) { - if (request != null) - request.Abort (); OnUploadFileCompleted (new UploadFileCompletedEventArgs (null, null, true, null)); throw; } catch (Exception ex) { @@ -1994,8 +1991,7 @@ namespace System.Net } } - async Task UploadFileTaskAsyncCore (WebRequest request, string method, - string fileName, CancellationToken token) + async Task UploadFileTaskAsyncCore (Uri address, string method, string fileName, CancellationToken token) { token.ThrowIfCancellationRequested (); @@ -2018,9 +2014,15 @@ namespace System.Net Stream reqStream = null; Stream fStream = null; WebResponse response = null; + WebRequest request = null; fileName = Path.GetFullPath (fileName); + try { + request = await SetupRequestAsync (address, method, true).ConfigureAwait (false); + } catch (OperationCanceledException) { + } + try { fStream = File.OpenRead (fileName); token.ThrowIfCancellationRequested (); @@ -2042,7 +2044,9 @@ namespace System.Net Path.GetFileName (fileName), fileCType); byte [] partHeadersBytes = Encoding.UTF8.GetBytes (partHeaders); ms.Write (partHeadersBytes, 0, partHeadersBytes.Length); - await ms.CopyToAsync (reqStream, (int)ms.Position, token).ConfigureAwait (false); + var msLength = (int)ms.Position; + ms.Seek (0, SeekOrigin.Begin); + await ms.CopyToAsync (reqStream, msLength, token).ConfigureAwait (false); } } int nread; @@ -2084,7 +2088,9 @@ namespace System.Net ms.WriteByte ((byte) '-'); ms.WriteByte ((byte) '\r'); ms.WriteByte ((byte) '\n'); - await ms.CopyToAsync (reqStream, (int)ms.Position, token).ConfigureAwait (false); + var msLength = (int)ms.Position; + ms.Seek (0, SeekOrigin.Begin); + await ms.CopyToAsync (reqStream, msLength, token).ConfigureAwait (false); } } reqStream.Close (); diff --git a/mcs/class/System/System/Uri.cs b/mcs/class/System/System/Uri.cs index 105004e39c..fb9c14eead 100644 --- a/mcs/class/System/System/Uri.cs +++ b/mcs/class/System/System/Uri.cs @@ -1725,7 +1725,7 @@ namespace System { private UriParser Parser { get { if (parser == null) { - parser = UriParser.GetParser (Scheme); + parser = UriParser.GetParser (scheme); // no specific parser ? then use a default one if (parser == null) parser = new DefaultUriParser ("*"); @@ -1737,6 +1737,9 @@ namespace System { public string GetComponents (UriComponents components, UriFormat format) { + if ((components & UriComponents.SerializationInfoString) == 0) + EnsureAbsoluteUri (); + return Parser.GetComponents (this, components, format); } diff --git a/mcs/class/System/System/UriParser.cs b/mcs/class/System/System/UriParser.cs index 8abfdc9b35..5eda9aadc1 100644 --- a/mcs/class/System/System/UriParser.cs +++ b/mcs/class/System/System/UriParser.cs @@ -50,6 +50,16 @@ namespace System { if ((format < UriFormat.UriEscaped) || (format > UriFormat.SafeUnescaped)) throw new ArgumentOutOfRangeException ("format"); + if ((components & UriComponents.SerializationInfoString) != 0) { + if (components != UriComponents.SerializationInfoString) + throw new ArgumentOutOfRangeException ("components", "UriComponents.SerializationInfoString must not be combined with other UriComponents."); + + if (!uri.IsAbsoluteUri) + return UriHelper.FormatRelative (uri.OriginalString, "", format); + + components |= UriComponents.AbsoluteUri; + } + return GetComponentsHelper (uri, components, format); } diff --git a/mcs/class/System/System_test.dll.sources b/mcs/class/System/System_test.dll.sources index e47a4c9821..6ff1a9488a 100644 --- a/mcs/class/System/System_test.dll.sources +++ b/mcs/class/System/System_test.dll.sources @@ -182,6 +182,7 @@ System.Diagnostics/DelimitedListTraceListenerTest.cs System.Diagnostics/EventLogTest.cs System.Diagnostics/StopwatchTest.cs System.Diagnostics/SourceSwitchTest.cs +System.Diagnostics/TextWriterTraceListenerHelper.cs System.Diagnostics/TextWriterTraceListenerTest.cs System.Diagnostics/TraceSourceTest.cs System.Diagnostics/TraceListenerTest.cs diff --git a/mcs/class/System/Test/System.CodeDom.Compiler/CodeDomProviderCas.cs b/mcs/class/System/Test/System.CodeDom.Compiler/CodeDomProviderCas.cs index 979734af05..a9d536085b 100644 --- a/mcs/class/System/Test/System.CodeDom.Compiler/CodeDomProviderCas.cs +++ b/mcs/class/System/Test/System.CodeDom.Compiler/CodeDomProviderCas.cs @@ -317,7 +317,7 @@ namespace MonoCasTests.System.CodeDom.Compiler { [ExpectedException (typeof (SecurityException))] public void LinkDemand_IsDefinedExtension_Deny_Anything () { - MethodInfo mi = mi = typeof (CodeDomProvider).GetMethod ("IsDefinedExtension"); + MethodInfo mi = typeof (CodeDomProvider).GetMethod ("IsDefinedExtension"); Assert.IsNotNull (mi, "IsDefinedExtension"); Assert.IsFalse ((bool) mi.Invoke (null, new object[1] { String.Empty }), "IsDefinedExtension('')"); // requires full trust (i.e. unrestricted permission set) @@ -328,7 +328,7 @@ namespace MonoCasTests.System.CodeDom.Compiler { [ExpectedException (typeof (SecurityException))] public void LinkDemand_IsDefinedLanguage_Deny_Anything () { - MethodInfo mi = mi = typeof (CodeDomProvider).GetMethod ("IsDefinedLanguage"); + MethodInfo mi = typeof (CodeDomProvider).GetMethod ("IsDefinedLanguage"); Assert.IsNotNull (mi, "IsDefinedLanguage"); Assert.IsFalse ((bool) mi.Invoke (null, new object[1] { String.Empty }), "IsDefinedLanguage('')"); // requires full trust (i.e. unrestricted permission set) diff --git a/mcs/class/System/Test/System.Collections.Concurrent/BlockingCollectionTests.cs b/mcs/class/System/Test/System.Collections.Concurrent/BlockingCollectionTests.cs index 9f0e9b0190..bf41aeee21 100644 --- a/mcs/class/System/Test/System.Collections.Concurrent/BlockingCollectionTests.cs +++ b/mcs/class/System/Test/System.Collections.Concurrent/BlockingCollectionTests.cs @@ -237,7 +237,7 @@ namespace MonoTests.System.Collections.Concurrent t = Task.Factory.StartNew (() => { try { return BlockingCollection.TakeFromAny (arr, out res, cts.Token); - } catch (OperationCanceledException WE_GOT_CANCELED) { + } catch (OperationCanceledException) { res = "canceled"; return -10; } @@ -247,6 +247,40 @@ namespace MonoTests.System.Collections.Concurrent Assert.AreEqual (-10, t.Result, "#5"); Assert.AreEqual ("canceled", res, "#6"); } + + [Test, ExpectedException (typeof(OperationCanceledException))] + public void BoundedAddLimit () + { + const int elNumber = 5; + + var c = new BlockingCollection (elNumber); + var token = new CancellationTokenSource (100); + + for (var i = 0; i < elNumber + 1; i++) { + c.Add (1, token.Token); + } + } + + [Test] + public void AddAnyCancellable () + { + const int elNumber = 5; + const int colNumber = 5; + + var cols = new BlockingCollection [colNumber]; + for (var i = 0; i < colNumber; i++) { + cols[i] = new BlockingCollection (elNumber); + } + + var token = new CancellationTokenSource (100); + for (var i = 0; i < colNumber * elNumber; i++) { + BlockingCollection .AddToAny (cols, 1, token.Token); + } + + foreach (var col in cols) { + Assert.AreEqual (elNumber, col.Count); + } + } } } #endif diff --git a/mcs/class/System/Test/System.ComponentModel.Design.Serialization/InstanceDescriptorTest.cs b/mcs/class/System/Test/System.ComponentModel.Design.Serialization/InstanceDescriptorTest.cs index 16d12af943..dbc4110cb2 100644 --- a/mcs/class/System/Test/System.ComponentModel.Design.Serialization/InstanceDescriptorTest.cs +++ b/mcs/class/System/Test/System.ComponentModel.Design.Serialization/InstanceDescriptorTest.cs @@ -277,7 +277,7 @@ namespace MonoTests.System.ComponentModel.Design.Serialization { } } - class InstanceField + public class InstanceField { public string Name; } diff --git a/mcs/class/System/Test/System.ComponentModel/CharConverterTest.cs b/mcs/class/System/Test/System.ComponentModel/CharConverterTest.cs index d0b78f97fb..815a9a6255 100644 --- a/mcs/class/System/Test/System.ComponentModel/CharConverterTest.cs +++ b/mcs/class/System/Test/System.ComponentModel/CharConverterTest.cs @@ -20,7 +20,6 @@ namespace MonoTests.System.ComponentModel public class CharConverterTest { private CharConverter converter; - private string pattern; [SetUp] public void SetUp () @@ -28,7 +27,6 @@ namespace MonoTests.System.ComponentModel converter = new CharConverter (); DateTimeFormatInfo info = CultureInfo.CurrentCulture.DateTimeFormat; - pattern = info.ShortDatePattern + " " + info.ShortTimePattern; } [Test] diff --git a/mcs/class/System/Test/System.ComponentModel/ContainerTest.cs b/mcs/class/System/Test/System.ComponentModel/ContainerTest.cs index 16a6a4124d..46706fd348 100644 --- a/mcs/class/System/Test/System.ComponentModel/ContainerTest.cs +++ b/mcs/class/System/Test/System.ComponentModel/ContainerTest.cs @@ -733,10 +733,6 @@ namespace MonoTests.System.ComponentModel container.Add (this); return container; } - - public Container Container { - get { return container; } - } } class MyContainer : IContainer diff --git a/mcs/class/System/Test/System.Diagnostics/DiagnosticsConfigurationHandlerTest.cs b/mcs/class/System/Test/System.Diagnostics/DiagnosticsConfigurationHandlerTest.cs index 9af93d5a2f..8c9049470d 100644 --- a/mcs/class/System/Test/System.Diagnostics/DiagnosticsConfigurationHandlerTest.cs +++ b/mcs/class/System/Test/System.Diagnostics/DiagnosticsConfigurationHandlerTest.cs @@ -159,6 +159,30 @@ namespace MonoTests.System.Diagnostics ValidateExceptions ("#TAT:BadChildren", "{0}", badChildren); } + [Test] + [Category ("NotDotNet")] + public void PerformanceCountersTag () + { + string[] goodAttributes = { + "", + "filemappingsize=\"1048576\"", + "filemappingsize=\"0\"" + }; + ValidateSuccess ("#PCT:Good", "", goodAttributes); + + string[] badAttributes = { + "FileMappingSize=\"1048576\"", + "filemappingsize=\"\"", + "filemappingsize=\"non-int-value\"" + }; + ValidateExceptions ("#PCT:BadAttrs", "", badAttributes); + + string[] badChildren = { + "" + }; + ValidateExceptions ("#PCT:BadChildren", "{0}", badChildren); + } + [Test] [Category ("NotDotNet")] public void TraceTag_Attributes () diff --git a/mcs/class/System/Test/System.Diagnostics/ProcessTest.cs b/mcs/class/System/Test/System.Diagnostics/ProcessTest.cs index 88de1d72a8..d6ae37eb0f 100644 --- a/mcs/class/System/Test/System.Diagnostics/ProcessTest.cs +++ b/mcs/class/System/Test/System.Diagnostics/ProcessTest.cs @@ -722,7 +722,7 @@ namespace MonoTests.System.Diagnostics } } - int bytesRead = -1; + public int bytesRead = -1; #if NET_2_0 // Not technically a 2.0 only test, but I use lambdas, so I need gmcs @@ -836,7 +836,7 @@ namespace MonoTests.System.Diagnostics try { var x = p.Handle; Assert.Fail ("Handle should throw for unstated procs, but returned " + x); - } catch (InvalidOperationException ex) { + } catch (InvalidOperationException) { } } } diff --git a/mcs/class/System/Test/System.Diagnostics/SourceSwitchTest.cs b/mcs/class/System/Test/System.Diagnostics/SourceSwitchTest.cs index 05e0a6d129..820e84d2a8 100644 --- a/mcs/class/System/Test/System.Diagnostics/SourceSwitchTest.cs +++ b/mcs/class/System/Test/System.Diagnostics/SourceSwitchTest.cs @@ -31,6 +31,8 @@ #if !MOBILE +#define TRACE + using NUnit.Framework; using System; using System.Text; @@ -43,11 +45,15 @@ namespace MonoTests.System.Diagnostics [TestFixture] public class SourceSwitchTest { + internal TraceSource traceSource { get; set; } + internal TestTextWriterTraceListener txtTraceListener; + + [Test] public void ConstructorNullName () { SourceSwitch s = new SourceSwitch (null); - Assert.IsNull (s.DisplayName); + Assert.IsEmpty (s.DisplayName); } [Test] @@ -98,6 +104,80 @@ namespace MonoTests.System.Diagnostics Assert.IsTrue (s.ShouldTrace (TraceEventType.Resume), "#9"); Assert.IsTrue (s.ShouldTrace (TraceEventType.Transfer), "#10"); } + + + [SetUp] + public void InitalizeSourceSwitchTest() + { + // Initializing the TraceSource instance + traceSource = new TraceSource ("LoggingTraceSource"); + traceSource.Listeners.Remove("Default"); + traceSource.Switch = new SourceSwitch ("MySwitch"); + + // Initializing the TraceListener instance + txtTraceListener = new TestTextWriterTraceListener (Console.Out); + traceSource.Listeners.Add (txtTraceListener); + } + + [Test] + public void setSwitchToCritical() + { + traceSource.Switch.Level = SourceLevels.Critical; + LogAllTraceLevels (); + // Switch.Level is Critical so it should log Critical + Assert.AreEqual (1, txtTraceListener.TotalMessageCount); + Assert.AreEqual (1, txtTraceListener.CritialMessageCount); + } + + [Test] + public void setSwitchToError() + { + traceSource.Switch.Level = SourceLevels.Error; + LogAllTraceLevels (); + // Switch.Level is Error so it should log Critical, Error + Assert.AreEqual (2, txtTraceListener.TotalMessageCount); + Assert.AreEqual (1, txtTraceListener.ErrorMessageCount); + } + + [Test] + public void setSwitchToWarning() + { + traceSource.Switch.Level = SourceLevels.Warning; + LogAllTraceLevels (); + // Switch.Level is Warning so it should log Critical, Error, Warning + Assert.AreEqual (3, txtTraceListener.TotalMessageCount); + Assert.AreEqual (1, txtTraceListener.WarningMessageCount); + } + + [Test] + public void setSwitchToInfo() + { + traceSource.Switch.Level = SourceLevels.Information; + LogAllTraceLevels (); + // Switch.Level is Information so it should log Critical, Error, Warning, Information + Assert.AreEqual (4, txtTraceListener.TotalMessageCount); + Assert.AreEqual (1, txtTraceListener.InfoMessageCount); + } + + [Test] + public void setSwitchToVerbose() + { + traceSource.Switch.Level = SourceLevels.Verbose; + LogAllTraceLevels (); + // Switch.Level is Verbose so it should log Critical, Error, Warning, Information, Verbose + Assert.AreEqual (5, txtTraceListener.TotalMessageCount); + Assert.AreEqual (1, txtTraceListener.VerboseMessageCount); + } + + void LogAllTraceLevels () + { + traceSource.TraceEvent (TraceEventType.Critical, 123, "Critical Level message."); + traceSource.TraceEvent (TraceEventType.Error, 123, "Error Level message."); + traceSource.TraceEvent (TraceEventType.Warning, 123, "Warning Level message."); + traceSource.TraceEvent (TraceEventType.Information, 123, "Information Level message."); + traceSource.TraceEvent (TraceEventType.Verbose, 123, "Verbose Level message."); + traceSource.Flush (); + } } } diff --git a/mcs/class/System/Test/System.Diagnostics/SwitchesTest.cs b/mcs/class/System/Test/System.Diagnostics/SwitchesTest.cs index c21a1ca524..4c52cb109a 100644 --- a/mcs/class/System/Test/System.Diagnostics/SwitchesTest.cs +++ b/mcs/class/System/Test/System.Diagnostics/SwitchesTest.cs @@ -80,6 +80,12 @@ namespace MonoTests.System.Diagnostics { } } + class TestNullSwitch : Switch { + public TestNullSwitch () : base (null, null) + { + } + } + [TestFixture] public class SwitchesTest { @@ -184,8 +190,16 @@ namespace MonoTests.System.Diagnostics { BooleanSwitch s = new BooleanSwitch ("test", "", "hoge"); Assert.IsTrue (!s.Enabled); } + + [Test] + public void NullSwitchHasEmptyDisplayNameAndDescription () + { + var s = new TestNullSwitch (); + Assert.IsEmpty (s.DisplayName); + Assert.IsEmpty (s.Description); + } #endif } } -#endif \ No newline at end of file +#endif diff --git a/mcs/class/System/Test/System.Diagnostics/TextWriterTraceListenerHelper.cs b/mcs/class/System/Test/System.Diagnostics/TextWriterTraceListenerHelper.cs new file mode 100644 index 0000000000..248e2ee081 --- /dev/null +++ b/mcs/class/System/Test/System.Diagnostics/TextWriterTraceListenerHelper.cs @@ -0,0 +1,88 @@ +// TextWriterTraceListenerHelper.cs - +// Test Helper for System.Diagnostics/SourceSwitchTest.cs + +// +// Author: +// Ramtin Raji Kermani +// +// Copyright (C) 2006 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. +// + +#if !MOBILE + +using System; +using System.IO; +using System.Diagnostics; + +namespace MonoTests.System.Diagnostics +{ + public class TestTextWriterTraceListener: TextWriterTraceListener + { + public int TotalMessageCount { set; get;} + public int CritialMessageCount { get; set;} + public int ErrorMessageCount { get; set;} + public int WarningMessageCount { get; set;} + public int InfoMessageCount { get; set;} + public int VerboseMessageCount { set; get;} + + public TestTextWriterTraceListener(TextWriter textWriter): base(textWriter) + { + Console.WriteLine ("TextWriterTraceListener is instantiated."); + } + + + public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message) + { + base.TraceEvent (eventCache, source, eventType, id, message); + TotalMessageCount++; + + switch (eventType) { + case TraceEventType.Critical: + CritialMessageCount++; break; + case TraceEventType.Error: + ErrorMessageCount++; break; + case TraceEventType.Warning: + WarningMessageCount++; break; + case TraceEventType.Information: + InfoMessageCount++; break; + case TraceEventType.Verbose: + VerboseMessageCount++; break; + default: + break; + } + } + + public void clearMessageCounters() + { + TotalMessageCount = 0; + CritialMessageCount = 0; + WarningMessageCount = 0; + ErrorMessageCount = 0; + InfoMessageCount = 0; + VerboseMessageCount = 0; + } + + } +} + +#endif \ No newline at end of file diff --git a/mcs/class/System/Test/System.Net.Sockets/TcpClientCas.cs b/mcs/class/System/Test/System.Net.Sockets/TcpClientCas.cs index 9b2577c41e..e245fcd5b0 100644 --- a/mcs/class/System/Test/System.Net.Sockets/TcpClientCas.cs +++ b/mcs/class/System/Test/System.Net.Sockets/TcpClientCas.cs @@ -29,7 +29,6 @@ namespace MonoCasTests.System.Net.Sockets { static ManualResetEvent reset; private string message; - private string uri = "http://www.google.com"; [TestFixtureSetUp] public void FixtureSetUp () diff --git a/mcs/class/System/Test/System.Net.Sockets/UdpClientTest.cs b/mcs/class/System/Test/System.Net.Sockets/UdpClientTest.cs index 9b2453bd6f..51c3ac795b 100644 --- a/mcs/class/System/Test/System.Net.Sockets/UdpClientTest.cs +++ b/mcs/class/System/Test/System.Net.Sockets/UdpClientTest.cs @@ -936,7 +936,7 @@ namespace MonoTests.System.Net.Sockets { try { client = new UdpClient (port); break; - } catch (Exception ex) { + } catch (Exception) { if (i == 5) throw; } diff --git a/mcs/class/System/Test/System.Net.WebSockets/ClientWebSocketTest.cs b/mcs/class/System/Test/System.Net.WebSockets/ClientWebSocketTest.cs index e193a5f530..389c1e3c64 100644 --- a/mcs/class/System/Test/System.Net.WebSockets/ClientWebSocketTest.cs +++ b/mcs/class/System/Test/System.Net.WebSockets/ClientWebSocketTest.cs @@ -49,7 +49,10 @@ namespace MonoTests.System.Net.WebSockets [Test] public void ServerHandshakeReturnCrapStatusCodeTest () { + // On purpose, + #pragma warning disable 4014 HandleHttpRequestAsync ((req, resp) => resp.StatusCode = 418); + #pragma warning restore 4014 try { Assert.IsTrue (socket.ConnectAsync (new Uri ("ws://localhost:" + Port), CancellationToken.None).Wait (5000)); } catch (AggregateException e) { @@ -62,10 +65,12 @@ namespace MonoTests.System.Net.WebSockets [Test] public void ServerHandshakeReturnWrongUpgradeHeader () { + #pragma warning disable 4014 HandleHttpRequestAsync ((req, resp) => { resp.StatusCode = 101; resp.Headers["Upgrade"] = "gtfo"; }); + #pragma warning restore 4014 try { Assert.IsTrue (socket.ConnectAsync (new Uri ("ws://localhost:" + Port), CancellationToken.None).Wait (5000)); } catch (AggregateException e) { @@ -78,12 +83,14 @@ namespace MonoTests.System.Net.WebSockets [Test] public void ServerHandshakeReturnWrongConnectionHeader () { + #pragma warning disable 4014 HandleHttpRequestAsync ((req, resp) => { resp.StatusCode = 101; resp.Headers["Upgrade"] = "websocket"; // Mono http request doesn't like the forcing, test still valid since the default connection header value is empty //ForceSetHeader (resp.Headers, "Connection", "Foo"); }); + #pragma warning restore 4014 try { Assert.IsTrue (socket.ConnectAsync (new Uri ("ws://localhost:" + Port), CancellationToken.None).Wait (5000)); } catch (AggregateException e) { @@ -94,6 +101,7 @@ namespace MonoTests.System.Net.WebSockets } [Test] + [Ignore ("See bug #24340")] public void EchoTest () { const string Payload = "This is a websocket test"; @@ -118,6 +126,7 @@ namespace MonoTests.System.Net.WebSockets } [Test] + [Ignore ("See bug #24340")] public void CloseOutputAsyncTest () { Assert.IsTrue (socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (5000)); diff --git a/mcs/class/System/Test/System.Net/DnsCas.cs b/mcs/class/System/Test/System.Net/DnsCas.cs index f362e8291e..b532428fd5 100644 --- a/mcs/class/System/Test/System.Net/DnsCas.cs +++ b/mcs/class/System/Test/System.Net/DnsCas.cs @@ -30,14 +30,13 @@ namespace MonoCasTests.System.Net { static ManualResetEvent reset; private string message; private string hostname; - private IPAddress ip; [TestFixtureSetUp] public void FixtureSetUp () { reset = new ManualResetEvent (false); hostname = Dns.GetHostName (); - ip = Dns.Resolve (site).AddressList[0]; + var ip = Dns.Resolve (site).AddressList[0]; } [TestFixtureTearDown] diff --git a/mcs/class/System/Test/System.Net/HttpListenerTest.cs b/mcs/class/System/Test/System.Net/HttpListenerTest.cs index 25f7b96a9b..7f3011e2b9 100644 --- a/mcs/class/System/Test/System.Net/HttpListenerTest.cs +++ b/mcs/class/System/Test/System.Net/HttpListenerTest.cs @@ -36,6 +36,14 @@ using NUnit.Framework; namespace MonoTests.System.Net { [TestFixture] public class HttpListenerTest { + + int port; + + [SetUp] + public void SetUp () { + port = new Random ().Next (7777, 8000); + } + [Test] public void DefaultProperties () { @@ -115,7 +123,7 @@ namespace MonoTests.System.Net { socket.Listen(1); } } - catch(Exception ex) { + catch(Exception) { //Can be AccessDeniedException(ports 80/443 need root access) or //SocketException because other application is listening return false; @@ -152,10 +160,12 @@ namespace MonoTests.System.Net { [Test] public void TwoListeners_SameAddress () { + if (!CanOpenPort (port)) + Assert.Ignore ("port"); HttpListener listener1 = new HttpListener (); - listener1.Prefixes.Add ("http://127.0.0.1:7777/"); + listener1.Prefixes.Add ("http://127.0.0.1:" + port + "/"); HttpListener listener2 = new HttpListener (); - listener2.Prefixes.Add ("http://127.0.0.1:7777/hola/"); + listener2.Prefixes.Add ("http://127.0.0.1:" + port + "/hola/"); listener1.Start (); listener2.Start (); } @@ -164,10 +174,12 @@ namespace MonoTests.System.Net { [ExpectedException (typeof (HttpListenerException))] public void TwoListeners_SameURL () { + if (!CanOpenPort (port)) + Assert.Ignore ("port"); HttpListener listener1 = new HttpListener (); - listener1.Prefixes.Add ("http://127.0.0.1:7777/hola/"); + listener1.Prefixes.Add ("http://127.0.0.1:" + port + "/hola/"); HttpListener listener2 = new HttpListener (); - listener2.Prefixes.Add ("http://127.0.0.1:7777/hola/"); + listener2.Prefixes.Add ("http://127.0.0.1:" + port + "/hola/"); listener1.Start (); listener2.Start (); } @@ -176,8 +188,10 @@ namespace MonoTests.System.Net { [ExpectedException (typeof (HttpListenerException))] public void MultipleSlashes () { + if (!CanOpenPort (port)) + Assert.Ignore ("port"); HttpListener listener = new HttpListener (); - listener.Prefixes.Add ("http://localhost:7777/hola////"); + listener.Prefixes.Add ("http://localhost:" + port + "/hola////"); // this one throws on Start(), not when adding it. listener.Start (); } @@ -186,8 +200,10 @@ namespace MonoTests.System.Net { [ExpectedException (typeof (HttpListenerException))] public void PercentSign () { + if (!CanOpenPort (port)) + Assert.Ignore ("port"); HttpListener listener = new HttpListener (); - listener.Prefixes.Add ("http://localhost:7777/hola%3E/"); + listener.Prefixes.Add ("http://localhost:" + port + "/hola%3E/"); // this one throws on Start(), not when adding it. listener.Start (); } @@ -202,8 +218,10 @@ namespace MonoTests.System.Net { [Test] public void CloseTwice () { + if (!CanOpenPort (port)) + Assert.Ignore ("port"); HttpListener listener = new HttpListener (); - listener.Prefixes.Add ("http://localhost:7777/hola/"); + listener.Prefixes.Add ("http://localhost:" + port + "/hola/"); listener.Start (); listener.Close (); listener.Close (); @@ -212,8 +230,10 @@ namespace MonoTests.System.Net { [Test] public void StartStopStart () { + if (!CanOpenPort (port)) + Assert.Ignore ("port"); HttpListener listener = new HttpListener (); - listener.Prefixes.Add ("http://localhost:7777/hola/"); + listener.Prefixes.Add ("http://localhost:" + port + "/hola/"); listener.Start (); listener.Stop (); listener.Start (); @@ -223,8 +243,10 @@ namespace MonoTests.System.Net { [Test] public void StartStopDispose () { + if (!CanOpenPort (port)) + Assert.Ignore ("port"); using (HttpListener listener = new HttpListener ()){ - listener.Prefixes.Add ("http://localhost:7777/hola/"); + listener.Prefixes.Add ("http://localhost:" + port + "/hola/"); listener.Start (); listener.Stop (); } @@ -240,8 +262,10 @@ namespace MonoTests.System.Net { [Test] public void AbortTwice () { + if (!CanOpenPort (port)) + Assert.Ignore ("port"); HttpListener listener = new HttpListener (); - listener.Prefixes.Add ("http://localhost:7777/hola/"); + listener.Prefixes.Add ("http://localhost:" + port + "/hola/"); listener.Start (); listener.Abort (); listener.Abort (); diff --git a/mcs/class/System/Test/System.Net/NetworkCredentialTest.cs b/mcs/class/System/Test/System.Net/NetworkCredentialTest.cs index 610b4aca31..dbe3255cd6 100644 --- a/mcs/class/System/Test/System.Net/NetworkCredentialTest.cs +++ b/mcs/class/System/Test/System.Net/NetworkCredentialTest.cs @@ -31,7 +31,7 @@ using System.Net; using NUnit.Framework; -namespace MoonTest.System.Net { +namespace MonoTests.System.Net { [TestFixture] public class NetworkCredentialTest { diff --git a/mcs/class/System/Test/System.Net/WebClientTest.cs b/mcs/class/System/Test/System.Net/WebClientTest.cs index 48722d4551..ef3f681742 100644 --- a/mcs/class/System/Test/System.Net/WebClientTest.cs +++ b/mcs/class/System/Test/System.Net/WebClientTest.cs @@ -2221,6 +2221,28 @@ namespace MonoTests.System.Net webClient.UploadFileAsync (uri, "PUT", tempFile); }); } + + [Test] + public void UploadFileAsyncContentType () + { + var serverUri = "http://localhost:13370/"; + var filename = Path.GetTempFileName (); + + HttpListener listener = new HttpListener (); + listener.Prefixes.Add (serverUri); + listener.Start (); + + using (var client = new WebClient ()) + { + client.UploadFileTaskAsync (new Uri (serverUri), filename); + var request = listener.GetContext ().Request; + + var expected = "multipart/form-data; boundary=------------"; + Assert.AreEqual (expected.Length + 15, request.ContentType.Length); + Assert.AreEqual (expected, request.ContentType.Substring (0, expected.Length)); + } + listener.Close (); + } #endif #if NET_4_0 diff --git a/mcs/class/System/Test/System.Security.Cryptography.X509Certificates/X500DistinguishedNameTest.cs b/mcs/class/System/Test/System.Security.Cryptography.X509Certificates/X500DistinguishedNameTest.cs index 88bd3b1cdd..799152f5bb 100644 --- a/mcs/class/System/Test/System.Security.Cryptography.X509Certificates/X500DistinguishedNameTest.cs +++ b/mcs/class/System/Test/System.Security.Cryptography.X509Certificates/X500DistinguishedNameTest.cs @@ -52,6 +52,7 @@ namespace MonoTests.System.Security.Cryptography.X509Certificates { private static byte[] cert_a_issuer_raw = new byte[] { 0x30, 0x5F, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x17, 0x52, 0x53, 0x41, 0x20, 0x44, 0x61, 0x74, 0x61, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2C, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x31, 0x2E, 0x30, 0x2C, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x13, 0x25, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6F, 0x72, 0x69, 0x74, 0x79 }; +#if false private static byte[] cert_b = { 0x30,0x82,0x03,0x04,0x30,0x82,0x02,0xC4,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x03,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x38,0x04,0x03,0x30,0x51,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x18,0x30,0x16,0x06,0x03,0x55,0x04,0x0A,0x13,0x0F,0x55,0x2E,0x53,0x2E,0x20,0x47,0x6F,0x76,0x65,0x72,0x6E,0x6D,0x65,0x6E,0x74,0x31,0x0C,0x30,0x0A,0x06,0x03,0x55,0x04,0x0B,0x13,0x03,0x44,0x6F,0x44,0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x41,0x72,0x6D,0x65,0x64,0x20,0x46,0x6F, 0x72,0x63,0x65,0x73,0x20,0x52,0x6F,0x6F,0x74,0x30,0x1E,0x17,0x0D,0x30,0x30,0x31,0x30,0x32,0x35,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x30,0x33,0x30,0x31,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x51,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x18,0x30,0x16,0x06,0x03,0x55,0x04,0x0A,0x13,0x0F,0x55,0x2E,0x53,0x2E,0x20,0x47,0x6F,0x76,0x65,0x72,0x6E,0x6D,0x65,0x6E,0x74,0x31,0x0C,0x30,0x0A,0x06,0x03,0x55,0x04,0x0B,0x13,0x03,0x44,0x6F,0x44,0x31,0x1A,0x30,0x18, 0x06,0x03,0x55,0x04,0x03,0x13,0x11,0x41,0x72,0x6D,0x65,0x64,0x20,0x46,0x6F,0x72,0x63,0x65,0x73,0x20,0x52,0x6F,0x6F,0x74,0x30,0x82,0x01,0xB6,0x30,0x82,0x01,0x2B,0x06,0x07,0x2A,0x86,0x48,0xCE,0x38,0x04,0x01,0x30,0x82,0x01,0x1E,0x02,0x81,0x81,0x00,0x90,0x89,0x3E,0x18,0x1B,0xFE,0xA3,0x1D,0x16,0x89,0x00,0xB4,0xD5,0x40,0x82,0x4C,0x2E,0xEC,0x3D,0x66,0x0D,0x0D,0xB9,0x17,0x40,0x6E,0x3A,0x5C,0x03,0x7B,0x1B,0x93,0x28,0x0C,0xEF,0xB9,0x97,0xE3,0xA1,0xEB,0xE2,0xA3,0x7C,0x61,0xDD,0x6F,0xD5,0xAD,0x15,0x69,0x00, @@ -60,6 +61,7 @@ namespace MonoTests.System.Security.Cryptography.X509Certificates { 0x54,0x4B,0xC0,0xA8,0x40,0xEF,0x71,0xE8,0x56,0x6B,0xA2,0x29,0xCB,0x1E,0x09,0x7D,0x27,0x39,0x91,0x3B,0x20,0x4F,0x98,0x39,0xE8,0x39,0xCA,0x98,0xC5,0xAF,0x54,0x03,0x81,0x84,0x00,0x02,0x81,0x80,0x54,0xA8,0x88,0xB5,0x8F,0x01,0x56,0xCE,0x18,0x8F,0xA6,0xD6,0x7C,0x29,0x29,0x75,0x45,0xE8,0x31,0xA4,0x07,0x17,0xED,0x1E,0x5D,0xB2,0x7B,0xBB,0xCE,0x3C,0x97,0x67,0x1E,0x88,0x0A,0xFE,0x7D,0x00,0x22,0x27,0x1D,0x66,0xEE,0xF6,0x1B,0xB6,0x95,0x7F,0x5A,0xFF,0x06,0x34,0x02,0x43,0xC3,0x83,0xC4,0x66,0x2C,0xA1,0x05,0x0E, 0x68,0xB3,0xCA,0xDC,0xD3,0xF9,0x0C,0xC0,0x66,0xDF,0x85,0x84,0x4B,0x20,0x5D,0x41,0xAC,0xC0,0xEC,0x37,0x92,0x0E,0x97,0x19,0xBF,0x53,0x35,0x63,0x27,0x18,0x33,0x35,0x42,0x4D,0xF0,0x2D,0x6D,0xA7,0xA4,0x98,0xAA,0x57,0xF3,0xD2,0xB8,0x6E,0x4E,0x8F,0xFF,0xBE,0x6F,0x4E,0x0F,0x0B,0x44,0x24,0xEE,0xDF,0x4C,0x22,0x5B,0x44,0x98,0x94,0xCB,0xB8,0xA3,0x2F,0x30,0x2D,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x9D,0x2D,0x73,0xC3,0xB8,0xE3,0x4D,0x29,0x28,0xC3,0x65,0xBE,0xA9,0x98,0xCB,0xD6,0x8A,0x06,0x68, 0x9C,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x38,0x04,0x03,0x03,0x2F,0x00,0x30,0x2C,0x02,0x14,0x5A,0x1B,0x2D,0x08,0x0E,0xE6,0x99,0x38,0x8F,0xB5,0x09,0xC9,0x89,0x79,0x7E,0x01,0x30,0xBD,0xCE,0xF0,0x02,0x14,0x71,0x7B,0x08,0x51,0x97,0xCE,0x4D,0x1F,0x6A,0x84,0x47,0x3A,0xC0,0xBD,0x13,0x89,0x81,0xB9,0x01,0x97 }; +#endif static public byte[] RFC3280MandatoryAttributeTypesCACert_crt = { 0x30, 0x82, 0x02, 0xC1, 0x30, 0x82, 0x02, 0x2A, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x60, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x40, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0C, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x41, 0x6E, 0x63, 0x68, 0x6F, 0x72, 0x30, 0x1E, 0x17, 0x0D, 0x30, 0x31, 0x30, 0x34, 0x31, 0x39, 0x31, 0x34, 0x35, 0x37, 0x32, 0x30, 0x5A, 0x17, 0x0D, 0x31, 0x31, 0x30, 0x34, 0x31, 0x39, 0x31, 0x34, 0x35, 0x37, 0x32, 0x30, 0x5A, 0x30, 0x81, 0x8E, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1A, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x13, 0x11, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0A, 0x09, 0x92, 0x26, 0x89, 0x93, 0xF2, 0x2C, 0x64, 0x01, 0x19, 0x16, 0x03, 0x67, 0x6F, 0x76, 0x31, 0x20, 0x30, 0x1E, 0x06, 0x0A, 0x09, @@ -82,13 +84,13 @@ namespace MonoTests.System.Security.Cryptography.X509Certificates { static public AsnEncodedData emptyData = new AsnEncodedData (new byte[0]); private X509Certificate2 x509a; - private X509Certificate2 x509b; + //private X509Certificate2 x509b; [TestFixtureSetUp] public void FixtureSetUp () { x509a = new X509Certificate2 (cert_a); - x509b = new X509Certificate2 (cert_b); + //x509b = new X509Certificate2 (cert_b); } private void Empty (X500DistinguishedName dn) diff --git a/mcs/class/System/Test/System.Security.Cryptography.X509Certificates/X509ChainTest.cs b/mcs/class/System/Test/System.Security.Cryptography.X509Certificates/X509ChainTest.cs index 9439f666cc..0ef6418bc1 100644 --- a/mcs/class/System/Test/System.Security.Cryptography.X509Certificates/X509ChainTest.cs +++ b/mcs/class/System/Test/System.Security.Cryptography.X509Certificates/X509ChainTest.cs @@ -41,7 +41,7 @@ namespace MonoTests.System.Security.Cryptography.X509Certificates { [TestFixture] public class X509ChainTest { - private X509Certificate2Collection empty; + //private X509Certificate2Collection empty; private X509Certificate2Collection collection; private X509Certificate2 cert_empty; @@ -56,7 +56,7 @@ namespace MonoTests.System.Security.Cryptography.X509Certificates { cert1 = new X509Certificate2 (X509Certificate2Test.farscape_pfx, "farscape", X509KeyStorageFlags.Exportable); cert2 = new X509Certificate2 (Encoding.ASCII.GetBytes (X509Certificate2Test.base64_cert)); - empty = new X509Certificate2Collection (); + //empty = new X509Certificate2Collection (); collection = new X509Certificate2Collection (); collection.Add (cert1); collection.Add (cert2); diff --git a/mcs/class/System/Test/System.Text.RegularExpressions/RegexReplaceTests.cs b/mcs/class/System/Test/System.Text.RegularExpressions/RegexReplaceTests.cs index 5d30f5d7ed..55dd1e6d05 100644 --- a/mcs/class/System/Test/System.Text.RegularExpressions/RegexReplaceTests.cs +++ b/mcs/class/System/Test/System.Text.RegularExpressions/RegexReplaceTests.cs @@ -22,7 +22,7 @@ namespace MonoTests.System.Text.RegularExpressions try { result = Regex.Replace (original, pattern, replacement); } - catch (Exception e) { + catch (Exception) { result = "Error."; } Assert.AreEqual (expected, result, "rr#: {0} ~ s,{1},{2},", diff --git a/mcs/class/System/Test/System.Text.RegularExpressions/RegexResultTests.cs b/mcs/class/System/Test/System.Text.RegularExpressions/RegexResultTests.cs index 1cf18ee74d..4129b75a12 100644 --- a/mcs/class/System/Test/System.Text.RegularExpressions/RegexResultTests.cs +++ b/mcs/class/System/Test/System.Text.RegularExpressions/RegexResultTests.cs @@ -24,7 +24,7 @@ namespace MonoTests.System.Text.RegularExpressions Match match = Regex.Match (original, pattern); result = match.Result (replacement); } - catch (Exception e) { + catch (Exception) { result = "Error."; } Assert.AreEqual (expected, result, "rr#: {0} ~ s,{1},{2},", diff --git a/mcs/class/System/Test/System/UriParserTest.cs b/mcs/class/System/Test/System/UriParserTest.cs index 79111f90fc..0373ef20c4 100644 --- a/mcs/class/System/Test/System/UriParserTest.cs +++ b/mcs/class/System/Test/System/UriParserTest.cs @@ -217,28 +217,28 @@ namespace MonoTests.System { public void GetComponents_Ftp2 () { UnitTestUriParser p = new UnitTestUriParser (); - Assert.AreEqual ("ftp", p._GetComponents (ftp, UriComponents.Scheme, UriFormat.Unescaped), "ftp.Scheme"); - Assert.AreEqual ("username:password", p._GetComponents (ftp, UriComponents.UserInfo, UriFormat.Unescaped), "ftp.UserInfo"); - Assert.AreEqual ("ftp.go-mono.com", p._GetComponents (ftp, UriComponents.Host, UriFormat.Unescaped), "ftp.Host"); - Assert.AreEqual (String.Empty, p._GetComponents (ftp, UriComponents.Port, UriFormat.Unescaped), "ftp.Port"); - Assert.AreEqual ("with some spaces/mono.tgz", p._GetComponents (ftp, UriComponents.Path, UriFormat.Unescaped), "ftp.Path"); - Assert.AreEqual ("with%20some%20spaces/mono.tgz", p._GetComponents (ftp, UriComponents.Path, UriFormat.UriEscaped), "ftp.Path-UriEscaped"); - Assert.AreEqual ("with some spaces/mono.tgz", p._GetComponents (ftp, UriComponents.Path, UriFormat.SafeUnescaped), "ftp.Path-SafeUnescaped"); - Assert.AreEqual (String.Empty, p._GetComponents (ftp, UriComponents.Query, UriFormat.Unescaped), "ftp.Query"); - Assert.AreEqual (String.Empty, p._GetComponents (ftp, UriComponents.Fragment, UriFormat.Unescaped), "ftp.Fragment"); - Assert.AreEqual ("21", p._GetComponents (ftp, UriComponents.StrongPort, UriFormat.Unescaped), "ftp.StrongPort"); - Assert.AreEqual (String.Empty, p._GetComponents (ftp, UriComponents.KeepDelimiter, UriFormat.Unescaped), "http.KeepDelimiter"); - Assert.AreEqual ("ftp.go-mono.com:21", p._GetComponents (ftp, UriComponents.HostAndPort, UriFormat.Unescaped), "http.HostAndPort"); - Assert.AreEqual ("username:password@ftp.go-mono.com:21", p._GetComponents (ftp, UriComponents.StrongAuthority, UriFormat.Unescaped), "http.StrongAuthority"); - Assert.AreEqual ("ftp://username:password@ftp.go-mono.com/with some spaces/mono.tgz", p._GetComponents (ftp, UriComponents.AbsoluteUri, UriFormat.Unescaped), "http.AbsoluteUri"); - Assert.AreEqual ("/with some spaces/mono.tgz", p._GetComponents (ftp, UriComponents.PathAndQuery, UriFormat.Unescaped), "http.PathAndQuery"); - Assert.AreEqual ("ftp://ftp.go-mono.com/with some spaces/mono.tgz", p._GetComponents (ftp, UriComponents.HttpRequestUrl, UriFormat.Unescaped), "http.HttpRequestUrl"); - Assert.AreEqual ("ftp://ftp.go-mono.com", p._GetComponents (ftp, UriComponents.SchemeAndServer, UriFormat.Unescaped), "http.SchemeAndServer"); - Assert.AreEqual ("ftp://username:password@ftp.go-mono.com/with some spaces/mono.tgz", p._GetComponents (ftp, UriComponents.SerializationInfoString, UriFormat.Unescaped), "http.SerializationInfoString"); + Assert.AreEqual ("ftp", p._GetComponents (ftp2, UriComponents.Scheme, UriFormat.Unescaped), "ftp.Scheme"); + Assert.AreEqual ("username:password", p._GetComponents (ftp2, UriComponents.UserInfo, UriFormat.Unescaped), "ftp.UserInfo"); + Assert.AreEqual ("ftp.go-mono.com", p._GetComponents (ftp2, UriComponents.Host, UriFormat.Unescaped), "ftp.Host"); + Assert.AreEqual (String.Empty, p._GetComponents (ftp2, UriComponents.Port, UriFormat.Unescaped), "ftp.Port"); + Assert.AreEqual ("with some spaces/mono.tgz", p._GetComponents (ftp2, UriComponents.Path, UriFormat.Unescaped), "ftp.Path"); + Assert.AreEqual ("with%20some%20spaces/mono.tgz", p._GetComponents (ftp2, UriComponents.Path, UriFormat.UriEscaped), "ftp.Path-UriEscaped"); + Assert.AreEqual ("with some spaces/mono.tgz", p._GetComponents (ftp2, UriComponents.Path, UriFormat.SafeUnescaped), "ftp.Path-SafeUnescaped"); + Assert.AreEqual (String.Empty, p._GetComponents (ftp2, UriComponents.Query, UriFormat.Unescaped), "ftp.Query"); + Assert.AreEqual (String.Empty, p._GetComponents (ftp2, UriComponents.Fragment, UriFormat.Unescaped), "ftp.Fragment"); + Assert.AreEqual ("21", p._GetComponents (ftp2, UriComponents.StrongPort, UriFormat.Unescaped), "ftp.StrongPort"); + Assert.AreEqual (String.Empty, p._GetComponents (ftp2, UriComponents.KeepDelimiter, UriFormat.Unescaped), "http.KeepDelimiter"); + Assert.AreEqual ("ftp.go-mono.com:21", p._GetComponents (ftp2, UriComponents.HostAndPort, UriFormat.Unescaped), "http.HostAndPort"); + Assert.AreEqual ("username:password@ftp.go-mono.com:21", p._GetComponents (ftp2, UriComponents.StrongAuthority, UriFormat.Unescaped), "http.StrongAuthority"); + Assert.AreEqual ("ftp://username:password@ftp.go-mono.com/with some spaces/mono.tgz", p._GetComponents (ftp2, UriComponents.AbsoluteUri, UriFormat.Unescaped), "http.AbsoluteUri"); + Assert.AreEqual ("/with some spaces/mono.tgz", p._GetComponents (ftp2, UriComponents.PathAndQuery, UriFormat.Unescaped), "http.PathAndQuery"); + Assert.AreEqual ("ftp://ftp.go-mono.com/with some spaces/mono.tgz", p._GetComponents (ftp2, UriComponents.HttpRequestUrl, UriFormat.Unescaped), "http.HttpRequestUrl"); + Assert.AreEqual ("ftp://ftp.go-mono.com", p._GetComponents (ftp2, UriComponents.SchemeAndServer, UriFormat.Unescaped), "http.SchemeAndServer"); + Assert.AreEqual ("ftp://username:password@ftp.go-mono.com/with some spaces/mono.tgz", p._GetComponents (ftp2, UriComponents.SerializationInfoString, UriFormat.Unescaped), "http.SerializationInfoString"); Assert.AreSame (p, p._OnNewUri (), "OnNewUri"); // strange mixup - Assert.AreEqual ("ftp://username:password@", p._GetComponents (ftp, UriComponents.Scheme | UriComponents.UserInfo, UriFormat.Unescaped), "ftp.Scheme+UserInfo"); - Assert.AreEqual (":21/with some spaces/mono.tgz", p._GetComponents (ftp, UriComponents.Path | UriComponents.StrongPort, UriFormat.Unescaped), "ftp.Path+StrongPort"); + Assert.AreEqual ("ftp://username:password@", p._GetComponents (ftp2, UriComponents.Scheme | UriComponents.UserInfo, UriFormat.Unescaped), "ftp.Scheme+UserInfo"); + Assert.AreEqual (":21/with some spaces/mono.tgz", p._GetComponents (ftp2, UriComponents.Path | UriComponents.StrongPort, UriFormat.Unescaped), "ftp.Path+StrongPort"); } // Test case for Xamarin#17665 diff --git a/mcs/class/System/Test/System/UriTest.cs b/mcs/class/System/Test/System/UriTest.cs index f0a67b7a7c..fa76c2a67d 100644 --- a/mcs/class/System/Test/System/UriTest.cs +++ b/mcs/class/System/Test/System/UriTest.cs @@ -1951,6 +1951,38 @@ namespace MonoTests.System Assert.IsTrue (Uri.TryCreate (mainUri, uriPath, out result), "#1"); Assert.AreEqual ("http://www.imdb.com/title/tt0106521", result.ToString (), "#2"); } + + [Test] + public void GetSerializationInfoStringOnRelativeUri () + { + var uri = new Uri ("/relative/path", UriKind.Relative); + var result = uri.GetComponents (UriComponents.SerializationInfoString, UriFormat.UriEscaped); + + Assert.AreEqual (uri.OriginalString, result); + } + + [Test] + [ExpectedException (typeof (ArgumentOutOfRangeException))] + public void GetSerializationInfoStringException () + { + var uri = new Uri ("/relative/path", UriKind.Relative); + uri.GetComponents (UriComponents.SerializationInfoString | UriComponents.Host, UriFormat.UriEscaped); + } + + [Test] + public void UserInfo_EscapedLetter () + { + var uri = new Uri ("https://first%61second@host"); + Assert.AreEqual ("firstasecond", uri.UserInfo); + } + + [Test] + public void UserInfo_EscapedAt () + { + var userinfo = "first%40second"; + var uri = new Uri ("https://" + userinfo + "@host"); + Assert.AreEqual (userinfo, uri.UserInfo); + } } // Tests non default IriParsing @@ -1961,7 +1993,7 @@ namespace MonoTests.System private bool originalIriParsing; [TestFixtureSetUp] - public void GetReady () + public void GetReady2 () { isWin32 = (Path.DirectorySeparatorChar == '\\'); diff --git a/mcs/class/System/mobile_System.dll.sources b/mcs/class/System/mobile_System.dll.sources index b8a2698a10..6a014b9133 100644 --- a/mcs/class/System/mobile_System.dll.sources +++ b/mcs/class/System/mobile_System.dll.sources @@ -318,6 +318,7 @@ System.IO.Compression/CompressionLevel.cs System.IO.Compression/CompressionMode.cs System.IO.Compression/DeflateStream.cs System.IO.Compression/GZipStream.cs +System.IO/InternalBufferOverflowException.cs System.IO/InvalidDataException.cs System.IO/MonoSyncFileStream.cs System.Net.Cache/HttpCacheAgeControl.cs diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackage.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackage.cs index 54df0eb5e8..2818cd5e45 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackage.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackage.cs @@ -25,9 +25,11 @@ using System; +using System.IO; +using System.IO.Packaging; using System.Collections.Generic; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { public class FakePackage : Package { Dictionary Parts { get; set; } @@ -77,4 +79,4 @@ namespace System.IO.Packaging.Tests { return p; } } -} \ No newline at end of file +} diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackagePart.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackagePart.cs index 9a7871c6ed..1ca0bb20f0 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackagePart.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackagePart.cs @@ -24,9 +24,11 @@ // using System; +using System.IO; +using System.IO.Packaging; using System.Collections.Generic; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { class FakePackagePart : PackagePart { diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackagePartTests.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackagePartTests.cs index 731aed62ff..216a1686f6 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackagePartTests.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackagePartTests.cs @@ -26,9 +26,12 @@ using System; using System.Linq; using System.Collections.Generic; +using System.IO; +using System.IO.Packaging; +using System.Xml; using NUnit.Framework; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { [TestFixture] public class FakePackagePartTests : TestBase { @@ -146,7 +149,7 @@ namespace System.IO.Packaging.Tests { } [Test] - [ExpectedException (typeof (Xml.XmlException))] + [ExpectedException (typeof (XmlException))] public void CreateDupeRelationship () { part.CreateRelationship (uris [1], TargetMode.External, "blah", "asda"); @@ -154,7 +157,7 @@ namespace System.IO.Packaging.Tests { } [Test] - [ExpectedException (typeof (Xml.XmlException))] + [ExpectedException (typeof (XmlException))] public void CreateDupeRelationshipId () { part.CreateRelationship (uris [1], TargetMode.External, "blah", "asda"); diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackageTests.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackageTests.cs index bd75154292..bfea3c8497 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackageTests.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakePackageTests.cs @@ -26,11 +26,13 @@ using System; using System.Collections.Generic; +using System.IO; +using System.IO.Packaging; using System.Linq; using System.Text; using NUnit.Framework; -namespace System.IO.Packaging.Tests +namespace MonoTests.System.IO.Packaging { [TestFixture] diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakeStream.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakeStream.cs index b095375b17..aafc02e25e 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/FakeStream.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/FakeStream.cs @@ -25,9 +25,10 @@ using System; +using System.IO; using System.Collections.Generic; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { public class FakeStream : MemoryStream { public bool canRead; diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackUriHelperTests.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackUriHelperTests.cs index c5361214f7..d231315a0e 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackUriHelperTests.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackUriHelperTests.cs @@ -8,7 +8,7 @@ using System; using System.IO.Packaging; using NUnit.Framework; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { [TestFixture] public class PackUriHelperTests { diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartFileTests.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartFileTests.cs index 3f2850b602..557e4a98b5 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartFileTests.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartFileTests.cs @@ -3,7 +3,7 @@ using System.IO; using System.IO.Packaging; using NUnit.Framework; -namespace System.IO.Packaging.Tests +namespace MonoTests.System.IO.Packaging { [TestFixture] public class PackagePartFileTests @@ -135,4 +135,4 @@ namespace System.IO.Packaging.Tests } } } -} \ No newline at end of file +} diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartStreamTests.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartStreamTests.cs index 915c2a09a9..1bf6022108 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartStreamTests.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartStreamTests.cs @@ -26,11 +26,13 @@ using System; using System.Collections.Generic; +using System.IO; +using System.IO.Packaging; using System.Linq; using System.Text; using NUnit.Framework; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { [TestFixture] public class PackagePartStreamTests : TestBase { @@ -190,4 +192,4 @@ namespace System.IO.Packaging.Tests { Assert.IsTrue (stream.Length > buffer.Length * 2, "#4"); } } -} \ No newline at end of file +} diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartTest.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartTest.cs index 07015c2017..ad7eb968c3 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartTest.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackagePartTest.cs @@ -26,12 +26,14 @@ using System; using System.Collections.Generic; +using System.IO; +using System.IO.Packaging; using System.Linq; using System.Text; using NUnit.Framework; using System.Xml; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { [TestFixture] public class PackagePartTest : TestBase { diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackageRelationshipTests.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackageRelationshipTests.cs index 8c4b031de9..6ce92d31e5 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackageRelationshipTests.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackageRelationshipTests.cs @@ -28,12 +28,14 @@ using System; using System.Collections.Generic; +using System.IO; +using System.IO.Packaging; using System.Linq; using System.Text; using System.Xml; using NUnit.Framework; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { [TestFixture] public class PackageRelationshipTests : TestBase { diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackageTest.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackageTest.cs index ae7c5945de..933449052f 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/PackageTest.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/PackageTest.cs @@ -26,11 +26,13 @@ using System; using System.Collections.Generic; +using System.IO; +using System.IO.Packaging; using System.Linq; using System.Text; using NUnit.Framework; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { [TestFixture] public class PackageTest : TestBase { @@ -411,8 +413,8 @@ namespace System.IO.Packaging.Tests { [ExpectedException (typeof (FileFormatException))] public void WriteOnlyAccessExists () { - System.IO.File.Create (path).Close (); + File.Create (path).Close (); package = Package.Open (path, FileMode.OpenOrCreate, FileAccess.Write); } } -} \ No newline at end of file +} diff --git a/mcs/class/WindowsBase/Test/System.IO.Packaging/TestBase.cs b/mcs/class/WindowsBase/Test/System.IO.Packaging/TestBase.cs index 6d8b43d057..28afcd4315 100644 --- a/mcs/class/WindowsBase/Test/System.IO.Packaging/TestBase.cs +++ b/mcs/class/WindowsBase/Test/System.IO.Packaging/TestBase.cs @@ -26,11 +26,13 @@ using System; using System.Collections.Generic; +using System.IO; +using System.IO.Packaging; using System.Linq; using System.Text; using NUnit.Framework; -namespace System.IO.Packaging.Tests { +namespace MonoTests.System.IO.Packaging { public abstract class TestBase { protected string contentType = "mime/type"; diff --git a/mcs/class/corlib/System.Globalization/CalendricalCalculations.cs b/mcs/class/corlib/System.Globalization/CalendricalCalculations.cs index 685c0f372f..accba935b6 100644 --- a/mcs/class/corlib/System.Globalization/CalendricalCalculations.cs +++ b/mcs/class/corlib/System.Globalization/CalendricalCalculations.cs @@ -466,6 +466,11 @@ static class CCGregorianCalendar { /// An integer value representing the fixed day number. /// public static int fixed_from_dmy(int day, int month, int year) { + if (month > 12) { + year += CCMath.div_mod (out month, month - 1, 12); + month++; + } + int k = epoch - 1; k += 365 * (year-1); k += CCMath.div(year-1, 4); @@ -944,6 +949,12 @@ static class CCJulianCalendar { /// public static int fixed_from_dmy(int day, int month, int year) { int y = year < 0 ? year+1 : year; + + if (month > 12) { + y += CCMath.div_mod (out month, month - 1, 12); + month++; + } + int k = epoch - 1; k += 365 * (y-1); k += CCMath.div(y-1, 4); @@ -1371,6 +1382,13 @@ static class CCHebrewCalendar { /// An integer value representing the fixed day number. /// public static int fixed_from_dmy(int day, int month, int year) { + var lastMonth = last_month_of_year (year); + while (month > lastMonth) { + year++; + month -= lastMonth; + lastMonth = last_month_of_year (year); + } + int m; int k = epoch-1; k += elapsed_days(year); @@ -1686,6 +1704,11 @@ static class CCHijriCalendar { /// An integer value representing the fixed day number. /// public static int fixed_from_dmy(int day, int month, int year) { + if (month > 12) { + year += CCMath.div_mod (out month, month - 1, 12); + month++; + } + int k = epoch - 1; k += 354 * (year-1); k += CCMath.div(3+11*year, 30); diff --git a/mcs/class/corlib/System.IO/DirectoryInfo.cs b/mcs/class/corlib/System.IO/DirectoryInfo.cs index ce55874351..09ed552f62 100644 --- a/mcs/class/corlib/System.IO/DirectoryInfo.cs +++ b/mcs/class/corlib/System.IO/DirectoryInfo.cs @@ -6,10 +6,12 @@ // Jim Richardson, develop@wtfo-guru.com // Dan Lewis, dihlewis@yahoo.co.uk // Sebastien Pouliot +// Marek Safar // // Copyright (C) 2002 Ximian, Inc. // Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com) +// Copyright (C) 2014 Xamarin, Inc (http://www.xamarin.com) // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -441,25 +443,19 @@ namespace System.IO { throw MonoIO.GetException (Path.GetDirectoryName (path_with_pattern), (MonoIOError) error); try { - if (((rattr & FileAttributes.ReparsePoint) == 0)){ - if ((rattr & FileAttributes.Directory) != 0) - yield return new DirectoryInfo (s); - else - yield return new FileInfo (s); - } - - while ((s = MonoIO.FindNext (handle, out rattr, out error)) != null){ - if ((rattr & FileAttributes.ReparsePoint) != 0) - continue; - if ((rattr & FileAttributes.Directory) != 0) - yield return new DirectoryInfo (s); - else - yield return new FileInfo (s); - + do { + if (((rattr & FileAttributes.ReparsePoint) == 0)){ + if ((rattr & FileAttributes.Directory) != 0) + yield return new DirectoryInfo (s); + else + yield return new FileInfo (s); + } + if (((rattr & FileAttributes.Directory) != 0) && subdirs) foreach (FileSystemInfo child in EnumerateFileSystemInfos (s, searchPattern, searchOption)) yield return child; - } + + } while ((s = MonoIO.FindNext (handle, out rattr, out error)) != null); } finally { MonoIO.FindClose (handle); } diff --git a/mcs/class/corlib/System.Reflection/MonoGenericClass.cs b/mcs/class/corlib/System.Reflection/MonoGenericClass.cs index c053a4bbfc..34c2b84894 100644 --- a/mcs/class/corlib/System.Reflection/MonoGenericClass.cs +++ b/mcs/class/corlib/System.Reflection/MonoGenericClass.cs @@ -495,11 +495,15 @@ namespace System.Reflection public override object [] GetCustomAttributes (bool inherit) { + if (IsCreated) + return generic_type.GetCustomAttributes (inherit); throw new NotSupportedException (); } public override object [] GetCustomAttributes (Type attributeType, bool inherit) { + if (IsCreated) + return generic_type.GetCustomAttributes (attributeType, inherit); throw new NotSupportedException (); } diff --git a/mcs/class/corlib/System.Security.Cryptography/HMAC.cs b/mcs/class/corlib/System.Security.Cryptography/HMAC.cs index e83eb67e69..eb165dc56c 100644 --- a/mcs/class/corlib/System.Security.Cryptography/HMAC.cs +++ b/mcs/class/corlib/System.Security.Cryptography/HMAC.cs @@ -117,6 +117,7 @@ namespace System.Security.Cryptography { protected override void Dispose (bool disposing) { if (!_disposed) { + _disposed = true; base.Dispose (disposing); } } diff --git a/mcs/class/corlib/System.Text/UTF8Encoding.cs b/mcs/class/corlib/System.Text/UTF8Encoding.cs index cdddb802b1..b3a93f1427 100644 --- a/mcs/class/corlib/System.Text/UTF8Encoding.cs +++ b/mcs/class/corlib/System.Text/UTF8Encoding.cs @@ -436,7 +436,7 @@ fail_no_space: private unsafe static int InternalGetCharCount ( byte[] bytes, int index, int count, uint leftOverBits, uint leftOverCount, object provider, - ref DecoderFallbackBuffer fallbackBuffer, ref byte [] bufferArg, bool flush) + ref DecoderFallbackBuffer fallbackBuffer, bool flush) { // Validate the parameters. if (bytes == null) { @@ -453,22 +453,22 @@ fail_no_space: return 0; fixed (byte *bptr = bytes) return InternalGetCharCount (bptr + index, count, - leftOverBits, leftOverCount, provider, ref fallbackBuffer, ref bufferArg, flush); + leftOverBits, leftOverCount, provider, ref fallbackBuffer, flush); } private unsafe static int InternalGetCharCount ( - byte* bytes, int count, uint leftOverBits, + byte* bytes, int byteCount, uint leftOverBits, uint leftOverCount, object provider, - ref DecoderFallbackBuffer fallbackBuffer, ref byte [] bufferArg, bool flush) + ref DecoderFallbackBuffer fallbackBuffer, bool flush) { - int index = 0; + int byteIndex = 0; int length = 0; if (leftOverCount == 0) { - int end = index + count; - for (; index < end; index++, count--) { - if (bytes [index] < 0x80) + int end = byteIndex + byteCount; + for (; byteIndex < end; byteIndex++, byteCount--) { + if (bytes [byteIndex] < 0x80) length++; else break; @@ -480,9 +480,11 @@ fail_no_space: uint leftBits = leftOverBits; uint leftSoFar = (leftOverCount & (uint)0x0F); uint leftSize = ((leftOverCount >> 4) & (uint)0x0F); - while (count > 0) { - ch = (uint)(bytes[index++]); - --count; + + int byteEnd = byteIndex + byteCount; + for(; byteIndex < byteEnd; byteIndex++) { + // Fetch the next character from the byte buffer. + ch = (uint)(bytes[byteIndex]); if (leftSize == 0) { // Process a UTF-8 start character. if (ch < (uint)0x0080) { @@ -515,7 +517,7 @@ fail_no_space: leftSize = 6; } else { // Invalid UTF-8 start character. - length += Fallback (provider, ref fallbackBuffer, ref bufferArg, bytes, index - 1, 1); + length += Fallback (provider, ref fallbackBuffer, bytes, byteIndex, 1); } } else { // Process an extra byte in a multi-byte sequence. @@ -544,34 +546,34 @@ fail_no_space: break; } if (overlong) { - length += Fallback (provider, ref fallbackBuffer, ref bufferArg, bytes, index - leftSoFar, leftSoFar); + length += Fallback (provider, ref fallbackBuffer, bytes, byteIndex - leftSoFar, leftSoFar); + --byteIndex; //process byte again } else if ((leftBits & 0xF800) == 0xD800) { // UTF-8 doesn't use surrogate characters - length += Fallback (provider, ref fallbackBuffer, ref bufferArg, bytes, index - leftSoFar, leftSoFar); + length += Fallback (provider, ref fallbackBuffer, bytes, byteIndex - leftSoFar, leftSoFar); } else ++length; } else if (leftBits < (uint)0x110000) { length += 2; } else { - length += Fallback (provider, ref fallbackBuffer, ref bufferArg, bytes, index - leftSoFar, leftSoFar); + length += Fallback (provider, ref fallbackBuffer, bytes, byteIndex - leftSoFar, leftSoFar); } leftSize = 0; } } else { // Invalid UTF-8 sequence: clear and restart. - length += Fallback (provider, ref fallbackBuffer, ref bufferArg, bytes, index - leftSoFar, leftSoFar); + length += Fallback (provider, ref fallbackBuffer, bytes, byteIndex - leftSoFar, leftSoFar); leftSize = 0; - --index; - ++count; + --byteIndex; } } } if (flush && leftSize != 0) { // We had left-over bytes that didn't make up // a complete UTF-8 character sequence. - length += Fallback (provider, ref fallbackBuffer, ref bufferArg, bytes, index - leftSoFar, leftSoFar); + length += Fallback (provider, ref fallbackBuffer, bytes, byteIndex - leftSoFar, leftSoFar); } // Return the final length to the caller. @@ -579,7 +581,7 @@ fail_no_space: } // for GetCharCount() - static unsafe int Fallback (object provider, ref DecoderFallbackBuffer buffer, ref byte [] bufferArg, byte* bytes, long index, uint size) + static unsafe int Fallback (object provider, ref DecoderFallbackBuffer buffer, byte* bytes, long index, uint size) { if (buffer == null) { DecoderFallback fb = provider as DecoderFallback; @@ -588,20 +590,21 @@ fail_no_space: else buffer = ((Decoder) provider).FallbackBuffer; } - if (bufferArg == null) - bufferArg = new byte [1]; - int ret = 0; - for (int i = 0; i < size; i++) { - bufferArg [0] = bytes [(int) index + i]; - buffer.Fallback (bufferArg, 0); - ret += buffer.Remaining; - buffer.Reset (); - } + + var bufferArg = new byte [size]; + + for (int i = 0; i < size; i++) + bufferArg [i] = bytes [(int) index + i]; + + buffer.Fallback (bufferArg, 0); + int ret = buffer.Remaining; + buffer.Reset (); + return ret; } // for GetChars() - static unsafe void Fallback (object provider, ref DecoderFallbackBuffer buffer, ref byte [] bufferArg, byte* bytes, long byteIndex, uint size, + static unsafe void Fallback (object provider, ref DecoderFallbackBuffer buffer, byte* bytes, long byteIndex, uint size, char* chars, ref int charIndex) { if (buffer == null) { @@ -611,23 +614,23 @@ fail_no_space: else buffer = ((Decoder) provider).FallbackBuffer; } - if (bufferArg == null) - bufferArg = new byte [1]; - for (int i = 0; i < size; i++) { - bufferArg [0] = bytes [byteIndex + i]; - buffer.Fallback (bufferArg, 0); - while (buffer.Remaining > 0) - chars [charIndex++] = buffer.GetNextChar (); - buffer.Reset (); - } + + var bufferArg = new byte [size]; + + for (int i = 0; i < size; i++) + bufferArg [i] = bytes [byteIndex + i]; + + buffer.Fallback (bufferArg, 0); + while (buffer.Remaining > 0) + chars [charIndex++] = buffer.GetNextChar (); + buffer.Reset (); } // Get the number of characters needed to decode a byte buffer. public override int GetCharCount (byte[] bytes, int index, int count) { DecoderFallbackBuffer buf = null; - byte [] bufferArg = null; - return InternalGetCharCount (bytes, index, count, 0, 0, DecoderFallback, ref buf, ref bufferArg, true); + return InternalGetCharCount (bytes, index, count, 0, 0, DecoderFallback, ref buf, true); } [CLSCompliant (false)] @@ -635,8 +638,7 @@ fail_no_space: public unsafe override int GetCharCount (byte* bytes, int count) { DecoderFallbackBuffer buf = null; - byte [] bufferArg = null; - return InternalGetCharCount (bytes, count, 0, 0, DecoderFallback, ref buf, ref bufferArg, true); + return InternalGetCharCount (bytes, count, 0, 0, DecoderFallback, ref buf, true); } // Get the characters that result from decoding a byte buffer. @@ -644,7 +646,7 @@ fail_no_space: byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex, ref uint leftOverBits, ref uint leftOverCount, object provider, - ref DecoderFallbackBuffer fallbackBuffer, ref byte [] bufferArg, bool flush) + ref DecoderFallbackBuffer fallbackBuffer, bool flush) { // Validate the parameters. if (bytes == null) { @@ -668,10 +670,10 @@ fail_no_space: fixed (char* cptr = chars) { if (byteCount == 0 || byteIndex == bytes.Length) - return InternalGetChars (null, 0, cptr + charIndex, chars.Length - charIndex, ref leftOverBits, ref leftOverCount, provider, ref fallbackBuffer, ref bufferArg, flush); + return InternalGetChars (null, 0, cptr + charIndex, chars.Length - charIndex, ref leftOverBits, ref leftOverCount, provider, ref fallbackBuffer, flush); // otherwise... fixed (byte* bptr = bytes) - return InternalGetChars (bptr + byteIndex, byteCount, cptr + charIndex, chars.Length - charIndex, ref leftOverBits, ref leftOverCount, provider, ref fallbackBuffer, ref bufferArg, flush); + return InternalGetChars (bptr + byteIndex, byteCount, cptr + charIndex, chars.Length - charIndex, ref leftOverBits, ref leftOverCount, provider, ref fallbackBuffer, flush); } } @@ -679,7 +681,7 @@ fail_no_space: byte* bytes, int byteCount, char* chars, int charCount, ref uint leftOverBits, ref uint leftOverCount, object provider, - ref DecoderFallbackBuffer fallbackBuffer, ref byte [] bufferArg, bool flush) + ref DecoderFallbackBuffer fallbackBuffer, bool flush) { int charIndex = 0, byteIndex = 0; int length = charCount; @@ -744,7 +746,7 @@ fail_no_space: leftSize = 6; } else { // Invalid UTF-8 start character. - Fallback (provider, ref fallbackBuffer, ref bufferArg, bytes, byteIndex, 1, chars, ref posn); + Fallback (provider, ref fallbackBuffer, bytes, byteIndex, 1, chars, ref posn); } } else { // Process an extra byte in a multi-byte sequence. @@ -773,11 +775,12 @@ fail_no_space: break; } if (overlong) { - Fallback (provider, ref fallbackBuffer, ref bufferArg, bytes, byteIndex - leftSoFar, leftSoFar, chars, ref posn); + Fallback (provider, ref fallbackBuffer, bytes, byteIndex - leftSoFar, leftSoFar, chars, ref posn); + --byteIndex; //process byte again } else if ((leftBits & 0xF800) == 0xD800) { // UTF-8 doesn't use surrogate characters - Fallback (provider, ref fallbackBuffer, ref bufferArg, bytes, byteIndex - leftSoFar, leftSoFar, chars, ref posn); + Fallback (provider, ref fallbackBuffer, bytes, byteIndex - leftSoFar, leftSoFar, chars, ref posn); } else { if (posn >= length) { @@ -797,13 +800,13 @@ fail_no_space: chars[posn++] = (char)((leftBits & (uint)0x3FF) + (uint)0xDC00); } else { - Fallback (provider, ref fallbackBuffer, ref bufferArg, bytes, byteIndex - leftSoFar, leftSoFar, chars, ref posn); + Fallback (provider, ref fallbackBuffer, bytes, byteIndex - leftSoFar, leftSoFar, chars, ref posn); } leftSize = 0; } } else { // Invalid UTF-8 sequence: clear and restart. - Fallback (provider, ref fallbackBuffer, ref bufferArg, bytes, byteIndex - leftSoFar, leftSoFar, chars, ref posn); + Fallback (provider, ref fallbackBuffer, bytes, byteIndex - leftSoFar, leftSoFar, chars, ref posn); leftSize = 0; --byteIndex; } @@ -812,7 +815,7 @@ fail_no_space: if (flush && leftSize != 0) { // We had left-over bytes that didn't make up // a complete UTF-8 character sequence. - Fallback (provider, ref fallbackBuffer, ref bufferArg, bytes, byteIndex - leftSoFar, leftSoFar, chars, ref posn); + Fallback (provider, ref fallbackBuffer, bytes, byteIndex - leftSoFar, leftSoFar, chars, ref posn); } leftOverBits = leftBits; leftOverCount = (leftSoFar | (leftSize << 4)); @@ -828,9 +831,8 @@ fail_no_space: uint leftOverBits = 0; uint leftOverCount = 0; DecoderFallbackBuffer buf = null; - byte [] bufferArg = null; return InternalGetChars (bytes, byteIndex, byteCount, chars, - charIndex, ref leftOverBits, ref leftOverCount, DecoderFallback, ref buf, ref bufferArg, true); + charIndex, ref leftOverBits, ref leftOverCount, DecoderFallback, ref buf, true); } [CLSCompliant (false)] @@ -838,11 +840,10 @@ fail_no_space: public unsafe override int GetChars (byte* bytes, int byteCount, char* chars, int charCount) { DecoderFallbackBuffer buf = null; - byte [] bufferArg = null; uint leftOverBits = 0; uint leftOverCount = 0; return InternalGetChars (bytes, byteCount, chars, - charCount, ref leftOverBits, ref leftOverCount, DecoderFallback, ref buf, ref bufferArg, true); + charCount, ref leftOverBits, ref leftOverCount, DecoderFallback, ref buf, true); } // Get the maximum number of bytes needed to encode a @@ -952,17 +953,15 @@ fail_no_space: public override int GetCharCount (byte[] bytes, int index, int count) { DecoderFallbackBuffer buf = null; - byte [] bufferArg = null; return InternalGetCharCount (bytes, index, count, - leftOverBits, leftOverCount, this, ref buf, ref bufferArg, false); + leftOverBits, leftOverCount, this, ref buf, false); } public override int GetChars (byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) { DecoderFallbackBuffer buf = null; - byte [] bufferArg = null; return InternalGetChars (bytes, byteIndex, byteCount, - chars, charIndex, ref leftOverBits, ref leftOverCount, this, ref buf, ref bufferArg, false); + chars, charIndex, ref leftOverBits, ref leftOverCount, this, ref buf, false); } } // class UTF8Decoder diff --git a/mcs/class/corlib/System.Text/UnicodeEncoding.cs b/mcs/class/corlib/System.Text/UnicodeEncoding.cs index edb57e69ca..48077a2452 100644 --- a/mcs/class/corlib/System.Text/UnicodeEncoding.cs +++ b/mcs/class/corlib/System.Text/UnicodeEncoding.cs @@ -345,7 +345,7 @@ public class UnicodeEncoding : Encoding if (charCount < 0) { throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_NonNegative")); } - return charCount * 2; + return charCount * 2 + 2; } // Get the maximum number of characters needed to decode a @@ -356,7 +356,7 @@ public class UnicodeEncoding : Encoding throw new ArgumentOutOfRangeException ("byteCount", _("ArgRange_NonNegative")); } - return byteCount / 2; + return (byteCount + 1) / 2 + 1; } // Get a Unicode-specific decoder that is attached to this instance. diff --git a/mcs/class/corlib/System.Threading.Tasks/Task.cs b/mcs/class/corlib/System.Threading.Tasks/Task.cs index 1f8165a0d4..4f4abd33e9 100644 --- a/mcs/class/corlib/System.Threading.Tasks/Task.cs +++ b/mcs/class/corlib/System.Threading.Tasks/Task.cs @@ -635,7 +635,7 @@ namespace System.Threading.Tasks #region Cancel and Wait related method - internal void CancelReal () + internal void CancelReal (bool notifyParent = false) { Status = TaskStatus.Canceled; @@ -643,6 +643,9 @@ namespace System.Threading.Tasks wait_handle.Set (); ProcessCompleteDelegates (); + + if (notifyParent && parent != null && NotifyParentOnFinish ()) + parent = null; } void HandleGenericException (Exception e) diff --git a/mcs/class/corlib/System.Threading.Tasks/TaskContinuation.cs b/mcs/class/corlib/System.Threading.Tasks/TaskContinuation.cs index 2a0547850b..8ede25eebe 100644 --- a/mcs/class/corlib/System.Threading.Tasks/TaskContinuation.cs +++ b/mcs/class/corlib/System.Threading.Tasks/TaskContinuation.cs @@ -94,7 +94,7 @@ namespace System.Threading.Tasks public void Execute () { if (!ContinuationStatusCheck (continuationOptions)) { - task.CancelReal (); + task.CancelReal (notifyParent : true); task.Dispose (); return; } diff --git a/mcs/class/corlib/System/AppDomain.cs b/mcs/class/corlib/System/AppDomain.cs index 5ebd4db216..f04fe2a006 100644 --- a/mcs/class/corlib/System/AppDomain.cs +++ b/mcs/class/corlib/System/AppDomain.cs @@ -1354,6 +1354,11 @@ namespace System { DomainUnload(this, null); } + internal void DoUnhandledException (UnhandledExceptionEventArgs args) { + if (UnhandledException != null) + UnhandledException (this, args); + } + internal byte[] GetMarshalledDomainObjRef () { ObjRef oref = RemotingServices.Marshal (AppDomain.CurrentDomain, null, typeof (AppDomain)); @@ -1405,6 +1410,10 @@ namespace System { [method: SecurityPermission (SecurityAction.LinkDemand, ControlAppDomain = true)] public event UnhandledExceptionEventHandler UnhandledException; +#if NET_4_5 + public event EventHandler FirstChanceException; +#endif + #if NET_4_0 [MonoTODO] public bool IsHomogenous { diff --git a/mcs/class/corlib/System/DateTime.cs b/mcs/class/corlib/System/DateTime.cs index 735599680c..8ff4901e4a 100644 --- a/mcs/class/corlib/System/DateTime.cs +++ b/mcs/class/corlib/System/DateTime.cs @@ -107,7 +107,7 @@ namespace System "H:mzzz", "H:m", "H tt", // Specifies AM to disallow '8'. - "H'\u6642'm'\u5206's'\u79D2'", + "H'\u6642'm'\u5206's'\u79D2'" }; // DateTime.Parse date patterns extend ParseExact patterns as follows: @@ -885,6 +885,9 @@ namespace System if (_DoParse (s, firstPart, ParseTimeFormats [j], false, out result, out dto, dfi, styles, true, ref incompleteFormat, ref longYear)) return true; } + + if (_DoParse (s, firstPart, "zzz", false, out result, out dto, dfi, styles, true, ref incompleteFormat, ref longYear)) + return true; } // @@ -1466,6 +1469,25 @@ namespace System if (num_parsed == -1) return false; fractionalSeconds = decimalNumber / Math.Pow(10.0, num_parsed); + + //Parse ISO8601 with an unlimited number of fractional digits. + if (!exact && num == 6 && hour != -1 && minute != -1 && second != -1) { + var total_num_parsed = num_parsed; + while (true) { + valuePos += num_parsed; + decimalNumber = (double) _ParseNumber (s, valuePos, 0, 1, leading_zeros, sloppy_parsing, out num_parsed); + if (num_parsed < 1) { + num_parsed = 0; + break; + } + + total_num_parsed += num_parsed; + if (total_num_parsed > 15) + continue; //not enough precision, ignore additional digits. + + fractionalSeconds += decimalNumber / Math.Pow (10.0, total_num_parsed); + } + } break; case 't': if (!_ParseAmPm (s, valuePos, num > 0 ? 0 : 1, dfi, exact, out num_parsed, ref ampm)) @@ -1722,7 +1744,7 @@ namespace System if (tzsign == -1) { if (result != DateTime.MinValue) { try { - if ((style & DateTimeStyles.AssumeUniversal) != 0) { + if (((style & DateTimeStyles.AssumeUniversal) != 0) || useutc) { dto = new DateTimeOffset (result, TimeSpan.Zero); } else if ((style & DateTimeStyles.AssumeLocal) != 0) { var offset = use_invariant ? diff --git a/mcs/class/corlib/System/Environment.cs b/mcs/class/corlib/System/Environment.cs index 1226062123..21128defd9 100644 --- a/mcs/class/corlib/System/Environment.cs +++ b/mcs/class/corlib/System/Environment.cs @@ -44,7 +44,7 @@ using System.Threading; namespace System { [ComVisible (true)] - public static class Environment { + public static partial class Environment { /* * This is the version number of the corlib-runtime interface. When @@ -475,9 +475,6 @@ namespace System { } #endif - [MethodImplAttribute (MethodImplOptions.InternalCall)] - private extern static string GetWindowsFolderPath (int folder); - /// /// Returns the fully qualified path of the /// folder specified by the "folder" parameter @@ -486,6 +483,12 @@ namespace System { { return GetFolderPath (folder, SpecialFolderOption.None); } + +// for monotouch, not monotouch_runtime +#if !(MONOTOUCH && FULL_AOT_RUNTIME) + [MethodImplAttribute (MethodImplOptions.InternalCall)] + private extern static string GetWindowsFolderPath (int folder); + #if NET_4_0 public #endif @@ -577,38 +580,15 @@ namespace System { // personal == ~ case SpecialFolder.Personal: -#if MONOTOUCH - return Path.Combine (home, "Documents"); -#else return home; -#endif + // use FDO's CONFIG_HOME. This data will be synced across a network like the windows counterpart. case SpecialFolder.ApplicationData: -#if MONOTOUCH - { - string dir = Path.Combine (Path.Combine (home, "Documents"), ".config"); - if (option == SpecialFolderOption.Create){ - if (!Directory.Exists (dir)) - Directory.CreateDirectory (dir); - } - return dir; - } -#else return config; -#endif + //use FDO's DATA_HOME. This is *NOT* synced case SpecialFolder.LocalApplicationData: -#if MONOTOUCH - { - string dir = Path.Combine (home, "Documents"); - if (!Directory.Exists (dir)) - Directory.CreateDirectory (dir); - - return dir; - } -#else return data; -#endif case SpecialFolder.Desktop: case SpecialFolder.DesktopDirectory: @@ -705,8 +685,9 @@ namespace System { return "/usr/share"; default: throw new ArgumentException ("Invalid SpecialFolder"); - } - } + } + } +#endif [EnvironmentPermission (SecurityAction.Demand, Unrestricted=true)] @@ -884,7 +865,7 @@ namespace System { } // private methods -#if MOBILE +#if (MONOTOUCH || MONODROID || XAMMAC) internal const bool IsRunningOnWindows = false; #else internal static bool IsRunningOnWindows { diff --git a/mcs/class/corlib/System/FirstChanceExceptionEventArgs.cs b/mcs/class/corlib/System/FirstChanceExceptionEventArgs.cs new file mode 100644 index 0000000000..d39fbdc715 --- /dev/null +++ b/mcs/class/corlib/System/FirstChanceExceptionEventArgs.cs @@ -0,0 +1,44 @@ +// +// System.FirstChangeExceptionEventArgs.cs +// +// Copyright 2014 Xamarin Inc (http://www.xamarin.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. +// + +#if NET_4_5 +using System; + +public class FirstChanceExceptionEventArgs : EventArgs +{ + Exception exception; + + public FirstChanceExceptionEventArgs (Exception exception) { + this.exception = exception; + } + + public Exception Exception { + get { + return exception; + } + } +} + +#endif \ No newline at end of file diff --git a/mcs/class/corlib/System/InvalidTimeZoneException.cs b/mcs/class/corlib/System/InvalidTimeZoneException.cs index 7096e56cd3..7beb2d4982 100644 --- a/mcs/class/corlib/System/InvalidTimeZoneException.cs +++ b/mcs/class/corlib/System/InvalidTimeZoneException.cs @@ -24,8 +24,6 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if NET_4_0 - using System.Runtime.CompilerServices; namespace System @@ -36,7 +34,10 @@ namespace System #elif NET_4_0 [TypeForwardedFrom (Consts.AssemblySystemCore_3_5)] #endif - public class InvalidTimeZoneException : Exception +#if NET_4_0 + public +#endif + class InvalidTimeZoneException : Exception { public InvalidTimeZoneException () : base () {} @@ -51,5 +52,3 @@ namespace System {} } } - -#endif diff --git a/mcs/class/corlib/System/String.cs b/mcs/class/corlib/System/String.cs index 2a408933ea..65e460647c 100644 --- a/mcs/class/corlib/System/String.cs +++ b/mcs/class/corlib/System/String.cs @@ -2688,24 +2688,8 @@ namespace System } } - internal unsafe void InternalSetLength (int newLength) - { - if (newLength > length) - throw new ArgumentOutOfRangeException ("newLength", "newLength as to be <= length"); - - // zero terminate, we can pass string objects directly via pinvoke - // we also zero the rest of the string, since the new GC needs to be - // able to handle the changing size (it will skip the 0 bytes). - fixed (char * pStr = &start_char) { - char *p = pStr + newLength; - char *end = pStr + length; - while (p < end) { - p [0] = '\0'; - p++; - } - } - length = newLength; - } + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal extern void InternalSetLength (int newLength); [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)] // When modifying it, GetCaseInsensitiveHashCode() should be modified as well. diff --git a/mcs/class/corlib/System/TimeSpan.cs b/mcs/class/corlib/System/TimeSpan.cs index 7762dfc917..f6937ef3ca 100644 --- a/mcs/class/corlib/System/TimeSpan.cs +++ b/mcs/class/corlib/System/TimeSpan.cs @@ -614,41 +614,76 @@ namespace System element = parser.GetNextElement (); switch (element.Type) { - case FormatElementType.Days: - value = Math.Abs (Days); - break; - case FormatElementType.Hours: - value = Math.Abs (Hours); - break; - case FormatElementType.Minutes: - value = Math.Abs (Minutes); - break; - case FormatElementType.Seconds: - value = Math.Abs (Seconds); - break; - case FormatElementType.Ticks: - case FormatElementType.TicksUppercase: - value = Math.Abs (Milliseconds); - if (value == 0) { - if (element.Type == FormatElementType.Ticks) - break; + case FormatElementType.Days: + value = Math.Abs (Days); + break; + case FormatElementType.Hours: + value = Math.Abs (Hours); + break; + case FormatElementType.Minutes: + value = Math.Abs (Minutes); + break; + case FormatElementType.Seconds: + value = Math.Abs (Seconds); + break; + case FormatElementType.Ticks: + case FormatElementType.TicksUppercase: + // + // TODO: Unify with datetime ticks formatting + // + value = (int)(_ticks % TicksPerSecond); + if (value == 0) { + if (element.Type == FormatElementType.Ticks) + break; - continue; - } + continue; + } - int threshold = (int)Math.Pow (10, element.IntValue); - while (value >= threshold) + int total_length = element.IntValue; + const int max_length = 7; + int digits = max_length; + for (var dv = (int)Math.Pow (10, max_length - 1); dv > value; dv /= 10, --digits) + ; + + // + // Skip only leading zeros in F format + // + if (element.Type == FormatElementType.TicksUppercase && max_length - digits >= total_length) + continue; + + // + // Add leading zeros + // + int leading = 0; + for (; leading < total_length && leading < max_length - digits; ++leading) { + sb.Append ("0"); + } + + if (total_length == leading) + continue; + + // + // Remove trailing zeros + // + if (element.Type == FormatElementType.TicksUppercase) { + while (value % 10 == 0) value /= 10; - sb.Append (value.ToString ()); - continue; - case FormatElementType.EscapedChar: - sb.Append (element.CharValue); - continue; - case FormatElementType.Literal: - sb.Append (element.StringValue); - continue; - default: - throw new FormatException ("The format is not recognized."); + } + + var max_value = (int)Math.Pow (10, total_length - leading); + while (value >= max_value) + value /= 10; + + sb.Append (value.ToString (CultureInfo.InvariantCulture)); + continue; + case FormatElementType.EscapedChar: + sb.Append (element.CharValue); + continue; + case FormatElementType.Literal: + sb.Append (element.StringValue); + continue; + default: + throw new FormatException ("The format is not recognized."); } sb.Append (value.ToString ("D" + element.IntValue.ToString ())); diff --git a/mcs/class/corlib/System/TimeZone.cs b/mcs/class/corlib/System/TimeZone.cs index cea224133e..f4e01b03be 100644 --- a/mcs/class/corlib/System/TimeZone.cs +++ b/mcs/class/corlib/System/TimeZone.cs @@ -144,22 +144,7 @@ namespace System return DateTime.SpecifyKind (DateTime.MinValue, DateTimeKind.Local); } - DateTime local = DateTime.SpecifyKind (time.Add (utcOffset), DateTimeKind.Local); - DaylightTime dlt = GetDaylightChanges (time.Year); - if (dlt.Delta.Ticks == 0) - return DateTime.SpecifyKind (local, DateTimeKind.Local); - - // FIXME: check all of the combination of - // - basis: local-based or UTC-based - // - hemisphere: Northern or Southern - // - offset: positive or negative - - // PST should work fine here. - if (local < dlt.End && dlt.End.Subtract (dlt.Delta) <= local) - return DateTime.SpecifyKind (local, DateTimeKind.Local); - - TimeSpan localOffset = GetUtcOffset (local); - return DateTime.SpecifyKind (time.Add (localOffset), DateTimeKind.Local); + return DateTime.SpecifyKind (time.Add (utcOffset), DateTimeKind.Local); } public virtual DateTime ToUniversalTime (DateTime time) @@ -252,17 +237,6 @@ namespace System // A yearwise cache of DaylightTime. private Dictionary m_CachedDaylightChanges = new Dictionary (1); - // the offset when daylightsaving is not on (in ticks) - private long m_ticksOffset; - - // the offset when daylightsaving is not on. - [NonSerialized] - private TimeSpan utcOffsetWithOutDLS; - - // the offset when daylightsaving is on. - [NonSerialized] - private TimeSpan utcOffsetWithDLS; - internal enum TimeZoneData { DaylightSavingStartIdx, @@ -315,8 +289,6 @@ namespace System m_standardName = Locale.GetText (names[(int)TimeZoneNames.StandardNameIdx]); m_daylightName = Locale.GetText (names[(int)TimeZoneNames.DaylightNameIdx]); - m_ticksOffset = data[(int)TimeZoneData.UtcOffsetIdx]; - DaylightTime dlt = GetDaylightTimeFromData (data); m_CachedDaylightChanges.Add (now.Year, dlt); OnDeserialization (dlt); @@ -366,20 +338,7 @@ namespace System if (time.Kind == DateTimeKind.Utc) return TimeSpan.Zero; - if (IsDaylightSavingTime (time) && !IsAmbiguousTime (time)) - return utcOffsetWithDLS; - - return utcOffsetWithOutDLS; - } - - private bool IsAmbiguousTime (DateTime time) - { - if (time.Kind == DateTimeKind.Utc) - return false; - - DaylightTime changes = GetDaylightChanges (time.Year); - - return time < changes.End && time >= changes.End - changes.Delta; + return TimeZoneInfo.Local.GetUtcOffset (time); } void IDeserializationCallback.OnDeserialization (object sender) @@ -400,8 +359,6 @@ namespace System } else this_year = dlt.Start.Year; - utcOffsetWithOutDLS = new TimeSpan (m_ticksOffset); - utcOffsetWithDLS = new TimeSpan (m_ticksOffset + dlt.Delta.Ticks); this_year_dlt = dlt; } diff --git a/mcs/class/corlib/System/TimeZoneNotFoundException.cs b/mcs/class/corlib/System/TimeZoneNotFoundException.cs index 79b094ddde..643b82104b 100644 --- a/mcs/class/corlib/System/TimeZoneNotFoundException.cs +++ b/mcs/class/corlib/System/TimeZoneNotFoundException.cs @@ -24,7 +24,6 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#if NET_4_0 using System.Runtime.CompilerServices; @@ -36,7 +35,10 @@ namespace System #elif NET_4_0 [TypeForwardedFrom (Consts.AssemblySystemCore_3_5)] #endif - public class TimeZoneNotFoundException : Exception +#if NET_4_0 + public +#endif + class TimeZoneNotFoundException : Exception { public TimeZoneNotFoundException () : base () {} @@ -51,5 +53,3 @@ namespace System {} } } - -#endif diff --git a/mcs/class/corlib/Test/Mono/DataConvertTest.cs b/mcs/class/corlib/Test/Mono/DataConvertTest.cs index 89f99e918c..f02a6a7db4 100644 --- a/mcs/class/corlib/Test/Mono/DataConvertTest.cs +++ b/mcs/class/corlib/Test/Mono/DataConvertTest.cs @@ -8,7 +8,7 @@ using Mono; using NUnit.Framework.SyntaxHelpers; #endif -namespace MonoTests { +namespace MonoTests.Mono { [TestFixture] public class DataConverterTest @@ -50,9 +50,9 @@ namespace MonoTests { [Test] public void StringAlignment () { - byte[] packed = Mono.DataConverter.Pack ("bz8", 1, TEST_STRING); + byte[] packed = global::Mono.DataConverter.Pack ("bz8", 1, TEST_STRING); - IList unpacked = Mono.DataConverter.Unpack ("bz8", packed, 0); + IList unpacked = global::Mono.DataConverter.Unpack ("bz8", packed, 0); Assert.AreEqual(1, (byte) unpacked[0]); Assert.AreEqual(TEST_STRING, new string((char[]) unpacked[1])); @@ -65,4 +65,4 @@ namespace MonoTests { Assert.That ((f - 3.14f), Is.LessThanOrEqualTo (Single.Epsilon)); } } -} \ No newline at end of file +} diff --git a/mcs/class/corlib/Test/System.Globalization/CalendarTest.cs b/mcs/class/corlib/Test/System.Globalization/CalendarTest.cs index 0987da7aed..c1b34196e9 100644 --- a/mcs/class/corlib/Test/System.Globalization/CalendarTest.cs +++ b/mcs/class/corlib/Test/System.Globalization/CalendarTest.cs @@ -3,6 +3,7 @@ // (C) 2002 Ulrich Kunitz // +using System.Collections.Generic; using NUnit.Framework; using System; using System.Globalization; @@ -797,6 +798,44 @@ public class CalendarTest { Assert.AreEqual (4363, kc.ToFourDigitYear (4363), "#4-4"); } + public void TestDaysInYear (Calendar calendar, int year) + { + var daysInYear = calendar.GetDaysInYear (year); + var daysInMonths = 0; + var monthInYear = calendar.GetMonthsInYear (year); + for (var m = 1; m <= monthInYear; m++) + daysInMonths += calendar.GetDaysInMonth (year, m); + + Assert.AreEqual (daysInYear, daysInMonths, string.Format("Calendar:{0} Year:{1}",calendar.GetType(), year)); + } + + [Test] + public void DaysInYear () + { + var calendars = new List (acal) { + new UmAlQuraCalendar () + }; + + foreach (var calendar in calendars) { + var minYear = calendar.GetYear (calendar.MinSupportedDateTime); + var maxYear = calendar.GetYear (calendar.MaxSupportedDateTime) - 1 ; + var midYear = calendar.GetYear (DateTime.Now); + var yearsTested = Math.Min (1000, (maxYear - minYear) / 2); + + midYear -= yearsTested / 2; + + int y1 = minYear, y2 = maxYear, y3 = midYear; + for (var i = 0; i < yearsTested; i++) { + TestDaysInYear (calendar, y1); + TestDaysInYear (calendar, y2); + if (y3 > minYear && y3 < maxYear) + TestDaysInYear (calendar, y3); + + y1++; y2--; y3++; + } + } + } + // TODO: more tests :-) } // class CalendarTest diff --git a/mcs/class/corlib/Test/System.IO/DirectoryInfoTest.cs b/mcs/class/corlib/Test/System.IO/DirectoryInfoTest.cs index 699f94be80..3e34c81352 100644 --- a/mcs/class/corlib/Test/System.IO/DirectoryInfoTest.cs +++ b/mcs/class/corlib/Test/System.IO/DirectoryInfoTest.cs @@ -10,6 +10,7 @@ using System; using System.Collections; +using System.Collections.Generic; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; @@ -1059,6 +1060,23 @@ namespace MonoTests.System.IO Assert.AreEqual (TempFolder + DSC + "ToString.Test", info.ToString ()); } +#if NET_4_0 + [Test] + public void EnumerateFileSystemInfosTest () + { + var dirInfo = new DirectoryInfo (TempFolder); + dirInfo.CreateSubdirectory ("1").CreateSubdirectory ("a"); + dirInfo.CreateSubdirectory ("2").CreateSubdirectory ("b"); + + var l = new List (); + foreach (var info in dirInfo.EnumerateFileSystemInfos ("*", SearchOption.AllDirectories)) + l.Add (info.Name); + + l.Sort (); + Assert.AreEqual ("1,2,a,b", string.Join (",", l), "#1"); + } +#endif + #if !MOBILE [Test] public void Serialization () @@ -1111,7 +1129,7 @@ namespace MonoTests.System.IO try { Directory.CreateDirectory (path); Directory.CreateDirectory (dir); - Mono.Unix.UnixSymbolicLinkInfo li = new Mono.Unix.UnixSymbolicLinkInfo (link); + global::Mono.Unix.UnixSymbolicLinkInfo li = new global::Mono.Unix.UnixSymbolicLinkInfo (link); li.CreateSymbolicLinkTo (dir); DirectoryInfo info = new DirectoryInfo (path); diff --git a/mcs/class/corlib/Test/System.IO/DirectoryTest.cs b/mcs/class/corlib/Test/System.IO/DirectoryTest.cs index 82536169f5..f2d7e03d3d 100644 --- a/mcs/class/corlib/Test/System.IO/DirectoryTest.cs +++ b/mcs/class/corlib/Test/System.IO/DirectoryTest.cs @@ -374,11 +374,11 @@ public class DirectoryTest string path = TempFolder + DSC + "ExistsAccessDenied"; Directory.CreateDirectory (path); - Mono.Posix.Syscall.chmod (path, 0); + global::Mono.Posix.Syscall.chmod (path, 0); try { Assert.IsFalse (Directory.Exists(path + DSC + "b")); } finally { - Mono.Posix.Syscall.chmod (path, (Mono.Posix.FileMode) 755); + global::Mono.Posix.Syscall.chmod (path, (global::Mono.Posix.FileMode) 755); Directory.Delete (path); } } diff --git a/mcs/class/corlib/Test/System.Reflection.Emit/DynamicMethodTest.cs b/mcs/class/corlib/Test/System.Reflection.Emit/DynamicMethodTest.cs index 271412269c..f65ac28ef5 100644 --- a/mcs/class/corlib/Test/System.Reflection.Emit/DynamicMethodTest.cs +++ b/mcs/class/corlib/Test/System.Reflection.Emit/DynamicMethodTest.cs @@ -317,10 +317,12 @@ namespace MonoTests.System.Reflection.Emit m1.Invoke(null, new object[] { 5 }); } + // Disabl known warning, the Field is never used directly from C# + #pragma warning disable 414 class Host { static string Field = "foo"; } - + #pragma warning restore 414 [Test] [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=297416 public void TestOwnerMemberAccess () diff --git a/mcs/class/corlib/Test/System.Reflection.Emit/GenericTypeParameterBuilderTest.cs b/mcs/class/corlib/Test/System.Reflection.Emit/GenericTypeParameterBuilderTest.cs index 1559d66369..7f9db3b99f 100644 --- a/mcs/class/corlib/Test/System.Reflection.Emit/GenericTypeParameterBuilderTest.cs +++ b/mcs/class/corlib/Test/System.Reflection.Emit/GenericTypeParameterBuilderTest.cs @@ -27,7 +27,6 @@ namespace MonoTests.System.Reflection.Emit { AssemblyBuilder assembly; ModuleBuilder module; - int typeCount; static string ASSEMBLY_NAME = "MonoTests.System.Reflection.Emit.TypeBuilderTest"; [SetUp] @@ -46,7 +45,6 @@ namespace MonoTests.System.Reflection.Emit assemblyName, mode, Path.GetTempPath ()); module = assembly.DefineDynamicModule ("module1"); - typeCount = 0; } [Test] diff --git a/mcs/class/corlib/Test/System.Reflection.Emit/TypeBuilderTest.cs.REMOVED.git-id b/mcs/class/corlib/Test/System.Reflection.Emit/TypeBuilderTest.cs.REMOVED.git-id index e49547c263..8f8bc27478 100644 --- a/mcs/class/corlib/Test/System.Reflection.Emit/TypeBuilderTest.cs.REMOVED.git-id +++ b/mcs/class/corlib/Test/System.Reflection.Emit/TypeBuilderTest.cs.REMOVED.git-id @@ -1 +1 @@ -382f3f255279b48e53d7e85bf3b9d869cbf2488c \ No newline at end of file +b1b7cf320f3f5346dd7e01ef4551018929f2d874 \ No newline at end of file diff --git a/mcs/class/corlib/Test/System.Reflection/AssemblyNameCas.cs b/mcs/class/corlib/Test/System.Reflection/AssemblyNameCas.cs index a24a4868d9..087297b6f2 100644 --- a/mcs/class/corlib/Test/System.Reflection/AssemblyNameCas.cs +++ b/mcs/class/corlib/Test/System.Reflection/AssemblyNameCas.cs @@ -42,7 +42,6 @@ namespace MonoCasTests.System.Reflection { public class AssemblyNameCas { private MonoTests.System.Reflection.AssemblyNameTest ant; - private AssemblyName main; [TestFixtureSetUp] public void FixtureSetUp () diff --git a/mcs/class/corlib/Test/System.Reflection/FieldInfoTest.cs b/mcs/class/corlib/Test/System.Reflection/FieldInfoTest.cs index ccd923fa59..a3639864f6 100644 --- a/mcs/class/corlib/Test/System.Reflection/FieldInfoTest.cs +++ b/mcs/class/corlib/Test/System.Reflection/FieldInfoTest.cs @@ -73,6 +73,8 @@ namespace MonoTests.System.Reflection { } + // Disable this warning, as the purpose of this struct is to poke at the internal via reflection + #pragma warning disable 649 class FieldInvokeMatrix { public Byte field_Byte; @@ -102,6 +104,7 @@ namespace MonoTests.System.Reflection public Int64Enum field_Int64Enum; public UInt64Enum field_UInt64Enum; } + #pragma warning restore 649 public enum ByteEnum : byte { @@ -376,10 +379,13 @@ namespace MonoTests.System.Reflection Assert.AreEqual (typeof (Marshal1), Type.GetType (attr.MarshalType), "#I4"); } + // Disable "field not used warning", this is intended. +#pragma warning disable 649 class Foo { public static int static_field; public int field; } +#pragma warning restore 649 [ExpectedException (typeof (ArgumentException))] public void GetValueWrongObject () @@ -1359,16 +1365,24 @@ namespace MonoTests.System.Reflection } + // We do not refernece the field, that is expected +#pragma warning disable 169 // Helper classes class RefOnlyFieldClass { // Helper property static int RefOnlyField; } - +#pragma warning restore 169 + class NonPublicFieldClass { protected int protectedField; + + public void Dummy () + { + protectedField = 1; + } } public class FieldInfoTest diff --git a/mcs/class/corlib/Test/System.Reflection/MethodInfoTest.cs b/mcs/class/corlib/Test/System.Reflection/MethodInfoTest.cs index 65adf97aa5..00349880e1 100644 --- a/mcs/class/corlib/Test/System.Reflection/MethodInfoTest.cs +++ b/mcs/class/corlib/Test/System.Reflection/MethodInfoTest.cs @@ -42,9 +42,12 @@ using System.Collections.Generic; #endif namespace A.B.C { + // Disable expected warning +#pragma warning disable 169 public struct MethodInfoTestStruct { int p; } +#pragma warning restore 169 } namespace MonoTests.System.Reflection { @@ -253,7 +256,7 @@ namespace MonoTests.System.Reflection public struct SimpleStruct { - int a; + public int a; } public static unsafe SimpleStruct* PtrFunc2 (SimpleStruct* a, A.B.C.MethodInfoTestStruct *b) diff --git a/mcs/class/corlib/Test/System.Reflection/MonoGenericClassTest.cs b/mcs/class/corlib/Test/System.Reflection/MonoGenericClassTest.cs index 0b02596ec5..e47b5e1eb7 100644 --- a/mcs/class/corlib/Test/System.Reflection/MonoGenericClassTest.cs +++ b/mcs/class/corlib/Test/System.Reflection/MonoGenericClassTest.cs @@ -178,7 +178,7 @@ namespace MonoTests.System.Reflection.Emit } public class Bar { - public class Foo {} + public class Foo {} } [Test] diff --git a/mcs/class/corlib/Test/System.Reflection/ReflectedTypeTest.cs b/mcs/class/corlib/Test/System.Reflection/ReflectedTypeTest.cs index bcc814e04d..8347b4dabf 100644 --- a/mcs/class/corlib/Test/System.Reflection/ReflectedTypeTest.cs +++ b/mcs/class/corlib/Test/System.Reflection/ReflectedTypeTest.cs @@ -29,6 +29,8 @@ using System; using System.Reflection; using NUnit.Framework; +// Various fields in this class are not used directly by the C# code, they are only here to be reflected upon +#pragma warning disable 649 namespace MonoTests.System.Reflection { [TestFixture] diff --git a/mcs/class/corlib/Test/System.Runtime.CompilerServices/ConditionalWeakTableTest.cs b/mcs/class/corlib/Test/System.Runtime.CompilerServices/ConditionalWeakTableTest.cs index 92d19fe367..f6f4dabe2b 100644 --- a/mcs/class/corlib/Test/System.Runtime.CompilerServices/ConditionalWeakTableTest.cs +++ b/mcs/class/corlib/Test/System.Runtime.CompilerServices/ConditionalWeakTableTest.cs @@ -402,9 +402,12 @@ namespace MonoTests.System.Runtime.CompilerServices { static int reachable = 0; public class FinalizableLink { + // The sole purpose of this object is to keep a reference to another object, so it is fine to not use it. + #pragma warning disable 414 object obj; - ConditionalWeakTable cwt; int id; + #pragma warning restore 414 + ConditionalWeakTable cwt; public FinalizableLink (int id, object obj, ConditionalWeakTable cwt) { this.id = id; diff --git a/mcs/class/corlib/Test/System.Runtime.CompilerServices/RuntimeHelpersTest.cs b/mcs/class/corlib/Test/System.Runtime.CompilerServices/RuntimeHelpersTest.cs index fc4010bd21..593305d4a6 100644 --- a/mcs/class/corlib/Test/System.Runtime.CompilerServices/RuntimeHelpersTest.cs +++ b/mcs/class/corlib/Test/System.Runtime.CompilerServices/RuntimeHelpersTest.cs @@ -94,8 +94,10 @@ namespace MonoTests.System.Runtime.CompilerServices { RuntimeHelpers.RunClassConstructor (rth); } + // Expected the handle here is that way, because we are going to test for an ArgumentException being thrown +#pragma warning disable 649 static RuntimeTypeHandle handle; - +#pragma warning restore 649 [Test] [ExpectedException (typeof (ArgumentException))] public void RunClassConstructor_Uninitialized () @@ -122,7 +124,11 @@ namespace MonoTests.System.Runtime.CompilerServices { } static RuntimeFieldHandle rfh = typeof (Fielder).GetField ("array").FieldHandle; + + // Disable expected warning: the point of the test is to validate that an exception is thrown for something with a null (the default value in this case) + #pragma warning disable 649 static RuntimeFieldHandle static_rfh; + #pragma warning restore 649 [Test] [ExpectedException (typeof (ArgumentNullException))] diff --git a/mcs/class/corlib/Test/System.Runtime.CompilerServices/TaskAwaiterTest.cs b/mcs/class/corlib/Test/System.Runtime.CompilerServices/TaskAwaiterTest.cs index 5237e377e3..1bc9d38414 100644 --- a/mcs/class/corlib/Test/System.Runtime.CompilerServices/TaskAwaiterTest.cs +++ b/mcs/class/corlib/Test/System.Runtime.CompilerServices/TaskAwaiterTest.cs @@ -72,6 +72,11 @@ namespace MonoTests.System.Runtime.CompilerServices Interlocked.Increment (ref ic); return false; } + + public override string ToString () + { + return "Scheduler-" + name; + } } class SingleThreadSynchronizationContext : SynchronizationContext diff --git a/mcs/class/corlib/Test/System.Runtime.InteropServices/GCHandleTest.cs b/mcs/class/corlib/Test/System.Runtime.InteropServices/GCHandleTest.cs index 1ac8a825b6..17fe0d9045 100644 --- a/mcs/class/corlib/Test/System.Runtime.InteropServices/GCHandleTest.cs +++ b/mcs/class/corlib/Test/System.Runtime.InteropServices/GCHandleTest.cs @@ -18,8 +18,11 @@ namespace MonoTests.System.Runtime.InteropServices [TestFixture] public class GCHandleTest { + // Expected warning, the tests that reference this handle are testing for the default values of the object + #pragma warning disable 649 static GCHandle handle; - + #pragma warning restore 649 + [Test] public void DefaultZeroValue_Allocated () { diff --git a/mcs/class/corlib/Test/System.Runtime.InteropServices/MarshalTest.cs b/mcs/class/corlib/Test/System.Runtime.InteropServices/MarshalTest.cs index d6f2a49bf3..28943159aa 100644 --- a/mcs/class/corlib/Test/System.Runtime.InteropServices/MarshalTest.cs +++ b/mcs/class/corlib/Test/System.Runtime.InteropServices/MarshalTest.cs @@ -28,7 +28,7 @@ namespace MonoTests.System.Runtime.InteropServices public int field; } - class ClsNoLayout { + public class ClsNoLayout { public int field; } @@ -173,12 +173,12 @@ namespace MonoTests.System.Runtime.InteropServices Marshal.FreeHGlobal (ptr); } - struct Foo { - int a; - static int b; - long c; - static char d; - int e; + public struct Foo { + public int a; + public static int b; + public long c; + public static char d; + public int e; } [Test] diff --git a/mcs/class/corlib/Test/System.Runtime.Serialization/SerializationTest.cs b/mcs/class/corlib/Test/System.Runtime.Serialization/SerializationTest.cs index 90b2d3f73f..48e686ab8d 100644 --- a/mcs/class/corlib/Test/System.Runtime.Serialization/SerializationTest.cs +++ b/mcs/class/corlib/Test/System.Runtime.Serialization/SerializationTest.cs @@ -637,6 +637,8 @@ namespace MonoTests.System.Runtime.Serialization Assert.AreEqual (_char, obj._char, context + "._char"); Assert.AreEqual (_dateTime, obj._dateTime, context + "._dateTime"); Assert.AreEqual (_decimal, obj._decimal, context + "._decimal"); + Assert.AreEqual (_double, obj._double, context + "._double"); + Assert.AreEqual (_short, obj._short, context = "._short"); Assert.AreEqual (_int, obj._int, context + "._int"); Assert.AreEqual (_long, obj._long, context + "._long"); Assert.AreEqual (_sbyte, obj._sbyte, context + "._sbyte"); diff --git a/mcs/class/corlib/Test/System.Security.Cryptography/CryptoStreamTest.cs b/mcs/class/corlib/Test/System.Security.Cryptography/CryptoStreamTest.cs index 10328b8e60..3ad6cce71f 100644 --- a/mcs/class/corlib/Test/System.Security.Cryptography/CryptoStreamTest.cs +++ b/mcs/class/corlib/Test/System.Security.Cryptography/CryptoStreamTest.cs @@ -144,7 +144,6 @@ namespace MonoTests.System.Security.Cryptography { Stream readStream; Stream writeStream; ICryptoTransform encryptor; - ICryptoTransform decryptor; CryptoStream cs; SymmetricAlgorithm aes; @@ -156,7 +155,6 @@ namespace MonoTests.System.Security.Cryptography { writeStream = new MemoryStream (new byte [0], true); aes = SymmetricAlgorithm.Create (); encryptor = aes.CreateEncryptor (); - decryptor = aes.CreateEncryptor (); } } diff --git a/mcs/class/corlib/Test/System.Security.Cryptography/HMACSHA384Test.cs b/mcs/class/corlib/Test/System.Security.Cryptography/HMACSHA384Test.cs index 115bdf30cc..e243712d80 100644 --- a/mcs/class/corlib/Test/System.Security.Cryptography/HMACSHA384Test.cs +++ b/mcs/class/corlib/Test/System.Security.Cryptography/HMACSHA384Test.cs @@ -28,6 +28,9 @@ namespace MonoTests.System.Security.Cryptography { public class SelectableHmacSha384: HMAC { + // legacy parameter: + // http://blogs.msdn.com/shawnfa/archive/2007/01/31/please-do-not-use-the-net-2-0-hmacsha512-and-hmacsha384-classes.aspx + public SelectableHmacSha384 (byte[] key, bool legacy) { HashName = "SHA384"; @@ -45,7 +48,6 @@ namespace MonoTests.System.Security.Cryptography { public class HMACSHA384Test : KeyedHashAlgorithmTest { protected HMACSHA384 algo; - private bool legacy; [SetUp] public override void SetUp () @@ -53,8 +55,6 @@ namespace MonoTests.System.Security.Cryptography { algo = new HMACSHA384 (); algo.Key = new byte [8]; hash = algo; - // http://blogs.msdn.com/shawnfa/archive/2007/01/31/please-do-not-use-the-net-2-0-hmacsha512-and-hmacsha384-classes.aspx - legacy = (new HS384 ().BlockSize == 64); } // the hash algorithm only exists as a managed implementation diff --git a/mcs/class/corlib/Test/System.Security.Cryptography/HMACSHA512Test.cs b/mcs/class/corlib/Test/System.Security.Cryptography/HMACSHA512Test.cs index 04497415d0..55a7b87589 100644 --- a/mcs/class/corlib/Test/System.Security.Cryptography/HMACSHA512Test.cs +++ b/mcs/class/corlib/Test/System.Security.Cryptography/HMACSHA512Test.cs @@ -26,6 +26,9 @@ namespace MonoTests.System.Security.Cryptography { public class SelectableHmacSha512: HMAC { + // Legacy parameter explanation: + // http://blogs.msdn.com/shawnfa/archive/2007/01/31/please-do-not-use-the-net-2-0-hmacsha512-and-hmacsha384-classes.aspx + public SelectableHmacSha512 (byte[] key, bool legacy) { HashName = "SHA512"; @@ -43,7 +46,6 @@ namespace MonoTests.System.Security.Cryptography { public class HMACSHA512Test : KeyedHashAlgorithmTest { protected HMACSHA512 algo; - private bool legacy; [SetUp] public override void SetUp () @@ -51,8 +53,6 @@ namespace MonoTests.System.Security.Cryptography { algo = new HMACSHA512 (); algo.Key = new byte [8]; hash = algo; - // http://blogs.msdn.com/shawnfa/archive/2007/01/31/please-do-not-use-the-net-2-0-hmacsha512-and-hmacsha384-classes.aspx - legacy = (new HS512 ().BlockSize == 64); } // the hash algorithm only exists as a managed implementation diff --git a/mcs/class/corlib/Test/System.Security.Permissions/RegistryPermissionTest.cs b/mcs/class/corlib/Test/System.Security.Permissions/RegistryPermissionTest.cs index fb3770db4b..f95691c7f5 100644 --- a/mcs/class/corlib/Test/System.Security.Permissions/RegistryPermissionTest.cs +++ b/mcs/class/corlib/Test/System.Security.Permissions/RegistryPermissionTest.cs @@ -38,7 +38,6 @@ namespace MonoTests.System.Security.Permissions { private static string className = "System.Security.Permissions.RegistryPermission, "; private static string keyCurrentUser = @"HKEY_CURRENT_USER\Software\Novell iFolder\spouliot\Home"; - private static string keyCurrentUserSubset = @"HKEY_CURRENT_USER\Software\Novell iFolder\"; private static string keyLocalMachine = @"HKEY_LOCAL_MACHINE\SOFTWARE\Novell\Novell iFolder\1.00.000"; private static string keyLocalMachineSubset = @"HKEY_LOCAL_MACHINE\SOFTWARE\Novell\"; diff --git a/mcs/class/corlib/Test/System.Security.Permissions/UrlIdentityPermissionTest.cs b/mcs/class/corlib/Test/System.Security.Permissions/UrlIdentityPermissionTest.cs index 62a0c35e1c..f9a7d8ae21 100644 --- a/mcs/class/corlib/Test/System.Security.Permissions/UrlIdentityPermissionTest.cs +++ b/mcs/class/corlib/Test/System.Security.Permissions/UrlIdentityPermissionTest.cs @@ -51,12 +51,6 @@ namespace MonoTests.System.Security.Permissions { "*", }; - // accepted as Url but fails to work (as expected) in some methods - static string[] SemiBadUrls = { - "www.mono-project.com:80", - String.Empty, - }; - [Test] public void PermissionState_None () { diff --git a/mcs/class/corlib/Test/System.Text/EncodingTester.cs b/mcs/class/corlib/Test/System.Text/EncodingTester.cs new file mode 100644 index 0000000000..939d38160f --- /dev/null +++ b/mcs/class/corlib/Test/System.Text/EncodingTester.cs @@ -0,0 +1,116 @@ +// +// EncodingTester.cs +// +// Author: +// Marcos Henrich +// +// (C) 2014 Xamarin, Inc. +// + +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Text; + +namespace MonoTests.System.Text +{ + class EncodingTester + { + class DecoderTestFallbackBuffer : DecoderFallbackBuffer + { + DecoderFallbackBuffer buffer; + private FallbackDelegate fallbackAction; + + public DecoderTestFallbackBuffer (DecoderReplacementFallback fallback, FallbackDelegate fallbackAction) + { + this.fallbackAction = fallbackAction; + buffer = new DecoderReplacementFallbackBuffer (fallback); + } + + public override bool Fallback (byte [] bytesUnknown, int index) + { + fallbackAction (bytesUnknown, index); + return buffer.Fallback (bytesUnknown, index); + } + + public override char GetNextChar () + { + return buffer.GetNextChar (); + } + + public override bool MovePrevious () + { + return buffer.MovePrevious (); + } + + public override int Remaining + { + get { return buffer.Remaining; } + } + + public override void Reset () + { + buffer.Reset (); + } + } + + class DecoderTestFallback : DecoderFallback + { + private DecoderReplacementFallback fallback; + private FallbackDelegate fallbackAction; + + public DecoderTestFallback (FallbackDelegate fallbackAction) + { + this.fallbackAction = fallbackAction; + } + + public override DecoderFallbackBuffer CreateFallbackBuffer () + { + fallback = new DecoderReplacementFallback (); + return new DecoderTestFallbackBuffer (fallback, fallbackAction); + } + + public override int MaxCharCount + { + get { return fallback.MaxCharCount; } + } + } + + public delegate void FallbackDelegate (byte [] bytesUnknown, int index); + + Encoding encoding; + + byte [][] expectedUnknownBytes; + int expectedUnknownBytesIndex; + + public EncodingTester (string encodingName) + { + var decoderFallback = new DecoderTestFallback (this.DecoderFallback); + encoding = Encoding.GetEncoding (encodingName, new EncoderReplacementFallback(), decoderFallback); + } + + private void DecoderFallback (byte [] bytesUnknown, int index) + { + if (expectedUnknownBytesIndex == expectedUnknownBytes.Length) + expectedUnknownBytesIndex = 0; + + var expectedBytes = expectedUnknownBytes [expectedUnknownBytesIndex++]; + Assert.AreEqual (expectedBytes, bytesUnknown); + } + + public void TestDecoderFallback (byte [] data, string expectedString, params byte [][] expectedUnknownBytes) + { + lock (this) + { + this.expectedUnknownBytes = expectedUnknownBytes; + this.expectedUnknownBytesIndex = 0; + + Assert.AreEqual (expectedString.Length, encoding.GetCharCount (data)); + Assert.AreEqual (expectedUnknownBytesIndex, expectedUnknownBytes.Length); + + Assert.AreEqual (expectedString, encoding.GetString (data)); + Assert.AreEqual (expectedUnknownBytesIndex, expectedUnknownBytes.Length); + } + } + } +} \ No newline at end of file diff --git a/mcs/class/corlib/Test/System.Text/UTF8EncodingTest.cs b/mcs/class/corlib/Test/System.Text/UTF8EncodingTest.cs index 91a465c13d..8943ab6b09 100644 --- a/mcs/class/corlib/Test/System.Text/UTF8EncodingTest.cs +++ b/mcs/class/corlib/Test/System.Text/UTF8EncodingTest.cs @@ -1198,5 +1198,88 @@ namespace MonoTests.System.Text int charactersWritten = Encoding.UTF8.GetDecoder ().GetChars (bytes, 0, 0, chars, 10, false); Assert.AreEqual (0, charactersWritten, "#3"); } + + [Test] + public void EncodingFallback () + { + /* Legal UTF-8 Byte Sequences + * 1st 2nd 3rd 4th + * 00..7F + * C2..DF 80..BF + * E0 A0..BF 80..BF + * E1..EF 80..BF 80..BF + * F0 90..BF 80..BF 80..BF + * F1..F3 80..BF 80..BF 80..BF + * F4 80..8F 80..BF 80..BF + */ + + var t = new EncodingTester ("utf-8"); + byte [] data; + + // Invalid 1st byte + for (byte b = 0x80; b <= 0xC1; b++) { + data = new byte [] { b }; + t.TestDecoderFallback (data, "?", new byte [] { b }); + } + + ///Invalid 2nd byte + // C2..DF 80..BF + for (byte b = 0xC2; b <= 0xDF; b++) { + data = new byte [] { b, 0x61 }; + t.TestDecoderFallback (data, "?a", new byte [] { b }); + } + + // E0 A0..BF + data = new byte [] { 0xE0, 0x99}; + t.TestDecoderFallback (data, "?", new byte [] { 0xE0, 0x99}); + + // E1..EF 80..BF + for (byte b = 0xE1; b <= 0xEF; b++) { + data = new byte [] { b, 0x61 }; + t.TestDecoderFallback (data, "?a", new byte [] { b }); + } + + // F0 90..BF + data = new byte [] { 0xF0, 0x8F}; + t.TestDecoderFallback (data, "?", new byte [] { 0xF0, 0x8F }); + + // F1..F4 80..XX + for (byte b = 0xF1; b <= 0xF4; b++) { + data = new byte [] { b, 0x61 }; + t.TestDecoderFallback (data, "?a", new byte [] { b }); + } + + // C2..F3 XX..BF + for (byte b = 0xC2; b <= 0xF3; b++) { + data = new byte [] { b, 0xC0 }; + t.TestDecoderFallback (data, "??", new byte [] { b }, new byte [] { 0xC0 }); + } + + // Invalid 3rd byte + // E0..F3 90..BF 80..BF + for (byte b = 0xE0; b <= 0xF3; b++) { + data = new byte [] { b, 0xB0, 0x61 }; + t.TestDecoderFallback (data, "?a", new byte [] { b, 0xB0 }); + data = new byte [] { b, 0xB0, 0xC0 }; + t.TestDecoderFallback (data, "??", new byte [] { b, 0xB0 }, new byte [] { 0xC0 }); + } + + // F4 80..8F 80..BF + data = new byte [] { 0xF4, 0x8F, 0xC0 }; + t.TestDecoderFallback (data, "??", new byte [] { 0xF4, 0x8F }, new byte [] { 0xC0 }); + + // Invalid 4th byte + // F0..F3 90..BF 80..BF 80..BF + for (byte b = 0xF0; b <= 0xF3; b++) { + data = new byte [] { b, 0xB0, 0xB0, 0x61 }; + t.TestDecoderFallback (data, "?a", new byte [] { b, 0xB0, 0xB0 }); + data = new byte [] { b, 0xB0, 0xB0, 0xC0 }; + t.TestDecoderFallback (data, "??", new byte [] { b, 0xB0, 0xB0 }, new byte [] { 0xC0 }); + } + + // F4 80..8F 80..BF 80..BF + data = new byte [] { 0xF4, 0x8F, 0xB0, 0xC0 }; + t.TestDecoderFallback (data, "??", new byte [] { 0xF4, 0x8F, 0xB0 }, new byte [] { 0xC0 }); + } } } diff --git a/mcs/class/corlib/Test/System.Text/UnicodeEncodingTest.cs b/mcs/class/corlib/Test/System.Text/UnicodeEncodingTest.cs index 9938bcef1a..e780524afe 100644 --- a/mcs/class/corlib/Test/System.Text/UnicodeEncodingTest.cs +++ b/mcs/class/corlib/Test/System.Text/UnicodeEncodingTest.cs @@ -164,34 +164,18 @@ namespace MonoTests.System.Text } [Test] -#if NET_2_0 - [Category ("NotWorking")] -#endif public void TestMaxCharCount() { UnicodeEncoding UnicodeEnc = new UnicodeEncoding (); -#if NET_2_0 - // where is this extra 1 coming from? Assert.AreEqual (26, UnicodeEnc.GetMaxCharCount(50), "UTF #1"); Assert.AreEqual (27, UnicodeEnc.GetMaxCharCount(51), "UTF #2"); -#else - Assert.AreEqual (25, UnicodeEnc.GetMaxCharCount(50), "UTF #1"); -#endif } [Test] -#if NET_2_0 - [Category ("NotWorking")] -#endif public void TestMaxByteCount() { UnicodeEncoding UnicodeEnc = new UnicodeEncoding (); -#if NET_2_0 - // is this extra 2 BOM? Assert.AreEqual (102, UnicodeEnc.GetMaxByteCount(50), "UTF #1"); -#else - Assert.AreEqual (100, UnicodeEnc.GetMaxByteCount(50), "UTF #1"); -#endif } [Test] @@ -257,5 +241,27 @@ namespace MonoTests.System.Text Assert.AreEqual (2, s.Length, "Length"); Assert.AreEqual (65533, (int) s [1], "1"); } + + [Test] + public void GetMaxByteCountIncludesBOM () + { + Assert.AreEqual (2, Encoding.Unicode.GetMaxByteCount (0), "#1"); + Assert.AreEqual (4, Encoding.Unicode.GetMaxByteCount (1), "#2"); + Assert.AreEqual (6, Encoding.Unicode.GetMaxByteCount (2), "#3"); + Assert.AreEqual (10, Encoding.Unicode.GetMaxByteCount (4), "#4"); + Assert.AreEqual (20, Encoding.Unicode.GetMaxByteCount (9), "#5"); + Assert.AreEqual (22, Encoding.Unicode.GetMaxByteCount (10), "#6"); + } + + [Test] + public void GetMaxCharCountRoundsCorrectly () + { + Assert.AreEqual (1, Encoding.Unicode.GetMaxCharCount (0), "#1"); + Assert.AreEqual (2, Encoding.Unicode.GetMaxCharCount (1), "#2"); + Assert.AreEqual (2, Encoding.Unicode.GetMaxCharCount (2), "#3"); + Assert.AreEqual (3, Encoding.Unicode.GetMaxCharCount (4), "#4"); + Assert.AreEqual (6, Encoding.Unicode.GetMaxCharCount (9), "#5"); + Assert.AreEqual (6, Encoding.Unicode.GetMaxCharCount (10), "#6"); + } } } diff --git a/mcs/class/corlib/Test/System.Threading.Tasks/TaskTest.cs b/mcs/class/corlib/Test/System.Threading.Tasks/TaskTest.cs index 63eb8a2aff..1ad12d0088 100644 --- a/mcs/class/corlib/Test/System.Threading.Tasks/TaskTest.cs +++ b/mcs/class/corlib/Test/System.Threading.Tasks/TaskTest.cs @@ -104,6 +104,8 @@ namespace MonoTests.System.Threading.Tasks } } + int workerThreads; + int completionPortThreads; Task[] tasks; const int max = 6; @@ -111,9 +113,18 @@ namespace MonoTests.System.Threading.Tasks [SetUp] public void Setup() { + ThreadPool.GetMinThreads (out workerThreads, out completionPortThreads); + ThreadPool.SetMinThreads (1, 1); + tasks = new Task[max]; } + [TearDown] + public void Teardown() + { + ThreadPool.SetMinThreads (workerThreads, completionPortThreads); + } + void InitWithDelegate(Action action) { for (int i = 0; i < max; i++) { @@ -616,18 +627,18 @@ namespace MonoTests.System.Threading.Tasks public void ContinueWithChildren () { ParallelTestHelper.Repeat (delegate { - bool result = false; + bool result = false; - var t = Task.Factory.StartNew (() => Task.Factory.StartNew (() => {}, TaskCreationOptions.AttachedToParent)); + var t = Task.Factory.StartNew (() => Task.Factory.StartNew (() => {}, TaskCreationOptions.AttachedToParent)); var mre = new ManualResetEvent (false); - t.ContinueWith (l => { + t.ContinueWith (l => { result = true; mre.Set (); }); Assert.IsTrue (mre.WaitOne (1000), "#1"); - Assert.IsTrue (result, "#2"); + Assert.IsTrue (result, "#2"); }, 2); } @@ -788,19 +799,64 @@ namespace MonoTests.System.Threading.Tasks { ParallelTestHelper.Repeat (delegate { var evt = new ManualResetEventSlim (); - var t = Task.Factory.StartNew (() => evt.Wait (5000)); + var monitor = new object (); + int finished = 0; + var t = Task.Factory.StartNew (delegate { + var r = evt.Wait (5000); + lock (monitor) { + finished ++; + Monitor.Pulse (monitor); + } + return r ? 1 : 10; //1 -> ok, 10 -> evt wait failed + }); var cntd = new CountdownEvent (2); var cntd2 = new CountdownEvent (2); - bool r1 = false, r2 = false; - ThreadPool.QueueUserWorkItem (delegate { cntd.Signal (); r1 = t.Wait (1000) && t.Result; cntd2.Signal (); }); - ThreadPool.QueueUserWorkItem (delegate { cntd.Signal (); r2 = t.Wait (1000) && t.Result; cntd2.Signal (); }); + int r1 = 0, r2 = 0; + ThreadPool.QueueUserWorkItem (delegate { + cntd.Signal (); + if (!t.Wait (1000)) + r1 = 20; // 20 -> task wait failed + else if (t.Result != 1) + r1 = 30 + t.Result; // 30 -> task result is bad + else + r1 = 2; //2 -> ok + cntd2.Signal (); + lock (monitor) { + finished ++; + Monitor.Pulse (monitor); + } + }); + ThreadPool.QueueUserWorkItem (delegate { + cntd.Signal (); + if (!t.Wait (1000)) + r2 = 40; // 40 -> task wait failed + else if (t.Result != 1) + r2 = 50 + t.Result; // 50 -> task result is bad + else + r2 = 3; //3 -> ok + cntd2.Signal (); + lock (monitor) { + finished ++; + Monitor.Pulse (monitor); + } + }); Assert.IsTrue (cntd.Wait (2000), "#1"); evt.Set (); Assert.IsTrue (cntd2.Wait (2000), "#2"); - Assert.IsTrue (r1, "r1"); - Assert.IsTrue (r2, "r2"); + Assert.AreEqual (2, r1, "r1"); + Assert.AreEqual (3, r2, "r2"); + + // Wait for everything to finish to avoid overloading the tpool + lock (monitor) { + while (true) { + if (finished == 3) + break; + else + Monitor.Wait (monitor); + } + } }, 10); } @@ -905,7 +961,7 @@ namespace MonoTests.System.Threading.Tasks }; var inner = new ApplicationException (); Thread t = new Thread (delegate () { - Task.Factory.StartNew (() => { Console.WriteLine ("HIT!"); throw inner; }); + Task.Factory.StartNew (() => { throw inner; }); }); t.Start (); t.Join (); @@ -1094,7 +1150,7 @@ namespace MonoTests.System.Threading.Tasks var t = new Task (() => { new Task (() => { r1 = true; }, TaskCreationOptions.AttachedToParent).RunSynchronously (); Task.Factory.StartNew (() => { Thread.Sleep (100); r2 = true; }, TaskCreationOptions.AttachedToParent); - }); + }); t.RunSynchronously (); Assert.IsTrue (r1); @@ -1932,6 +1988,24 @@ namespace MonoTests.System.Threading.Tasks } } + [Test] + public void ChildTaskWithUnscheduledContinuationAttachedToParent () + { + Task inner = null; + var child = Task.Factory.StartNew (() => { + inner = Task.Run (() => { + throw new ApplicationException (); + }).ContinueWith (task => { }, TaskContinuationOptions.AttachedToParent | TaskContinuationOptions.NotOnFaulted | TaskContinuationOptions.ExecuteSynchronously); + }); + + int counter = 0; + var t = child.ContinueWith (t2 => ++counter, TaskContinuationOptions.ExecuteSynchronously); + Assert.IsTrue (t.Wait (5000), "#1"); + Assert.AreEqual (1, counter, "#2"); + Assert.AreEqual (TaskStatus.RanToCompletion, child.Status, "#3"); + Assert.AreEqual (TaskStatus.Canceled, inner.Status, "#4"); + } + [Test] [Category("NotWorking")] public void TaskContinuationChainLeak() diff --git a/mcs/class/corlib/Test/System.Threading/ThreadTest.cs b/mcs/class/corlib/Test/System.Threading/ThreadTest.cs index 8c82931acc..67bcd941d4 100644 --- a/mcs/class/corlib/Test/System.Threading/ThreadTest.cs +++ b/mcs/class/corlib/Test/System.Threading/ThreadTest.cs @@ -85,10 +85,10 @@ namespace MonoTests.System.Threading [Category("MobileNotWorking")] // Abort #10240 public class ThreadTest { - TimeSpan Infinite = new TimeSpan (-10000); // -10000 ticks == -1 ms + //TimeSpan Infinite = new TimeSpan (-10000); // -10000 ticks == -1 ms TimeSpan SmallNegative = new TimeSpan (-2); // between 0 and -1.0 (infinite) ms TimeSpan Negative = new TimeSpan (-20000); // really negative - TimeSpan MaxValue = TimeSpan.FromMilliseconds ((long) Int32.MaxValue); + //TimeSpan MaxValue = TimeSpan.FromMilliseconds ((long) Int32.MaxValue); TimeSpan TooLarge = TimeSpan.FromMilliseconds ((long) Int32.MaxValue + 1); static bool is_win32; @@ -526,13 +526,44 @@ namespace MonoTests.System.Threading [Test] [ExpectedException (typeof (InvalidOperationException))] - public void ReName () + public void Rename () { - Thread t = new Thread (new ThreadStart (ReName)); + Thread t = new Thread (new ThreadStart (Rename)); t.Name = "a"; t.Name = "b"; } + bool rename_finished; + bool rename_failed; + + [Test] + public void RenameTpThread () + { + object monitor = new object (); + ThreadPool.QueueUserWorkItem (new WaitCallback (Rename_callback), monitor); + lock (monitor) { + if (!rename_finished) + Monitor.Wait (monitor); + } + Assert.IsTrue (!rename_failed); + } + + void Rename_callback (object o) { + Thread.CurrentThread.Name = "a"; + try { + Thread.CurrentThread.Name = "b"; + //Console.WriteLine ("Thread name is: {0}", Thread.CurrentThread.Name); + } catch (Exception e) { + //Console.Error.WriteLine (e); + rename_failed = true; + } + object monitor = o; + lock (monitor) { + rename_finished = true; + Monitor.Pulse (monitor); + } + } + [Test] public void TestNestedThreads1() { diff --git a/mcs/class/corlib/Test/System/AppDomainTest.cs.REMOVED.git-id b/mcs/class/corlib/Test/System/AppDomainTest.cs.REMOVED.git-id index a956e5126a..1cd72ee102 100644 --- a/mcs/class/corlib/Test/System/AppDomainTest.cs.REMOVED.git-id +++ b/mcs/class/corlib/Test/System/AppDomainTest.cs.REMOVED.git-id @@ -1 +1 @@ -8772d7afdea04e8771c54266715144cacfffa015 \ No newline at end of file +0836640057e3cfabdb47c8cc3ab4990f87869cad \ No newline at end of file diff --git a/mcs/class/corlib/Test/System/DateTimeOffsetTest.cs b/mcs/class/corlib/Test/System/DateTimeOffsetTest.cs index a898f2db6e..13564426ae 100644 --- a/mcs/class/corlib/Test/System/DateTimeOffsetTest.cs +++ b/mcs/class/corlib/Test/System/DateTimeOffsetTest.cs @@ -705,6 +705,23 @@ namespace MonoTests.System { expected = string.Format ("{0:D2}/{1:D2}/{2} 00:00:45 +00:00", now.Month, now.Day, now.Year); Assert.AreEqual (expected, date.ToString (CultureInfo.InvariantCulture)); } + + [Test] + public void TestDateOnlyWithTimeOffset () + { + var fp = CultureInfo.InvariantCulture; + var date = DateTimeOffset.Parse("2013-11-07+11:00", fp, DateTimeStyles.AssumeUniversal); + var expected = string.Format ("{0:D2}/{1:D2}/{2} 00:00:00 +11:00", 11, 7, 2013); + Assert.AreEqual (expected, date.ToString (CultureInfo.InvariantCulture)); + } + + [Test] + public void GMTDateTime () + { + var date = DateTimeOffset.Parse ("Wed, 10 Sep 2014 22:01:40 GMT", CultureInfo.InvariantCulture); + var expected = "09/10/2014 22:01:40 +00:00"; + Assert.AreEqual (expected, date.ToString (CultureInfo.InvariantCulture)); + } } } diff --git a/mcs/class/corlib/Test/System/DateTimeTest.cs b/mcs/class/corlib/Test/System/DateTimeTest.cs index 343e723be8..202c3d2117 100644 --- a/mcs/class/corlib/Test/System/DateTimeTest.cs +++ b/mcs/class/corlib/Test/System/DateTimeTest.cs @@ -2584,5 +2584,40 @@ namespace MonoTests.System Assert.AreEqual (dt, parsed, "#1"); } + + [Test] + public void ISO8601FractionalDigits () + { + string date = "2014-08-25T01:20:23.601911612343423423465789789365674575676746756747467Z"; + long expectedTicks = 635445264236019116; + + var dt = DateTime.Parse (date, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind); + + Assert.AreEqual (expectedTicks, dt.Ticks); + } + + [Test] + [ExpectedException (typeof (FormatException))] + public void ISO8601FractionalDigitsException1 () + { + string date = "2014-08-25T01:20:23.60191161234342342346578978936567457567:6746756747467Z"; + DateTime.Parse (date, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind); + } + + [Test] + [ExpectedException (typeof (FormatException))] + public void ISO8601FractionalDigitsException2 () + { + string date = "2014-08-25T01:20:23.6019116-12343423423465789789365674575676746756747467Z"; + DateTime.Parse (date, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind); + } + + [Test] + [ExpectedException (typeof (FormatException))] + public void ISO8601FractionalDigitsException3 () + { + string date = "2014-08-25T01:20:23.601911612343423423465789789365674575676746756747467%Z"; + DateTime.Parse (date, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind); + } } } diff --git a/mcs/class/corlib/Test/System/SByteTest.cs b/mcs/class/corlib/Test/System/SByteTest.cs index 9bf4d31a1c..c8d40396c2 100644 --- a/mcs/class/corlib/Test/System/SByteTest.cs +++ b/mcs/class/corlib/Test/System/SByteTest.cs @@ -24,12 +24,15 @@ public class SByteTest private const string MyString3 = "127"; private string[] Formats1 = {"c", "d", "e", "f", "g", "n", "p", "x" }; private string[] Formats2 = {"c5", "d5", "e5", "f5", "g5", "n5", "p5", "x5" }; +#if false + // These are not currently being tested against, due to the locale-specific nature of the test, we need a different way of doing this private string[] Results1 = {"("+NumberFormatInfo.CurrentInfo.CurrencySymbol+"128.00)", "-128", "-1.280000e+002", "-128.00", "-128", "-128.00", "-12,800.00 %", "80"}; private string[] Results2 = {NumberFormatInfo.CurrentInfo.CurrencySymbol+"127.00000", "00127", "1.27000e+002", "127.00000", "127", "127.00000", "12,700.00000 %", "0007f"}; +#endif private string[] ResultsNfi1 = {"("+NumberFormatInfo.InvariantInfo.CurrencySymbol+"128.00)", "-128", "-1.280000e+002", "-128.00", "-128", "-128.00", "-12,800.00 %", "80"}; @@ -161,14 +164,17 @@ public class SByteTest Assert.IsTrue(String.Compare(MyString2, MySByte2.ToString()) == 0, "MyString2, MySByte2.ToString()"); Assert.IsTrue(String.Compare(MyString3, MySByte3.ToString()) == 0, "MyString3, MySByte3.ToString()"); //test ToString(string format) + +#if false /* - TODO: These tests depend on the culture of the system running the test. - So, this needs to be tested in a different way. + * TODO: These tests depend on the culture of the system running the test. + * So, this needs to be tested in a different way. + / for (int i=0; i < Formats1.Length; i++) { Assert.IsTrue("i="+i+", Results1[i]="+Results1[i]+", MySByte2.ToString(Formats1[i])="+MySByte2.ToString(Formats1[i]), String.Compare(Results1[i], MySByte2.ToString(Formats1[i])) == 0); Assert.IsTrue(String.Compare(Results2[i], MySByte3.ToString(Formats2[i])) == 0, "Results2[i], MySByte3.ToString(Formats2[i])"); } - */ +#endif //test ToString(string format, IFormatProvider provider); for (int i=0; i < Formats1.Length; i++) { Assert.IsTrue(String.Compare(ResultsNfi1[i], MySByte2.ToString(Formats1[i], Nfi)) == 0, "i="+i+", ResultsNfi1[i]="+ResultsNfi1[i]+", MySByte2.ToString(Formats1[i]="+Formats1[i]+"): Expected "+ResultsNfi1[i]+" but got "+MySByte2.ToString(Formats1[i], Nfi)); diff --git a/mcs/class/corlib/Test/System/TimeSpanTest.cs b/mcs/class/corlib/Test/System/TimeSpanTest.cs index 101cad48a9..2d9e098499 100644 --- a/mcs/class/corlib/Test/System/TimeSpanTest.cs +++ b/mcs/class/corlib/Test/System/TimeSpanTest.cs @@ -1430,6 +1430,18 @@ public class TimeSpanTest { ts = new TimeSpan (123456789); Assert.AreEqual ("12.3", ts.ToString ("s\\.f"), "#F0"); Assert.AreEqual ("12.3", ts.ToString ("s\\.F"), "#F1"); + Assert.AreEqual ("12.3456789", ts.ToString ("s\\.fffffff"), "#F2"); + Assert.AreEqual ("12.345678", ts.ToString ("s\\.ffffff"), "#F3"); + + ts = new TimeSpan (1234); + Assert.AreEqual ("0.000123", ts.ToString ("s\\.ffffff"), "#G0"); + Assert.AreEqual ("0.0001", ts.ToString ("s\\.ffff"), "#G1"); + Assert.AreEqual ("0.", ts.ToString ("s\\.F"), "#G2"); + Assert.AreEqual ("0.", ts.ToString ("s\\.FFF"), "#G3"); + + ts = TimeSpan.FromSeconds (0.05); + Assert.AreEqual (".0", ts.ToString ("\\.f"), "#H0"); + Assert.AreEqual (".", ts.ToString ("\\.F"), "#H1"); } [Test] diff --git a/mcs/class/corlib/Test/System/TimeZoneTest.cs b/mcs/class/corlib/Test/System/TimeZoneTest.cs index 6f97c359eb..47915f722b 100644 --- a/mcs/class/corlib/Test/System/TimeZoneTest.cs +++ b/mcs/class/corlib/Test/System/TimeZoneTest.cs @@ -303,11 +303,12 @@ public class TimeZoneTest { TimeZone tz = TimeZone.CurrentTimeZone; - DaylightTime daylightChanges = tz.GetDaylightChanges(2007); + int year = DateTime.Now.Year; + DaylightTime daylightChanges = tz.GetDaylightChanges(year); DateTime dst_end = daylightChanges.End; if (dst_end == DateTime.MinValue) - Assert.Ignore (tz.StandardName + " did not observe daylight saving time during 2007."); + Assert.Ignore (tz.StandardName + " did not observe daylight saving time during " + year + "."); var standardOffset = tz.GetUtcOffset(daylightChanges.Start.AddMinutes(-1)); diff --git a/mcs/class/corlib/Test/System/TypeTest.cs.REMOVED.git-id b/mcs/class/corlib/Test/System/TypeTest.cs.REMOVED.git-id index 34af34a320..5c7b6694c4 100644 --- a/mcs/class/corlib/Test/System/TypeTest.cs.REMOVED.git-id +++ b/mcs/class/corlib/Test/System/TypeTest.cs.REMOVED.git-id @@ -1 +1 @@ -00131c8d47f1d59ef4266e335ec71b293424a720 \ No newline at end of file +6acbac2dd9f4343e294871c32192c68a76bef31b \ No newline at end of file diff --git a/mcs/class/corlib/corlib.dll.sources b/mcs/class/corlib/corlib.dll.sources index 2626ca0fa3..b1516b8bb1 100644 --- a/mcs/class/corlib/corlib.dll.sources +++ b/mcs/class/corlib/corlib.dll.sources @@ -160,6 +160,7 @@ System/EventHandler.cs System/Exception.cs System/ExecutionEngineException.cs System/FieldAccessException.cs +System/FirstChanceExceptionEventArgs.cs System/FlagsAttribute.cs System/FormatException.cs System/Funcs.cs diff --git a/mcs/class/corlib/corlib_test.dll.sources b/mcs/class/corlib/corlib_test.dll.sources index 1742ea7ff2..8cb367e813 100644 --- a/mcs/class/corlib/corlib_test.dll.sources +++ b/mcs/class/corlib/corlib_test.dll.sources @@ -394,6 +394,7 @@ System.Text/EncoderReplacementFallbackTest.cs System.Text/EncoderReplacementFallbackBufferTest.cs System.Text/EncoderTest.cs System.Text/EncodingTest.cs +System.Text/EncodingTester.cs System.Text/EncodingInfoTest.cs System.Text/StringBuilderTest.cs System.Text/TestEncoding.cs diff --git a/mcs/class/lib/monolite/Mono.Security.dll.REMOVED.git-id b/mcs/class/lib/monolite/Mono.Security.dll.REMOVED.git-id index 9240a600a5..d55c74b89a 100644 --- a/mcs/class/lib/monolite/Mono.Security.dll.REMOVED.git-id +++ b/mcs/class/lib/monolite/Mono.Security.dll.REMOVED.git-id @@ -1 +1 @@ -5b8e224fa9481084001662643e1cdbc1f673e10d \ No newline at end of file +9ba190dcc3688e2a5c13d7497222758bd633e940 \ No newline at end of file diff --git a/mcs/class/lib/monolite/System.Configuration.dll.REMOVED.git-id b/mcs/class/lib/monolite/System.Configuration.dll.REMOVED.git-id index e7bc5aa74e..c78f33d1ea 100644 --- a/mcs/class/lib/monolite/System.Configuration.dll.REMOVED.git-id +++ b/mcs/class/lib/monolite/System.Configuration.dll.REMOVED.git-id @@ -1 +1 @@ -b20597424d2e2135392b1a3e5aa67833c75adf31 \ No newline at end of file +e4a2800a0dcd404b2c1b5b83674c10e1fbbfc422 \ No newline at end of file diff --git a/mcs/class/lib/monolite/System.Core.dll.REMOVED.git-id b/mcs/class/lib/monolite/System.Core.dll.REMOVED.git-id index e8d6e8857b..900521a7dd 100644 --- a/mcs/class/lib/monolite/System.Core.dll.REMOVED.git-id +++ b/mcs/class/lib/monolite/System.Core.dll.REMOVED.git-id @@ -1 +1 @@ -ca8421296f0aa9bfdef632b978a2fd7e3e6940bb \ No newline at end of file +8d3febc3bcc1a68179e2254527f999c81709567e \ No newline at end of file diff --git a/mcs/class/lib/monolite/System.Security.dll.REMOVED.git-id b/mcs/class/lib/monolite/System.Security.dll.REMOVED.git-id index be80e53cf1..65dc310376 100644 --- a/mcs/class/lib/monolite/System.Security.dll.REMOVED.git-id +++ b/mcs/class/lib/monolite/System.Security.dll.REMOVED.git-id @@ -1 +1 @@ -9253977cbe70921348857fb0ef21dead19122c87 \ No newline at end of file +de746eb848148a6d8d547c4fe4957549830f4100 \ No newline at end of file diff --git a/mcs/class/lib/monolite/System.Xml.dll.REMOVED.git-id b/mcs/class/lib/monolite/System.Xml.dll.REMOVED.git-id index 871cd6ee04..85e1bdff09 100644 --- a/mcs/class/lib/monolite/System.Xml.dll.REMOVED.git-id +++ b/mcs/class/lib/monolite/System.Xml.dll.REMOVED.git-id @@ -1 +1 @@ -32454d725a6010db4fd251c735e405c1ebc59977 \ No newline at end of file +388c79223d2c9dfd31370959baa8e0732bf2c782 \ No newline at end of file diff --git a/mcs/class/lib/monolite/System.dll.REMOVED.git-id b/mcs/class/lib/monolite/System.dll.REMOVED.git-id index 206678145f..81f82b792f 100644 --- a/mcs/class/lib/monolite/System.dll.REMOVED.git-id +++ b/mcs/class/lib/monolite/System.dll.REMOVED.git-id @@ -1 +1 @@ -ba60082d7e7490b58fb91795fdb420ff05591835 \ No newline at end of file +954b224e92c0ca40db3ed841324c99ac14419a15 \ No newline at end of file diff --git a/mcs/class/lib/monolite/basic.exe.REMOVED.git-id b/mcs/class/lib/monolite/basic.exe.REMOVED.git-id index f26bded4cd..04199ecf5b 100644 --- a/mcs/class/lib/monolite/basic.exe.REMOVED.git-id +++ b/mcs/class/lib/monolite/basic.exe.REMOVED.git-id @@ -1 +1 @@ -00b0a4fdfb9c1ef66208d8d7ad98eec76756d82a \ No newline at end of file +7eb420e04eb9641a8be30dbe4ad33d7591466e00 \ No newline at end of file diff --git a/mcs/class/lib/monolite/mscorlib.dll.REMOVED.git-id b/mcs/class/lib/monolite/mscorlib.dll.REMOVED.git-id index abc8942ce8..511b2a6d04 100644 --- a/mcs/class/lib/monolite/mscorlib.dll.REMOVED.git-id +++ b/mcs/class/lib/monolite/mscorlib.dll.REMOVED.git-id @@ -1 +1 @@ -200d0dc081762380fe545c97520cb5d550c5d368 \ No newline at end of file +289dd62af9a9073a05a3d659b08b4bdb0fe1db4a \ No newline at end of file diff --git a/mcs/errors/cs0023-25.cs b/mcs/errors/cs0023-25.cs new file mode 100644 index 0000000000..d6f5c5bbe1 --- /dev/null +++ b/mcs/errors/cs0023-25.cs @@ -0,0 +1,10 @@ +// CS0023: The `?' operator cannot be applied to operand of type `T' +// Line: 8 + +class C +{ + static void Foo (T t) where T : struct + { + var r = t?.ToString (); + } +} \ No newline at end of file diff --git a/mcs/errors/cs0111-12.cs b/mcs/errors/cs0111-12.cs new file mode 100644 index 0000000000..034963c22a --- /dev/null +++ b/mcs/errors/cs0111-12.cs @@ -0,0 +1,15 @@ +// CS0111: A member `S3.S3(string)' is already defined. Rename this member or use different parameter types +// Line: 6 + +struct S3 (string s) +{ + public S3 (string s) + : this (1) + { + } + + public S3 (int i) + : this ("") + { + } +} diff --git a/mcs/errors/cs0411-24.cs b/mcs/errors/cs0411-24.cs new file mode 100644 index 0000000000..1462cbac23 --- /dev/null +++ b/mcs/errors/cs0411-24.cs @@ -0,0 +1,15 @@ +// CS0411: The type arguments for method `C.Foo(out T)' cannot be inferred from the usage. Try specifying the type arguments explicitly +// Line: 8 + +public class C +{ + public static void Main () + { + Foo (out var y); + } + + static void Foo (out T t) + { + t = default (T); + } +} \ No newline at end of file diff --git a/mcs/errors/cs0429-5.cs b/mcs/errors/cs0429-5.cs deleted file mode 100644 index 1cc67a2281..0000000000 --- a/mcs/errors/cs0429-5.cs +++ /dev/null @@ -1,26 +0,0 @@ -// CS0429: Unreachable expression code detected -// Line: 24 -// Compiler options: -warnaserror - -using System; - -struct S -{ -} - -class C -{ - public static implicit operator S (C c) - { - return new S (); - } -} - -class Program -{ - static void Main () - { - C c = new C (); - Console.WriteLine (c ?? new S ()); - } -} diff --git a/mcs/errors/cs0516-3.cs b/mcs/errors/cs0516-3.cs new file mode 100644 index 0000000000..1ff6d06289 --- /dev/null +++ b/mcs/errors/cs0516-3.cs @@ -0,0 +1,9 @@ +// CS0516: Constructor `Sample.Sample()' cannot call itself +// Line: 6 + +struct Sample { + public Sample () + : this () + { + } +} diff --git a/mcs/errors/cs0516.cs b/mcs/errors/cs0516.cs index 47b0fdee73..5c41f8dc4e 100644 --- a/mcs/errors/cs0516.cs +++ b/mcs/errors/cs0516.cs @@ -1,9 +1,9 @@ // CS0516: Constructor `Sample.Sample()' cannot call itself -// Line: 5 +// Line: 6 class Sample { - public Sample (): this () {} + public Sample () + : this () + { + } } - - - diff --git a/mcs/errors/cs0568.cs b/mcs/errors/cs0568.cs deleted file mode 100644 index 944d7a90b7..0000000000 --- a/mcs/errors/cs0568.cs +++ /dev/null @@ -1,14 +0,0 @@ -// CS0568: Structs cannot contain explicit parameterless constructors -// Line: 5 -struct A { - int a; - A () { a = 1; } -} - -class D { - static void Main () - { - A [] a = new A [10]; - - } -} diff --git a/mcs/errors/cs0573-2.cs b/mcs/errors/cs0573-2.cs new file mode 100644 index 0000000000..443bed3912 --- /dev/null +++ b/mcs/errors/cs0573-2.cs @@ -0,0 +1,7 @@ +// CS0573: 'S': Structs cannot have instance property or field initializers +// Line: 6 + +struct S +{ + public int Prop { get; set; } = 3; +} diff --git a/mcs/errors/cs0573.cs b/mcs/errors/cs0573.cs new file mode 100644 index 0000000000..fd8de1ebc6 --- /dev/null +++ b/mcs/errors/cs0573.cs @@ -0,0 +1,7 @@ +// CS0573: 'S': Structs cannot have instance property or field initializers +// Line: 6 + +struct S +{ + int v = 0; +} diff --git a/mcs/errors/cs0619-58.cs b/mcs/errors/cs0619-58.cs new file mode 100644 index 0000000000..faf79c7dab --- /dev/null +++ b/mcs/errors/cs0619-58.cs @@ -0,0 +1,20 @@ +// CS0619: `S.S()' is obsolete: `ctor' +// Line: 18 + +using System; + +struct S +{ + [Obsolete ("ctor", true)] + public S () + { + } +} + +class C +{ + public static void Main () + { + new S (); + } +} diff --git a/mcs/errors/cs0677-5.cs b/mcs/errors/cs0677-5.cs new file mode 100644 index 0000000000..a6d2248640 --- /dev/null +++ b/mcs/errors/cs0677-5.cs @@ -0,0 +1,11 @@ +// CS0677: `X.e': A volatile field cannot be of the type `E' +// Line: 10 + +enum E : long +{ +} + +class X +{ + volatile E e; +} diff --git a/mcs/errors/cs0815-7.cs b/mcs/errors/cs0815-7.cs new file mode 100644 index 0000000000..ae41a72d91 --- /dev/null +++ b/mcs/errors/cs0815-7.cs @@ -0,0 +1,15 @@ +// CS0815: An implicitly typed local variable declaration cannot be initialized with `void' +// Line: 8 + +class X +{ + public static void Main () + { + Foo (out var x = Main ()); + } + + static void Foo (out int i) + { + i = 0; + } +} \ No newline at end of file diff --git a/mcs/errors/cs0841-5.cs b/mcs/errors/cs0841-5.cs new file mode 100644 index 0000000000..798b33547c --- /dev/null +++ b/mcs/errors/cs0841-5.cs @@ -0,0 +1,15 @@ +// CS0841: A local variable `x' cannot be used before it is declared +// Line: 8 + +class X +{ + public static void Main () + { + Foo (x, out var x); + } + + static void Foo (int arg, out int value) + { + value = 3; + } +} \ No newline at end of file diff --git a/mcs/errors/cs1501-18.cs b/mcs/errors/cs1501-18.cs new file mode 100644 index 0000000000..b22ab55c40 --- /dev/null +++ b/mcs/errors/cs1501-18.cs @@ -0,0 +1,22 @@ +// CS1501: No overload for method `Bar' takes `2' arguments +// Line: 19 + +using System; + +class T +{ + void Foo (int arg, Action a) + { + } + + void Foo (string title, Action a) + { + } + + void Bar () + { + Foo (arg: 1, a: () => { + Bar ("a", "b"); + }); + } +} \ No newline at end of file diff --git a/mcs/errors/cs1503-17.cs b/mcs/errors/cs1503-17.cs new file mode 100644 index 0000000000..26766c0ade --- /dev/null +++ b/mcs/errors/cs1503-17.cs @@ -0,0 +1,14 @@ +// CS1501: Argument `#1' cannot convert `ref string' expression to type `ref int' +// Line: 8 + +class C +{ + public static void Main () + { + Foo (ref var x = ""); + } + + static void Foo (ref int i) + { + } +} \ No newline at end of file diff --git a/mcs/errors/cs1525-10.cs b/mcs/errors/cs1525-10.cs index ca5ff02ecb..3bd7f52d6d 100755 --- a/mcs/errors/cs1525-10.cs +++ b/mcs/errors/cs1525-10.cs @@ -1,4 +1,4 @@ -// CS1525: Unexpected symbol `ref', expecting `.', `?', `[', `', or `identifier' +// CS1525: Unexpected symbol `ref' // Line: 8 public class Test diff --git a/mcs/errors/cs1615-3.cs b/mcs/errors/cs1615-3.cs new file mode 100644 index 0000000000..c64fb7fe84 --- /dev/null +++ b/mcs/errors/cs1615-3.cs @@ -0,0 +1,18 @@ +// CS1615: Argument `#1' does not require `out' modifier. Consider removing `out' modifier +// Line: 8 + +public class C +{ + public static void Main () + { + Foo (out var y); + } + + static void Foo (int x) + { + } + + static void Foo (string x) + { + } +} \ No newline at end of file diff --git a/mcs/errors/cs1644-45.cs b/mcs/errors/cs1644-45.cs new file mode 100644 index 0000000000..3aa2033141 --- /dev/null +++ b/mcs/errors/cs1644-45.cs @@ -0,0 +1,10 @@ +// CS1644: Feature `struct parameterless instance constructor' cannot be used because it is not part of the C# 5.0 language specification +// Line: 12 +// Compiler options: -langversion:5 + +struct S +{ + public S () + { + } +} \ No newline at end of file diff --git a/mcs/errors/cs1644-47.cs b/mcs/errors/cs1644-47.cs new file mode 100644 index 0000000000..b756cd7b60 --- /dev/null +++ b/mcs/errors/cs1644-47.cs @@ -0,0 +1,11 @@ +// CS1644: Feature `declaration expression' cannot be used because it is not part of the C# 5.0 language specification +// Line: 12 +// Compiler options: -langversion:5 + +class C +{ + public static void Main () + { + int.TryParse ("0", out var v); + } +} \ No newline at end of file diff --git a/mcs/errors/cs1736-2.cs b/mcs/errors/cs1736-2.cs new file mode 100644 index 0000000000..c9c9e849a2 --- /dev/null +++ b/mcs/errors/cs1736-2.cs @@ -0,0 +1,16 @@ +// CS1736: The expression being assigned to optional parameter `s' must be a constant or default value +// Line: 11 + +struct S +{ + public S () + { + } +} + +class X +{ + public void Foo (S s = new S ()) + { + } +} \ No newline at end of file diff --git a/mcs/errors/cs7048.cs b/mcs/errors/cs7048.cs new file mode 100644 index 0000000000..398c32e7dc --- /dev/null +++ b/mcs/errors/cs7048.cs @@ -0,0 +1,26 @@ +// CS7048: First argument of a security attribute `CustomSecurityAttribute' must be a valid SecurityAction +// Line: 20 + +using System.Security; +using System.Security.Permissions; + +public class CustomSecurityAttribute : CodeAccessSecurityAttribute +{ + public CustomSecurityAttribute () + : base (SecurityAction.Demand) + { + } + + public override IPermission CreatePermission() + { + return null; + } +} + +[CustomSecurity] +class X +{ + public static void Main () + { + } +} diff --git a/mcs/errors/cs8046.cs b/mcs/errors/cs8046.cs new file mode 100644 index 0000000000..f8b9ad556f --- /dev/null +++ b/mcs/errors/cs8046.cs @@ -0,0 +1,19 @@ +// CS8046: An expression tree cannot contain a declaration expression +// Line: 11 + +using System; +using System.Linq.Expressions; + +class C +{ + static void Main() + { + Expression> e = () => Out (out int x); + } + + static bool Out (out int value) + { + value = 3; + return true; + } +} \ No newline at end of file diff --git a/mcs/errors/cs8047.cs b/mcs/errors/cs8047.cs new file mode 100644 index 0000000000..7171d569ce --- /dev/null +++ b/mcs/errors/cs8047.cs @@ -0,0 +1,19 @@ +// CS8047: Declaration expression cannot be used in this context +// Line: 8 + +public class C +{ + public static void Main () + { + dynamic target = 3; + var x = new Test (target, out var y); + } +} + +class Test +{ + public Test (int x, out int y) + { + y = 0; + } +} \ No newline at end of file diff --git a/mcs/errors/cs8054-2.cs b/mcs/errors/cs8054-2.cs deleted file mode 100644 index e633f17606..0000000000 --- a/mcs/errors/cs8054-2.cs +++ /dev/null @@ -1,6 +0,0 @@ -// CS0573: `A.a': Structs without explicit constructors cannot contain members with initializers -// Line: 5 - -partial struct A { - int a = 1; -} diff --git a/mcs/errors/cs8054-3.cs b/mcs/errors/cs8054-3.cs deleted file mode 100644 index b06047fb6e..0000000000 --- a/mcs/errors/cs8054-3.cs +++ /dev/null @@ -1,6 +0,0 @@ -// CS0573: `A.a': Structs without explicit constructors cannot contain members with initializers -// Line: 5 - -struct A { - int a = 1; -} diff --git a/mcs/errors/cs8054.cs b/mcs/errors/cs8054.cs deleted file mode 100644 index 4b8fc2ed44..0000000000 --- a/mcs/errors/cs8054.cs +++ /dev/null @@ -1,7 +0,0 @@ -// CS8054: `S.P': Structs without explicit constructors cannot contain members with initializers -// Line: 6 - -struct S -{ - public decimal P { get; } = -3; -} \ No newline at end of file diff --git a/mcs/errors/cs8075.cs b/mcs/errors/cs8075.cs new file mode 100644 index 0000000000..93333f7187 --- /dev/null +++ b/mcs/errors/cs8075.cs @@ -0,0 +1,9 @@ +// CS8075: `A.A()': Structs parameterless instance constructor must be public +// Line: 6 + +struct A +{ + A () + { + } +} diff --git a/mcs/mcs/anonymous.cs b/mcs/mcs/anonymous.cs index 9d9558f7ec..847cbcfd5d 100644 --- a/mcs/mcs/anonymous.cs +++ b/mcs/mcs/anonymous.cs @@ -1792,11 +1792,9 @@ namespace Mono.CSharp { // this argument is generated during compilation which speeds up dispatch // by about 25% // - + // Unused as it breaks compatibility // - // Disabled for now due to JIT bug - // - //method_parameters = ParametersCompiled.Prefix (method_parameters, + // method_parameters = ParametersCompiled.Prefix (method_parameters, // new Parameter (null, null, 0, null, loc), ec.Module.Compiler.BuiltinTypes.Object); } diff --git a/mcs/mcs/attribute.cs b/mcs/mcs/attribute.cs index 7318f26059..8cf9eb9d30 100644 --- a/mcs/mcs/attribute.cs +++ b/mcs/mcs/attribute.cs @@ -832,9 +832,9 @@ namespace Mono.CSharp { /// bool IsSecurityActionValid () { - SecurityAction action = GetSecurityActionValue (); + Constant c = null; + var action = GetSecurityActionValue (ref c); bool for_assembly = Target == AttributeTargets.Assembly || Target == AttributeTargets.Module; - var c = (Constant)pos_args [0].Expr; switch (action) { #pragma warning disable 618 @@ -855,6 +855,10 @@ namespace Mono.CSharp { return true; break; #pragma warning restore 618 + case null: + Report.Error (7048, loc, "First argument of a security attribute `{0}' must be a valid SecurityAction", + Type.GetSignatureForError ()); + return false; default: Report.Error (7049, c.Location, "Security attribute `{0}' has an invalid SecurityAction value `{1}'", @@ -876,9 +880,25 @@ namespace Mono.CSharp { return false; } - System.Security.Permissions.SecurityAction GetSecurityActionValue () + SecurityAction? GetSecurityActionValue (ref Constant value) { - return (SecurityAction) ((Constant) pos_args[0].Expr).GetValue (); + if (pos_args == null) { + var predefined = context.Module.PredefinedAttributes; + + // + // BCL defines System.Security.Permissions.HostProtectionAttribute with parameterless + // contructor which should not be valid but it's already part of the framework + // + if (Type == predefined.HostProtection.TypeSpec) { + value = new IntConstant (context.Module.Compiler.BuiltinTypes, (int)SecurityAction.LinkDemand, loc); + return SecurityAction.LinkDemand; + } + + return null; + } + + value = (Constant) pos_args [0].Expr; + return (SecurityAction) value.GetValue (); } /// @@ -888,9 +908,14 @@ namespace Mono.CSharp { public void ExtractSecurityPermissionSet (MethodSpec ctor, ref SecurityType permissions) { #if STATIC - object[] values = new object[pos_args.Count]; - for (int i = 0; i < values.Length; ++i) - values[i] = ((Constant) pos_args[i].Expr).GetValue (); + object[] values; + if (pos_args != null) { + values = new object[pos_args.Count]; + for (int i = 0; i < values.Length; ++i) + values[i] = ((Constant) pos_args[i].Expr).GetValue (); + } else { + values = null; + } PropertyInfo[] prop; object[] prop_values; @@ -1679,6 +1704,7 @@ namespace Mono.CSharp { public readonly PredefinedDebuggerBrowsableAttribute DebuggerBrowsable; public readonly PredefinedAttribute DebuggerStepThrough; public readonly PredefinedDebuggableAttribute Debuggable; + public readonly PredefinedAttribute HostProtection; // New in .NET 3.5 public readonly PredefinedAttribute Extension; @@ -1734,6 +1760,7 @@ namespace Mono.CSharp { DefaultParameterValue = new PredefinedAttribute (module, "System.Runtime.InteropServices", "DefaultParameterValueAttribute"); OptionalParameter = new PredefinedAttribute (module, "System.Runtime.InteropServices", "OptionalAttribute"); UnverifiableCode = new PredefinedAttribute (module, "System.Security", "UnverifiableCodeAttribute"); + HostProtection = new PredefinedAttribute (module, "System.Security.Permissions", "HostProtectionAttribute"); DefaultCharset = new PredefinedAttribute (module, "System.Runtime.InteropServices", "DefaultCharSetAttribute"); TypeForwarder = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "TypeForwardedToAttribute"); diff --git a/mcs/mcs/class.cs.REMOVED.git-id b/mcs/mcs/class.cs.REMOVED.git-id index 8244f9dd8e..ad8df6e06b 100644 --- a/mcs/mcs/class.cs.REMOVED.git-id +++ b/mcs/mcs/class.cs.REMOVED.git-id @@ -1 +1 @@ -b1db2644e3be19de5f04184f3f8ac5e55b99f6e9 \ No newline at end of file +5dac7c44002dad96b133628063cb42ce2bb7edb4 \ No newline at end of file diff --git a/mcs/mcs/codegen.cs b/mcs/mcs/codegen.cs index 55a061cf03..6dfe7b6ce6 100644 --- a/mcs/mcs/codegen.cs +++ b/mcs/mcs/codegen.cs @@ -222,6 +222,8 @@ namespace Mono.CSharp public List TryFinallyUnwind { get; set; } + public Label RecursivePatternLabel { get; set; } + #endregion public void AddStatementEpilog (IExpressionCleanup cleanupExpression) @@ -547,13 +549,10 @@ namespace Mono.CSharp switch (type.BuiltinType) { case BuiltinTypeSpec.Type.Bool: // - // Workaround MSIL limitation. Load bool element as single bit, - // bool array can actually store any byte value + // bool array can actually store any byte value in underlying byte slot + // and C# spec does not specify any normalization rule, except the result + // is undefined // - ig.Emit (OpCodes.Ldelem_U1); - ig.Emit (OpCodes.Ldc_I4_0); - ig.Emit (OpCodes.Cgt_Un); - break; case BuiltinTypeSpec.Type.Byte: ig.Emit (OpCodes.Ldelem_U1); break; @@ -769,12 +768,8 @@ namespace Mono.CSharp ig.Emit (OpCodes.Ldind_U1); break; case BuiltinTypeSpec.Type.SByte: - ig.Emit (OpCodes.Ldind_I1); - break; case BuiltinTypeSpec.Type.Bool: ig.Emit (OpCodes.Ldind_I1); - ig.Emit (OpCodes.Ldc_I4_0); - ig.Emit (OpCodes.Cgt_Un); break; case BuiltinTypeSpec.Type.ULong: case BuiltinTypeSpec.Type.Long: @@ -1064,7 +1059,7 @@ namespace Mono.CSharp var ie = new InstanceEmitter (instance_copy, IsAddressCall (instance_copy, call_op, method.DeclaringType)); if (Arguments == null) { - ie.EmitLoad (ec); + ie.EmitLoad (ec, true); } } else if (!InstanceExpressionOnStack) { var ie = new InstanceEmitter (InstanceExpression, IsAddressCall (InstanceExpression, call_op, method.DeclaringType)); @@ -1226,7 +1221,7 @@ namespace Mono.CSharp instance_address = instance as LocalTemporary; if (instance_address == null) { - EmitLoad (ec); + EmitLoad (ec, false); ec.Emit (OpCodes.Dup); ec.EmitLoadFromPtr (instance.Type); @@ -1234,11 +1229,8 @@ namespace Mono.CSharp } else { instance.Emit (ec); } - - if (instance.Type.Kind == MemberKind.TypeParameter) - ec.Emit (OpCodes.Box, instance.Type); } else { - EmitLoad (ec); + EmitLoad (ec, !conditionalAccess); if (conditionalAccess) { conditional_access_dup = !IsInexpensiveLoad (); @@ -1248,6 +1240,9 @@ namespace Mono.CSharp } if (conditionalAccess) { + if (instance.Type.Kind == MemberKind.TypeParameter) + ec.Emit (OpCodes.Box, instance.Type); + ec.Emit (OpCodes.Brtrue_S, NullOperatorLabel); if (conditional_access_dup) @@ -1280,7 +1275,7 @@ namespace Mono.CSharp } } - public void EmitLoad (EmitContext ec) + public void EmitLoad (EmitContext ec, bool boxInstance) { var instance_type = instance.Type; @@ -1311,8 +1306,9 @@ namespace Mono.CSharp instance.Emit (ec); // Only to make verifier happy - if (RequiresBoxing ()) + if (boxInstance && RequiresBoxing ()) { ec.Emit (OpCodes.Box, instance_type); + } } public TypeSpec GetStackType (EmitContext ec) @@ -1340,6 +1336,9 @@ namespace Mono.CSharp return false; } + // + // Returns true for cheap race-free load, where we can avoid using dup + // bool IsInexpensiveLoad () { if (instance is Constant) @@ -1349,8 +1348,10 @@ namespace Mono.CSharp return false; var vr = instance as VariableReference; - if (vr != null) - return !vr.IsRef; + if (vr != null) { + // Load from captured local would be racy without dup + return !vr.IsRef && !vr.IsHoisted; + } if (instance is LocalTemporary) return true; diff --git a/mcs/mcs/cs-parser.jay.REMOVED.git-id b/mcs/mcs/cs-parser.jay.REMOVED.git-id index 078b6dd032..97a50f2185 100644 --- a/mcs/mcs/cs-parser.jay.REMOVED.git-id +++ b/mcs/mcs/cs-parser.jay.REMOVED.git-id @@ -1 +1 @@ -726b1f6dcdd3a442f01b3273228c570a4dc5f031 \ No newline at end of file +a9c68262d33108b6c93fa08841628ef19b74b8fa \ No newline at end of file diff --git a/mcs/mcs/cs-tokenizer.cs b/mcs/mcs/cs-tokenizer.cs index 8637fda870..9647a4bd7e 100644 --- a/mcs/mcs/cs-tokenizer.cs +++ b/mcs/mcs/cs-tokenizer.cs @@ -1268,6 +1268,7 @@ namespace Mono.CSharp int next_token; int parens = 0; int generics = 0; + int brackets = 0; var nt = xtoken (); switch (nt) { @@ -1319,7 +1320,6 @@ namespace Mono.CSharp case Token.COMMA: case Token.SEMICOLON: case Token.OPEN_BRACE: - case Token.CLOSE_PARENS: case Token.IN: next_token = Token.INTERR_NULLABLE; break; @@ -1334,6 +1334,15 @@ namespace Mono.CSharp ++parens; goto default; + case Token.OPEN_BRACKET: + case Token.OPEN_BRACKET_EXPR: + ++brackets; + goto default; + + case Token.CLOSE_PARENS: + --parens; + goto default; + case Token.OP_GENERICS_LT: case Token.OP_GENERICS_LT_DECL: case Token.GENERIC_DIMENSION: @@ -1345,7 +1354,6 @@ namespace Mono.CSharp int interrs = 1; int colons = 0; int braces = 0; - int brackets = 0; // // All shorcuts failed, do it hard way // diff --git a/mcs/mcs/dynamic.cs b/mcs/mcs/dynamic.cs index 5604a3fcdc..8a9a0c87de 100644 --- a/mcs/mcs/dynamic.cs +++ b/mcs/mcs/dynamic.cs @@ -289,6 +289,13 @@ namespace Mono.CSharp protected bool DoResolveCore (ResolveContext rc) { + foreach (var arg in arguments) { + if (arg.Type == InternalType.VarOutType) { + // Should be special error message about dynamic dispatch + rc.Report.Error (8047, arg.Expr.Location, "Declaration expression cannot be used in this context"); + } + } + if (rc.CurrentTypeParameters != null && rc.CurrentTypeParameters[0].IsMethodTypeParameter) context_mvars = rc.CurrentTypeParameters; diff --git a/mcs/mcs/ecore.cs.REMOVED.git-id b/mcs/mcs/ecore.cs.REMOVED.git-id index 12b22480bb..bfce98d3d5 100644 --- a/mcs/mcs/ecore.cs.REMOVED.git-id +++ b/mcs/mcs/ecore.cs.REMOVED.git-id @@ -1 +1 @@ -5729e21b3e7e9275a1fe18a577598f104e3fe16e \ No newline at end of file +3143908b63accad973ddba473d1f532987e364e5 \ No newline at end of file diff --git a/mcs/mcs/expression.cs.REMOVED.git-id b/mcs/mcs/expression.cs.REMOVED.git-id index fbe1f3affe..fb99a9e845 100644 --- a/mcs/mcs/expression.cs.REMOVED.git-id +++ b/mcs/mcs/expression.cs.REMOVED.git-id @@ -1 +1 @@ -4fa922c0110f8f4278cecea17e40d6b036d503ac \ No newline at end of file +6699377f8df408e355b889789f3a2ffce55cdd2d \ No newline at end of file diff --git a/mcs/mcs/field.cs b/mcs/mcs/field.cs index e3555b9383..824b5c781c 100644 --- a/mcs/mcs/field.cs +++ b/mcs/mcs/field.cs @@ -425,7 +425,7 @@ namespace Mono.CSharp } // Create nested fixed buffer container - string name = String.Format ("<{0}>__FixedBuffer{1}", Name, GlobalCounter++); + string name = String.Format ("<{0}>__FixedBuffer{1}", TypeDefinition.FilterNestedName (Name), GlobalCounter++); fixed_buffer_type = Parent.TypeBuilder.DefineNestedType (name, TypeAttributes.NestedPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit, Compiler.BuiltinTypes.ValueType.GetMetaInfo ()); @@ -605,9 +605,23 @@ namespace Mono.CSharp if (TypeSpec.IsReferenceType (MemberType)) return true; - if (MemberType.IsEnum) + if (MemberType.IsPointer) return true; + if (MemberType.IsEnum) { + switch (EnumSpec.GetUnderlyingType (MemberType).BuiltinType) { + case BuiltinTypeSpec.Type.SByte: + case BuiltinTypeSpec.Type.Byte: + case BuiltinTypeSpec.Type.Short: + case BuiltinTypeSpec.Type.UShort: + case BuiltinTypeSpec.Type.Int: + case BuiltinTypeSpec.Type.UInt: + return true; + default: + return false; + } + } + return false; } diff --git a/mcs/mcs/generic.cs b/mcs/mcs/generic.cs index d369ccf816..f549432b29 100644 --- a/mcs/mcs/generic.cs +++ b/mcs/mcs/generic.cs @@ -1325,16 +1325,22 @@ namespace Mono.CSharp { foreach (var ta in targs) { var tps = ta as TypeParameterSpec; IList ifaces; + TypeSpec b_type; if (tps != null) { - var b_type = tps.GetEffectiveBase (); - if (b_type != null && b_type.BuiltinType != BuiltinTypeSpec.Type.Object && b_type.BuiltinType != BuiltinTypeSpec.Type.ValueType) - cache.AddBaseType (b_type); - + b_type = tps.GetEffectiveBase (); ifaces = tps.InterfacesDefined; } else { + b_type = ta; ifaces = ta.Interfaces; } + // + // Don't add base type which was inflated from base constraints but it's not valid + // in C# context + // + if (b_type != null && b_type.BuiltinType != BuiltinTypeSpec.Type.Object && b_type.BuiltinType != BuiltinTypeSpec.Type.ValueType && !b_type.IsStructOrEnum) + cache.AddBaseType (b_type); + if (ifaces != null) { foreach (var iface_type in ifaces) { cache.AddInterface (iface_type); @@ -2758,7 +2764,7 @@ namespace Mono.CSharp { // // Tracks successful rate of type inference // - int score = int.MaxValue; + int score; readonly Arguments arguments; readonly int arg_count; @@ -2831,12 +2837,12 @@ namespace Mono.CSharp { AnonymousMethodExpression am = a.Expr as AnonymousMethodExpression; if (am != null) { if (am.ExplicitTypeInference (tic, method_parameter)) - --score; + ++score; continue; } if (a.IsByRef) { - score -= tic.ExactInference (a.Type, method_parameter); + score += tic.ExactInference (a.Type, method_parameter); continue; } @@ -2844,14 +2850,14 @@ namespace Mono.CSharp { continue; if (TypeSpec.IsValueType (method_parameter)) { - score -= tic.LowerBoundInference (a.Type, method_parameter); + score += tic.LowerBoundInference (a.Type, method_parameter); continue; } // // Otherwise an output type inference is made // - score -= tic.OutputTypeInference (ec, a.Expr, method_parameter); + score += tic.OutputTypeInference (ec, a.Expr, method_parameter); } // @@ -2901,7 +2907,7 @@ namespace Mono.CSharp { if (arguments[i] == null) continue; - score -= tic.OutputTypeInference (ec, arguments[i].Expr, t_i); + score += tic.OutputTypeInference (ec, arguments[i].Expr, t_i); } } @@ -3008,7 +3014,7 @@ namespace Mono.CSharp { // Some types cannot be used as type arguments // if ((bound.Type.Kind == MemberKind.Void && !voidAllowed) || bound.Type.IsPointer || bound.Type.IsSpecialRuntimeType || - bound.Type == InternalType.MethodGroup || bound.Type == InternalType.AnonymousMethod) + bound.Type == InternalType.MethodGroup || bound.Type == InternalType.AnonymousMethod || bound.Type == InternalType.VarOutType) return; var a = bounds [index]; @@ -3034,8 +3040,8 @@ namespace Mono.CSharp { continue; } - if (TypeManager.IsGenericType (t)) - return AllTypesAreFixed (TypeManager.GetTypeArguments (t)); + if (t.IsGeneric && !AllTypesAreFixed (t.TypeArguments)) + return false; } return true; diff --git a/mcs/mcs/method.cs b/mcs/mcs/method.cs index aa54bc4a4d..bd1a6aabb9 100644 --- a/mcs/mcs/method.cs +++ b/mcs/mcs/method.cs @@ -1498,15 +1498,6 @@ namespace Mono.CSharp { "`{0}': Struct constructors cannot call base constructors", caller_builder.GetSignatureForError ()); return this; } - } else { - // - // It is legal to have "this" initializers that take no arguments - // in structs - // - // struct D { public D (int a) : this () {} - // - if (ec.CurrentType.IsStruct && argument_list == null) - return this; } base_ctor = ConstructorLookup (ec, type, ref argument_list, loc); @@ -1663,12 +1654,6 @@ namespace Mono.CSharp { protected override bool CheckBase () { if ((ModFlags & Modifiers.STATIC) != 0) { - if (!parameters.IsEmpty) { - Report.Error (132, Location, "`{0}': The static constructor must be parameterless", - GetSignatureForError ()); - return false; - } - if ((caching_flags & Flags.MethodOverloadsExist) != 0) Parent.MemberCache.CheckExistingMembersOverloads (this, parameters); @@ -1683,12 +1668,6 @@ namespace Mono.CSharp { if ((caching_flags & Flags.MethodOverloadsExist) != 0) Parent.MemberCache.CheckExistingMembersOverloads (this, parameters); - if (Parent.PartialContainer.Kind == MemberKind.Struct && parameters.IsEmpty) { - Report.Error (568, Location, - "Structs cannot contain explicit parameterless constructors"); - return false; - } - CheckProtectedModifier (); return true; @@ -2571,6 +2550,9 @@ namespace Mono.CSharp { Implicit, Explicit, + // Pattern matching + Is, + // Just because of enum TOP }; @@ -2608,6 +2590,7 @@ namespace Mono.CSharp { names [(int) OpType.LessThanOrEqual] = new string [] { "<=", "op_LessThanOrEqual" }; names [(int) OpType.Implicit] = new string [] { "implicit", "op_Implicit" }; names [(int) OpType.Explicit] = new string [] { "explicit", "op_Explicit" }; + names [(int) OpType.Is] = new string[] { "is", "op_Is" }; } public Operator (TypeDefinition parent, OpType type, FullNamedExpression ret_type, Modifiers mod_flags, ParametersCompiled parameters, diff --git a/mcs/mcs/module.cs b/mcs/mcs/module.cs index e7e02a0bf1..138ec61638 100644 --- a/mcs/mcs/module.cs +++ b/mcs/mcs/module.cs @@ -105,6 +105,141 @@ namespace Mono.CSharp } #endif + public sealed class PatternMatchingHelper : CompilerGeneratedContainer + { + public PatternMatchingHelper (ModuleContainer module) + : base (module, new MemberName ("", Location.Null), + Modifiers.STATIC | Modifiers.INTERNAL | Modifiers.DEBUGGER_HIDDEN) + { + } + + public Method NumberMatcher { get; private set; } + + protected override bool DoDefineMembers () + { + if (!base.DoDefineMembers ()) + return false; + + NumberMatcher = GenerateNumberMatcher (); + return true; + } + + Method GenerateNumberMatcher () + { + var loc = Location; + var parameters = ParametersCompiled.CreateFullyResolved ( + new [] { + new Parameter (new TypeExpression (Compiler.BuiltinTypes.Object, loc), "obj", 0, null, loc), + new Parameter (new TypeExpression (Compiler.BuiltinTypes.Object, loc), "value", 0, null, loc), + new Parameter (new TypeExpression (Compiler.BuiltinTypes.Bool, loc), "enumType", 0, null, loc), + }, + new [] { + Compiler.BuiltinTypes.Object, + Compiler.BuiltinTypes.Object, + Compiler.BuiltinTypes.Bool + }); + + var m = new Method (this, new TypeExpression (Compiler.BuiltinTypes.Bool, loc), + Modifiers.PUBLIC | Modifiers.STATIC | Modifiers.DEBUGGER_HIDDEN, new MemberName ("NumberMatcher", loc), + parameters, null); + + parameters [0].Resolve (m, 0); + parameters [1].Resolve (m, 1); + parameters [2].Resolve (m, 2); + + ToplevelBlock top_block = new ToplevelBlock (Compiler, parameters, loc); + m.Block = top_block; + + // + // if (enumType) + // return Equals (obj, value); + // + var equals_args = new Arguments (2); + equals_args.Add (new Argument (top_block.GetParameterReference (0, loc))); + equals_args.Add (new Argument (top_block.GetParameterReference (1, loc))); + + var if_type = new If ( + top_block.GetParameterReference (2, loc), + new Return (new Invocation (new SimpleName ("Equals", loc), equals_args), loc), + loc); + + top_block.AddStatement (if_type); + + // + // if (obj is Enum || obj == null) + // return false; + // + + var if_enum = new If ( + new Binary (Binary.Operator.LogicalOr, + new Is (top_block.GetParameterReference (0, loc), new TypeExpression (Compiler.BuiltinTypes.Enum, loc), loc), + new Binary (Binary.Operator.Equality, top_block.GetParameterReference (0, loc), new NullLiteral (loc))), + new Return (new BoolLiteral (Compiler.BuiltinTypes, false, loc), loc), + loc); + + top_block.AddStatement (if_enum); + + + var system_convert = new MemberAccess (new QualifiedAliasMember ("global", "System", loc), "Convert", loc); + var expl_block = new ExplicitBlock (top_block, loc, loc); + + // + // var converted = System.Convert.ChangeType (obj, System.Convert.GetTypeCode (value)); + // + var lv_converted = LocalVariable.CreateCompilerGenerated (Compiler.BuiltinTypes.Object, top_block, loc); + + var arguments_gettypecode = new Arguments (1); + arguments_gettypecode.Add (new Argument (top_block.GetParameterReference (1, loc))); + + var gettypecode = new Invocation (new MemberAccess (system_convert, "GetTypeCode", loc), arguments_gettypecode); + + var arguments_changetype = new Arguments (1); + arguments_changetype.Add (new Argument (top_block.GetParameterReference (0, loc))); + arguments_changetype.Add (new Argument (gettypecode)); + + var changetype = new Invocation (new MemberAccess (system_convert, "ChangeType", loc), arguments_changetype); + + expl_block.AddStatement (new StatementExpression (new SimpleAssign (new LocalVariableReference (lv_converted, loc), changetype, loc))); + + + // + // return converted.Equals (value) + // + var equals_arguments = new Arguments (1); + equals_arguments.Add (new Argument (top_block.GetParameterReference (1, loc))); + var equals_invocation = new Invocation (new MemberAccess (new LocalVariableReference (lv_converted, loc), "Equals"), equals_arguments); + expl_block.AddStatement (new Return (equals_invocation, loc)); + + var catch_block = new ExplicitBlock (top_block, loc, loc); + catch_block.AddStatement (new Return (new BoolLiteral (Compiler.BuiltinTypes, false, loc), loc)); + top_block.AddStatement (new TryCatch (expl_block, new List () { + new Catch (catch_block, loc) + }, loc, false)); + + m.Define (); + m.PrepareEmit (); + AddMember (m); + + return m; + } + } + + PatternMatchingHelper pmh; + + public PatternMatchingHelper CreatePatterMatchingHelper () + { + if (pmh == null) { + pmh = new PatternMatchingHelper (this); + + pmh.CreateContainer (); + pmh.DefineContainer (); + pmh.Define (); + AddCompilerGeneratedClass (pmh); + } + + return pmh; + } + public CharSet? DefaultCharSet; public TypeAttributes DefaultCharSetType = TypeAttributes.AnsiClass; diff --git a/mcs/mcs/namespace.cs b/mcs/mcs/namespace.cs index 8b7775160c..0a35cc4c61 100644 --- a/mcs/mcs/namespace.cs +++ b/mcs/mcs/namespace.cs @@ -488,7 +488,21 @@ namespace Mono.CSharp { public void RemoveContainer (TypeContainer tc) { - types.Remove (tc.MemberName.Basename); + IList found; + if (types.TryGetValue (tc.MemberName.Name, out found)) { + for (int i = 0; i < found.Count; ++i) { + if (tc.MemberName.Arity != found [i].Arity) + continue; + + if (found.Count == 1) + types.Remove (tc.MemberName.Name); + else + found.RemoveAt (i); + + break; + } + } + cached_types.Remove (tc.MemberName.Basename); } diff --git a/mcs/mcs/nullable.cs b/mcs/mcs/nullable.cs index e857e36541..f3ed348c14 100644 --- a/mcs/mcs/nullable.cs +++ b/mcs/mcs/nullable.cs @@ -1220,12 +1220,6 @@ namespace Mono.CSharp.Nullable return ReducedExpression.Create (right, this, false).Resolve (ec); left = Convert.ImplicitConversion (ec, unwrap ?? left, rtype, loc); - - if (TypeSpec.IsValueType (left.Type) && !left.Type.IsNullableType) { - Warning_UnreachableExpression (ec, right.Location); - return ReducedExpression.Create (left, this, false).Resolve (ec); - } - type = rtype; return this; } @@ -1285,16 +1279,52 @@ namespace Mono.CSharp.Nullable return; } - left.Emit (ec); - ec.Emit (OpCodes.Dup); + // + // Null check is done on original expression not after expression is converted to + // result type. This is in most cases same but when user conversion is involved + // we can end up in situation when use operator does the null handling which is + // not what the operator is supposed to do + // + var op_expr = left as UserCast; + if (op_expr != null) { + op_expr.Source.Emit (ec); + LocalTemporary temp; - // Only to make verifier happy - if (left.Type.IsGenericParameter) - ec.Emit (OpCodes.Box, left.Type); + // TODO: More load kinds can be special cased + if (!(op_expr.Source is VariableReference)) { + temp = new LocalTemporary (op_expr.Source.Type); + temp.Store (ec); + temp.Emit (ec); + op_expr.Source = temp; + } else { + temp = null; + } - ec.Emit (OpCodes.Brtrue, end_label); + var right_label = ec.DefineLabel (); + ec.Emit (OpCodes.Brfalse_S, right_label); + left.Emit (ec); + ec.Emit (OpCodes.Br, end_label); + ec.MarkLabel (right_label); + + if (temp != null) + temp.Release (ec); + } else { + // + // Common case where expression is not modified before null check and + // we generate better/smaller code + // + left.Emit (ec); + ec.Emit (OpCodes.Dup); + + // Only to make verifier happy + if (left.Type.IsGenericParameter) + ec.Emit (OpCodes.Box, left.Type); + + ec.Emit (OpCodes.Brtrue, end_label); + + ec.Emit (OpCodes.Pop); + } - ec.Emit (OpCodes.Pop); right.Emit (ec); ec.MarkLabel (end_label); diff --git a/mcs/mcs/parameter.cs b/mcs/mcs/parameter.cs index 1a30ae384c..adac136fdc 100644 --- a/mcs/mcs/parameter.cs +++ b/mcs/mcs/parameter.cs @@ -1418,7 +1418,7 @@ namespace Mono.CSharp { expr = Child; - if (!(expr is Constant || expr is DefaultValueExpression || (expr is New && ((New) expr).IsDefaultStruct))) { + if (!(expr is Constant || expr is DefaultValueExpression || (expr is New && ((New) expr).IsGeneratedStructConstructor))) { if (!(expr is ErrorExpression)) { rc.Report.Error (1736, Location, "The expression being assigned to optional parameter `{0}' must be a constant or default value", diff --git a/mcs/mcs/statement.cs.REMOVED.git-id b/mcs/mcs/statement.cs.REMOVED.git-id index 8cad4c82e6..f3daf08076 100644 --- a/mcs/mcs/statement.cs.REMOVED.git-id +++ b/mcs/mcs/statement.cs.REMOVED.git-id @@ -1 +1 @@ -441d65780c1fe7095e5ab81f6536b7abc8b220ca \ No newline at end of file +00d61eba2b764a6a5a53607bae1860b887ed2303 \ No newline at end of file diff --git a/mcs/mcs/typespec.cs b/mcs/mcs/typespec.cs index a33159d847..6b42112f9e 100644 --- a/mcs/mcs/typespec.cs +++ b/mcs/mcs/typespec.cs @@ -1446,6 +1446,7 @@ namespace Mono.CSharp public static readonly InternalType FakeInternalType = new InternalType (""); public static readonly InternalType Namespace = new InternalType (""); public static readonly InternalType ErrorType = new InternalType (""); + public static readonly InternalType VarOutType = new InternalType ("var out"); readonly string name; diff --git a/mcs/tests/gtest-409.cs b/mcs/tests/gtest-409.cs index 1d2a5ad00f..2f5ea10ae8 100644 --- a/mcs/tests/gtest-409.cs +++ b/mcs/tests/gtest-409.cs @@ -150,6 +150,16 @@ public class ConditionalParsing } } + void Test_18 (bool b, Action a) + { + var e = b ? () => { } : a; + } + + void Test_19 (int[,] table) + { + var x = 1 > 0 ? table[5, 1] : 0; + } + static void Helper (T arg) { } diff --git a/mcs/tests/gtest-623-lib.il b/mcs/tests/gtest-623-lib.il new file mode 100644 index 0000000000..25c5b72ca4 --- /dev/null +++ b/mcs/tests/gtest-623-lib.il @@ -0,0 +1,42 @@ +.assembly extern mscorlib +{ +} + +.assembly 'gtest-623-lib' +{ +} + +.module 'gtest-623-lib.dll' + + .class public sequential ansi sealed beforefieldinit S + extends [mscorlib]System.ValueType + implements I { + + .field public int32 Field + + .method public hidebysig specialname rtspecialname + instance default void '.ctor' () cil managed + { + ldarg.0 + ldc.i4.3 + stfld int32 S::Field + ret + } + + .method public final virtual hidebysig newslot + instance default int32 GetValue () cil managed + { + ldarg.0 + ldfld int32 S::Field + ret + } + } + + .class interface public auto ansi abstract I + { + + .method public virtual hidebysig newslot abstract + instance default int32 GetValue () cil managed + { + } + } diff --git a/mcs/tests/gtest-623.cs b/mcs/tests/gtest-623.cs new file mode 100644 index 0000000000..ce9b79d1bd --- /dev/null +++ b/mcs/tests/gtest-623.cs @@ -0,0 +1,24 @@ +// Compiler options: -r:gtest-623-lib.dll + +using System; + +public class C +{ + static bool Test () where T : struct, I + { + var t = new T (); + if (t.GetValue () != 3) + return false; + + return true; + } + + public static int Main () + { + if (!Test ()) + return 1; + + Console.WriteLine ("ok"); + return 0; + } +} \ No newline at end of file diff --git a/mcs/tests/gtest-624.cs b/mcs/tests/gtest-624.cs new file mode 100644 index 0000000000..0299d095e0 --- /dev/null +++ b/mcs/tests/gtest-624.cs @@ -0,0 +1,36 @@ +using System; + +class Model +{ + public int Value; +} + +class C1 +{ + public void Add (Func t) + { + } +} + +abstract class C2 +{ + public abstract void ApplyImpl (C1 c1) where U : TModel; +} + +class C3 : C2 +{ + public override void ApplyImpl (C1 c1) + { + c1.Add (t => t.Value); + } +} + +class Program +{ + static void Main () + { + var v1 = new C1 (); + var c3 = new C3 (); + c3.ApplyImpl (v1); + } +} diff --git a/mcs/tests/gtest-625.cs b/mcs/tests/gtest-625.cs new file mode 100644 index 0000000000..d733a809dc --- /dev/null +++ b/mcs/tests/gtest-625.cs @@ -0,0 +1,21 @@ +struct S +{ + public static bool operator true (S? S) + { + return true; + } + + public static bool operator false (S? S) + { + return true; + } +} + +class P +{ + static void Main () + { + if (new S? ()) { + } + } +} \ No newline at end of file diff --git a/mcs/tests/gtest-autoproperty-09.cs b/mcs/tests/gtest-autoproperty-09.cs index b6109d943c..42c12e9add 100644 --- a/mcs/tests/gtest-autoproperty-09.cs +++ b/mcs/tests/gtest-autoproperty-09.cs @@ -1,3 +1,4 @@ +// Compiler options: -langversion:experimental using System; struct S diff --git a/mcs/tests/gtest-autoproperty-10.cs b/mcs/tests/gtest-autoproperty-10.cs new file mode 100644 index 0000000000..036d9c3a43 --- /dev/null +++ b/mcs/tests/gtest-autoproperty-10.cs @@ -0,0 +1,17 @@ +// Compiler options: -langversion:experimental +struct S +{ + public decimal P { get; } = -3; +} + +class X +{ + public static int Main () + { + var s = new S (); + if (s.P != -3) + return 1; + + return 0; + } +} \ No newline at end of file diff --git a/mcs/tests/gtest-etree-01.cs b/mcs/tests/gtest-etree-01.cs index e538021cd0..43f605e6b5 100644 --- a/mcs/tests/gtest-etree-01.cs +++ b/mcs/tests/gtest-etree-01.cs @@ -210,6 +210,14 @@ struct MyTypeImplicitOnly } } +struct StructWithUserConstructor +{ + public StructWithUserConstructor () + { + + } +} + class MemberAccessData { public bool BoolValue; @@ -2190,6 +2198,17 @@ class Tester Assert (0, e.Compile ().Invoke ()); } + void NewTest_8 () + { + Expression> e = () => new DateTime (); + AssertNodeType (e, ExpressionType.New); + Assert (null, ((NewExpression)e.Body).Constructor, "default ctor"); + + Expression> e2 = () => new StructWithUserConstructor (); + AssertNodeType (e2, ExpressionType.New); + Assert ("Void .ctor()", ((NewExpression)e2.Body).Constructor.ToString (), "user ctor"); + } + void NotTest () { Expression> e = (bool a) => !a; diff --git a/mcs/tests/gtest-lambda-36.cs b/mcs/tests/gtest-lambda-36.cs new file mode 100644 index 0000000000..0d4d772c69 --- /dev/null +++ b/mcs/tests/gtest-lambda-36.cs @@ -0,0 +1,26 @@ +using System; + +class D +{ + public void S (Func ftu, Func ftuv) + { + } +} + +class Test +{ + static D Factory (V v) + { + return new D (); + } + + static void Main () + { + var danon = Factory (new { q = 5 }); + + danon.S ( + () => "x", + (l, str) => new { str } + ); + } +} \ No newline at end of file diff --git a/mcs/tests/gtest-named-06.cs b/mcs/tests/gtest-named-06.cs new file mode 100644 index 0000000000..e9b2de5b5c --- /dev/null +++ b/mcs/tests/gtest-named-06.cs @@ -0,0 +1,18 @@ +// parser test + +class X +{ + public static int T1 (int seconds) + { + return T1_Foo (value: seconds * 1000); + } + + public static int T1_Foo (int value = 0) + { + return value; + } + + public static void Main () + { + } +} \ No newline at end of file diff --git a/mcs/tests/gtest-optional-34.cs b/mcs/tests/gtest-optional-34.cs new file mode 100644 index 0000000000..bf865a7bbe --- /dev/null +++ b/mcs/tests/gtest-optional-34.cs @@ -0,0 +1,14 @@ +public struct S +{ + public S (double left = 0, double top = 0) + : this () + { + } +} + +class X +{ + public static void Main () + { + } +} \ No newline at end of file diff --git a/mcs/tests/test-251.cs b/mcs/tests/test-251.cs index 7878999c1d..3b2ffbaa9c 100644 --- a/mcs/tests/test-251.cs +++ b/mcs/tests/test-251.cs @@ -1,3 +1,4 @@ +// Compiler options: -unsafe // // Tests the valid value types for volatile fields. // @@ -11,6 +12,9 @@ enum XX { A } +struct S { +} + class X { volatile byte a; volatile sbyte b; @@ -26,6 +30,9 @@ class X { volatile XX dd; volatile IntPtr ip; volatile UIntPtr uip; + unsafe volatile ushort* uc; + unsafe volatile XX* udd; + unsafe volatile S* us; public static void Main () {} } diff --git a/mcs/tests/test-898.cs b/mcs/tests/test-898.cs deleted file mode 100644 index 5b6940372f..0000000000 --- a/mcs/tests/test-898.cs +++ /dev/null @@ -1,79 +0,0 @@ -// Compiler options: -unsafe - -using System; - -class BoolArrayWithByteValues -{ - - static int Foo (ref bool b) - { - bool b2 = true; - bool r; - r = b == true; - if (!r) - return 10; - - r = b == b2; - if (!r) - return 11; - - return 0; - } - - static unsafe bool Ptr () - { - bool rv; - - var arr = new byte [256]; - for (int i = 0; i < arr.Length; i++) - arr [i] = (byte) i; - fixed (byte* bptr = arr) { - rv = true; - for (int i = 0; i < arr.Length; i++) { - bool* boptr = (bool*)(bptr + i); - if (arr[i] > 0 && !*boptr) - rv = false; - System.Console.WriteLine ("#{0} = {1}", i, *boptr); - } - } - - return rv; - } - - static int Main() - { - var a = new bool[1]; - Buffer.SetByte (a, 0, 5); - - var b = true; - bool r; - r = a [0]; - if (!r) - return 1; - - r = a [0] == true; - if (!r) - return 2; - - r = a [0] == b; - if (!r) - return 3; - - r = a [0] != false; - if (!r) - return 4; - - r = a [0] != b; - if (r) - return 5; - - var res = Foo (ref a [0]); - if (res != 0) - return res; - - if (!Ptr ()) - return 6; - - return 0; - } -} \ No newline at end of file diff --git a/mcs/tests/test-903.cs b/mcs/tests/test-903.cs index 44513478a8..7dedb674da 100644 --- a/mcs/tests/test-903.cs +++ b/mcs/tests/test-903.cs @@ -6,17 +6,36 @@ struct S class C { + public static int ConversionCalled; + public static implicit operator S (C c) { + ++ConversionCalled; return new S (); } } class Program { - static void Main () + static C field; + + static int Main () { C c = new C (); var x = c ?? new S (); + + if (C.ConversionCalled != 1) + return 1; + + c = null; + x = c ?? new S (); + if (C.ConversionCalled != 1) + return 2; + + x = field ?? new S (); + if (C.ConversionCalled != 1) + return 3; + + return 0; } } \ No newline at end of file diff --git a/mcs/tests/test-906.cs b/mcs/tests/test-906.cs new file mode 100644 index 0000000000..9a34e43877 --- /dev/null +++ b/mcs/tests/test-906.cs @@ -0,0 +1,76 @@ +// Compiler options: -langversion:experimental +using System; + +struct S1 +{ + public readonly int Value; + + public S1 () + { + Value = 17; + } +} + +struct S2 +{ + public readonly int Value = 23; +} + +struct S3 +{ + public readonly int Value = 11; + + public S3 () + { + Value = 5; + } +} + +struct S4 +{ + public readonly int Value = 11; + + public S4 (int v) + { + } +} + +struct S5 +{ + public readonly int Value = 7; + + public S5 (int v) + : this () + { + this.Value += v; + } +} + +class C +{ + static int Main () + { + var s = new S1 (); + if (s.Value != 17) + return 1; + + var s2 = new S2 (); + if (s2.Value != 23) + return 2; + + var s3 = new S3 (); + if (s3.Value != 5) + return 3; + + var s4 = new S4 (5); + if (s4.Value != 11) + return 4; + + var s5 = new S5 (2); + if (s5.Value != 9) + return 5; + + Console.WriteLine ("ok"); + return 0; + } +} \ No newline at end of file diff --git a/mcs/tests/test-907.cs b/mcs/tests/test-907.cs new file mode 100644 index 0000000000..0a832c9112 --- /dev/null +++ b/mcs/tests/test-907.cs @@ -0,0 +1,22 @@ +public enum Foo { One, Two }; + +class MainClass +{ + public static int Main () + { + const Foo foo = Foo.Two; + int obj; + + switch (foo) { + case Foo.One: + case Foo.Two: + obj = 2; + break; + } + + if (obj != 2) + return 1; + + return 0; + } +} diff --git a/mcs/tests/test-910.cs b/mcs/tests/test-910.cs new file mode 100644 index 0000000000..0cbdf42476 --- /dev/null +++ b/mcs/tests/test-910.cs @@ -0,0 +1,10 @@ +using System.Security; +using System.Security.Permissions; + +[HostProtection] +class X +{ + public static void Main () + { + } +} diff --git a/mcs/tests/test-anon-172.cs b/mcs/tests/test-anon-172.cs new file mode 100644 index 0000000000..c316a1ba24 --- /dev/null +++ b/mcs/tests/test-anon-172.cs @@ -0,0 +1,30 @@ +using System; +using System.Reflection.Emit; +using System.Reflection; + +class MainClass +{ + public static int Main () + { + var dynMethod = new DynamicMethod ("Metoda", MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, + null, Type.EmptyTypes, typeof (MainClass), true); + var generator = dynMethod.GetILGenerator (); + + generator.Emit (OpCodes.Ldc_I4_7); + GenerateCodeCall (generator, (int a) => { + Console.WriteLine (a); + }); + + generator.Emit (OpCodes.Ret); + + var deleg = (Action)dynMethod.CreateDelegate (typeof (Action)); + deleg (); + return 0; + } + + static void GenerateCodeCall (ILGenerator generator, Action a) + { + generator.Emit (OpCodes.Call, a.Method); + } +} + diff --git a/mcs/tests/test-async-76.cs b/mcs/tests/test-async-76.cs new file mode 100644 index 0000000000..5fa226accc --- /dev/null +++ b/mcs/tests/test-async-76.cs @@ -0,0 +1,42 @@ +// Compiler options: -r:../class/lib/net_4_5/Mono.Cecil.dll + +using System; +using System.Threading.Tasks; +using Mono.Cecil; + +namespace N +{ + class C + { + } + + interface I + { + void Foo (T t); + } + + class X : I + { + async void I.Foo (C c) + { + await Task.Delay (1); + } + + public static void Main () + { + var assembly = AssemblyDefinition.ReadAssembly (typeof (X).Assembly.Location); + foreach (var t in assembly.MainModule.Types) { + PrintType (t, 0); + } + } + + static void PrintType (TypeDefinition td, int indent) + { + if (td.IsNested && !string.IsNullOrEmpty (td.Namespace)) + throw new ApplicationException ("BROKEN NESTED TYPE:"); + Console.WriteLine ("{2} Namespace: {0} Name: {1}", td.Namespace, td.Name, new string (' ', indent * 4)); + foreach (var tn in td.NestedTypes) + PrintType (tn, indent + 1); + } + } +} \ No newline at end of file diff --git a/mcs/tests/test-decl-expr-01.cs b/mcs/tests/test-decl-expr-01.cs new file mode 100644 index 0000000000..31ff669038 --- /dev/null +++ b/mcs/tests/test-decl-expr-01.cs @@ -0,0 +1,65 @@ +using System; + +class DeclarationExpression +{ + public static int Main () + { + Out (out int o); + if (o != 3) + return 1; + + if (Out (out int o1)) { + if (o1 != 3) + return 2; + } + + Out (out int o2 = 2); + if (o2 != 3) + return 3; + + Out (out var o3); + if (o3 != 3) + return 4; + + Ref (ref int r = 2); + if (r != 7) + return 5; + + Ref (ref ((var r2 = 3))); + if (r2 != 8) + return 6; + +// Out2 (str: "b", v: out var o5); +// if (o5 != 9) +// return 7; + + Out3 (out var o6 = 9m); + if (o6.GetType () != typeof (decimal)) + return 8; + + Console.WriteLine ("ok"); + return 0; + } + + static bool Out (out int value) + { + value = 3; + return true; + } + + static bool Out2 (out int v, string str) + { + v = 9; + return true; + } + + static void Out3 (out T t) + { + t = default (T); + } + + static void Ref (ref int arg) + { + arg += 5; + } +} \ No newline at end of file diff --git a/mcs/tests/test-null-operator-010.cs b/mcs/tests/test-null-operator-010.cs new file mode 100644 index 0000000000..2d72403432 --- /dev/null +++ b/mcs/tests/test-null-operator-010.cs @@ -0,0 +1,41 @@ +using System; + +class Test +{ + static void Main () + { + Test_1 (""); + Test_1 (null); + + Test_2 (null); + Test_2 ("z"); + Test_2 (0); + Test_2 ((long?) -8); + + Test_3 (new int[1]); + Test_3 (new int[] { 5 }); + } + + static void Test_1 (T x) where T : class + { + x?.Call (); + } + + static void Test_2 (T x) + { + x?.Call (); + } + + static void Test_3 (T[] x) + { + x[0]?.Call (); + } +} + +static class Ext +{ + public static void Call (this T t) + { + Console.WriteLine (typeof (T)); + } +} diff --git a/mcs/tests/test-pattern-01.cs b/mcs/tests/test-pattern-01.cs index f9d627f0e6..6db67fb167 100644 --- a/mcs/tests/test-pattern-01.cs +++ b/mcs/tests/test-pattern-01.cs @@ -7,7 +7,7 @@ class TypePattern public static int Main () { object o = 3; - bool r = o is string t1; + bool r = o is System.String t1; if (t1 != null) return 1; diff --git a/mcs/tests/test-pattern-02.cs b/mcs/tests/test-pattern-02.cs new file mode 100644 index 0000000000..695775ec17 --- /dev/null +++ b/mcs/tests/test-pattern-02.cs @@ -0,0 +1,93 @@ +// Compiler options: -langversion:experimental + +using System; + +enum MyEnum : short +{ + V_4 = 4 +} + +class ConstantPattern +{ + static bool Generic (T t) where T : class + { + return t is default (T); + } + + public static int Main () + { + bool b4 = false; + b4 = !b4; + object o = "x"; + bool r1 = o is "y"; + if (r1) + return 1; + + r1 = o is "x"; + if (!r1) + return 2; + + string s = "o"; + if (s is null) + return 3; + + if (s is "oo") + return 4; + + if (!(s is "o")) + return 5; + + int? o3 = 4; + bool r3 = o3 is null; + if (r3) + return 6; + + r3 = o3 is 4; + if (!r3) + return 7; + + object o4 = (byte?)255; + var ggg = o4 is 255; + if (!ggg) + return 8; + + if (o4 is null) + return 9; + + object o5 = (double)-255; + if (!(o5 is -byte.MaxValue)) + return 10; + + object o6 = MyEnum.V_4; + bool r4 = o6 is 4; + if (r4) + return 11; + + r4 = o6 is MyEnum.V_4; + if (!r4) + return 12; + + ConstantPattern o7 = new ConstantPattern (); + if (!(o7 is ConstantPattern)) + return 13; + + if (!(o7 is object)) + return 14; + + object o8 = true; + if (o8 is false) + return 15; + + if (!(o8 is true)) + return 16; + + if (Generic ("")) + return 17; + + if (!Generic (null)) + return 18; + + Console.WriteLine ("ok"); + return 0; + } +} \ No newline at end of file diff --git a/mcs/tests/test-pattern-03.cs b/mcs/tests/test-pattern-03.cs new file mode 100644 index 0000000000..c4793bdb9d --- /dev/null +++ b/mcs/tests/test-pattern-03.cs @@ -0,0 +1,14 @@ +// Compiler options: -langversion:experimental + +class WildcardPattern +{ + static int Main () + { + long? o = 1; + bool b = o is *; + if (!b) + return 1; + + return 0; + } +} \ No newline at end of file diff --git a/mcs/tests/test-pattern-04.cs b/mcs/tests/test-pattern-04.cs new file mode 100644 index 0000000000..dff391cde5 --- /dev/null +++ b/mcs/tests/test-pattern-04.cs @@ -0,0 +1,77 @@ +// Compiler options: -langversion:experimental + +using System; + +class RecursivePattern +{ + static int Main () + { + object o = null; + bool b = o is C1 (8); + if (b) + return 1; + + o = new C1 (); + b = o is C1 (-4); + if (b) + return 2; + + b = o is C1 (8); + if (!b) + return 3; + + b = o is C1 (C1 (9), C1 (8)); + if (b) + return 4; + + b = o is C1 (C1 (*), C1 (8)); + if (!b) + return 41; + + b = o is C1 (0); + if (b) + return 5; + + ValueType vt = new S (); + b = vt is S (null, 0); + if (b) + return 6; + + b = vt is S (8, 0); + if (b) + return 7; + + b = vt is S (8, 2); + if (!b) + return 8; + + Console.WriteLine ("ok"); + return 0; + } +} + +class C1 +{ + public static bool operator is (C1 c, out int x) + { + x = 8; + return true; + } + + public static bool operator is (C1 c, out C1 c2, out C1 c3) + { + c2 = null; + c3 = null; + return true; + } +} + +struct S +{ + public static bool operator is (S s, out int? x, out decimal d) + { + x = 8; + d = 2; + return true; + } +} \ No newline at end of file diff --git a/mcs/tests/test-pattern-05.cs b/mcs/tests/test-pattern-05.cs new file mode 100644 index 0000000000..7553acd6df --- /dev/null +++ b/mcs/tests/test-pattern-05.cs @@ -0,0 +1,39 @@ +// Compiler options: -langversion:experimental + +using System; + +class RecursiveNamedPattern +{ + public static int Main () + { + object o = new C (); + bool b = o is C (name2: "", name1: -2); + if (b) + return 1; + + b = o is C (name2: "n2", name1: -2); + if (!b) + return 2; + + b = o is C (); + if (b) + return 3; + + return 0; + } +} + +class C +{ + public static bool operator is (C c, out long name1, out string name2) + { + name1 = -2; + name2 = "n2"; + return true; + } + + public static bool operator is (C c) + { + return false; + } +} \ No newline at end of file diff --git a/mcs/tests/test-pattern-06.cs b/mcs/tests/test-pattern-06.cs new file mode 100644 index 0000000000..3b54b840ac --- /dev/null +++ b/mcs/tests/test-pattern-06.cs @@ -0,0 +1,68 @@ +// Compiler options: -langversion:experimental + +using System; + +class RecursiveNamedPattern +{ + public static int Main () + { + if (Switch_1 (null) != 4) + return 1; + + if (Switch_1 ("x") != 5) + return 2; + + if (Switch_1 (1) != 1) + return 3; + + if (Switch_1 (new C1 ()) != 3) + return 4; + + if (Switch_1 ((byte?) 1) != 1) + return 5; + + if (Switch_2 (new C1 ()) != 3) + return 10; + + if (Switch_2 (null) != 2) + return 11; + + Console.WriteLine ("ok"); + return 0; + } + + static int Switch_1 (object o) + { + switch (o) { + case 1: + return 1; + case C1 (3): + return 2; + case C1 (2): + return 3; + case null: + return 4; + default: + return 5; + } + } + + static int Switch_2 (C1 o) + { + switch (o) { + case null: + return 2; + } + + return 3; + } +} + +public class C1 +{ + public static bool operator is (C1 c1, out int i) + { + i = 2; + return true; + } +} diff --git a/mcs/tests/test-pattern-07.cs b/mcs/tests/test-pattern-07.cs new file mode 100644 index 0000000000..bc7dfda0a8 --- /dev/null +++ b/mcs/tests/test-pattern-07.cs @@ -0,0 +1,75 @@ +// Compiler options: -langversion:experimental + +using System; + +class PropertyPattern +{ + static int Main () + { + object o = new DateTime (2014, 8, 30); + + if (!(o is DateTime { Day is 30 })) + return 1; + + if (!(o is DateTime { Month is 8, Day is 30, Year is * })) + return 2; + + if (o is X { Field is 30 }) + return 3; + + object o2 = new X () { + Field = new Y () { + Prop = 'f' + } + }; + + bool res2 = o2 is X { Field is Y { Prop is 'f' }, Field is Y (4) }; + if (!res2) + return 4; + + res2 = o2 is X { Field is Y { Prop is 'g' } }; + if (res2) + return 5; + + object o3 = new X () { + Value = 5 + }; + + if (o3 is X { Value is 6 }) + return 6; + + if (!(o3 is X { Value is 5 })) + return 7; + + object o4 = new X () { + NullableValue = 4 + }; + + bool res3 = o4 is X { NullableValue is (byte) 4 }; + if (!res3) + return 8; + + Console.WriteLine("ok"); + return 0; + } +} + +class X +{ + public object Field { get; set; } + + public object Value { get; set; } + + public long? NullableValue { get; set; } +} + +class Y +{ + public char Prop { get; set; } + + public static bool operator is (Y y, out int x) + { + x = 4; + return true; + } +} diff --git a/mcs/tests/test-primary-ctor-01.cs b/mcs/tests/test-primary-ctor-01.cs index f2b2239fd4..5b2eeaed8d 100644 --- a/mcs/tests/test-primary-ctor-01.cs +++ b/mcs/tests/test-primary-ctor-01.cs @@ -1,3 +1,4 @@ +// Compiler options: -langversion:experimental class Simple(int arg) { int Property { get; } = arg; diff --git a/mcs/tests/test-primary-ctor-07.cs b/mcs/tests/test-primary-ctor-07.cs index 233cfd0d03..79a1c2991e 100644 --- a/mcs/tests/test-primary-ctor-07.cs +++ b/mcs/tests/test-primary-ctor-07.cs @@ -1,3 +1,5 @@ +// Compiler options: -langversion:experimental + using System; struct S (int x) @@ -14,6 +16,21 @@ struct S (int x) } } +struct S2 (int arg) +{ + public readonly int v = arg; +} + +struct S3 (string s = "arg") +{ + public readonly string V2 = s; + + public S3 (int i, string s = "arg2") + : this (s) + { + } +} + class X { public static int Main () @@ -24,6 +41,15 @@ class X if (new S ('x').y != 1) return 2; + if (new S2 (2).v != 2) + return 3; + + if (new S3 ("x").V2 != "x") + return 4; + + if (new S3 (0).V2 != "arg2") + return 5; + return 0; } } \ No newline at end of file diff --git a/mcs/tests/ver-il-net_4_5.xml.REMOVED.git-id b/mcs/tests/ver-il-net_4_5.xml.REMOVED.git-id index e8755e9ae4..e57b04493a 100644 --- a/mcs/tests/ver-il-net_4_5.xml.REMOVED.git-id +++ b/mcs/tests/ver-il-net_4_5.xml.REMOVED.git-id @@ -1 +1 @@ -91a4ae6f2bcbaf1188bd0fc3e58da6a232f1cbd2 \ No newline at end of file +1f39ec3918ab572ca2c5655633d1814a6bb834b2 \ No newline at end of file diff --git a/mcs/tools/corcompare/mono-api-info.cs b/mcs/tools/corcompare/mono-api-info.cs index 2dc4bcebb3..a689210b12 100644 --- a/mcs/tools/corcompare/mono-api-info.cs +++ b/mcs/tools/corcompare/mono-api-info.cs @@ -545,6 +545,9 @@ namespace CorCompare if (TypeHelper.IsDelegate(t)) return "delegate"; + if (t.IsPointer) + return "pointer"; + return "class"; } @@ -907,6 +910,8 @@ namespace CorCompare AddAttribute (p, "abstract", "true"); if (mbase.IsVirtual) AddAttribute (p, "virtual", "true"); + if (mbase.IsFinal && mbase.IsVirtual && mbase.IsReuseSlot) + AddAttribute (p, "sealed", "true"); if (mbase.IsStatic) AddAttribute (p, "static", "true"); diff --git a/mcs/tools/mdoc/Makefile b/mcs/tools/mdoc/Makefile index e4ff1eed87..3b7e698d60 100644 --- a/mcs/tools/mdoc/Makefile +++ b/mcs/tools/mdoc/Makefile @@ -90,9 +90,23 @@ cleanup: -rm -Rf Test/en.actual Test/html.actual -rm -f monodocer1.exe* +Test/DocTest-DropNS-classic-secondary.dll: + @echo $(value @) + $(CSCOMPILE) $(TEST_CSCFLAGS) -debug -unsafe -target:library -out:$@ Test/DocTest-DropNS-classic-secondary.cs + +Test/DocTest-DropNS-classic.dll: + @echo $(value @) + $(CSCOMPILE) $(TEST_CSCFLAGS) -debug -unsafe -target:library -out:$@ Test/DocTest-DropNS-classic.cs + +Test/DocTest-DropNS-unified.dll: + $(CSCOMPILE) $(TEST_CSCFLAGS) -debug -unsafe -target:library -out:$@ Test/DocTest-DropNS-unified.cs + Test/DocTest.dll: $(CSCOMPILE) $(TEST_CSCFLAGS) -debug -unsafe -target:library -out:$@ Test/DocTest.cs +Test/DocTest-InternalInterface.dll: + $(CSCOMPILE) $(TEST_CSCFLAGS) -debug -unsafe -target:library -out:$@ Test/DocTest-InternalInterface.cs + Test/DocTest.dll-v1: -rm -f Test/DocTest.cs cp Test/DocTest-v1.cs Test/DocTest.cs @@ -106,6 +120,42 @@ Test/DocTest.dll-v2: -rm -f Test/DocTest.dll $(MAKE) TEST_CSCFLAGS=$(TEST_CSCFLAGS) Test/DocTest.dll +check-monodocer-dropns-classic: $(PROGRAM) + # tests the simplest --dropns case, a single class where the root namespace was dropped. + -rm -Rf Test/en.actual + $(MAKE) Test/DocTest-DropNS-classic.dll + $(MONO) $(PROGRAM) update --exceptions=all -o Test/en.actual Test/DocTest-DropNS-classic.dll + $(MAKE) update-monodocer-dropns-unified + diff --exclude=.svn -rup Test/en.expected-dropns-classic-v1 Test/en.actual + +check-monodocer-dropns-classic-withsecondary: $(PROGRAM) + # tests case where a secondary assembly is included with a --dropns parameter + -rm -Rf Test/en.actual + $(MAKE) Test/DocTest-DropNS-classic.dll + $(MAKE) Test/DocTest-DropNS-classic-secondary.dll + $(MONO) $(PROGRAM) update --exceptions=all -o Test/en.actual Test/DocTest-DropNS-classic.dll Test/DocTest-DropNS-classic-secondary.dll + $(MAKE) update-monodocer-dropns-unified-withsecondary + diff --exclude=.svn -rup Test/en.expected-dropns-classic-withsecondary Test/en.actual + +update-monodocer-dropns-unified: $(PROGRAM) + $(MAKE) Test/DocTest-DropNS-unified.dll + $(MONO) $(PROGRAM) update --exceptions=all -o Test/en.actual Test/DocTest-DropNS-unified.dll --dropns Test/DocTest-DropNS-unified.dll=MyFramework + +update-monodocer-dropns-unified-withsecondary: $(PROGRAM) + $(MAKE) Test/DocTest-DropNS-unified.dll + $(MONO) $(PROGRAM) update --exceptions=all -o Test/en.actual Test/DocTest-DropNS-unified.dll Test/DocTest-DropNS-classic-secondary.dll --dropns Test/DocTest-DropNS-unified.dll=MyFramework + +update-monodocer-dropns-classic-secondary: $(PROGRAM) + $(MAKE) Test/DocTest-DropNS-classic-secondary.dll + $(MONO) $(PROGRAM) update --exceptions=all -o Test/en.actual Test/DocTest-DropNS-classic-secondary.dll + +check-monodocer-internal-interface: $(PROGRAM) + # Tests to make sure internal interfaces that are explicitly implemented are not documented + -rm -Rf Test/en.actual + $(MAKE) Test/DocTest-InternalInterface.dll + $(MONO) $(PROGRAM) update --exceptions=all -o Test/en.actual Test/DocTest-InternalInterface.dll + diff --exclude=.svn -rup Test/en.expected-internal-interface Test/en.actual + check-monodocer-update: $(PROGRAM) find Test/en.expected -name \*.xml -exec rm "{}" \; $(MAKE) Test/DocTest.dll-v1 @@ -262,8 +312,12 @@ check-doc-tools-update: check-monodocer-since-update \ check-monodocer-importecmadoc-update \ check-monodocer-importslashdoc-update \ check-monodocer-update \ + check-monodocer-dropns-classic \ + check-monodocer-dropns-classic-withsecondary \ + check-monodocer-internal-interface \ check-monodocer-delete-update \ check-mdoc-export-html-update \ check-mdoc-export-msxdoc-update \ - check-mdoc-validate-update + check-mdoc-validate-update + diff --git a/mcs/tools/mdoc/Mono.Documentation/monodocer.cs.REMOVED.git-id b/mcs/tools/mdoc/Mono.Documentation/monodocer.cs.REMOVED.git-id index f9e0fabb45..02b8bae4ec 100644 --- a/mcs/tools/mdoc/Mono.Documentation/monodocer.cs.REMOVED.git-id +++ b/mcs/tools/mdoc/Mono.Documentation/monodocer.cs.REMOVED.git-id @@ -1 +1 @@ -75a6d5ca63e3306dfd27c5996a930a3118ebe725 \ No newline at end of file +842a4ae439f36136fbb90c5e5942dcf8b5d56cbb \ No newline at end of file diff --git a/mcs/tools/mdoc/Test/en.expected-dropns-classic-v0/MyFramework.MyNamespace/MyClass.xml b/mcs/tools/mdoc/Test/en.expected-dropns-classic-v0/MyFramework.MyNamespace/MyClass.xml new file mode 100644 index 0000000000..1e0522f64f --- /dev/null +++ b/mcs/tools/mdoc/Test/en.expected-dropns-classic-v0/MyFramework.MyNamespace/MyClass.xml @@ -0,0 +1,67 @@ + + + + + DocTest-DropNS-classic + 0.0.0.0 + + + System.Object + + + + To be added. + To be added. + + + + + + Constructor + + 0.0.0.0 + + + + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Single + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Property + + 0.0.0.0 + + + System.String + + + To be added. + To be added. + To be added. + + + + diff --git a/mcs/tools/mdoc/Test/en.expected-dropns-classic-v0/index.xml b/mcs/tools/mdoc/Test/en.expected-dropns-classic-v0/index.xml new file mode 100644 index 0000000000..4f7838baac --- /dev/null +++ b/mcs/tools/mdoc/Test/en.expected-dropns-classic-v0/index.xml @@ -0,0 +1,22 @@ + + + + + + System.Diagnostics.Debuggable(System.Diagnostics.DebuggableAttribute+DebuggingModes.IgnoreSymbolStoreSequencePoints) + + + System.Runtime.CompilerServices.RuntimeCompatibility(WrapNonExceptionThrows=true) + + + + + To be added. + To be added. + + + + + + DocTest-DropNS-classic + diff --git a/mcs/tools/mdoc/Test/en.expected-dropns-classic-v0/ns-MyFramework.MyNamespace.xml b/mcs/tools/mdoc/Test/en.expected-dropns-classic-v0/ns-MyFramework.MyNamespace.xml new file mode 100644 index 0000000000..74df75af20 --- /dev/null +++ b/mcs/tools/mdoc/Test/en.expected-dropns-classic-v0/ns-MyFramework.MyNamespace.xml @@ -0,0 +1,6 @@ + + + To be added. + To be added. + + diff --git a/mcs/tools/mdoc/Test/en.expected-dropns-classic-v1/MyFramework.MyNamespace/MyClass.xml b/mcs/tools/mdoc/Test/en.expected-dropns-classic-v1/MyFramework.MyNamespace/MyClass.xml new file mode 100644 index 0000000000..e3cda6d9d9 --- /dev/null +++ b/mcs/tools/mdoc/Test/en.expected-dropns-classic-v1/MyFramework.MyNamespace/MyClass.xml @@ -0,0 +1,80 @@ + + + + + DocTest-DropNS-classic + 0.0.0.0 + + + DocTest-DropNS-unified + 0.0.0.0 + + + System.Object + + + + To be added. + To be added. + + + + + + Constructor + + 0.0.0.0 + + + 0.0.0.0 + + + + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + 0.0.0.0 + + + System.Single + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Property + + 0.0.0.0 + + + 0.0.0.0 + + + System.String + + + To be added. + To be added. + To be added. + + + + diff --git a/mcs/tools/mdoc/Test/en.expected-dropns-classic-v1/index.xml b/mcs/tools/mdoc/Test/en.expected-dropns-classic-v1/index.xml new file mode 100644 index 0000000000..edacc723f5 --- /dev/null +++ b/mcs/tools/mdoc/Test/en.expected-dropns-classic-v1/index.xml @@ -0,0 +1,22 @@ + + + + + + System.Diagnostics.Debuggable(System.Diagnostics.DebuggableAttribute+DebuggingModes.IgnoreSymbolStoreSequencePoints) + + + System.Runtime.CompilerServices.RuntimeCompatibility(WrapNonExceptionThrows=true) + + + + + To be added. + To be added. + + + + + + DocTest-DropNS-classic + diff --git a/mcs/tools/mdoc/Test/en.expected-dropns-classic-v1/ns-MyFramework.MyNamespace.xml b/mcs/tools/mdoc/Test/en.expected-dropns-classic-v1/ns-MyFramework.MyNamespace.xml new file mode 100644 index 0000000000..74df75af20 --- /dev/null +++ b/mcs/tools/mdoc/Test/en.expected-dropns-classic-v1/ns-MyFramework.MyNamespace.xml @@ -0,0 +1,6 @@ + + + To be added. + To be added. + + diff --git a/mcs/tools/mdoc/Test/en.expected-dropns-classic-withsecondary/MyFramework.MyNamespace/MyClass.xml b/mcs/tools/mdoc/Test/en.expected-dropns-classic-withsecondary/MyFramework.MyNamespace/MyClass.xml new file mode 100644 index 0000000000..e3cda6d9d9 --- /dev/null +++ b/mcs/tools/mdoc/Test/en.expected-dropns-classic-withsecondary/MyFramework.MyNamespace/MyClass.xml @@ -0,0 +1,80 @@ + + + + + DocTest-DropNS-classic + 0.0.0.0 + + + DocTest-DropNS-unified + 0.0.0.0 + + + System.Object + + + + To be added. + To be added. + + + + + + Constructor + + 0.0.0.0 + + + 0.0.0.0 + + + + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + 0.0.0.0 + + + System.Single + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Property + + 0.0.0.0 + + + 0.0.0.0 + + + System.String + + + To be added. + To be added. + To be added. + + + + diff --git a/mcs/tools/mdoc/Test/en.expected-dropns-classic-withsecondary/MyFramework.MyOtherNamespace/MyOtherClass.xml b/mcs/tools/mdoc/Test/en.expected-dropns-classic-withsecondary/MyFramework.MyOtherNamespace/MyOtherClass.xml new file mode 100644 index 0000000000..a178fc47d6 --- /dev/null +++ b/mcs/tools/mdoc/Test/en.expected-dropns-classic-withsecondary/MyFramework.MyOtherNamespace/MyOtherClass.xml @@ -0,0 +1,67 @@ + + + + + DocTest-DropNS-classic-secondary + 0.0.0.0 + + + System.Object + + + + To be added. + To be added. + + + + + + Constructor + + 0.0.0.0 + + + + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Single + + + + + + To be added. + To be added. + To be added. + To be added. + + + + + + Property + + 0.0.0.0 + + + System.String + + + To be added. + To be added. + To be added. + + + + diff --git a/mcs/tools/mdoc/Test/en.expected-dropns-classic-withsecondary/index.xml b/mcs/tools/mdoc/Test/en.expected-dropns-classic-withsecondary/index.xml new file mode 100644 index 0000000000..d0fb593627 --- /dev/null +++ b/mcs/tools/mdoc/Test/en.expected-dropns-classic-withsecondary/index.xml @@ -0,0 +1,35 @@ + + + + + + System.Diagnostics.Debuggable(System.Diagnostics.DebuggableAttribute+DebuggingModes.IgnoreSymbolStoreSequencePoints) + + + System.Runtime.CompilerServices.RuntimeCompatibility(WrapNonExceptionThrows=true) + + + + + + + System.Diagnostics.Debuggable(System.Diagnostics.DebuggableAttribute+DebuggingModes.IgnoreSymbolStoreSequencePoints) + + + System.Runtime.CompilerServices.RuntimeCompatibility(WrapNonExceptionThrows=true) + + + + + To be added. + To be added. + + + + + + + + + Untitled + diff --git a/mcs/tools/mdoc/Test/en.expected-dropns-classic-withsecondary/ns-MyFramework.MyNamespace.xml b/mcs/tools/mdoc/Test/en.expected-dropns-classic-withsecondary/ns-MyFramework.MyNamespace.xml new file mode 100644 index 0000000000..74df75af20 --- /dev/null +++ b/mcs/tools/mdoc/Test/en.expected-dropns-classic-withsecondary/ns-MyFramework.MyNamespace.xml @@ -0,0 +1,6 @@ + + + To be added. + To be added. + + diff --git a/mcs/tools/mdoc/Test/en.expected-dropns-classic-withsecondary/ns-MyFramework.MyOtherNamespace.xml b/mcs/tools/mdoc/Test/en.expected-dropns-classic-withsecondary/ns-MyFramework.MyOtherNamespace.xml new file mode 100644 index 0000000000..8bdef1c777 --- /dev/null +++ b/mcs/tools/mdoc/Test/en.expected-dropns-classic-withsecondary/ns-MyFramework.MyOtherNamespace.xml @@ -0,0 +1,6 @@ + + + To be added. + To be added. + + diff --git a/mcs/tools/mdoc/Test/en.expected-internal-interface/MyNamespace/MyClass.xml b/mcs/tools/mdoc/Test/en.expected-internal-interface/MyNamespace/MyClass.xml new file mode 100644 index 0000000000..614b7b7d59 --- /dev/null +++ b/mcs/tools/mdoc/Test/en.expected-internal-interface/MyNamespace/MyClass.xml @@ -0,0 +1,63 @@ + + + + + DocTest-InternalInterface + 0.0.0.0 + + + System.Object + + + + To be added. + To be added. + + + + + + Constructor + + 0.0.0.0 + + + + To be added. + To be added. + + + + + + Property + + 0.0.0.0 + + + System.String + + + To be added. + To be added. + To be added. + + + + + + Method + + 0.0.0.0 + + + System.Void + + + + To be added. + To be added. + + + + diff --git a/mcs/tools/mdoc/Test/en.expected-internal-interface/index.xml b/mcs/tools/mdoc/Test/en.expected-internal-interface/index.xml new file mode 100644 index 0000000000..5b49f3c71d --- /dev/null +++ b/mcs/tools/mdoc/Test/en.expected-internal-interface/index.xml @@ -0,0 +1,22 @@ + + + + + + System.Diagnostics.Debuggable(System.Diagnostics.DebuggableAttribute+DebuggingModes.IgnoreSymbolStoreSequencePoints) + + + System.Runtime.CompilerServices.RuntimeCompatibility(WrapNonExceptionThrows=true) + + + + + To be added. + To be added. + + + + + + DocTest-InternalInterface + diff --git a/mcs/tools/mdoc/Test/en.expected-internal-interface/ns-MyNamespace.xml b/mcs/tools/mdoc/Test/en.expected-internal-interface/ns-MyNamespace.xml new file mode 100644 index 0000000000..bd8d43168a --- /dev/null +++ b/mcs/tools/mdoc/Test/en.expected-internal-interface/ns-MyNamespace.xml @@ -0,0 +1,6 @@ + + + To be added. + To be added. + + diff --git a/mcs/tools/mkbundle/mkbundle.cs b/mcs/tools/mkbundle/mkbundle.cs index f13ce63d02..6e11899537 100755 --- a/mcs/tools/mkbundle/mkbundle.cs +++ b/mcs/tools/mkbundle/mkbundle.cs @@ -715,9 +715,14 @@ void mono_register_config_for_assembly (const char* assembly_name, cons if (use_dos2unix == null) { use_dos2unix = false; try { - var dos2unix = Process.Start ("dos2unix"); + var info = new ProcessStartInfo ("dos2unix"); + info.CreateNoWindow = true; + info.RedirectStandardInput = true; + info.UseShellExecute = false; + var dos2unix = Process.Start (info); dos2unix.StandardInput.WriteLine ("aaa"); dos2unix.StandardInput.WriteLine ("\u0004"); + dos2unix.StandardInput.Close (); dos2unix.WaitForExit (); if (dos2unix.ExitCode == 0) use_dos2unix = true; diff --git a/mcs/tools/security/Makefile b/mcs/tools/security/Makefile index c9baa67ccf..ba771b5166 100644 --- a/mcs/tools/security/Makefile +++ b/mcs/tools/security/Makefile @@ -6,7 +6,7 @@ include ../../build/rules.make LOCAL_MCS_FLAGS = /lib:$(topdir)/class/lib/$(PROFILE) -r:Mono.Security.dll SECURITY_PROGRAMS = secutil.exe cert2spc.exe sn.exe makecert.exe chktrust.exe crlupdate.exe \ - signcode.exe setreg.exe certmgr.exe caspol.exe permview.exe mozroots.exe + signcode.exe setreg.exe certmgr.exe caspol.exe permview.exe mozroots.exe cert-sync.exe SECURITY_PROGRAMS_2_0 = httpcfg.exe HELPER_SOURCES = AssemblyInfo.cs $(topdir)/build/common/Consts.cs diff --git a/mcs/tools/security/cert-sync.cs b/mcs/tools/security/cert-sync.cs new file mode 100644 index 0000000000..44280675dd --- /dev/null +++ b/mcs/tools/security/cert-sync.cs @@ -0,0 +1,226 @@ +// +// cert-sync.cs: Import the root certificates from Linux SSL store into Mono +// +// Authors: +// Sebastien Pouliot +// Jo Shields +// +// Copyright (C) 2005 Novell, Inc (http://www.novell.com) +// Copyright (C) 2014 Xamarin, Inc (http://www.xamarin.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. +// + +using System; +using System.Collections; +using System.IO; +using System.Net; +using System.Reflection; +using System.Security.Cryptography; +using System.Text; + +using Mono.Security.X509; + +[assembly: AssemblyTitle ("Linux Cert Store Sync")] +[assembly: AssemblyDescription ("Synchronize local certs with certs from local Linux trust store.")] + +namespace Mono.Tools +{ + + class CertSync + { + + static string inputFile; + static bool quiet; + + static X509Certificate DecodeCertificate (string s) + { + byte[] rawdata = Convert.FromBase64String (s); + return new X509Certificate (rawdata); + } + + static Stream GetFile () + { + try { + if (inputFile != null) { + return File.OpenRead (inputFile); + } else { + return null; + } + } catch { + return null; + } + } + + static X509CertificateCollection DecodeCollection () + { + X509CertificateCollection roots = new X509CertificateCollection (); + StringBuilder sb = new StringBuilder (); + bool processing = false; + + using (Stream s = GetFile ()) { + if (s == null) { + WriteLine ("Couldn't retrieve the file using the supplied information."); + return null; + } + + StreamReader sr = new StreamReader (s); + while (true) { + string line = sr.ReadLine (); + if (line == null) + break; + + if (processing) { + if (line.StartsWith ("-----END CERTIFICATE-----")) { + processing = false; + X509Certificate root = DecodeCertificate (sb.ToString ()); + roots.Add (root); + + sb = new StringBuilder (); + continue; + } + sb.Append (line); + } else { + processing = line.StartsWith ("-----BEGIN CERTIFICATE-----"); + } + } + return roots; + } + } + + static int Process () + { + X509CertificateCollection roots = DecodeCollection (); + if (roots == null) { + return 1; + } else if (roots.Count == 0) { + WriteLine ("No certificates were found."); + return 0; + } + + X509Stores stores = (X509StoreManager.LocalMachine); + X509CertificateCollection trusted = stores.TrustedRoot.Certificates; + int additions = 0; + WriteLine ("I already trust {0}, your new list has {1}", trusted.Count, roots.Count); + foreach (X509Certificate root in roots) { + if (!trusted.Contains (root)) { + try { + stores.TrustedRoot.Import (root); + WriteLine ("Certificate added: {0}", root.SubjectName); + } catch { + WriteLine ("Warning: Could not import {0}"); + } + additions++; + } + } + if (additions > 0) + WriteLine ("{0} new root certificates were added to your trust store.", additions); + + X509CertificateCollection removed = new X509CertificateCollection (); + foreach (X509Certificate trust in trusted) { + if (!roots.Contains (trust)) { + removed.Add (trust); + } + } + if (removed.Count > 0) { + WriteLine ("{0} previously trusted certificates were removed.", removed.Count); + + foreach (X509Certificate old in removed) { + stores.TrustedRoot.Remove (old); + WriteLine ("Certificate removed: {0}", old.SubjectName); + } + } + WriteLine ("Import process completed."); + return 0; + } + + static string Thumbprint (string algorithm, X509Certificate certificate) + { + HashAlgorithm hash = HashAlgorithm.Create (algorithm); + byte[] digest = hash.ComputeHash (certificate.RawData); + return BitConverter.ToString (digest); + } + + static bool ParseOptions (string[] args) + { + if (args.Length < 1) + return false; + + for (int i = 0; i < args.Length - 1; i++) { + switch (args [i]) { + case "--quiet": + quiet = true; + break; + default: + WriteLine ("Unknown option '{0}'."); + return false; + } + } + inputFile = args [args.Length - 1]; + if (!File.Exists (inputFile)) { + WriteLine ("Unknown option or file not found '{0}'."); + return false; + } + return true; + } + + static void Header () + { + Console.WriteLine (new AssemblyInfo ().ToString ()); + } + + static void Help () + { + Console.WriteLine ("Usage: cert-sync [--quiet] system-ca-bundle.crt"); + Console.WriteLine ("Where system-ca-bundle.crt is in PEM format"); + } + + static void WriteLine (string str) + { + if (!quiet) + Console.WriteLine (str); + } + + static void WriteLine (string format, params object[] args) + { + if (!quiet) + Console.WriteLine (format, args); + } + + static int Main (string[] args) + { + try { + if (!ParseOptions (args)) { + Header (); + Help (); + return 1; + } + if (!quiet) { + Header (); + } + return Process (); + } catch (Exception e) { + // ignore quiet on exception + Console.WriteLine ("Error: {0}", e); + return 1; + } + } + } +} \ No newline at end of file diff --git a/mono-core.spec b/mono-core.spec index 4f78c977fd..35ad888122 100644 --- a/mono-core.spec +++ b/mono-core.spec @@ -12,7 +12,7 @@ License: LGPL v2.1 only Group: Development/Languages/Mono Summary: A .NET Runtime Environment Url: http://www.mono-project.com -Version: 3.10.0 +Version: 3.12.0 Release: 0 Source0: mono-%{version}.tar.bz2 BuildRequires: bison diff --git a/mono/Makefile.am b/mono/Makefile.am index 495f16922e..df1a9c1c22 100644 --- a/mono/Makefile.am +++ b/mono/Makefile.am @@ -1,5 +1,5 @@ if CROSS_COMPILING -SUBDIRS = arch utils io-layer cil metadata $(interpreter_dir) mini dis profiler +SUBDIRS = arch utils io-layer cil metadata mini dis profiler else if INSTALL_MONOTOUCH SUBDIRS = utils io-layer metadata arch mini profiler @@ -26,7 +26,7 @@ monotouch-do-clean: (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$target); \ done; else -SUBDIRS = arch utils io-layer cil metadata $(interpreter_dir) mini dis monograph tests unit-tests benchmark profiler +SUBDIRS = arch utils io-layer cil metadata mini dis monograph tests unit-tests benchmark profiler endif endif -DIST_SUBDIRS = arch utils io-layer cil metadata interpreter mini dis monograph tests unit-tests benchmark profiler +DIST_SUBDIRS = arch utils io-layer cil metadata mini dis monograph tests unit-tests benchmark profiler diff --git a/mono/Makefile.in b/mono/Makefile.in index 70b0089cc9..bd315424c3 100644 --- a/mono/Makefile.in +++ b/mono/Makefile.in @@ -380,10 +380,10 @@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -@CROSS_COMPILING_FALSE@@INSTALL_MONOTOUCH_FALSE@SUBDIRS = arch utils io-layer cil metadata $(interpreter_dir) mini dis monograph tests unit-tests benchmark profiler +@CROSS_COMPILING_FALSE@@INSTALL_MONOTOUCH_FALSE@SUBDIRS = arch utils io-layer cil metadata mini dis monograph tests unit-tests benchmark profiler @CROSS_COMPILING_FALSE@@INSTALL_MONOTOUCH_TRUE@SUBDIRS = utils io-layer metadata arch mini profiler -@CROSS_COMPILING_TRUE@SUBDIRS = arch utils io-layer cil metadata $(interpreter_dir) mini dis profiler -DIST_SUBDIRS = arch utils io-layer cil metadata interpreter mini dis monograph tests unit-tests benchmark profiler +@CROSS_COMPILING_TRUE@SUBDIRS = arch utils io-layer cil metadata mini dis profiler +DIST_SUBDIRS = arch utils io-layer cil metadata mini dis monograph tests unit-tests benchmark profiler all: all-recursive .SUFFIXES: diff --git a/mono/arch/Makefile.am b/mono/arch/Makefile.am index 3d687949f9..87416872f6 100644 --- a/mono/arch/Makefile.am +++ b/mono/arch/Makefile.am @@ -2,23 +2,9 @@ DIST_SUBDIRS = x86 ppc sparc arm arm64 s390x amd64 ia64 mips AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) -if INTERP_SUPPORTED -SUBDIRS = $(arch_target) -else if ARM # arm needs to build some stuff even in JIT mode SUBDIRS = $(arch_target) -endif -endif - -if INTERP_SUPPORTED - -noinst_LTLIBRARIES = libmonoarch.la - -libmonoarch_la_SOURCES = unknown.c - -libmonoarch_la_LIBADD = $(arch_target)/libmonoarch-$(arch_target).la - endif EXTRA_DIST = ChangeLog diff --git a/mono/arch/Makefile.in b/mono/arch/Makefile.in index 78530945c7..2ff2a76bb8 100644 --- a/mono/arch/Makefile.in +++ b/mono/arch/Makefile.in @@ -13,7 +13,6 @@ # PARTICULAR PURPOSE. @SET_MAKE@ - VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ @@ -81,7 +80,7 @@ host_triplet = @host@ target_triplet = @target@ subdir = mono/arch DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp ChangeLog + $(top_srcdir)/mkinstalldirs ChangeLog ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/iconv.m4 \ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ @@ -97,16 +96,6 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -@INTERP_SUPPORTED_TRUE@libmonoarch_la_DEPENDENCIES = $(arch_target)/libmonoarch-$(arch_target).la -am__libmonoarch_la_SOURCES_DIST = unknown.c -@INTERP_SUPPORTED_TRUE@am_libmonoarch_la_OBJECTS = unknown.lo -libmonoarch_la_OBJECTS = $(am_libmonoarch_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -@INTERP_SUPPORTED_TRUE@am_libmonoarch_la_rpath = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -119,26 +108,8 @@ AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libmonoarch_la_SOURCES) -DIST_SOURCES = $(am__libmonoarch_la_SOURCES_DIST) +SOURCES = +DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ @@ -411,17 +382,13 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ DIST_SUBDIRS = x86 ppc sparc arm arm64 s390x amd64 ia64 mips AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) + # arm needs to build some stuff even in JIT mode -@ARM_TRUE@@INTERP_SUPPORTED_FALSE@SUBDIRS = $(arch_target) -@INTERP_SUPPORTED_TRUE@SUBDIRS = $(arch_target) -@INTERP_SUPPORTED_TRUE@noinst_LTLIBRARIES = libmonoarch.la -@INTERP_SUPPORTED_TRUE@libmonoarch_la_SOURCES = unknown.c -@INTERP_SUPPORTED_TRUE@libmonoarch_la_LIBADD = $(arch_target)/libmonoarch-$(arch_target).la +@ARM_TRUE@SUBDIRS = $(arch_target) EXTRA_DIST = ChangeLog all: all-recursive .SUFFIXES: -.SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -453,52 +420,6 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -libmonoarch.la: $(libmonoarch_la_OBJECTS) $(libmonoarch_la_DEPENDENCIES) $(EXTRA_libmonoarch_la_DEPENDENCIES) - $(AM_V_CCLD)$(LINK) $(am_libmonoarch_la_rpath) $(libmonoarch_la_OBJECTS) $(libmonoarch_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unknown.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - mostlyclean-libtool: -rm -f *.lo @@ -661,7 +582,7 @@ distdir: $(DISTFILES) done check-am: all-am check: check-recursive -all-am: Makefile $(LTLIBRARIES) +all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive @@ -696,14 +617,11 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am +clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive - -rm -rf ./$(DEPDIR) -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags +distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive @@ -746,14 +664,12 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive - -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool +mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive @@ -768,9 +684,8 @@ uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ - check-am clean clean-generic clean-libtool \ - clean-noinstLTLIBRARIES cscopelist-am ctags ctags-am distclean \ - distclean-compile distclean-generic distclean-libtool \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ @@ -778,9 +693,8 @@ uninstall-am: install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/mono/arch/amd64/Makefile.am b/mono/arch/amd64/Makefile.am index 3c72826319..47daaaff69 100644 --- a/mono/arch/amd64/Makefile.am +++ b/mono/arch/amd64/Makefile.am @@ -1,7 +1,2 @@ - -AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) - -noinst_LTLIBRARIES = libmonoarch-amd64.la - -libmonoarch_amd64_la_SOURCES = tramp.c amd64-codegen.h +EXTRA_DIST = amd64-codegen.h diff --git a/mono/arch/amd64/Makefile.in b/mono/arch/amd64/Makefile.in index 6f4b3eb966..335aa2e4e0 100644 --- a/mono/arch/amd64/Makefile.in +++ b/mono/arch/amd64/Makefile.in @@ -13,7 +13,6 @@ # PARTICULAR PURPOSE. @SET_MAKE@ - VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ @@ -81,7 +80,7 @@ host_triplet = @host@ target_triplet = @target@ subdir = mono/arch/amd64 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp + $(top_srcdir)/mkinstalldirs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/iconv.m4 \ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ @@ -97,14 +96,6 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -libmonoarch_amd64_la_LIBADD = -am_libmonoarch_amd64_la_OBJECTS = tramp.lo -libmonoarch_amd64_la_OBJECTS = $(am_libmonoarch_amd64_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -117,50 +108,14 @@ AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libmonoarch_amd64_la_SOURCES) -DIST_SOURCES = $(libmonoarch_amd64_la_SOURCES) +SOURCES = +DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -366,13 +321,10 @@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) -noinst_LTLIBRARIES = libmonoarch-amd64.la -libmonoarch_amd64_la_SOURCES = tramp.c amd64-codegen.h +EXTRA_DIST = amd64-codegen.h all: all-am .SUFFIXES: -.SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -404,109 +356,17 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -libmonoarch-amd64.la: $(libmonoarch_amd64_la_OBJECTS) $(libmonoarch_amd64_la_DEPENDENCIES) $(EXTRA_libmonoarch_amd64_la_DEPENDENCIES) - $(AM_V_CCLD)$(LINK) $(libmonoarch_amd64_la_OBJECTS) $(libmonoarch_amd64_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tramp.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs +tags TAGS: -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags +ctags CTAGS: -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am +cscope cscopelist: -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -540,7 +400,7 @@ distdir: $(DISTFILES) done check-am: all-am check: check-am -all-am: Makefile $(LTLIBRARIES) +all-am: Makefile installdirs: install: install-am install-exec: install-exec-am @@ -574,14 +434,11 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am +clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags +distclean-am: clean-am distclean-generic dvi: dvi-am @@ -624,14 +481,12 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool +mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am @@ -645,19 +500,17 @@ uninstall-am: .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ - ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am + tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/mono/arch/amd64/tramp.c b/mono/arch/amd64/tramp.c deleted file mode 100644 index 6dbec93e85..0000000000 --- a/mono/arch/amd64/tramp.c +++ /dev/null @@ -1,1054 +0,0 @@ -/* - * Create trampolines to invoke arbitrary functions. - * - * Copyright (C) Ximian Inc. - * - * Author: - * Zalman Stern - * Based on code by: - * Paolo Molaro (lupus@ximian.com) - * Dietmar Maurer (dietmar@ximian.com) - * - * To understand this code, one will want to the calling convention section of the ABI sepc at: - * http://x86-64.org/abi.pdf - * and the AMD64 architecture docs found at amd.com . - */ - -#include "config.h" -#include -#include -#include "amd64-codegen.h" -#include "mono/metadata/class.h" -#include "mono/metadata/tabledefs.h" -#include "mono/interpreter/interp.h" -#include "mono/metadata/appdomain.h" -#include "mono/metadata/marshal.h" - -/* - * The resulting function takes the form: - * void func (void (*callme)(), void *retval, void *this_obj, stackval *arguments); - */ -#define FUNC_ADDR_POS 8 -#define RETVAL_POS 12 -#define THIS_POS 16 -#define ARGP_POS 20 -#define LOC_POS -4 - -#define ARG_SIZE sizeof (stackval) - -#define MAX_INT_ARG_REGS 6 -#define MAX_FLOAT_ARG_REGS 8 - -// TODO get these right. They are upper bounds anyway, so it doesn't much matter. -#define PUSH_INT_STACK_ARG_SIZE 16 -#define MOVE_INT_REG_ARG_SIZE 16 -#define PUSH_FLOAT_STACK_ARG_SIZE 16 -#define MOVE_FLOAT_REG_ARG_SIZE 16 -#define COPY_STRUCT_STACK_ARG_SIZE 16 - -/* Maps an argument number (starting at 0) to the register it is passed in (if it fits). - * E.g. int foo(int bar, int quux) has the foo arg in RDI and the quux arg in RSI - * There is no such map for floating point args as they go in XMM0-XMM7 in order and thus the - * index is the register number. - */ -static int int_arg_regs[] = { AMD64_RDI, AMD64_RSI, AMD64_RDX, AMD64_RCX, AMD64_R8, AMD64_R9 }; - -/* This next block of code resolves the ABI rules for passing structures in the argument registers. - * These basically amount to "Use up to two registers if they are all integer or all floating point. - * If the structure is bigger than two registers or would be in one integer register and one floating point, - * it is passed in memory instead. - * - * It is possible this code needs to be recursive to be correct in the case when one of the structure members - * is itself a structure. - * - * The 80-bit floating point stuff is ignored. - */ -typedef enum { - ARG_IN_MEMORY, - ARG_IN_INT_REGS, - ARG_IN_FLOAT_REGS -} struct_arg_type; - -static struct_arg_type compute_arg_type(MonoType *type) -{ - guint32 simpletype = type->type; - - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_CHAR: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_I8: - return ARG_IN_INT_REGS; - break; - case MONO_TYPE_VALUETYPE: { - if (type->data.klass->enumtype) - return ARG_IN_INT_REGS; - return ARG_IN_MEMORY; - break; - } - case MONO_TYPE_R4: - case MONO_TYPE_R8: - return ARG_IN_FLOAT_REGS; - break; - default: - g_error ("Can't trampoline 0x%x", type->type); - } - - return ARG_IN_MEMORY; -} - -static struct_arg_type value_type_info(MonoClass *klass, int *native_size, int *regs_used, int *offset1, int *size1, int *offset2, int *size2) -{ - MonoMarshalType *info = mono_marshal_load_type_info (klass); - - *native_size = info->native_size; - - if (info->native_size > 8 || info->num_fields > 2) - { - *regs_used = 0; - *offset1 = -1; - *offset2 = -1; - return ARG_IN_MEMORY; - } - - if (info->num_fields == 1) - { - struct_arg_type result = compute_arg_type(info->fields[0].field->type); - if (result != ARG_IN_MEMORY) - { - *regs_used = 1; - *offset1 = info->fields[0].offset; - *size1 = mono_marshal_type_size (info->fields[0].field->type, info->fields[0].mspec, NULL, 1, 1); - } - else - { - *regs_used = 0; - *offset1 = -1; - } - - *offset2 = -1; - return result; - } - - struct_arg_type result1 = compute_arg_type(info->fields[0].field->type); - struct_arg_type result2 = compute_arg_type(info->fields[0].field->type); - - if (result1 == result2 && result1 != ARG_IN_MEMORY) - { - *regs_used = 2; - *offset1 = info->fields[0].offset; - *size1 = mono_marshal_type_size (info->fields[0].field->type, info->fields[0].mspec, NULL, 1, 1); - *offset2 = info->fields[1].offset; - *size2 = mono_marshal_type_size (info->fields[1].field->type, info->fields[1].mspec, NULL, 1, 1); - return result1; - } - - return ARG_IN_MEMORY; -} - -MonoPIFunc -mono_arch_create_trampoline (MonoMethodSignature *sig, gboolean string_ctor) -{ - unsigned char *p, *code_buffer; - guint32 stack_size = 0, code_size = 50; - guint32 arg_pos, simpletype; - int i; - static GHashTable *cache = NULL; - MonoPIFunc res; - - guint32 int_arg_regs_used = 0; - guint32 float_arg_regs_used = 0; - guint32 next_int_arg_reg = 0; - guint32 next_float_arg_reg = 0; - /* Indicates that the return value is filled in inside the called function. */ - int retval_implicit = 0; - char *arg_in_reg_bitvector; /* A set index by argument number saying if it is in a register - (integer or floating point according to type) */ - - if (!cache) - cache = g_hash_table_new ((GHashFunc)mono_signature_hash, - (GCompareFunc)mono_metadata_signature_equal); - - if ((res = (MonoPIFunc)g_hash_table_lookup (cache, sig))) - return res; - - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref && !sig->ret->data.klass->enumtype) { - int_arg_regs_used++; - code_size += MOVE_INT_REG_ARG_SIZE; - } - - if (sig->hasthis) { - int_arg_regs_used++; - code_size += MOVE_INT_REG_ARG_SIZE; - } - - /* Run through stuff to calculate code size and argument bytes that will be pushed on stack (stack_size). */ - for (i = 0; i < sig->param_count; ++i) { - if (sig->params [i]->byref) - simpletype = MONO_TYPE_PTR; - else - simpletype = sig->params [i]->type; -enum_calc_size: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_CHAR: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_I8: - if (int_arg_regs_used++ > MAX_INT_ARG_REGS) { - stack_size += 8; - code_size += PUSH_INT_STACK_ARG_SIZE; - } - else - code_size += MOVE_INT_REG_ARG_SIZE; - break; - case MONO_TYPE_VALUETYPE: { - int size; - int arg_type; - int regs_used; - int offset1; - int size1; - int offset2; - int size2; - - if (sig->params [i]->data.klass->enumtype) { - simpletype = sig->params [i]->data.klass->enum_basetype->type; - goto enum_calc_size; - } - - arg_type = value_type_info(sig->params [i]->data.klass, &size, ®s_used, &offset1, &size1, &offset2, &size2); - if (arg_type == ARG_IN_INT_REGS && - (int_arg_regs_used + regs_used) <= MAX_INT_ARG_REGS) - { - code_size += MOVE_INT_REG_ARG_SIZE; - int_arg_regs_used += regs_used; - break; - } - - if (arg_type == ARG_IN_FLOAT_REGS && - (float_arg_regs_used + regs_used) <= MAX_FLOAT_ARG_REGS) - { - code_size += MOVE_FLOAT_REG_ARG_SIZE; - float_arg_regs_used += regs_used; - break; - } - - /* Else item is in memory. */ - - stack_size += size + 7; - stack_size &= ~7; - code_size += COPY_STRUCT_STACK_ARG_SIZE; - - break; - } - case MONO_TYPE_R4: - case MONO_TYPE_R8: - if (float_arg_regs_used++ > MAX_FLOAT_ARG_REGS) { - stack_size += 8; - code_size += PUSH_FLOAT_STACK_ARG_SIZE; - } - else - code_size += MOVE_FLOAT_REG_ARG_SIZE; - break; - default: - g_error ("Can't trampoline 0x%x", sig->params [i]->type); - } - } - /* - * FIXME: take into account large return values. - * (Comment carried over from IA32 code. Not sure what it means :-) - */ - - code_buffer = p = alloca (code_size); - - /* - * Standard function prolog. - */ - amd64_push_reg (p, AMD64_RBP); - amd64_mov_reg_reg (p, AMD64_RBP, AMD64_RSP, 8); - /* - * and align to 16 byte boundary... - */ - - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref) { - MonoClass *klass = sig->ret->data.klass; - if (!klass->enumtype) { - retval_implicit = 1; - } - } - - if (sig->ret->byref || string_ctor || !(retval_implicit || sig->ret->type == MONO_TYPE_VOID)) { - /* Push the retval register so it is saved across the call. It will be addressed via RBP later. */ - amd64_push_reg (p, AMD64_RSI); - stack_size += 8; - } - - /* Ensure stack is 16 byte aligned when entering called function as required by calling convention. - * Getting this wrong results in a general protection fault on an SSE load or store somewhere in the - * code called under the trampoline. - */ - if ((stack_size & 15) != 0) - amd64_alu_reg_imm (p, X86_SUB, AMD64_RSP, 16 - (stack_size & 15)); - - /* - * On entry to generated function: - * RDI has target function address - * RSI has return value location address - * RDX has this pointer address - * RCX has the pointer to the args array. - * - * Inside the stub function: - * R10 holds the pointer to the args - * R11 holds the target function address. - * The return value address is pushed on the stack. - * The this pointer is moved into the first arg register at the start. - * - * Optimization note: we could keep the args pointer in RCX and then - * load over itself at the end. Ditto the callee addres could be left in RDI in some cases. - */ - - /* Move args pointer to temp register. */ - amd64_mov_reg_reg (p, AMD64_R10, AMD64_RCX, 8); - amd64_mov_reg_reg (p, AMD64_R11, AMD64_RDI, 8); - - /* First args register gets return value pointer, if need be. - * Note that "byref" equal true means the called function returns a pointer. - */ - if (retval_implicit) { - amd64_mov_reg_reg (p, int_arg_regs[next_int_arg_reg], AMD64_RSI, 8); - next_int_arg_reg++; - } - - /* this pointer goes in next args register. */ - if (sig->hasthis) { - amd64_mov_reg_reg (p, int_arg_regs[next_int_arg_reg], AMD64_RDX, 8); - next_int_arg_reg++; - } - - /* - * Generate code to handle arguments in registers. Stack arguments will happen in a loop after this. - */ - arg_in_reg_bitvector = (char *)alloca((sig->param_count + 7) / 8); - memset(arg_in_reg_bitvector, 0, (sig->param_count + 7) / 8); - - /* First, load all the arguments that are passed in registers into the appropriate registers. - * Below there is another loop to handle arguments passed on the stack. - */ - for (i = 0; i < sig->param_count; i++) { - arg_pos = ARG_SIZE * i; - - if (sig->params [i]->byref) - simpletype = MONO_TYPE_PTR; - else - simpletype = sig->params [i]->type; -enum_marshal: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_I8: - case MONO_TYPE_U8: - case MONO_TYPE_CLASS: - if (next_int_arg_reg < MAX_INT_ARG_REGS) { - amd64_mov_reg_membase (p, int_arg_regs[next_int_arg_reg], AMD64_R10, arg_pos, 8); - next_int_arg_reg++; - arg_in_reg_bitvector[i >> 3] |= (1 << (i & 7)); - } - break; - case MONO_TYPE_R4: - if (next_float_arg_reg < MAX_FLOAT_ARG_REGS) { - amd64_movss_reg_membase (p, next_float_arg_reg, AMD64_R10, arg_pos); - next_float_arg_reg++; - arg_in_reg_bitvector[i >> 3] |= (1 << (i & 7)); - } - break; - case MONO_TYPE_R8: - if (next_float_arg_reg < MAX_FLOAT_ARG_REGS) { - amd64_movsd_reg_membase (p, next_float_arg_reg, AMD64_R10, arg_pos); - next_float_arg_reg++; - arg_in_reg_bitvector[i >> 3] |= (1 << (i & 7)); - } - break; - case MONO_TYPE_VALUETYPE: { - if (!sig->params [i]->data.klass->enumtype) { - int size; - int arg_type; - int regs_used; - int offset1; - int size1; - int offset2; - int size2; - - arg_type = value_type_info(sig->params [i]->data.klass, &size, ®s_used, &offset1, &size1, &offset2, &size2); - - if (arg_type == ARG_IN_INT_REGS && - (next_int_arg_reg + regs_used) <= MAX_INT_ARG_REGS) - { - amd64_mov_reg_membase (p, int_arg_regs[next_int_arg_reg], AMD64_R10, arg_pos + offset1, size1); - next_int_arg_reg++; - if (regs_used > 1) - { - amd64_mov_reg_membase (p, int_arg_regs[next_int_arg_reg], AMD64_R10, arg_pos + offset2, size2); - next_int_arg_reg++; - } - arg_in_reg_bitvector[i >> 3] |= (1 << (i & 7)); - break; - } - - if (arg_type == ARG_IN_FLOAT_REGS && - (next_float_arg_reg + regs_used) <= MAX_FLOAT_ARG_REGS) - { - if (size1 == 4) - amd64_movss_reg_membase (p, next_float_arg_reg, AMD64_R10, arg_pos + offset1); - else - amd64_movsd_reg_membase (p, next_float_arg_reg, AMD64_R10, arg_pos + offset1); - next_float_arg_reg++; - - if (regs_used > 1) - { - if (size2 == 4) - amd64_movss_reg_membase (p, next_float_arg_reg, AMD64_R10, arg_pos + offset2); - else - amd64_movsd_reg_membase (p, next_float_arg_reg, AMD64_R10, arg_pos + offset2); - next_float_arg_reg++; - } - arg_in_reg_bitvector[i >> 3] |= (1 << (i & 7)); - break; - } - - /* Structs in memory are handled in the next loop. */ - } else { - /* it's an enum value */ - simpletype = sig->params [i]->data.klass->enum_basetype->type; - goto enum_marshal; - } - break; - } - default: - g_error ("Can't trampoline 0x%x", sig->params [i]->type); - } - } - - /* Handle stack arguments, pushing the rightmost argument first. */ - for (i = sig->param_count; i > 0; --i) { - arg_pos = ARG_SIZE * (i - 1); - if (sig->params [i - 1]->byref) - simpletype = MONO_TYPE_PTR; - else - simpletype = sig->params [i - 1]->type; -enum_marshal2: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_I8: - case MONO_TYPE_U8: - case MONO_TYPE_CLASS: - if ((arg_in_reg_bitvector[(i - 1) >> 3] & (1 << ((i - 1) & 7))) == 0) { - amd64_push_membase (p, AMD64_R10, arg_pos); - } - break; - case MONO_TYPE_R4: - if ((arg_in_reg_bitvector[(i - 1) >> 3] & (1 << ((i - 1) & 7))) == 0) { - amd64_push_membase (p, AMD64_R10, arg_pos); - } - break; - case MONO_TYPE_R8: - if ((arg_in_reg_bitvector[(i - 1) >> 3] & (1 << ((i - 1) & 7))) == 0) { - amd64_push_membase (p, AMD64_R10, arg_pos); - } - break; - case MONO_TYPE_VALUETYPE: - if (!sig->params [i - 1]->data.klass->enumtype) { - if ((arg_in_reg_bitvector[(i - 1) >> 3] & (1 << ((i - 1) & 7))) == 0) - { - int ss = mono_class_native_size (sig->params [i - 1]->data.klass, NULL); - ss += 7; - ss &= ~7; - - amd64_alu_reg_imm(p, X86_SUB, AMD64_RSP, ss); - /* Count register */ - amd64_mov_reg_imm(p, AMD64_RCX, ss); - /* Source register */ - amd64_lea_membase(p, AMD64_RSI, AMD64_R10, arg_pos); - /* Dest register */ - amd64_mov_reg_reg(p, AMD64_RDI, AMD64_RSP, 8); - - /* AMD64 calling convention guarantees direction flag is clear at call boundary. */ - x86_prefix(p, AMD64_REX(AMD64_REX_W)); - x86_prefix(p, X86_REP_PREFIX); - x86_movsb(p); - } - } else { - /* it's an enum value */ - simpletype = sig->params [i - 1]->data.klass->enum_basetype->type; - goto enum_marshal2; - } - break; - default: - g_error ("Can't trampoline 0x%x", sig->params [i - 1]->type); - } - } - - /* TODO: Set RAL to number of XMM registers used in case this is a varags function? */ - - /* - * Insert call to function - */ - amd64_call_reg (p, AMD64_R11); - - if (sig->ret->byref || string_ctor || !(retval_implicit || sig->ret->type == MONO_TYPE_VOID)) { - amd64_mov_reg_membase(p, AMD64_RSI, AMD64_RBP, -8, SIZEOF_VOID_P); - } - /* - * Handle retval. - * Small integer and pointer values are in EAX. - * Long integers are in EAX:EDX. - * FP values are on the FP stack. - */ - - if (sig->ret->byref || string_ctor) { - simpletype = MONO_TYPE_PTR; - } else { - simpletype = sig->ret->type; - } - enum_retvalue: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - amd64_mov_regp_reg (p, AMD64_RSI, X86_EAX, 1); - break; - case MONO_TYPE_CHAR: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - amd64_mov_regp_reg (p, AMD64_RSI, X86_EAX, 2); - break; - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_ARRAY: - case MONO_TYPE_STRING: - case MONO_TYPE_PTR: - amd64_mov_regp_reg (p, AMD64_RSI, X86_EAX, 8); - break; - case MONO_TYPE_R4: - amd64_movss_regp_reg (p, AMD64_RSI, AMD64_XMM0); - break; - case MONO_TYPE_R8: - amd64_movsd_regp_reg (p, AMD64_RSI, AMD64_XMM0); - break; - case MONO_TYPE_I8: - amd64_mov_regp_reg (p, AMD64_RSI, X86_EAX, 8); - break; - case MONO_TYPE_VALUETYPE: { - int size; - int arg_type; - int regs_used; - int offset1; - int size1; - int offset2; - int size2; - - if (sig->ret->data.klass->enumtype) { - simpletype = sig->ret->data.klass->enum_basetype->type; - goto enum_retvalue; - } - - arg_type = value_type_info(sig->params [i]->data.klass, &size, ®s_used, &offset1, &size1, &offset2, &size2); - - if (arg_type == ARG_IN_INT_REGS) - { - amd64_mov_membase_reg (p, AMD64_RSI, offset1, AMD64_RAX, size1); - if (regs_used > 1) - amd64_mov_membase_reg (p, AMD64_RSI, offset2, AMD64_RDX, size2); - break; - } - - if (arg_type == ARG_IN_FLOAT_REGS) - { - if (size1 == 4) - amd64_movss_membase_reg (p, AMD64_RSI, offset1, AMD64_XMM0); - else - amd64_movsd_membase_reg (p, AMD64_RSI, offset1, AMD64_XMM0); - - if (regs_used > 1) - { - if (size2 == 4) - amd64_movss_membase_reg (p, AMD64_RSI, offset2, AMD64_XMM1); - else - amd64_movsd_membase_reg (p, AMD64_RSI, offset2, AMD64_XMM1); - } - break; - } - - /* Else result should have been stored in place already. */ - break; - } - case MONO_TYPE_VOID: - break; - default: - g_error ("Can't handle as return value 0x%x", sig->ret->type); - } - - /* - * Standard epilog. - */ - amd64_leave (p); - amd64_ret (p); - - g_assert (p - code_buffer < code_size); - res = (MonoPIFunc)g_memdup (code_buffer, p - code_buffer); - - g_hash_table_insert (cache, sig, res); - - return res; -} - -/* - * Returns a pointer to a native function that can be used to - * call the specified method. - * The function created will receive the arguments according - * to the call convention specified in the method. - * This function works by creating a MonoInvocation structure, - * filling the fields in and calling ves_exec_method on it. - * Still need to figure out how to handle the exception stuff - * across the managed/unmanaged boundary. - */ -void * -mono_arch_create_method_pointer (MonoMethod *method) -{ - MonoMethodSignature *sig; - MonoJitInfo *ji; - unsigned char *p, *code_buffer; - guint32 simpletype; - gint32 local_size; - gint32 stackval_pos; - gint32 mono_invocation_pos; - int i, cpos; - int *vtbuf; - int *rbpoffsets; - int int_arg_regs_used = 0; - int float_arg_regs_used = 0; - int stacked_args_size = 0; /* bytes of register passed arguments pushed on stack for safe keeping. Used to get alignment right. */ - int next_stack_arg_rbp_offset = 16; - int retval_ptr_rbp_offset = 0; - int this_reg = -1; /* Remember register this ptr is in. */ - - /* - * If it is a static P/Invoke method, we can just return the pointer - * to the method implementation. - */ - if (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL && ((MonoMethodPInvoke*) method)->addr) { - ji = g_new0 (MonoJitInfo, 1); - ji->method = method; - ji->code_size = 1; - ji->code_start = ((MonoMethodPInvoke*) method)->addr; - - mono_jit_info_table_add (mono_get_root_domain (), ji); - return ((MonoMethodPInvoke*) method)->addr; - } - - sig = method->signature; - - code_buffer = p = alloca (512); /* FIXME: check for overflows... */ - vtbuf = alloca (sizeof(int)*sig->param_count); - rbpoffsets = alloca (sizeof(int)*sig->param_count); - - - /* - * Standard function prolog. - */ - amd64_push_reg (p, AMD64_RBP); - amd64_mov_reg_reg (p, AMD64_RBP, AMD64_RSP, 8); - - /* If there is an implicit return value pointer in the first args reg, save it now so - * the result can be stored through the pointer at the end. - */ - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref && !sig->ret->data.klass->enumtype) - { - amd64_push_reg (p, int_arg_regs[int_arg_regs_used]); - int_arg_regs_used++; - stacked_args_size += 8; - retval_ptr_rbp_offset = -stacked_args_size; - } - - /* - * If there is a this pointer, remember the number of the register it is in. - */ - if (sig->hasthis) { - this_reg = int_arg_regs[int_arg_regs_used++]; - } - - /* Put all arguments passed in registers on the stack. - * Record offsets from RBP to each argument. - */ - cpos = 0; - - for (i = 0; i < sig->param_count; i++) { - if (sig->params [i]->byref) - simpletype = MONO_TYPE_PTR; - else - simpletype = sig->params [i]->type; -enum_calc_size: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_CHAR: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_I8: - if (int_arg_regs_used < MAX_INT_ARG_REGS) { - amd64_push_reg (p, int_arg_regs[int_arg_regs_used]); - int_arg_regs_used++; - stacked_args_size += 8; - rbpoffsets[i] = -stacked_args_size; - } - else - { - rbpoffsets[i] = next_stack_arg_rbp_offset; - next_stack_arg_rbp_offset += 8; - } - break; - case MONO_TYPE_VALUETYPE: { - if (sig->params [i]->data.klass->enumtype) { - simpletype = sig->params [i]->data.klass->enum_basetype->type; - goto enum_calc_size; - } - else - { - int size; - int arg_type; - int regs_used; - int offset1; - int size1; - int offset2; - int size2; - - arg_type = value_type_info(sig->params [i]->data.klass, &size, ®s_used, &offset1, &size1, &offset2, &size2); - - if (arg_type == ARG_IN_INT_REGS && - (int_arg_regs_used + regs_used) <= MAX_INT_ARG_REGS) - { - amd64_alu_reg_imm (p, X86_SUB, AMD64_RSP, size); - stacked_args_size += size; - rbpoffsets[i] = stacked_args_size; - - amd64_mov_reg_membase (p, int_arg_regs[int_arg_regs_used], AMD64_RSP, offset1, size1); - int_arg_regs_used++; - if (regs_used > 1) - { - amd64_mov_reg_membase (p, int_arg_regs[int_arg_regs_used], AMD64_RSP, offset2, size2); - int_arg_regs_used++; - } - break; - } - - if (arg_type == ARG_IN_FLOAT_REGS && - (float_arg_regs_used + regs_used) <= MAX_FLOAT_ARG_REGS) - { - amd64_alu_reg_imm (p, X86_SUB, AMD64_RSP, size); - stacked_args_size += size; - rbpoffsets[i] = stacked_args_size; - - if (size1 == 4) - amd64_movss_reg_membase (p, float_arg_regs_used, AMD64_RSP, offset1); - else - amd64_movsd_reg_membase (p, float_arg_regs_used, AMD64_RSP, offset1); - float_arg_regs_used++; - - if (regs_used > 1) - { - if (size2 == 4) - amd64_movss_reg_membase (p, float_arg_regs_used, AMD64_RSP, offset2); - else - amd64_movsd_reg_membase (p, float_arg_regs_used, AMD64_RSP, offset2); - float_arg_regs_used++; - } - break; - } - - rbpoffsets[i] = next_stack_arg_rbp_offset; - next_stack_arg_rbp_offset += size; - } - break; - } - case MONO_TYPE_R4: - if (float_arg_regs_used < MAX_FLOAT_ARG_REGS) { - amd64_alu_reg_imm (p, X86_SUB, AMD64_RSP, 8); - amd64_movss_regp_reg (p, AMD64_RSP, float_arg_regs_used); - float_arg_regs_used++; - stacked_args_size += 8; - rbpoffsets[i] = -stacked_args_size; - } - else - { - rbpoffsets[i] = next_stack_arg_rbp_offset; - next_stack_arg_rbp_offset += 8; - } - break; - case MONO_TYPE_R8: - stacked_args_size += 8; - if (float_arg_regs_used < MAX_FLOAT_ARG_REGS) { - amd64_alu_reg_imm (p, X86_SUB, AMD64_RSP, 8); - amd64_movsd_regp_reg (p, AMD64_RSP, float_arg_regs_used); - float_arg_regs_used++; - stacked_args_size += 8; - rbpoffsets[i] = -stacked_args_size; - } - else - { - rbpoffsets[i] = next_stack_arg_rbp_offset; - next_stack_arg_rbp_offset += 8; - } - break; - default: - g_error ("Can't trampoline 0x%x", sig->params [i]->type); - } - } - - local_size = sizeof (MonoInvocation) + sizeof (stackval) * (sig->param_count + 1) + stacked_args_size; - - local_size += 15; - local_size &= ~15; - - stackval_pos = -local_size; - mono_invocation_pos = stackval_pos + sizeof (stackval) * (sig->param_count + 1); - - /* stacked_args_size has already been pushed onto the stack. Make room for the rest of it. */ - amd64_alu_reg_imm (p, X86_SUB, AMD64_RSP, local_size - stacked_args_size); - - /* Be careful not to trash any arg regs before saving this_reg to MonoInvocation structure below. */ - - /* - * Initialize MonoInvocation fields, first the ones known now. - */ - amd64_alu_reg_reg (p, X86_XOR, AMD64_RAX, AMD64_RAX); - amd64_mov_membase_reg (p, AMD64_RBP, (mono_invocation_pos + G_STRUCT_OFFSET (MonoInvocation, ex)), AMD64_RAX, SIZEOF_VOID_P); - amd64_mov_membase_reg (p, AMD64_RBP, (mono_invocation_pos + G_STRUCT_OFFSET (MonoInvocation, ex_handler)), AMD64_RAX, SIZEOF_VOID_P); - amd64_mov_membase_reg (p, AMD64_RBP, (mono_invocation_pos + G_STRUCT_OFFSET (MonoInvocation, parent)), AMD64_RAX, SIZEOF_VOID_P); - /* - * Set the method pointer. - */ - amd64_mov_membase_imm (p, AMD64_RBP, (mono_invocation_pos + G_STRUCT_OFFSET (MonoInvocation, method)), (long)method, SIZEOF_VOID_P); - - /* - * Handle this. - */ - if (sig->hasthis) - amd64_mov_membase_reg(p, AMD64_RBP, (mono_invocation_pos + G_STRUCT_OFFSET (MonoInvocation, obj)), this_reg, SIZEOF_VOID_P); - - /* - * Handle the arguments. stackval_pos is the offset from RBP of the stackval in the MonoInvocation args array . - * arg_pos is the offset from RBP to the incoming arg on the stack. - * We just call stackval_from_data to handle all the (nasty) issues.... - */ - amd64_lea_membase (p, AMD64_RAX, AMD64_RBP, stackval_pos); - amd64_mov_membase_reg (p, AMD64_RBP, (mono_invocation_pos + G_STRUCT_OFFSET (MonoInvocation, stack_args)), AMD64_RAX, SIZEOF_VOID_P); - for (i = 0; i < sig->param_count; ++i) { -/* Need to call stackval_from_data (MonoType *type, stackval *result, char *data, gboolean pinvoke); */ - amd64_mov_reg_imm (p, AMD64_R11, stackval_from_data); - amd64_mov_reg_imm (p, int_arg_regs[0], sig->params[i]); - amd64_lea_membase (p, int_arg_regs[1], AMD64_RBP, stackval_pos); - amd64_lea_membase (p, int_arg_regs[2], AMD64_RBP, rbpoffsets[i]); - amd64_mov_reg_imm (p, int_arg_regs[3], sig->pinvoke); - amd64_call_reg (p, AMD64_R11); - stackval_pos += sizeof (stackval); -#if 0 - /* fixme: alignment */ - if (sig->pinvoke) - arg_pos += mono_type_native_stack_size (sig->params [i], &align); - else - arg_pos += mono_type_stack_size (sig->params [i], &align); -#endif - } - - /* - * Handle the return value storage area. - */ - amd64_lea_membase (p, AMD64_RAX, AMD64_RBP, stackval_pos); - amd64_mov_membase_reg (p, AMD64_RBP, (mono_invocation_pos + G_STRUCT_OFFSET (MonoInvocation, retval)), AMD64_RAX, SIZEOF_VOID_P); - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref) { - MonoClass *klass = sig->ret->data.klass; - if (!klass->enumtype) { - amd64_mov_reg_membase (p, AMD64_RCX, AMD64_RBP, retval_ptr_rbp_offset, SIZEOF_VOID_P); - amd64_mov_membase_reg (p, AMD64_RBP, stackval_pos, AMD64_RCX, SIZEOF_VOID_P); - } - } - - /* - * Call the method. - */ - amd64_lea_membase (p, int_arg_regs[0], AMD64_RBP, mono_invocation_pos); - amd64_mov_reg_imm (p, AMD64_R11, ves_exec_method); - amd64_call_reg (p, AMD64_R11); - - /* - * Move the return value to the proper place. - */ - amd64_lea_membase (p, AMD64_RAX, AMD64_RBP, stackval_pos); - if (sig->ret->byref) { - amd64_mov_reg_membase (p, AMD64_RAX, AMD64_RAX, 0, SIZEOF_VOID_P); - } else { - int simpletype = sig->ret->type; - enum_retvalue: - switch (sig->ret->type) { - case MONO_TYPE_VOID: - break; - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - amd64_movzx_reg_membase (p, AMD64_RAX, AMD64_RAX, 0, 1); - break; - case MONO_TYPE_CHAR: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - amd64_movzx_reg_membase (p, AMD64_RAX, AMD64_RAX, 0, 2); - break; - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_CLASS: - amd64_movzx_reg_membase (p, AMD64_RAX, AMD64_RAX, 0, 4); - break; - case MONO_TYPE_I8: - amd64_movzx_reg_membase (p, AMD64_RAX, AMD64_RAX, 0, 8); - break; - case MONO_TYPE_R4: - amd64_movss_regp_reg (p, AMD64_RAX, AMD64_XMM0); - break; - case MONO_TYPE_R8: - amd64_movsd_regp_reg (p, AMD64_RAX, AMD64_XMM0); - break; - case MONO_TYPE_VALUETYPE: { - int size; - int arg_type; - int regs_used; - int offset1; - int size1; - int offset2; - int size2; - - if (sig->ret->data.klass->enumtype) { - simpletype = sig->ret->data.klass->enum_basetype->type; - goto enum_retvalue; - } - - arg_type = value_type_info(sig->params [i]->data.klass, &size, ®s_used, &offset1, &size1, &offset2, &size2); - - if (arg_type == ARG_IN_INT_REGS) - { - if (regs_used > 1) - amd64_mov_membase_reg (p, AMD64_RAX, offset2, AMD64_RDX, size2); - amd64_mov_membase_reg (p, AMD64_RAX, offset1, AMD64_RAX, size1); - break; - } - - if (arg_type == ARG_IN_FLOAT_REGS) - { - if (size1 == 4) - amd64_movss_membase_reg (p, AMD64_RAX, offset1, AMD64_XMM0); - else - amd64_movsd_membase_reg (p, AMD64_RAX, offset1, AMD64_XMM0); - - if (regs_used > 1) - { - if (size2 == 4) - amd64_movss_membase_reg (p, AMD64_RAX, offset2, AMD64_XMM1); - else - amd64_movsd_membase_reg (p, AMD64_RAX, offset2, AMD64_XMM1); - } - break; - } - - /* Else result should have been stored in place already. IA32 code has a stackval_to_data call here, which - * looks wrong to me as the pointer in the stack val being converted is setup to point to the output area anyway. - * It all looks a bit suspect anyway. - */ - break; - } - default: - g_error ("Type 0x%x not handled yet in thunk creation", sig->ret->type); - break; - } - } - - /* - * Standard epilog. - */ - amd64_leave (p); - amd64_ret (p); - - g_assert (p - code_buffer < 512); - - ji = g_new0 (MonoJitInfo, 1); - ji->method = method; - ji->code_size = p - code_buffer; - ji->code_start = g_memdup (code_buffer, p - code_buffer); - - mono_jit_info_table_add (mono_get_root_domain (), ji); - - return ji->code_start; -} diff --git a/mono/arch/ppc/Makefile.am b/mono/arch/ppc/Makefile.am index a4e2d5d2e7..9b209ef940 100644 --- a/mono/arch/ppc/Makefile.am +++ b/mono/arch/ppc/Makefile.am @@ -1,11 +1 @@ -if INTERP_SUPPORTED - -AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) - -noinst_LTLIBRARIES = libmonoarch-ppc.la - -libmonoarch_ppc_la_SOURCES = tramp.c ppc-codegen.h - -noinst_PROGRAMS = test - -endif +EXTRA_DIST = ppc-codegen.h \ No newline at end of file diff --git a/mono/arch/ppc/Makefile.in b/mono/arch/ppc/Makefile.in index 2953d2bf19..53f62fa658 100644 --- a/mono/arch/ppc/Makefile.in +++ b/mono/arch/ppc/Makefile.in @@ -13,8 +13,6 @@ # PARTICULAR PURPOSE. @SET_MAKE@ - - VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ @@ -80,10 +78,9 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -@INTERP_SUPPORTED_TRUE@noinst_PROGRAMS = test$(EXEEXT) subdir = mono/arch/ppc DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp + $(top_srcdir)/mkinstalldirs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/iconv.m4 \ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ @@ -99,20 +96,6 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -libmonoarch_ppc_la_LIBADD = -am__libmonoarch_ppc_la_SOURCES_DIST = tramp.c ppc-codegen.h -@INTERP_SUPPORTED_TRUE@am_libmonoarch_ppc_la_OBJECTS = tramp.lo -libmonoarch_ppc_la_OBJECTS = $(am_libmonoarch_ppc_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -@INTERP_SUPPORTED_TRUE@am_libmonoarch_ppc_la_rpath = -PROGRAMS = $(noinst_PROGRAMS) -test_SOURCES = test.c -test_OBJECTS = test.$(OBJEXT) -test_LDADD = $(LDADD) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -125,50 +108,14 @@ AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libmonoarch_ppc_la_SOURCES) test.c -DIST_SOURCES = $(am__libmonoarch_ppc_la_SOURCES_DIST) test.c +SOURCES = +DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -374,13 +321,10 @@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -@INTERP_SUPPORTED_TRUE@AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) -@INTERP_SUPPORTED_TRUE@noinst_LTLIBRARIES = libmonoarch-ppc.la -@INTERP_SUPPORTED_TRUE@libmonoarch_ppc_la_SOURCES = tramp.c ppc-codegen.h +EXTRA_DIST = ppc-codegen.h all: all-am .SUFFIXES: -.SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -412,123 +356,17 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -libmonoarch-ppc.la: $(libmonoarch_ppc_la_OBJECTS) $(libmonoarch_ppc_la_DEPENDENCIES) $(EXTRA_libmonoarch_ppc_la_DEPENDENCIES) - $(AM_V_CCLD)$(LINK) $(am_libmonoarch_ppc_la_rpath) $(libmonoarch_ppc_la_OBJECTS) $(libmonoarch_ppc_la_LIBADD) $(LIBS) - -clean-noinstPROGRAMS: - @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list - -test$(EXEEXT): $(test_OBJECTS) $(test_DEPENDENCIES) $(EXTRA_test_DEPENDENCIES) - @rm -f test$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(test_OBJECTS) $(test_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tramp.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs +tags TAGS: -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags +ctags CTAGS: -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am +cscope cscopelist: -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -562,7 +400,7 @@ distdir: $(DISTFILES) done check-am: all-am check: check-am -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) +all-am: Makefile installdirs: install: install-am install-exec: install-exec-am @@ -596,14 +434,11 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - clean-noinstPROGRAMS mostlyclean-am +clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags +distclean-am: clean-am distclean-generic dvi: dvi-am @@ -646,14 +481,12 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool +mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am @@ -667,19 +500,17 @@ uninstall-am: .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \ - cscopelist-am ctags ctags-am distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-dvi install-dvi-am \ - install-exec install-exec-am install-html install-html-am \ - install-info install-info-am install-man install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am + tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/mono/arch/ppc/test.c b/mono/arch/ppc/test.c deleted file mode 100644 index c19358dcab..0000000000 --- a/mono/arch/ppc/test.c +++ /dev/null @@ -1,35 +0,0 @@ -#include "ppc-codegen.h" -#include - -/* don't run the resulting program, it will destroy your computer, - * just objdump -d it to inspect we generated the correct assembler. - * On Mac OS X use otool[64] -v -t - */ - -int main() { - guint8 code [16000]; - guint8 *p = code; - guint8 *cp; - - printf (".text\n.align 4\n.globl main\n"); -#ifndef __APPLE__ - printf (".type main,@function\n"); -#endif - printf ("main:\n"); - - ppc_stwu (p, ppc_r1, -32, ppc_r1); - ppc_mflr (p, ppc_r0); - ppc_stw (p, ppc_r31, 28, ppc_r1); - ppc_or (p, ppc_r1, ppc_r2, ppc_r3); - ppc_mr (p, ppc_r31, ppc_r1); - ppc_lwz (p, ppc_r11, 0, ppc_r1); - ppc_mtlr (p, ppc_r0); - ppc_blr (p); - ppc_addi (p, ppc_r6, ppc_r6, 16); - - for (cp = code; cp < p; cp++) { - printf (".byte 0x%x\n", *cp); - } - - return 0; -} diff --git a/mono/arch/ppc/tramp.c b/mono/arch/ppc/tramp.c deleted file mode 100644 index 6bb1896255..0000000000 --- a/mono/arch/ppc/tramp.c +++ /dev/null @@ -1,895 +0,0 @@ -/* - * Create trampolines to invoke arbitrary functions. - * - * Copyright (C) Radek Doulik - * - */ - -#include "config.h" -#include -#include -#include "ppc-codegen.h" -#include "mono/metadata/class.h" -#include "mono/metadata/tabledefs.h" -#include "mono/interpreter/interp.h" -#include "mono/metadata/appdomain.h" - -#ifdef NEED_MPROTECT -#include -#include /* for PAGESIZE */ -#ifndef PAGESIZE -#define PAGESIZE 4096 -#endif -#endif - -#define DEBUG(x) - -/* gpointer -fake_func (gpointer (*callme)(gpointer), stackval *retval, void *this_obj, stackval *arguments) -{ - guint32 i = 0xc002becd; - - callme = (gpointer) 0x100fabcd; - - *(gpointer*)retval = (gpointer)(*callme) (arguments [0].data.p, arguments [1].data.p, arguments [2].data.p); - *(gdouble*) retval = (gdouble)(*callme) (arguments [0].data.f); - - return (gpointer) (*callme) (((MonoType *)arguments [0]. data.p)->data.klass); -} */ - -#define MIN_CACHE_LINE 8 - -static void inline -flush_icache (guint8 *code, guint size) -{ - guint i; - guint8 *p; - - p = code; - for (i = 0; i < size; i += MIN_CACHE_LINE, p += MIN_CACHE_LINE) { - asm ("dcbst 0,%0;" : : "r"(p) : "memory"); - } - asm ("sync"); - p = code; - for (i = 0; i < size; i += MIN_CACHE_LINE, p += MIN_CACHE_LINE) { - asm ("icbi 0,%0; sync;" : : "r"(p) : "memory"); - } - asm ("sync"); - asm ("isync"); -} - -static void -disassemble (guint8 *code, int size) -{ - int i; - FILE *ofd; - const char *tmp = g_getenv("TMP"); - char *as_file; - char *o_file; - char *cmd; - - if (tmp == NULL) - tmp = "/tmp"; - as_file = g_strdup_printf ("%s/test.s", tmp); - - if (!(ofd = fopen (as_file, "w"))) - g_assert_not_reached (); - - fprintf (ofd, "tmp:\n"); - - for (i = 0; i < size; ++i) - fprintf (ofd, ".byte %d\n", (unsigned int) code [i]); - - fclose (ofd); -#ifdef __APPLE__ -#define DIS_CMD "otool -V -v -t" -#else -#define DIS_CMD "objdump -d" -#endif - o_file = g_strdup_printf ("%s/test.o", tmp); - cmd = g_strdup_printf ("as %s -o %s", as_file, o_file); - system (cmd); - g_free (cmd); - cmd = g_strdup_printf (DIS_CMD " %s", o_file); - system (cmd); - g_free (cmd); - g_free (o_file); - g_free (as_file); -} - - -#define NOT_IMPLEMENTED(x) \ - g_error ("FIXME: %s is not yet implemented. (trampoline)", x); - -#define PROLOG_INS 8 -#define CALL_INS 2 -#define EPILOG_INS 6 -#define FLOAT_REGS 8 -#define GENERAL_REGS 8 -#ifdef __APPLE__ -#define MINIMAL_STACK_SIZE 10 -#define ALWAYS_ON_STACK(s) s -#define FP_ALSO_IN_REG(s) s -#define RET_ADDR_OFFSET 8 -#define STACK_PARAM_OFFSET 24 -#else -#define MINIMAL_STACK_SIZE 5 -#define ALWAYS_ON_STACK(s) -#define FP_ALSO_IN_REG(s) s -#define ALIGN_DOUBLES -#define RET_ADDR_OFFSET 4 -#define STACK_PARAM_OFFSET 8 -#endif - -static void inline -add_general (guint *gr, guint *stack_size, guint *code_size, gboolean simple) -{ - if (simple) { - if (*gr >= GENERAL_REGS) { - *stack_size += 4; - *code_size += 8; /* load from stack, save on stack */ - } else { - ALWAYS_ON_STACK (*stack_size += 4); - *code_size += 4; /* load from stack */ - } - } else { - if (*gr >= GENERAL_REGS - 1) { - *stack_size += 8; -#ifdef ALIGN_DOUBLES - *stack_size += (*stack_size % 8); -#endif - *code_size += 16; /* 2x load from stack, 2x save to stack */ - } else { - ALWAYS_ON_STACK (*stack_size += 8); - *code_size += 8; /* 2x load from stack */ - } -#ifdef ALIGN_DOUBLES - if ((*gr) & 1) - (*gr) ++; -#endif - (*gr) ++; - } - (*gr) ++; -} - -static void inline -calculate_sizes (MonoMethodSignature *sig, guint *stack_size, guint *code_size, gboolean string_ctor, gboolean *use_memcpy) -{ - guint i, fr, gr; - guint32 simpletype; - - fr = gr = 0; - *stack_size = MINIMAL_STACK_SIZE*4; - *code_size = (PROLOG_INS + CALL_INS + EPILOG_INS)*4; - - if (sig->hasthis) { - add_general (&gr, stack_size, code_size, TRUE); - } - DEBUG(printf("params: %d\n", sig->param_count)); - for (i = 0; i < sig->param_count; ++i) { - DEBUG(printf("param %d: ", i)); - if (sig->params [i]->byref) { - DEBUG(printf("byref\n")); - add_general (&gr, stack_size, code_size, TRUE); - continue; - } - simpletype = sig->params [i]->type; - enum_calc_size: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_CHAR: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - add_general (&gr, stack_size, code_size, TRUE); - break; - case MONO_TYPE_SZARRAY: - add_general (&gr, stack_size, code_size, TRUE); - *code_size += 4; - break; - case MONO_TYPE_VALUETYPE: { - gint size; - if (sig->params [i]->data.klass->enumtype) { - simpletype = sig->params [i]->data.klass->enum_basetype->type; - goto enum_calc_size; - } - size = mono_class_value_size (sig->params [i]->data.klass, NULL); - if (size != 4) { - DEBUG(printf ("copy %d bytes struct on stack\n", - mono_class_value_size (sig->params [i]->data.klass, NULL))); - *use_memcpy = TRUE; - *code_size += 8*4; - *stack_size += (size + 3) & (~3); - if (gr > GENERAL_REGS) { - *code_size += 4; - *stack_size += 4; - } - } else { - DEBUG(printf ("load %d bytes struct\n", - mono_class_value_size (sig->params [i]->data.klass, NULL))); - add_general (&gr, stack_size, code_size, TRUE); - *code_size += 4; - } - break; - } - case MONO_TYPE_I8: - add_general (&gr, stack_size, code_size, FALSE); - break; - case MONO_TYPE_R4: - if (fr < 7) { - *code_size += 4; - fr ++; - FP_ALSO_IN_REG (gr ++); - ALWAYS_ON_STACK (*stack_size += 4); - } else { - NOT_IMPLEMENTED ("R4 arg"); - } - break; - case MONO_TYPE_R8: - if (fr < 7) { - *code_size += 4; - fr ++; - FP_ALSO_IN_REG (gr += 2); - ALWAYS_ON_STACK (*stack_size += 8); - } else { - NOT_IMPLEMENTED ("R8 arg"); - } - break; - default: - g_error ("Can't trampoline 0x%x", sig->params [i]->type); - } - } - - if (sig->ret->byref || string_ctor) { - *code_size += 8; - } else { - simpletype = sig->ret->type; -enum_retvalue: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_R4: - case MONO_TYPE_R8: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_ARRAY: - case MONO_TYPE_STRING: - *code_size += 8; - break; - case MONO_TYPE_I8: - *code_size += 12; - break; - case MONO_TYPE_VALUETYPE: - if (sig->ret->data.klass->enumtype) { - simpletype = sig->ret->data.klass->enum_basetype->type; - goto enum_retvalue; - } - *code_size += 2*4; - break; - case MONO_TYPE_VOID: - break; - default: - g_error ("Can't handle as return value 0x%x", sig->ret->type); - } - } - - if (*use_memcpy) { - *stack_size += 2*4; /* for r14, r15 */ - *code_size += 6*4; - if (sig->hasthis) { - *stack_size += 4; /* for r16 */ - *code_size += 4; - } - } - - /* align stack size to 16 */ - DEBUG (printf (" stack size: %d (%d)\n code size: %d\n", (*stack_size + 15) & ~15, *stack_size, *code_size)); - *stack_size = (*stack_size + 15) & ~15; -} - -static inline guint8 * -emit_prolog (guint8 *p, MonoMethodSignature *sig, guint stack_size) -{ - /* function prolog */ - ppc_stwu (p, ppc_r1, -stack_size, ppc_r1); /* sp <--- sp - stack_size, sp[0] <---- sp save sp, alloc stack */ - ppc_mflr (p, ppc_r0); /* r0 <--- LR */ - ppc_stw (p, ppc_r31, stack_size - 4, ppc_r1); /* sp[+4] <--- r31 save r31 */ - ppc_stw (p, ppc_r0, stack_size + RET_ADDR_OFFSET, ppc_r1); /* sp[-4] <--- LR save return address for "callme" */ - ppc_mr (p, ppc_r31, ppc_r1); /* r31 <--- sp */ - - return p; -} - -#define ARG_BASE ppc_r12 -#define ARG_SIZE sizeof (stackval) -#define SAVE_4_IN_GENERIC_REGISTER \ - if (gr < GENERAL_REGS) { \ - ppc_lwz (p, ppc_r3 + gr, i*ARG_SIZE, ARG_BASE); \ - gr ++; \ - ALWAYS_ON_STACK (stack_par_pos += 4); \ - } else { \ - ppc_lwz (p, ppc_r11, i*ARG_SIZE, ARG_BASE); \ - ppc_stw (p, ppc_r11, stack_par_pos, ppc_r1); \ - stack_par_pos += 4; \ - } -#define SAVE_4_VAL_IN_GENERIC_REGISTER \ - if (gr < GENERAL_REGS) { \ - ppc_lwz (p, ppc_r3 + gr, i*ARG_SIZE, ARG_BASE); \ - ppc_lwz (p, ppc_r3 + gr, 0, ppc_r3 + gr); \ - gr ++; \ - ALWAYS_ON_STACK (stack_par_pos += 4); \ - } else { \ - ppc_lwz (p, ppc_r11, i*ARG_SIZE, ARG_BASE); \ - ppc_lwz (p, ppc_r11, 0, ppc_r11); \ - ppc_stw (p, ppc_r11, stack_par_pos, ppc_r1); \ - stack_par_pos += 4; \ - } - -inline static guint8* -emit_save_parameters (guint8 *p, MonoMethodSignature *sig, guint stack_size, gboolean use_memcpy) -{ - guint i, fr, gr, stack_par_pos, struct_pos, cur_struct_pos; - guint32 simpletype; - - fr = gr = 0; - stack_par_pos = STACK_PARAM_OFFSET; - - ppc_stw (p, ppc_r4, stack_size - 12, ppc_r31); /* preserve "retval", sp[+8] */ - - if (use_memcpy) { - ppc_stw (p, ppc_r14, stack_size - 16, ppc_r31); /* save r14 */ - ppc_stw (p, ppc_r15, stack_size - 20, ppc_r31); /* save r15 */ - ppc_mr (p, ppc_r14, ppc_r3); /* keep "callme" in register */ - ppc_mr (p, ppc_r15, ppc_r6); /* keep "arguments" in register */ - } else { - ppc_mr (p, ppc_r12, ppc_r6); /* keep "arguments" in register */ - ppc_mr (p, ppc_r0, ppc_r3); /* keep "callme" in register */ - } - - if (sig->hasthis) { - if (use_memcpy) { - ppc_stw (p, ppc_r16, stack_size - 24, ppc_r31); /* save r16 */ - ppc_mr (p, ppc_r16, ppc_r5); - } else - ppc_mr (p, ppc_r3, ppc_r5); - gr ++; - ALWAYS_ON_STACK (stack_par_pos += 4); - } - - if (use_memcpy) { - cur_struct_pos = struct_pos = stack_par_pos; - for (i = 0; i < sig->param_count; ++i) { - if (sig->params [i]->byref) - continue; - if (sig->params [i]->type == MONO_TYPE_VALUETYPE && !sig->params [i]->data.klass->enumtype) { - gint size; - - size = mono_class_value_size (sig->params [i]->data.klass, NULL); - if (size != 4) { - /* call memcpy */ - ppc_addi (p, ppc_r3, ppc_r1, stack_par_pos); - ppc_lwz (p, ppc_r4, i*16, ppc_r15); - /* FIXME check if size > 0xffff */ - ppc_li (p, ppc_r5, size & 0xffff); - ppc_lis (p, ppc_r0, (guint32) memcpy >> 16); - ppc_ori (p, ppc_r0, ppc_r0, (guint32) memcpy & 0xffff); - ppc_mtlr (p, ppc_r0); - ppc_blrl (p); - stack_par_pos += (size + 3) & (~3); - } - } - } - - if (sig->hasthis) { - ppc_mr (p, ppc_r3, ppc_r16); - ppc_lwz (p, ppc_r16, stack_size - 24, ppc_r31); /* restore r16 */ - } - ppc_mr (p, ppc_r0, ppc_r14); - ppc_mr (p, ppc_r12, ppc_r15); - ppc_lwz (p, ppc_r14, stack_size - 16, ppc_r31); /* restore r14 */ - ppc_lwz (p, ppc_r15, stack_size - 20, ppc_r31); /* restore r15 */ - } - - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref) { - MonoClass *klass = sig->ret->data.klass; - if (!klass->enumtype) { - gint size = mono_class_native_size (klass, NULL); - - DEBUG(printf ("retval value type size: %d\n", size)); - if (size > 8) { - ppc_lwz (p, ppc_r3, stack_size - 12, ppc_r31); - ppc_lwz (p, ppc_r3, 0, ppc_r3); - gr ++; - ALWAYS_ON_STACK (stack_par_pos += 4); - } else { - NOT_IMPLEMENTED ("retval valuetype <= 8 bytes"); - } - } - } - - for (i = 0; i < sig->param_count; ++i) { - if (sig->params [i]->byref) { - SAVE_4_IN_GENERIC_REGISTER; - continue; - } - simpletype = sig->params [i]->type; - enum_calc_size: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_SZARRAY: - SAVE_4_IN_GENERIC_REGISTER; - break; - case MONO_TYPE_VALUETYPE: { - gint size; - if (sig->params [i]->data.klass->enumtype) { - simpletype = sig->params [i]->data.klass->enum_basetype->type; - goto enum_calc_size; - } - size = mono_class_value_size (sig->params [i]->data.klass, NULL); - if (size == 4) { - SAVE_4_VAL_IN_GENERIC_REGISTER; - } else { - if (gr < GENERAL_REGS) { - ppc_addi (p, ppc_r3 + gr, ppc_r1, cur_struct_pos); - gr ++; - } else { - ppc_lwz (p, ppc_r11, cur_struct_pos, ppc_r1); - ppc_stw (p, ppc_r11, stack_par_pos, ppc_r1); - stack_par_pos += 4; - } - cur_struct_pos += (size + 3) & (~3); - } - break; - } - case MONO_TYPE_I8: -DEBUG(printf("Mono_Type_i8. gr = %d, arg_base = %d\n", gr, ARG_BASE)); -#ifdef ALIGN_DOUBLES - if (gr & 1) - gr++; -#endif - if (gr < 7) { - ppc_lwz (p, ppc_r3 + gr, i*ARG_SIZE, ARG_BASE); - ppc_lwz (p, ppc_r3 + gr + 1, i*ARG_SIZE + 4, ARG_BASE); - ALWAYS_ON_STACK (stack_par_pos += 8); - } else if (gr == 7) { - ppc_lwz (p, ppc_r3 + gr, i*ARG_SIZE, ARG_BASE); - ppc_lwz (p, ppc_r11, i*ARG_SIZE + 4, ARG_BASE); - ppc_stw (p, ppc_r11, stack_par_pos + 4, ppc_r1); - stack_par_pos += 8; - } else { - ppc_lwz (p, ppc_r11, i*ARG_SIZE, ARG_BASE); - ppc_stw (p, ppc_r11, stack_par_pos, ppc_r1); - ppc_lwz (p, ppc_r11, i*ARG_SIZE + 4, ARG_BASE); - ppc_stw (p, ppc_r11, stack_par_pos + 4, ppc_r1); - stack_par_pos += 8; - } - gr += 2; - break; - case MONO_TYPE_R4: - if (fr < 7) { - ppc_lfs (p, ppc_f1 + fr, i*ARG_SIZE, ARG_BASE); - fr ++; - FP_ALSO_IN_REG (gr ++); - ALWAYS_ON_STACK (stack_par_pos += 4); - } else { - NOT_IMPLEMENTED ("r4 on stack"); - } - break; - case MONO_TYPE_R8: - if (fr < 7) { - ppc_lfd (p, ppc_f1 + fr, i*ARG_SIZE, ARG_BASE); - fr ++; - FP_ALSO_IN_REG (gr += 2); - ALWAYS_ON_STACK (stack_par_pos += 8); - } else { - NOT_IMPLEMENTED ("r8 on stack"); - } - break; - default: - g_error ("Can't trampoline 0x%x", sig->params [i]->type); - } - } - - return p; -} - -static inline guint8 * -alloc_code_memory (guint code_size) -{ - guint8 *p; - -#ifdef NEED_MPROTECT - p = g_malloc (code_size + PAGESIZE - 1); - - /* Align to a multiple of PAGESIZE, assumed to be a power of two */ - p = (char *)(((int) p + PAGESIZE-1) & ~(PAGESIZE-1)); -#else - p = g_malloc (code_size); -#endif - DEBUG (printf (" align: %p (%d)\n", p, (guint)p % 4)); - - return p; -} - -/* static MonoString* -mono_string_new_wrapper (const char *text) -{ - return text ? mono_string_new (mono_domain_get (), text) : NULL; -} */ - -static inline guint8 * -emit_call_and_store_retval (guint8 *p, MonoMethodSignature *sig, guint stack_size, gboolean string_ctor) -{ - guint32 simpletype; - - /* call "callme" */ - ppc_mtlr (p, ppc_r0); - ppc_blrl (p); - - /* get return value */ - if (sig->ret->byref || string_ctor) { - ppc_lwz (p, ppc_r9, stack_size - 12, ppc_r31); /* load "retval" address */ - ppc_stw (p, ppc_r3, 0, ppc_r9); /* save return value (r3) to "retval" */ - } else { - simpletype = sig->ret->type; -enum_retvalue: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - ppc_lwz (p, ppc_r9, stack_size - 12, ppc_r31); /* load "retval" address */ - ppc_stb (p, ppc_r3, 0, ppc_r9); /* save return value (r3) to "retval" */ - break; - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: - ppc_lwz (p, ppc_r9, stack_size - 12, ppc_r31); /* load "retval" address */ - ppc_sth (p, ppc_r3, 0, ppc_r9); /* save return value (r3) to "retval" */ - break; - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_ARRAY: - case MONO_TYPE_STRING: - ppc_lwz (p, ppc_r9, stack_size - 12, ppc_r31); /* load "retval" address */ - ppc_stw (p, ppc_r3, 0, ppc_r9); /* save return value (r3) to "retval" */ - break; - case MONO_TYPE_R4: - ppc_lwz (p, ppc_r9, stack_size - 12, ppc_r31); /* load "retval" address */ - ppc_stfs (p, ppc_f1, 0, ppc_r9); /* save return value (f1) to "retval" */ - break; - case MONO_TYPE_R8: - ppc_lwz (p, ppc_r9, stack_size - 12, ppc_r31); /* load "retval" address */ - ppc_stfd (p, ppc_f1, 0, ppc_r9); /* save return value (f1) to "retval" */ - break; - case MONO_TYPE_I8: - ppc_lwz (p, ppc_r9, stack_size - 12, ppc_r31); /* load "retval" address */ - ppc_stw (p, ppc_r3, 0, ppc_r9); /* save return value (r3) to "retval" */ - ppc_stw (p, ppc_r4, 4, ppc_r9); /* save return value (r3) to "retval" */ - break; - case MONO_TYPE_VALUETYPE: - if (sig->ret->data.klass->enumtype) { - simpletype = sig->ret->data.klass->enum_basetype->type; - goto enum_retvalue; - } - break; - case MONO_TYPE_VOID: - break; - default: - g_error ("Can't handle as return value 0x%x", sig->ret->type); - } - } - - return p; -} - -static inline guint8 * -emit_epilog (guint8 *p, MonoMethodSignature *sig, guint stack_size) -{ - /* function epilog */ - ppc_lwz (p, ppc_r11, 0, ppc_r1); /* r11 <--- sp[0] load backchain from caller's function */ - ppc_lwz (p, ppc_r0, RET_ADDR_OFFSET, ppc_r11); /* r0 <--- r11[4] load return address */ - ppc_mtlr (p, ppc_r0); /* LR <--- r0 set return address */ - ppc_lwz (p, ppc_r31, -4, ppc_r11); /* r31 <--- r11[-4] restore r31 */ - ppc_mr (p, ppc_r1, ppc_r11); /* sp <--- r11 restore stack */ - ppc_blr (p); /* return */ - - return p; -} - -MonoPIFunc -mono_arch_create_trampoline (MonoMethodSignature *sig, gboolean string_ctor) -{ - guint8 *p, *code_buffer; - guint stack_size, code_size; - gboolean use_memcpy = FALSE; - - DEBUG (printf ("\nPInvoke [start emiting]\n")); - calculate_sizes (sig, &stack_size, &code_size, string_ctor, &use_memcpy); - - p = code_buffer = alloc_code_memory (code_size); - p = emit_prolog (p, sig, stack_size); - p = emit_save_parameters (p, sig, stack_size, use_memcpy); - p = emit_call_and_store_retval (p, sig, stack_size, string_ctor); - p = emit_epilog (p, sig, stack_size); - - /* { - guchar *cp; - printf (".text\n.align 4\n.globl main\n.type main,@function\nmain:\n"); - for (cp = code_buffer; cp < p; cp++) { - printf (".byte 0x%x\n", *cp); - } - } */ - -#ifdef NEED_MPROTECT - if (mprotect (code_buffer, 1024, PROT_READ | PROT_WRITE | PROT_EXEC)) { - g_error ("Cannot mprotect trampoline\n"); - } -#endif - - DEBUG (printf ("emited code size: %d\n", p - code_buffer)); - flush_icache (code_buffer, p - code_buffer); - - DEBUG (printf ("PInvoke [end emiting]\n")); - - return (MonoPIFunc) code_buffer; - /* return fake_func; */ -} - - -#ifdef __APPLE__ -#define MINV_POS 40 /* MonoInvocation structure offset on stack - STACK_PARAM_OFFSET + 4 pointer args for stackval_from_data */ -#else -#define MINV_POS 8 /* MonoInvocation structure offset on stack */ -#endif -#define STACK_POS (MINV_POS - sizeof (stackval) * sig->param_count) -#define OBJ_POS 8 -#define TYPE_OFFSET (G_STRUCT_OFFSET (stackval, type)) - -/* - * Returns a pointer to a native function that can be used to - * call the specified method. - * The function created will receive the arguments according - * to the call convention specified in the method. - * This function works by creating a MonoInvocation structure, - * filling the fields in and calling ves_exec_method on it. - * Still need to figure out how to handle the exception stuff - * across the managed/unmanaged boundary. - */ -void * -mono_arch_create_method_pointer (MonoMethod *method) -{ - MonoMethodSignature *sig; - MonoJitInfo *ji; - guint8 *p, *code_buffer; - guint i, align = 0, code_size, stack_size, stackval_arg_pos, local_pos, local_start, reg_param = 0, stack_param, - cpos, vt_cur; - gint *vtbuf; - guint32 simpletype; - - code_size = 1024; - stack_size = 1024; - stack_param = 0; - - sig = mono_method_signature (method); - - p = code_buffer = g_malloc (code_size); - - DEBUG (printf ("\nDelegate [start emiting] %s\n", mono_method_get_name (method))); - - /* prolog */ - ppc_stwu (p, ppc_r1, -stack_size, ppc_r1); /* sp <--- sp - stack_size, sp[0] <---- sp save sp, alloc stack */ - ppc_mflr (p, ppc_r0); /* r0 <--- LR */ - ppc_stw (p, ppc_r31, stack_size - 4, ppc_r1); /* sp[+4] <--- r31 save r31 */ - ppc_stw (p, ppc_r0, stack_size + RET_ADDR_OFFSET, ppc_r1); /* sp[-4] <--- LR save return address for "callme" */ - ppc_mr (p, ppc_r31, ppc_r1); /* r31 <--- sp */ - - /* let's fill MonoInvocation */ - /* first zero some fields */ - ppc_li (p, ppc_r0, 0); - ppc_stw (p, ppc_r0, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, ex)), ppc_r31); - ppc_stw (p, ppc_r0, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, ex_handler)), ppc_r31); - ppc_stw (p, ppc_r0, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, parent)), ppc_r31); - - /* set method pointer */ - ppc_lis (p, ppc_r0, (guint32) method >> 16); - ppc_ori (p, ppc_r0, ppc_r0, (guint32) method & 0xffff); - ppc_stw (p, ppc_r0, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, method)), ppc_r31); - - local_start = local_pos = MINV_POS + sizeof (MonoInvocation) + (sig->param_count + 1) * sizeof (stackval); - - if (sig->hasthis) { - ppc_stw (p, ppc_r3, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, obj)), ppc_r31); - reg_param = 1; - } - - if (sig->param_count) { - gint save_count = MIN (8, sig->param_count + sig->hasthis); - for (i = reg_param; i < save_count; i ++) { - ppc_stw (p, ppc_r3 + i, local_pos, ppc_r31); - local_pos += 4; - DEBUG (printf ("save r%d\n", 4 + i)); - } - } - - /* prepare space for valuetypes */ - vt_cur = local_pos; - vtbuf = alloca (sizeof(int)*sig->param_count); - cpos = 0; - for (i = 0; i < sig->param_count; i++) { - MonoType *type = sig->params [i]; - vtbuf [i] = -1; - if (type->type == MONO_TYPE_VALUETYPE) { - MonoClass *klass = type->data.klass; - gint size; - - if (klass->enumtype) - continue; - size = mono_class_native_size (klass, &align); - cpos += align - 1; - cpos &= ~(align - 1); - vtbuf [i] = cpos; - cpos += size; - } - } - cpos += 3; - cpos &= ~3; - - local_pos += cpos; - - /* set MonoInvocation::stack_args */ - stackval_arg_pos = MINV_POS + sizeof (MonoInvocation); - ppc_addi (p, ppc_r0, ppc_r31, stackval_arg_pos); - ppc_stw (p, ppc_r0, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, stack_args)), ppc_r31); - - /* add stackval arguments */ - for (i = 0; i < sig->param_count; ++i) { - if (reg_param < 8) { - ppc_addi (p, ppc_r5, ppc_r31, local_start + i*4); - reg_param ++; - } else { - ppc_addi (p, ppc_r5, stack_size + 8 + stack_param, ppc_r31); - stack_param ++; - } - ppc_lis (p, ppc_r3, (guint32) sig->params [i] >> 16); - - if (vtbuf [i] >= 0) { - ppc_addi (p, ppc_r4, ppc_r31, vt_cur); - ppc_stw (p, ppc_r4, stackval_arg_pos, ppc_r31); - ppc_addi (p, ppc_r4, ppc_r31, stackval_arg_pos); - ppc_lwz (p, ppc_r5, 0, ppc_r5); - vt_cur += vtbuf [i]; - } else { - ppc_addi (p, ppc_r4, ppc_r31, stackval_arg_pos); - } - ppc_ori (p, ppc_r3, ppc_r3, (guint32) sig->params [i] & 0xffff); - ppc_lis (p, ppc_r0, (guint32) stackval_from_data >> 16); - ppc_li (p, ppc_r6, sig->pinvoke); - ppc_ori (p, ppc_r0, ppc_r0, (guint32) stackval_from_data & 0xffff); - ppc_mtlr (p, ppc_r0); - ppc_blrl (p); - - stackval_arg_pos += sizeof (stackval); - } - - /* return value storage */ - if (sig->param_count) { - ppc_addi (p, ppc_r0, ppc_r31, stackval_arg_pos); - } - ppc_stw (p, ppc_r0, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, retval)), ppc_r31); - - /* call ves_exec_method */ - ppc_lis (p, ppc_r0, (guint32) ves_exec_method >> 16); - ppc_addi (p, ppc_r3, ppc_r31, MINV_POS); - ppc_ori (p, ppc_r0, ppc_r0, (guint32) ves_exec_method & 0xffff); - ppc_mtlr (p, ppc_r0); - ppc_blrl (p); - - /* move retval from stackval to proper place (r3/r4/...) */ - if (sig->ret->byref) { - DEBUG (printf ("ret by ref\n")); - ppc_lwz (p, ppc_r3, stackval_arg_pos, ppc_r31); - } else { - enum_retvalue: - switch (sig->ret->type) { - case MONO_TYPE_VOID: - break; - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - ppc_lbz (p, ppc_r3, stackval_arg_pos, ppc_r31); - break; - case MONO_TYPE_I2: - case MONO_TYPE_U2: - ppc_lhz (p, ppc_r3, stackval_arg_pos, ppc_r31); - break; - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_CLASS: - ppc_lwz (p, ppc_r3, stackval_arg_pos, ppc_r31); - break; - case MONO_TYPE_I8: - ppc_lwz (p, ppc_r3, stackval_arg_pos, ppc_r31); - ppc_lwz (p, ppc_r4, stackval_arg_pos + 4, ppc_r31); - break; - case MONO_TYPE_R4: - ppc_lfs (p, ppc_f1, stackval_arg_pos, ppc_r31); - break; - case MONO_TYPE_R8: - ppc_lfd (p, ppc_f1, stackval_arg_pos, ppc_r31); - break; - case MONO_TYPE_VALUETYPE: - if (sig->ret->data.klass->enumtype) { - simpletype = sig->ret->data.klass->enum_basetype->type; - goto enum_retvalue; - } - NOT_IMPLEMENTED ("value type as ret val from delegate"); - break; - default: - g_error ("Type 0x%x not handled yet in thunk creation", sig->ret->type); - break; - } - } - - /* epilog */ - ppc_lwz (p, ppc_r11, 0, ppc_r1); /* r11 <--- sp[0] load backchain from caller's function */ - ppc_lwz (p, ppc_r0, RET_ADDR_OFFSET, ppc_r11); /* r0 <--- r11[4] load return address */ - ppc_mtlr (p, ppc_r0); /* LR <--- r0 set return address */ - ppc_lwz (p, ppc_r31, -4, ppc_r11); /* r31 <--- r11[-4] restore r31 */ - ppc_mr (p, ppc_r1, ppc_r11); /* sp <--- r11 restore stack */ - ppc_blr (p); /* return */ - - DEBUG (printf ("emited code size: %d\n", p - code_buffer)); - DEBUG (disassemble (code_buffer, p - code_buffer)); - flush_icache (code_buffer, p - code_buffer); - - DEBUG (printf ("Delegate [end emiting]\n")); - - ji = g_new0 (MonoJitInfo, 1); - ji->method = method; - ji->code_size = p - code_buffer; - ji->code_start = code_buffer; - - mono_jit_info_table_add (mono_get_root_domain (), ji); - - return ji->code_start; -} diff --git a/mono/arch/unknown.c b/mono/arch/unknown.c deleted file mode 100644 index d865299001..0000000000 --- a/mono/arch/unknown.c +++ /dev/null @@ -1,18 +0,0 @@ -#include "mono/interpreter/interp.h" -#ifdef NO_PORT -MonoPIFunc -mono_create_trampoline (MonoMethodSignature *sig, gboolean string_ctor) -{ - g_error ("Unsupported arch"); - return NULL; -} - -void * -mono_create_method_pointer (MonoMethod *method) -{ - g_error ("Unsupported arch"); - return NULL; -} - -#endif - diff --git a/mono/arch/x86/Makefile.am b/mono/arch/x86/Makefile.am index 977823705a..bab0f9e54d 100644 --- a/mono/arch/x86/Makefile.am +++ b/mono/arch/x86/Makefile.am @@ -1,9 +1 @@ -if INTERP_SUPPORTED - -AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) - -noinst_LTLIBRARIES = libmonoarch-x86.la - -libmonoarch_x86_la_SOURCES = tramp.c x86-codegen.h - -endif +EXTRA_DIST = x86-codegen.h \ No newline at end of file diff --git a/mono/arch/x86/Makefile.in b/mono/arch/x86/Makefile.in index b03142a4ae..c6794eeef1 100644 --- a/mono/arch/x86/Makefile.in +++ b/mono/arch/x86/Makefile.in @@ -13,7 +13,6 @@ # PARTICULAR PURPOSE. @SET_MAKE@ - VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ @@ -81,7 +80,7 @@ host_triplet = @host@ target_triplet = @target@ subdir = mono/arch/x86 DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp + $(top_srcdir)/mkinstalldirs ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/iconv.m4 \ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ @@ -97,16 +96,6 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = -LTLIBRARIES = $(noinst_LTLIBRARIES) -libmonoarch_x86_la_LIBADD = -am__libmonoarch_x86_la_SOURCES_DIST = tramp.c x86-codegen.h -@INTERP_SUPPORTED_TRUE@am_libmonoarch_x86_la_OBJECTS = tramp.lo -libmonoarch_x86_la_OBJECTS = $(am_libmonoarch_x86_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -@INTERP_SUPPORTED_TRUE@am_libmonoarch_x86_la_rpath = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -119,50 +108,14 @@ AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libmonoarch_x86_la_SOURCES) -DIST_SOURCES = $(am__libmonoarch_x86_la_SOURCES_DIST) +SOURCES = +DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -368,13 +321,10 @@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -@INTERP_SUPPORTED_TRUE@AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) -@INTERP_SUPPORTED_TRUE@noinst_LTLIBRARIES = libmonoarch-x86.la -@INTERP_SUPPORTED_TRUE@libmonoarch_x86_la_SOURCES = tramp.c x86-codegen.h +EXTRA_DIST = x86-codegen.h all: all-am .SUFFIXES: -.SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -406,109 +356,17 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): -clean-noinstLTLIBRARIES: - -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) - @list='$(noinst_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -libmonoarch-x86.la: $(libmonoarch_x86_la_OBJECTS) $(libmonoarch_x86_la_DEPENDENCIES) $(EXTRA_libmonoarch_x86_la_DEPENDENCIES) - $(AM_V_CCLD)$(LINK) $(am_libmonoarch_x86_la_rpath) $(libmonoarch_x86_la_OBJECTS) $(libmonoarch_x86_la_LIBADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tramp.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs +tags TAGS: -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags +ctags CTAGS: -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am +cscope cscopelist: -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -542,7 +400,7 @@ distdir: $(DISTFILES) done check-am: all-am check: check-am -all-am: Makefile $(LTLIBRARIES) +all-am: Makefile installdirs: install: install-am install-exec: install-exec-am @@ -576,14 +434,11 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ - mostlyclean-am +clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags +distclean-am: clean-am distclean-generic dvi: dvi-am @@ -626,14 +481,12 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool +mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am @@ -647,19 +500,17 @@ uninstall-am: .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ - ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am + tags-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. diff --git a/mono/arch/x86/tramp.c b/mono/arch/x86/tramp.c deleted file mode 100644 index fab5a55325..0000000000 --- a/mono/arch/x86/tramp.c +++ /dev/null @@ -1,545 +0,0 @@ -/* - * Create trampolines to invoke arbitrary functions. - * - * Copyright (C) Ximian Inc. - * - * Authors: - * Paolo Molaro (lupus@ximian.com) - * Dietmar Maurer (dietmar@ximian.com) - * - */ - -#include "config.h" -#include -#include -#include "x86-codegen.h" -#include "mono/metadata/class.h" -#include "mono/metadata/tabledefs.h" -#include "mono/interpreter/interp.h" -#include "mono/metadata/appdomain.h" -#include "mono/metadata/marshal.h" - -/* - * The resulting function takes the form: - * void func (void (*callme)(), void *retval, void *this_obj, stackval *arguments); - */ -#define FUNC_ADDR_POS 8 -#define RETVAL_POS 12 -#define THIS_POS 16 -#define ARGP_POS 20 -#define LOC_POS -4 - -#define ARG_SIZE sizeof (stackval) - -MonoPIFunc -mono_arch_create_trampoline (MonoMethodSignature *sig, gboolean string_ctor) -{ - unsigned char *p, *code_buffer; - guint32 stack_size = 0, code_size = 50; - guint32 arg_pos, simpletype; - int i, stringp; - static GHashTable *cache = NULL; - MonoPIFunc res; - - if (!cache) - cache = g_hash_table_new ((GHashFunc)mono_signature_hash, - (GCompareFunc)mono_metadata_signature_equal); - - if ((res = (MonoPIFunc)g_hash_table_lookup (cache, sig))) - return res; - - if (sig->hasthis) { - stack_size += sizeof (gpointer); - code_size += 10; - } - - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref && !sig->ret->data.klass->enumtype) { - stack_size += sizeof (gpointer); - code_size += 5; - } - - for (i = 0; i < sig->param_count; ++i) { - if (sig->params [i]->byref) { - stack_size += sizeof (gpointer); - code_size += 20; - continue; - } - simpletype = sig->params [i]->type; -enum_calc_size: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_CHAR: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - stack_size += 4; - code_size += i < 10 ? 5 : 8; - break; - case MONO_TYPE_VALUETYPE: { - int size; - if (sig->params [i]->data.klass->enumtype) { - simpletype = sig->params [i]->data.klass->enum_basetype->type; - goto enum_calc_size; - } - if ((size = mono_class_native_size (sig->params [i]->data.klass, NULL)) != 4) { - stack_size += size + 3; - stack_size &= ~3; - code_size += 32; - } else { - stack_size += 4; - code_size += i < 10 ? 5 : 8; - } - break; - } - case MONO_TYPE_I8: - stack_size += 8; - code_size += i < 10 ? 5 : 8; - break; - case MONO_TYPE_R4: - stack_size += 4; - code_size += i < 10 ? 10 : 13; - break; - case MONO_TYPE_R8: - stack_size += 8; - code_size += i < 10 ? 7 : 10; - break; - default: - g_error ("Can't trampoline 0x%x", sig->params [i]->type); - } - } - /* - * FIXME: take into account large return values. - */ - - code_buffer = p = alloca (code_size); - - /* - * Standard function prolog. - */ - x86_push_reg (p, X86_EBP); - x86_mov_reg_reg (p, X86_EBP, X86_ESP, 4); - /* - * and align to 16 byte boundary... - */ - stack_size += 15; - stack_size &= ~15; - - if (stack_size) - x86_alu_reg_imm (p, X86_SUB, X86_ESP, stack_size); - - /* - * EDX has the pointer to the args. - */ - x86_mov_reg_membase (p, X86_EDX, X86_EBP, ARGP_POS, 4); - - /* - * Push arguments in reverse order. - */ - stringp = 0; - for (i = sig->param_count; i; --i) { - arg_pos = ARG_SIZE * (i - 1); - if (sig->params [i - 1]->byref) { - x86_push_membase (p, X86_EDX, arg_pos); - continue; - } - simpletype = sig->params [i - 1]->type; -enum_marshal: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_PTR: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - x86_push_membase (p, X86_EDX, arg_pos); - break; - case MONO_TYPE_R4: - x86_alu_reg_imm (p, X86_SUB, X86_ESP, 4); - x86_fld_membase (p, X86_EDX, arg_pos, TRUE); - x86_fst_membase (p, X86_ESP, 0, FALSE, TRUE); - break; - case MONO_TYPE_CLASS: - x86_push_membase (p, X86_EDX, arg_pos); - break; - case MONO_TYPE_SZARRAY: - x86_push_membase (p, X86_EDX, arg_pos); - break; - case MONO_TYPE_VALUETYPE: - if (!sig->params [i - 1]->data.klass->enumtype) { - int size = mono_class_native_size (sig->params [i - 1]->data.klass, NULL); - if (size == 4) { - /* it's a structure that fits in 4 bytes, need to push the value pointed to */ - x86_mov_reg_membase (p, X86_EAX, X86_EDX, arg_pos, 4); - x86_push_regp (p, X86_EAX); - } else { - int ss = size; - ss += 3; - ss &= ~3; - - x86_alu_reg_imm (p, X86_SUB, X86_ESP, ss); - x86_push_imm (p, size); - x86_push_membase (p, X86_EDX, arg_pos); - x86_lea_membase (p, X86_EAX, X86_ESP, 2*4); - x86_push_reg (p, X86_EAX); - x86_mov_reg_imm (p, X86_EAX, memcpy); - x86_call_reg (p, X86_EAX); - x86_alu_reg_imm (p, X86_ADD, X86_ESP, 12); - /* memcpy might clobber EDX so restore it */ - x86_mov_reg_membase (p, X86_EDX, X86_EBP, ARGP_POS, 4); - } - } else { - /* it's an enum value */ - simpletype = sig->params [i - 1]->data.klass->enum_basetype->type; - goto enum_marshal; - } - break; - case MONO_TYPE_I8: - case MONO_TYPE_U8: - case MONO_TYPE_R8: - x86_push_membase (p, X86_EDX, arg_pos + 4); - x86_push_membase (p, X86_EDX, arg_pos); - break; - default: - g_error ("Can't trampoline 0x%x", sig->params [i - 1]->type); - } - } - - if (sig->hasthis) { - if (sig->call_convention != MONO_CALL_THISCALL) { - x86_mov_reg_membase (p, X86_EDX, X86_EBP, THIS_POS, 4); - x86_push_reg (p, X86_EDX); - } else { - x86_mov_reg_membase (p, X86_ECX, X86_EBP, THIS_POS, 4); - } - } - - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref) { - MonoClass *klass = sig->ret->data.klass; - if (!klass->enumtype) { - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_push_membase (p, X86_ECX, 0); - } - } - - /* - * Insert call to function - */ - x86_mov_reg_membase (p, X86_EDX, X86_EBP, FUNC_ADDR_POS, 4); - x86_call_reg (p, X86_EDX); - - /* - * Handle retval. - * Small integer and pointer values are in EAX. - * Long integers are in EAX:EDX. - * FP values are on the FP stack. - */ - - if (sig->ret->byref || string_ctor) { - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_mov_regp_reg (p, X86_ECX, X86_EAX, 4); - } else { - simpletype = sig->ret->type; - enum_retvalue: - switch (simpletype) { - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_mov_regp_reg (p, X86_ECX, X86_EAX, 1); - break; - case MONO_TYPE_CHAR: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_mov_regp_reg (p, X86_ECX, X86_EAX, 2); - break; - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_ARRAY: - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_mov_regp_reg (p, X86_ECX, X86_EAX, 4); - break; - case MONO_TYPE_STRING: - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_mov_regp_reg (p, X86_ECX, X86_EAX, 4); - break; - case MONO_TYPE_R4: - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_fst_membase (p, X86_ECX, 0, FALSE, TRUE); - break; - case MONO_TYPE_R8: - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_fst_membase (p, X86_ECX, 0, TRUE, TRUE); - break; - case MONO_TYPE_I8: - x86_mov_reg_membase (p, X86_ECX, X86_EBP, RETVAL_POS, 4); - x86_mov_regp_reg (p, X86_ECX, X86_EAX, 4); - x86_mov_membase_reg (p, X86_ECX, 4, X86_EDX, 4); - break; - case MONO_TYPE_VALUETYPE: - if (sig->ret->data.klass->enumtype) { - simpletype = sig->ret->data.klass->enum_basetype->type; - goto enum_retvalue; - } - case MONO_TYPE_VOID: - break; - default: - g_error ("Can't handle as return value 0x%x", sig->ret->type); - } - } - - /* - * Standard epilog. - */ - x86_leave (p); - x86_ret (p); - - g_assert (p - code_buffer < code_size); - res = (MonoPIFunc)g_memdup (code_buffer, p - code_buffer); - - g_hash_table_insert (cache, sig, res); - - return res; -} - -#define MINV_POS (- sizeof (MonoInvocation)) -#define STACK_POS (MINV_POS - sizeof (stackval) * sig->param_count) -#define TYPE_OFFSET (G_STRUCT_OFFSET (stackval, type)) - -/* - * Returns a pointer to a native function that can be used to - * call the specified method. - * The function created will receive the arguments according - * to the call convention specified in the method. - * This function works by creating a MonoInvocation structure, - * filling the fields in and calling ves_exec_method on it. - * Still need to figure out how to handle the exception stuff - * across the managed/unmanaged boundary. - */ -void * -mono_arch_create_method_pointer (MonoMethod *method) -{ - MonoMethodSignature *sig; - MonoJitInfo *ji; - unsigned char *p, *code_buffer; - gint32 local_size; - gint32 stackval_pos, arg_pos = 8; - int i, size, align, cpos; - int *vtbuf; - - sig = method->signature; - - code_buffer = p = alloca (512); /* FIXME: check for overflows... */ - vtbuf = alloca (sizeof(int)*sig->param_count); - - local_size = sizeof (MonoInvocation) + sizeof (stackval) * (sig->param_count + 1); - - local_size += 7; - local_size &= ~7; - - stackval_pos = -local_size; - - cpos = 0; - for (i = 0; i < sig->param_count; i++) { - MonoType *type = sig->params [i]; - vtbuf [i] = -1; - if (type->type == MONO_TYPE_VALUETYPE) { - MonoClass *klass = type->data.klass; - if (klass->enumtype) - continue; - size = mono_class_native_size (klass, &align); - cpos += align - 1; - cpos &= ~(align - 1); - vtbuf [i] = cpos; - cpos += size; - } - } - - cpos += 7; - cpos &= ~7; - - local_size += cpos; - - /* - * Standard function prolog. - */ - x86_push_reg (p, X86_EBP); - x86_mov_reg_reg (p, X86_EBP, X86_ESP, 4); - x86_alu_reg_imm (p, X86_SUB, X86_ESP, local_size); - - /* - * Initialize MonoInvocation fields, first the ones known now. - */ - x86_mov_reg_imm (p, X86_EAX, 0); - x86_mov_membase_reg (p, X86_EBP, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, ex)), X86_EAX, 4); - x86_mov_membase_reg (p, X86_EBP, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, ex_handler)), X86_EAX, 4); - x86_mov_membase_reg (p, X86_EBP, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, parent)), X86_EAX, 4); - /* - * Set the method pointer. - */ - x86_mov_membase_imm (p, X86_EBP, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, method)), (int)method, 4); - - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref && !sig->ret->data.klass->enumtype) - arg_pos += 4; - - /* - * Handle this. - */ - if (sig->hasthis) { - if (sig->call_convention != MONO_CALL_THISCALL) { - /* - * Grab it from the stack, otherwise it's already in ECX. - */ - x86_mov_reg_membase (p, X86_ECX, X86_EBP, arg_pos, 4); - arg_pos += 4; - } - x86_mov_membase_reg (p, X86_EBP, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, obj)), X86_ECX, 4); - } - /* - * Handle the arguments. stackval_pos is the posset of the stackval array from EBP. - * arg_pos is the offset from EBP to the incoming arg on the stack. - * We just call stackval_from_data to handle all the (nasty) issues.... - */ - x86_lea_membase (p, X86_EAX, X86_EBP, stackval_pos); - x86_mov_membase_reg (p, X86_EBP, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, stack_args)), X86_EAX, 4); - for (i = 0; i < sig->param_count; ++i) { - if (vtbuf [i] >= 0) { - x86_lea_membase (p, X86_EAX, X86_EBP, - local_size + vtbuf [i]); - x86_mov_membase_reg (p, X86_EBP, stackval_pos, X86_EAX, 4); - } - x86_mov_reg_imm (p, X86_ECX, stackval_from_data); - x86_lea_membase (p, X86_EDX, X86_EBP, arg_pos); - x86_lea_membase (p, X86_EAX, X86_EBP, stackval_pos); - x86_push_imm (p, sig->pinvoke); - x86_push_reg (p, X86_EDX); - x86_push_reg (p, X86_EAX); - x86_push_imm (p, sig->params [i]); - x86_call_reg (p, X86_ECX); - x86_alu_reg_imm (p, X86_SUB, X86_ESP, 16); - stackval_pos += sizeof (stackval); - /* fixme: alignment */ - if (sig->pinvoke) - arg_pos += mono_type_native_stack_size (sig->params [i], &align); - else - arg_pos += mono_type_stack_size (sig->params [i], &align); - } - - /* - * Handle the return value storage area. - */ - x86_lea_membase (p, X86_EAX, X86_EBP, stackval_pos); - x86_mov_membase_reg (p, X86_EBP, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, retval)), X86_EAX, 4); - if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref) { - MonoClass *klass = sig->ret->data.klass; - if (!klass->enumtype) { - x86_mov_reg_membase (p, X86_ECX, X86_EBP, 8, 4); - x86_mov_membase_reg (p, X86_EBP, stackval_pos, X86_ECX, 4); - } - } - - /* - * Call the method. - */ - x86_lea_membase (p, X86_EAX, X86_EBP, MINV_POS); - x86_push_reg (p, X86_EAX); - x86_mov_reg_imm (p, X86_EDX, ves_exec_method); - x86_call_reg (p, X86_EDX); - - /* - * Move the return value to the proper place. - */ - x86_lea_membase (p, X86_EAX, X86_EBP, stackval_pos); - if (sig->ret->byref) { - x86_mov_reg_membase (p, X86_EAX, X86_EAX, 0, 4); - } else { - int simpletype = sig->ret->type; - enum_retvalue: - switch (sig->ret->type) { - case MONO_TYPE_VOID: - break; - case MONO_TYPE_BOOLEAN: - case MONO_TYPE_I1: - case MONO_TYPE_U1: - x86_mov_reg_membase (p, X86_EAX, X86_EAX, 0, 1); - break; - case MONO_TYPE_CHAR: - case MONO_TYPE_I2: - case MONO_TYPE_U2: - x86_mov_reg_membase (p, X86_EAX, X86_EAX, 0, 2); - break; - case MONO_TYPE_I4: - case MONO_TYPE_U4: - case MONO_TYPE_I: - case MONO_TYPE_U: - case MONO_TYPE_OBJECT: - case MONO_TYPE_STRING: - case MONO_TYPE_CLASS: - x86_mov_reg_membase (p, X86_EAX, X86_EAX, 0, 4); - break; - case MONO_TYPE_I8: - x86_mov_reg_membase (p, X86_EDX, X86_EAX, 4, 4); - x86_mov_reg_membase (p, X86_EAX, X86_EAX, 0, 4); - break; - case MONO_TYPE_R8: - x86_fld_membase (p, X86_EAX, 0, TRUE); - break; - case MONO_TYPE_VALUETYPE: - if (sig->ret->data.klass->enumtype) { - simpletype = sig->ret->data.klass->enum_basetype->type; - goto enum_retvalue; - } - - x86_push_imm (p, sig->pinvoke); - x86_push_membase (p, X86_EBP, stackval_pos); - x86_push_reg (p, X86_EAX); - x86_push_imm (p, sig->ret); - x86_mov_reg_imm (p, X86_ECX, stackval_to_data); - x86_call_reg (p, X86_ECX); - x86_alu_reg_imm (p, X86_SUB, X86_ESP, 16); - - break; - default: - g_error ("Type 0x%x not handled yet in thunk creation", sig->ret->type); - break; - } - } - - /* - * Standard epilog. - */ - x86_leave (p); - x86_ret (p); - - g_assert (p - code_buffer < 512); - - ji = g_new0 (MonoJitInfo, 1); - ji->method = method; - ji->code_size = p - code_buffer; - ji->code_start = g_memdup (code_buffer, p - code_buffer); - - mono_jit_info_table_add (mono_get_root_domain (), ji); - - return ji->code_start; -} diff --git a/mono/dis/Makefile.am b/mono/dis/Makefile.am index fd581ff551..0a6e86d0c0 100644 --- a/mono/dis/Makefile.am +++ b/mono/dis/Makefile.am @@ -4,7 +4,6 @@ if HOST_WIN32 export HOST_CC endif -if JIT_SUPPORTED if !SHARED_MONO static_libs= \ $(top_builddir)/mono/metadata/libmonoruntime-static.la \ @@ -17,9 +16,6 @@ runtime_lib=../mini/$(LIBMONO_LA) $(static_libs) else runtime_lib=../mini/$(LIBMONO_LA) endif -else -runtime_lib=../interpreter/libmint.la -endif if DISABLE_EXECUTABLES bin_PROGRAMS = diff --git a/mono/dis/Makefile.in b/mono/dis/Makefile.in index eefbb9a31e..5280392b68 100644 --- a/mono/dis/Makefile.in +++ b/mono/dis/Makefile.in @@ -116,18 +116,14 @@ PROGRAMS = $(bin_PROGRAMS) am_monodis_OBJECTS = dump.$(OBJEXT) main.$(OBJEXT) declsec.$(OBJEXT) monodis_OBJECTS = $(am_monodis_OBJECTS) am__DEPENDENCIES_1 = -@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@am__DEPENDENCIES_2 = $(top_builddir)/mono/metadata/libmonoruntime-static.la \ -@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(top_builddir)/mono/io-layer/libwapi.la \ -@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(top_builddir)/mono/utils/libmonoutils.la \ -@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(am__DEPENDENCIES_1) \ -@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(am__DEPENDENCIES_1) \ -@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(am__DEPENDENCIES_1) -@JIT_SUPPORTED_FALSE@am__DEPENDENCIES_3 = ../interpreter/libmint.la -@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@am__DEPENDENCIES_3 = \ -@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ ../mini/$(LIBMONO_LA) \ -@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(am__DEPENDENCIES_2) -@JIT_SUPPORTED_TRUE@@SHARED_MONO_TRUE@am__DEPENDENCIES_3 = \ -@JIT_SUPPORTED_TRUE@@SHARED_MONO_TRUE@ ../mini/$(LIBMONO_LA) +@SHARED_MONO_FALSE@am__DEPENDENCIES_2 = $(top_builddir)/mono/metadata/libmonoruntime-static.la \ +@SHARED_MONO_FALSE@ $(top_builddir)/mono/io-layer/libwapi.la \ +@SHARED_MONO_FALSE@ $(top_builddir)/mono/utils/libmonoutils.la \ +@SHARED_MONO_FALSE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ +@SHARED_MONO_FALSE@ $(am__DEPENDENCIES_1) +@SHARED_MONO_FALSE@am__DEPENDENCIES_3 = ../mini/$(LIBMONO_LA) \ +@SHARED_MONO_FALSE@ $(am__DEPENDENCIES_2) +@SHARED_MONO_TRUE@am__DEPENDENCIES_3 = ../mini/$(LIBMONO_LA) monodis_DEPENDENCIES = libmonodis.a $(am__DEPENDENCIES_3) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) @@ -430,16 +426,15 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) -@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@static_libs = \ -@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(top_builddir)/mono/metadata/libmonoruntime-static.la \ -@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(top_builddir)/mono/io-layer/libwapi.la \ -@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(top_builddir)/mono/utils/libmonoutils.la \ -@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(GLIB_LIBS) $(LIBICONV) \ -@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(LIBGC_STATIC_LIBS) +@SHARED_MONO_FALSE@static_libs = \ +@SHARED_MONO_FALSE@ $(top_builddir)/mono/metadata/libmonoruntime-static.la \ +@SHARED_MONO_FALSE@ $(top_builddir)/mono/io-layer/libwapi.la \ +@SHARED_MONO_FALSE@ $(top_builddir)/mono/utils/libmonoutils.la \ +@SHARED_MONO_FALSE@ $(GLIB_LIBS) $(LIBICONV) \ +@SHARED_MONO_FALSE@ $(LIBGC_STATIC_LIBS) -@JIT_SUPPORTED_FALSE@runtime_lib = ../interpreter/libmint.la -@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@runtime_lib = ../mini/$(LIBMONO_LA) $(static_libs) -@JIT_SUPPORTED_TRUE@@SHARED_MONO_TRUE@runtime_lib = ../mini/$(LIBMONO_LA) +@SHARED_MONO_FALSE@runtime_lib = ../mini/$(LIBMONO_LA) $(static_libs) +@SHARED_MONO_TRUE@runtime_lib = ../mini/$(LIBMONO_LA) noinst_LIBRARIES = libmonodis.a libmonodis_a_SOURCES = \ get.c \ diff --git a/mono/dis/dump.c b/mono/dis/dump.c index 2b3a4851de..391ec7fbc7 100755 --- a/mono/dis/dump.c +++ b/mono/dis/dump.c @@ -566,6 +566,7 @@ dump_table_method (MonoImage *m) current_type = 1; last_m = first_m = 1; for (i = 1; i <= t->rows; i++){ + MonoError error; guint32 cols [MONO_METHOD_SIZE]; char *sig, *impl_flags; const char *sigblob; @@ -583,13 +584,17 @@ dump_table_method (MonoImage *m) mono_metadata_string_heap (m, mono_metadata_decode_row_col (td, current_type - 2, MONO_TYPEDEF_NAME))); first_m = last_m; type_container = mono_metadata_load_generic_params (m, MONO_TOKEN_TYPE_DEF | (current_type - 1), NULL); - if (type_container) - mono_metadata_load_generic_param_constraints (m, MONO_TOKEN_TYPE_DEF | (current_type - 1), type_container); + if (type_container) { + mono_metadata_load_generic_param_constraints_checked (m, MONO_TOKEN_TYPE_DEF | (current_type - 1), type_container, &error); + g_assert (mono_error_ok (&error)); /*FIXME don't swallow the error message*/ + } } method_container = mono_metadata_load_generic_params (m, MONO_TOKEN_METHOD_DEF | i, type_container); - if (method_container) - mono_metadata_load_generic_param_constraints (m, MONO_TOKEN_METHOD_DEF | i, method_container); + if (method_container) { + mono_metadata_load_generic_param_constraints_checked (m, MONO_TOKEN_METHOD_DEF | i, method_container, &error); + g_assert (mono_error_ok (&error)); /*FIXME don't swallow the error message*/ + } mono_metadata_decode_table_row (m, MONO_TABLE_METHOD, i - 1, cols, MONO_METHOD_SIZE); sigblob = mono_metadata_blob_heap (m, cols [MONO_METHOD_SIGNATURE]); mono_metadata_decode_blob_size (sigblob, &sigblob); diff --git a/mono/dis/get.c.REMOVED.git-id b/mono/dis/get.c.REMOVED.git-id index 34e8796a45..d1aa48e57a 100644 --- a/mono/dis/get.c.REMOVED.git-id +++ b/mono/dis/get.c.REMOVED.git-id @@ -1 +1 @@ -34f87b0c8ad7913118ebbb5fcdb0d55fe66ce618 \ No newline at end of file +a3f2e7b9cac58f1e6d4be5783aab9fa825926828 \ No newline at end of file diff --git a/mono/dis/main.c b/mono/dis/main.c index 42d735b0f7..b56da24c35 100644 --- a/mono/dis/main.c +++ b/mono/dis/main.c @@ -854,10 +854,13 @@ dis_method_list (const char *klass_name, MonoImage *m, guint32 start, guint32 en mono_metadata_decode_blob_size (sig, &sig); container = mono_metadata_load_generic_params (m, MONO_TOKEN_METHOD_DEF | (i + 1), type_container); - if (container) - mono_metadata_load_generic_param_constraints (m, MONO_TOKEN_METHOD_DEF | (i + 1), container); - else + if (container) { + MonoError error; + mono_metadata_load_generic_param_constraints_checked (m, MONO_TOKEN_METHOD_DEF | (i + 1), container, &error); + g_assert (mono_error_ok (&error)); /*FIXME don't swallow the error message*/ + } else { container = type_container; + } ms = mono_metadata_parse_method_signature_full (m, container, i + 1, sig, &sig); if (ms != NULL){ @@ -1181,8 +1184,11 @@ dis_type (MonoImage *m, int n, int is_nested, int forward) } container = mono_metadata_load_generic_params (m, MONO_TOKEN_TYPE_DEF | (n + 1), NULL); - if (container) - mono_metadata_load_generic_param_constraints (m, MONO_TOKEN_TYPE_DEF | (n + 1), container); + if (container) { + MonoError error; + mono_metadata_load_generic_param_constraints_checked (m, MONO_TOKEN_TYPE_DEF | (n + 1), container, &error); + g_assert (mono_error_ok (&error)); /*FIXME don't swallow the error message*/ + } esname = get_escaped_name (name); if ((cols [MONO_TYPEDEF_FLAGS] & TYPE_ATTRIBUTE_CLASS_SEMANTIC_MASK) == TYPE_ATTRIBUTE_CLASS){ diff --git a/mono/interpreter/ChangeLog b/mono/interpreter/ChangeLog deleted file mode 100644 index 80baebfc26..0000000000 --- a/mono/interpreter/ChangeLog +++ /dev/null @@ -1,1376 +0,0 @@ -2009-11-10 Andrew Jorgensen - - * Makefile.am: mint man page should be conditional also - -2009-03-20 Zoltan Varga - - * interp.c: Change location of gc_wrapper.h. - -2007-06-04 Mark Probst - - * interp.c, interp.h (RuntimeMethod): Due to the jit_code_hash - change in MonoDomain this had to be changed slightly, too. - -2006-05-09 Miguel de Icaza - - * interp.c (ves_exec_method_with_context): Pass a temporary to the - mono_load_remote_field routine, instead of passing a NULL. - -Thu Aug 4 20:09:40 BST 2005 Paolo Molaro - - * interp.c: a real zombie is supposed to at least walk. - Compilation fix. - -2005-03-07 Zoltan Varga - - * transform.c (generate): Add CEE_MONO_NOT_TAKEN. - -2005-01-31 Bernie Solomon - - * interp.c: fix typo - -2005-01-29 Ben Maurer - - * *: MonoMethod->signature might be NULL now. You *MUST* use - mono_method_signature. - -2005-01-20 Bernie Solomon - - * interp.c: mono_init_icall got renamed - -2005-01-03 Zoltan Varga - - * transform.c (generate): Handle MONO_CLASSCONST. - -2004-12-04 Gonzalo Paniagua Javier - - * interp.c: fix the build. Dunno if it's correct. - -2004-12-02 Bernie Solomon - - * mintops.def: - * transform.c: - * interp.c: cope with new thread interruption icall - -2004-11-12 Ben Maurer - - * transform.c: Fix bug with delegates in interp. - -2004-11-10 Lluis Sanchez Gual - - * interp.c: Added MonoRemotingTarget parameter to signature - interp_create_remoting_trampoline. - -Tue Nov 9 17:28:48 CET 2004 Paolo Molaro - - * interp.c: update to exception clause structure changes. - -2004-11-08 Ben Maurer - - * interp.c: warning free - -2004-10-29 Zoltan Varga - - * Makefile.am (libgc_libs): Do some automake magic so libmono/mono - depends on libmonogc. - -Wed Sep 22 19:06:02 CEST 2004 Paolo Molaro - - * interp.c: updates for stack walk interface. - -2004-09-09 Lluis Sanchez Gual - - * interp.c: In interp_walk_stack, don't crash if the context is not set - (this may happen if the method is called by unmanaged code). - -2004-08-17 Ben Maurer - - * interp.c: thread local alloc - -2004-08-05 Bernie Solomon - - * interp.c: (mono_interp_init) use g_thread_supported - to stop multiple g_thread_init calls. - Also attach domain to thread like mono_jit_init - -2004-07-31 Bernie Solomon - - * interp.h: add mono_interp_ftnptr_to_delegate - - * transform.c (generate): use mono_interp_ftnptr_to_delegate - as ical function. - - * interp.c: add mono_interp_ftnptr_to_delegate to create - interpreter style delegate. fixes pinvoke3 - -2004-07-28 Lluis Sanchez Gual - - * interp.c: Use mono_init_from_assembly instead of mono_init. - -2004-07-27 Bernie Solomon - - * transform.c (mono_interp_transform_method): - quick fix to cope with the fake ptr classes - -2004-07-26 Bernie Solomon - - * mintops.def: more options on ICALL op code - - * interp.c: cope with exception in ICALL ops, more of them - - * transforms.c: more ICALL opcodes - -2004-07-21 Bernie Solomon - - * mintops.def: rename the ICALL op codes to give a better - clue about their signature. - - * transform.c (generate): use new ICALL types and add - a case for two args + a result - - * interp.c (ves_exec_method_with_context): new ICALL - op codes. - -2004-07-21 Bernie Solomon - - * mintops.def: add MINT_DUP_VT - - * transform.c (generate): cope with CEE_DUP on value type - - * interp.c (ves_exec_method_with_context): implement MINT_DUP_VT - (interp_mono_runtime_invoke): don't unbox this for valuetypes - here as it is now done in the callers. - -2004-07-09 Ben Maurer - - * interp.c: register gc roots - -2004-07-08 Zoltan Varga - - * interp.c mintops.def transform.c: Replace CEE_MONO_PROC with - CEE_MONO_ICALL. - -2004-07-05 Zoltan Varga - - * mintops.h: Applied patch from Marcin Krzyzanowski (krzak@pld-linux.org). Add support for unaligned access on little endian machines. - - * interp.c:Applied patch from Marcin Krzyzanowski (krzak@pld-linux.org). Fix crash seen on amd64. - -2004-06-24 David Waite - - * interp.c: change to C90-style comments from C99/C++-style - -Mon Jun 21 14:06:03 CEST 2004 Paolo Molaro - - * interp.h: API updates. - -2004-05-21 Bernie Solomon - - * transform.c: ignore new LMF opcodes - -2004-05-20 Lluis Sanchez Gual - - * interp.c, interp.h: Use the new methods for handling thread.abort. - -2004-05-04 Zoltan Varga - - * interp.c (ves_exec_method_with_context): Disable explicit assignment - of 'esi' to the ip variable, since it causes register allocation errors - on some versions of gcc. Fixes #58010. - -2004-04-29 Bernie Solomon - - * transform.c (generate): missed a couple - of places that should use ADD_CODE so buffer - gets grown properly. - - * interp.c (interp_mono_runtime_invoke): - restore state better on catching exception - via longjmp here - -2004-04-29 Bernie Solomon - - * transform.c: - * interp.c: - Implement STARG for valuetypes as mcs needs it. - -2004-04-28 Bernie Solomon - - * transform.c: Make sure ENSURE_I4 is called on - 32 bit machines too. - (mono_interp_transform_method): allow some stack - space for tracing to work. - -2004-04-26 David Waite - - * interp.h: remove comma from end of enumeration constants - declarations - -2004-04-21 Bernie Solomon - - * interp.h: put in space for old type field - for PPC as tramp.c assumes it. Quick fix until that's fixed. - - * interp.c: reenable instruction tracing for DEBUG_INTERP - -2004-04-19 Bernie Solomon - - * Makefile.am: - * interp.h: - * interp.c: now interprets different VM code - * mintops.h: - * mintops.def: - * mintops.c: definition of new VM code - * transform.c: convert CIL to new VM code - -2004-04-14 Zoltan Varga - - * interp.c (ves_exec_method_with_context): Add support for STRWLPARRAY - marshalling convention. - -2004-03-29 Bernie Solomon - - * interp.c interp.h: remove child from MonoInvocation - as it isn't used. - -2004-03-25 Martin Baulig - - * interp.c (stackval_from_data): Added MONO_TYPE_GENERICINST. - (stackval_to_data): Added MONO_TYPE_GENERICINST. - (calc_offsets): Use mono_class_get_full() and mono_get_method_full(). - (ves_exec_method_with_context): Likewise. - -2004-03-04 Lluis Sanchez Gual - - * interp.c: Get the type of transparent proxies from its remote_class. - -2004-02-02 Zoltan Varga - - * interp.c (ves_exec_method_with_context): Add new marshalling - conventions. - -2004-01-22 Zoltan Varga - - * interp.c (mono_main): Remove call to mono_verify_corlib (), since - the verification code is not up-to-date. - -2004-01-19 Bernie Solomon - - * interp.c (ves_exec_method_with_context): - get_native_wrapper removed and call - mono_marshal_get_native_wrapper directly - with new DllNotFoundException handling - -Mon Jan 19 17:52:33 CET 2004 Paolo Molaro - - * interp.c: eliminate CSIZE macro. - -2004-01-15 Zoltan Varga - - * interp.c (ves_array_set): Check for ArrayTypeMismatchException. - -2004-01-12 Gonzalo Paniagua Javier - - * interp.c: call setlocale (). Fixes bug #52100. - -2003-12-19 Bernie Solomon - - * embed.h, main.c: new files to enable embedding - the interpreter - - * interp.c: make main callable from main.c - rearrange main for embedding - - * Makefile.am: changes now most code is in a library - -2003-11-21 Lluis Sanchez Gual - - * interp.c: Added support for context static fields. - -2003-10-31 Zoltan Varga - - * interp.c (mono_create_method_pointer): New function which contains - the arch independent part of method wrapper creation. Add a cache - for the wrapper code, since Delegate::Equals depends on the wrapper - address being constant for a method. Fixes #50366. - -2003-10-30 Bernie Solomon - - * interp.c: (ves_exec_method_with_context) - we need to lookup internal calls now. - don't free type in CEE_SIZEOF. - fix CEE_NEWOBJ inside wrapper methods - -2003-10-24 Zoltan Varga - - * interp.c: Update after appdomain changes. - -2003-10-13 Bernie Solomon - - * interp.c - set large stack size on HP 64bit - -2003-10-02 Bernie Solomon - - * hacks.h - work round HP 64 bit problem with isunordered - -2003-10-03 Zoltan Varga - - * interp.c (dump_frame): Avoid crash on frames without a method. Patch - sam@superduper.net (sam clegg). Fixes #46197. - (ves_exec_method_with_context): Fix unbox casting. - -2003-09-25 Bernie Solomon - - * interp.c - reinstate use of mono_marshal_get_delegate_invoke - for ordering and fix CALLI to handle wrapper. More wrapper handling - in CALL and LDSTR. Add another string conversion case. - -2003-09-25 Zoltan Varga - - * interp.c (ves_exec_method): Fix warning. - (ves_exec_method_with_context): Fix CGT_UN and CLT_UN. Patch by - David Waite (mass@akuma.org). - -2003-9-24 Bernie Solomon - - * interp.c: I broke calling native delegates reinstate - old code for the moment. - -2003-9-22 Bernie Solomon - - * interp.c: use mono_marshal_get_delegate_invoke to get delegate - invocation order consistent. Fix THROW_EX, fix ip in overflow - exceptions. - -Fri Sep 12 10:42:08 CEST 2003 Paolo Molaro - - * interp.c, interp.h: patch from Bernie Solomon : - 64 bit/opcodes/exception handling fixes. - -2003-08-30 Zoltan Varga - - * interp.c: Use mono_field_from_token () in the appropriate places. - This simplifies the code and also fixes #48051. - -2003-08-27 Zoltan Varga - - * interp.c (main): Fix the order of initialization calls so it maches - the order in the JIT.Patch by Bernie Solomon (bernard@ugsolutions.com). - Also remove the unused ms mutex. - - * interp.c: Get rid of metadata_section. - -2003-08-22 Zoltan Varga - - * interp.c (main): Call g_thread_init () to make glib thread-safe. - Fixes #47682. Thanks to Laurent Morichetti (l_m@pacbell.net) for - reporting this. - -2003-08-18 Zoltan Varga - - * interp.c: Get rid of duplicate definition of CHECK_MUL_OVERFLOW. - * interp.h interp.c: Get rid of VAL_VALUETA, use VAL_MP instead. Fix - the INITOBJ opcode which was the only user of VALUETA. - -2003-08-16 Zoltan Varga - - * interp.c (ves_exec_method): Implemented mul.ovf correctly for int32 - and int64. Implement the conv.ovf opcodes for all argument types. - -2003-08-15 Zoltan Varga - - * interp.c (ves_exec_method): Handle non-valuetypes in CEE_STOBJ. - Fixes #46781. - (ves_exec_method): Added support for the synchronized flag to the - interpreter. Also fixed the CALLI opcode, and made exception handling - work though the managed-unmanaged barrier. - -Fri Jul 25 19:06:27 CEST 2003 Paolo Molaro - - * interp.c: updates for new instructions. - -2003-07-22 Zoltan Varga - - * interp.c: Use the new metadata_section lock instead of metadata_lock. - Patch by Bernie Solomon (bernard@ugsolutions.com). - -Fri Jul 18 15:11:44 CEST 2003 Paolo Molaro - - * interp.c: 64 bit fixes from Laurent Morichetti . - Install cleanup function. - -2003-07-13 Zoltan Varga - - * interp.c: Keep alloca()-d data on a free list to prevent stack - overflow errors when valuetypes are allocated in a loop. Fixes - #27420. Is the new code still faster than using malloc/free ? - - * interp.c (ves_array_get): Add index checking to ves_array_get/set. - Fixes decimal-array.exe. - - * interp.c (interp_mono_runtime_invoke): Unbox value type instances - before calling the method. Fixes appdomain2.exe. - - * interp.c: Fix warnings. - - * interp.c: Report unhandled exceptions correctly. - - * interp.c: Implement CEE_ISINST and CEE_CASTCLASS using - mono_object_isinst. Fixes bug #45539 and reflection-enum.exe. - -Tue May 27 16:36:41 CEST 2003 Paolo Molaro - - * interp.c: don't use relative numbering stuff. - -Tue May 27 12:18:44 CEST 2003 Paolo Molaro - - * interp.c: update for mono_class_vtable() changes. - -Tue May 13 16:43:18 CEST 2003 Paolo Molaro - - * interp.c: handle thread static fields. - -Sun Apr 27 13:27:59 CEST 2003 Paolo Molaro - - * interp.c: check for arraytypemismatch. - -2003-04-23 Martin Baulig - - * interp.c: When running with --dieonex, use the debugging code to - print source lines in the backtrace. - -2003-02-09 Gonzalo Paniagua Javier - - * interp.c: added a dummy mono_runtime_install_handlers function to - avoid crashing when ves_pinvoke_method tries to call it. - -2003-02-06 Piers Haken - - * interp.c: warning cleanups - -2002-11-15 Dick Porter - - * interp.c: mono_runtime_init() now has an extra parameter for - thread attaching. - -2002-10-31 Dick Porter - - * Makefile.am: The previous automake-1.6 fix broke automake-1.4 on - cygwin. Try again. - -2002-09-27 Dick Porter - - * interp.c: Tell glib what the program name is, by passing it the - name of the managed file we're executing - -2002-08-28 Dick Porter - - * interp.c: mono_set_rootdir() doesnt take any args now - - * Makefile.am: Export HOST_CC and turn on optimisation for w32 builds - -2002-08-28 Nick Drochak - - * interp.c: check and throw exception if needed for overflow on - multiplication of integer types. - -2002-08-07 Dietmar Maurer - - * interp.c (interp_walk_stack): removed the createdelegate icall - -2002-08-02 Dietmar Maurer - - * interp.c (get_virtual_method): support proxies - (ves_exec_method): impl. LDFLD/STFLD for proxies. - -Fri Aug 2 13:00:41 CEST 2002 Paolo Molaro - - * interp.c, interp.h: implemented exception trap for runtime_invoke - and handle exceptions across managed/unmanaged boundaries. - -2002-08-01 Dietmar Maurer - - * interp.c (stackval_from_data): add pinvoke argument - (stackval_to_data): add pinvoke argument. We need consider the - fact that unmanages structures may have different sizes. - (ves_pinvoke_method): do not call stackval_from_data if the result - is a value type. - -Wed Jul 31 17:47:11 CEST 2002 Paolo Molaro - - * interp.c: simplified some more branch code. - -Wed Jul 31 16:50:42 CEST 2002 Paolo Molaro - - * interp.c: fixed indentation, simplified some code. - -Wed Jul 31 14:29:43 CEST 2002 Paolo Molaro - - * interp.c: fix so that mint can at least get to executing Main(). - -2002-07-31 Dietmar Maurer - - * interp.c: use the new marshaling code. better delegate/remoting - support. - (ves_exec_method): bug fix - directly jump to handle_exception. - -2002-07-29 Dietmar Maurer - - * interp.c (main): install compile_method handler - -Wed Jul 24 13:02:12 CEST 2002 Paolo Molaro - - * interp.c: implemented stack walking function. - -Fri Jul 19 14:21:18 CEST 2002 Paolo Molaro - - * interp.c: fix float boxing on LE systems. - -Sat Jul 13 19:54:56 CEST 2002 Paolo Molaro - - * interp.c: advance ip in conv.r.un. - -2002-07-01 Dick Porter - - * interp.c (ves_exec): Removed unneeded argument to - mono_runtime_run_main() - -2002-06-25 Dick Porter - - * interp.c (ves_exec): Pass the assembly to mono_runtime_run_main - -Wed Jun 19 17:01:37 CEST 2002 Paolo Molaro - - * interp.c: un-broke after stack trace changes. - -Fri May 31 16:17:20 CEST 2002 Paolo Molaro - - * interp.c, hacks.h: compiler compatibility fixes. - -Fri May 31 13:25:57 CEST 2002 Paolo Molaro - - * interp.c, mint.1: added --config command line option. - -Thu May 30 14:14:16 CEST 2002 Paolo Molaro - - * interp.c: lookup P/Invoke method addr only when needed. - -2002-05-29 Dietmar Maurer - - * interp.c (ves_exec_method): free type in CEE_SIZEOF - -Tue May 28 16:10:49 CEST 2002 Paolo Molaro - - * interp.c: fixed SIZEOF to work with typedef/typeref. - -Fri May 24 15:33:50 CEST 2002 Paolo Molaro - - * interp.c: added partial async delegate and remoting support. - -Thu May 23 18:45:38 CEST 2002 Paolo Molaro - - * interp.c: special case string ctors in invoke. - Handle null object in throw. Misc integer type mismatch fixes. - -2002-05-23 Dietmar Maurer - - * interp.c (ves_runtime_method): share more code with the jit. - -Wed May 22 12:31:40 CEST 2002 Paolo Molaro - - * interp.c: fixed finally handling. In trace mode show - exception handling operations and the contents of the stack in the same - line as the executing instruction. - -2002-05-20 Miguel de Icaza - - * interp.c: Updated help display. - -2002-05-20 Radek Doulik - - * interp.c (dump_stack): print boxed values for --noptr - (ves_exec_method): use stackval_to_data as pointed out by lupus - -2002-05-17 Radek Doulik - - * interp.c (dump_stack): if --noptr then print content of strings - in form [str:] - -2002-05-16 Radek Doulik - - * interp.c (ves_exec_method): use data.i instead of data.l in i32 - case - (ves_exec_method): set type in I64 <--> I32 conversions - -2002-05-15 Radek Doulik - - * interp.c (ves_runtime_method): moved stackval_from_data call - inside #else branch, consulted on irc with lupus - -2002-05-15 Dietmar Maurer - - * interp.c (ves_exec_method): use new mono_unhandled_exception() - -2002-05-14 Radek Doulik - - * interp.c: introduced new --noptr option to suppres pointer - address printing. I find this useful for comparing trace outputs - while porting to ppc - -Tue May 14 16:37:55 CEST 2002 Paolo Molaro - - * interp.c: some finally handling fixes and compilation fixes for - changes in the runtime lib. - -2002-04-30 Dick Porter - - * interp.c: Tell glib to not abort when g_log() etc print - recursively - -Mon Apr 22 16:52:03 CEST 2002 Paolo Molaro - - * interp.c: handle muslticast delegates. Implement a couple more - convert opcodes. Pretend we spend some time jitting... - -2002-04-20 Dietmar Maurer - - * interp.c (ves_exec_method): support internalcall String constructors - -2002-04-19 Dan Lewis - - * interp.c: support for new szarray format. - -Tue Apr 16 20:12:58 CEST 2002 Paolo Molaro - - * interp.c: removed profiling code (moved to common library). - Implemented inlining for some special methods. - -2002-04-15 Patrik Torstensson - - * interp.c: Using fullnames when adding icall's (array) - -Wed Apr 10 16:07:23 CEST 2002 Paolo Molaro - - * interp.c: quick implementation for opcodes needed by the new parse - routines in corlib. - -Tue Apr 9 13:08:26 CEST 2002 Paolo Molaro - - * interp.c: make the interp thread-safe wrt the metadata lib. - -Mon Apr 8 17:15:48 CEST 2002 Paolo Molaro - - * interp.c: display return value with --trace. - Call mono_runtime_init (). - -2002-04-06 Dietmar Maurer - - * interp.c (interp_mono_runtime_invoke): handle more types, - removed runtime_exec_main - -Thu Apr 4 11:36:52 CEST 2002 Paolo Molaro - - * interp.c: don't try to get an IL opcode for runtime and internal - call methods. - -Thu Mar 28 16:54:51 CET 2002 Paolo Molaro - - * interp.c: spring warning cleanup. - -Thu Mar 28 12:03:28 CET 2002 Paolo Molaro - - * interp.c: check obj address in stfld. - -2002-03-27 Dietmar Maurer - - * interp.c (ves_exec_method): CASTCLASS: fix for transparent proxy - -Tue Mar 26 20:09:10 CET 2002 Paolo Molaro - - * interp.c: set frame->ip before dumping the stack trace. - -Tue Mar 26 19:54:45 CET 2002 Paolo Molaro - - * interp.c: remove glib mem vtable code. - -2002-03-26 Dick Porter - - * interp.c: Show thread ID's in trace output. - - New option "--traceclassinit" to put debug output around - runtime_class_init(). - - Make sure all options are displayed in usage(). - -Tue Mar 26 17:03:14 CET 2002 Paolo Molaro - - * interp.c: support fieldrefs when accessing instance fields. - -Mon Mar 25 12:59:52 CET 2002 Paolo Molaro - - * interp.c: allow tracing to be done on a per-method basis. - Fix interp_mono_runtime_invoke() to deal correcttly with the return - value. Disable glib mem vtable setting. - -Thu Mar 21 18:08:37 CET 2002 Paolo Molaro - - * interp.c: set stack trace info when throwing an exception. - -Thu Mar 21 17:32:46 CET 2002 Paolo Molaro - - * interp.c: intern strings before executing a method (and don't - intern command line arguments anymore). Add sanity checks in alloca - use. - -Sat Mar 16 19:15:18 CET 2002 Paolo Molaro - - * interp.c: restore frame on return from unmanaged calls. - Add support for continuing execution up to x IL insn. - Fix exception handling when an exception is raised in the catch - handler of the same method that issued the first one. - -2002-03-11 Dietmar Maurer - - * interp.c (ves_runtime_method): set method_info field - -Mon Mar 11 14:48:07 CET 2002 Paolo Molaro - - * interp.c: corlib consistency checls moved to libmetadata. - -Mon Mar 11 11:27:27 CET 2002 Paolo Molaro - - * interp.c: use the new facilities in debug-helpers to - disassemble CIL code and match method names to MonoMethods. - -Thu Mar 7 17:20:59 CET 2002 Paolo Molaro - - * interp.c: Boehm-GC enable. Fix some overflow opcodes. - -Tue Mar 5 18:12:40 CET 2002 Paolo Molaro - - * interp.c: fix non-debug build and some more opcode work. - -Mon Mar 4 11:21:44 CET 2002 Paolo Molaro - - * interp.c: print the address of 'this' in tracing mode. - -Thu Feb 28 19:18:59 CET 2002 Paolo Molaro - - * interp.c: add checks for more binary consistency. - -2002-02-27 Dietmar Maurer - - * interp.c (interp_mono_runtime_invoke): use alloca instead of g_new0 - -Tue Feb 26 11:43:34 CET 2002 Paolo Molaro - - * interp.c: added profiling for object creation. - -Mon Feb 25 17:37:07 CET 2002 Paolo Molaro - - * interp.c: use correct value for guint64 max. - -2002-02-22 Radek Doulik - - * interp.c: s/gulong/guint64 as it differs on ppc - -Wed Feb 20 22:18:40 CET 2002 Paolo Molaro - - * interp.c: more complete runtime_invoke () implementation. - Fixed castclass/isinst to work correctly with arrays. - -Tue Feb 19 20:21:14 CET 2002 Paolo Molaro - - * interp.c: implement the runtime_invoke function. - -Mon Feb 18 15:49:20 CET 2002 Paolo Molaro - - * interp.c: fix alignment code. Make sure to init classes - in more cases. Command-line arguments are interned. - -2002-02-16 Radek Doulik - - * interp.c (ves_exec_method): test type of sp [-1] instead of sp - [0], because sp [-1] is the value going to be shifted, fixed in - CEE_SHL, CEE_SHR, CEE_UN opcodes) - -Sat Feb 16 12:00:24 CET 2002 Paolo Molaro - - * interp.c: fixed cut&paste error for ldind.r4 and ldind.r8. - -Fri Feb 15 15:07:27 CET 2002 Paolo Molaro - - * interp.c: use strrchr instead of rindex. use _isnan and _finite on - win32 systems. - -2002-02-14 Jeffrey Stedfast - - * interp.c (ves_exec_method): replace - 'g_assert (sp->type = VAL_VALUETA)' with - 'g_assert (sp->type == VAL_VALUETA)' otherwise - the assert always passes. FIXME: should the test have been !=? - -2002-02-14 Dietmar Maurer - - * interp.c (stackval_from_data): fix for MONO_TYPE_PTR - -Wed Feb 13 16:17:38 CET 2002 Paolo Molaro - - * interp.c: fixed newobj implementation for valuetypes bug found by - dietmar. sub.ovf dummy code. - -Tue Feb 12 14:08:47 CET 2002 Paolo Molaro - - * hacks.h: check against redefining preprocessor symbol. - * interp.c: fix profile info to return more sensible results. - -Mon Feb 11 13:05:29 CET 2002 Paolo Molaro - - * interp.c: added "die on exception" command line argument. - When we segfault, set the message in the exception to "Segmentation - fault" so people can recognise what's going on. - -2002-02-10 Miguel de Icaza - - * interp.c (ves_exec_method): Compare the element_class type token - in the class we got as well, instead of the element class vs the - toplevel class. - - This fixes the invalid cast exceptions during unboxing - -Fri Feb 8 13:01:03 CET 2002 Paolo Molaro - - * interp.c: use opcode information from libmetadata. - -2002-02-05 Dietmar Maurer - - * interp.c (ves_exec_method): CEE_UNBOX: use element_class for - type check. - -2002-02-04 Dietmar Maurer - - * interp.c (main): impl. __array_Address icall - -Fri Feb 1 16:03:53 CET 2002 Paolo Molaro - - * interp.c: exception fixes. Use mono_method_pointer_get () - to easy porting to other archs. Some support for overflow detection. - -2002-01-25 Dietmar Maurer - - * interp.c, jit.c (main): install runtime_exec_main handler - (main): bug fix - call TlsAlloc () before we execute code - -2002-01-23 Dick Porter - - * interp.c: Added some kludges to cope with CONV_OVF_I2, - CONV_OVF_I4 and ADD_OVF so that number formatting works. Also - initialise and cleanup the network support. - -Thu Jan 10 20:59:59 CET 2002 Paolo Molaro - - * interp.c, interp.h: add a flag to mono_create_trampoline () - to handle runtime methods. - -Sat Jan 5 15:45:14 CET 2002 Paolo Molaro - - * interp.c: allow classname:method name in --debug argument. - Fix box opcode for valuetypes. Fix a few opcode to take a 16 bit - index instead of 32 (stloc, ldloc, starg, etc.). - -Thu Jan 3 23:19:27 CET 2002 Paolo Molaro - - * interp.c: temporary mul.ovf, mul.ovf.un, add.ovf.un implementations - to get the compiler going. - -Mon Dec 24 17:23:45 CET 2001 Paolo Molaro - - * interp.c: fix ldc.i8. - -Thu Dec 20 20:09:48 CET 2001 Paolo Molaro - - * interp.c: fix delegate method invocation to handle both - static and instance methods. - -Tue Dec 18 18:48:50 CET 2001 Paolo Molaro - - * interp.c: make segv_handler static, handle runtime methods in stack - trace. - -Thu Dec 13 20:24:28 CET 2001 Paolo Molaro - - * interp.c: correctly handle exceptions generated in C code. - Install an handler for SIGSEGV. Bare-bones profiler and hook for the - verifier. - -Mon Dec 3 17:15:44 CET 2001 Paolo Molaro - - * interp.c: call mono_init() after registering internal calls. - -2001-11-30 Dick Porter - - * interp.c: Replace get_named_exception() with - mono_exception_from_name() - -Fri Nov 30 12:05:21 CET 2001 Paolo Molaro - - * interp.c: calculate locals and args offsets only once - per method call. Cache trampoline code as well. - -2001-11-23 Dietmar Maurer - - * interp.c (ves_exec_method): bug fix for exception5.cs - -Mon Nov 19 11:33:00 CET 2001 Paolo Molaro - - * interp.c: start adding support for handling exceptions across - managed/unmanaged boundaries. Cleanup Delegate method invocation. - Pass the correct target object in Delegate::Invoke and use the correct - 'this' pointer in ldvirtftn (bugs pointed out by Dietmar). - -Thu Nov 15 17:40:24 CET 2001 Paolo Molaro - - * interp.c: handle enums with underlying type different from int32. - More checks for C structs <-> C# objects consistency. - -Wed Nov 14 19:23:00 CET 2001 Paolo Molaro - - * interp.c: move the stack frame dumping code to a function so it can - be called from the debugger. Fix virtual method lookup for interfaces. - Throw exceptions instead of aborting in more places. - Print also the message in an exception. Updates for field renames in - corlib. - -2001-11-09 Dick Porter - - * Makefile.am (mint_LDADD): Don't need THREAD_LIBS any more - -2001-11-07 Miguel de Icaza - - * interp.c: Include stdlib to kill warning. - (check_corlib): Adjust format encodings to remove warnings. - -Wed Nov 7 15:47:36 CET 2001 Paolo Molaro - - * interp.c: updates for changes in array code. - -Fri Nov 2 19:06:54 CET 2001 Paolo Molaro - - * interp.c: hanlde field refs. Throw an exception on NULL references. - Check consistency of corlib types with the C struct representation. - -2001-10-25 Dietmar Maurer - - * interp.c (ves_exec_method): use relative numbering for runtime - type checks (and make it work with interfaces) - -2001-10-15 Dietmar Maurer - - * interp.c: removed newobj() - -2001-10-10 Dietmar Maurer - - * interp.c (get_virtual_method): use the vtable - (arch_compile_method): added to compute vtable entry - -Mon Oct 8 16:14:40 CEST 2001 Paolo Molaro - - * interp.c: use the accessors provided in object.h to deal with - MonoArrays. Updates for API renames in metadata. Throw exception - in ldelema if index is out of bounds. - -Mon Oct 8 10:44:25 CEST 2001 Paolo Molaro - - * interp.c: fixes for changes in metadata. - -2001-10-04 Dick Porter - - * interp.c (ves_runtime_method): init_class() the - mono_defaults.delegate_class - Include mono-endian.h not endian.h - -Tue Oct 2 18:51:25 CEST 2001 Paolo Molaro - - * interp.c: set frame->ip in the leave opcode. Make db_methods static. - -Sun Sep 30 11:57:15 CEST 2001 Paolo Molaro - - * interp.c: compiler and ANSI C portability fixes. - -Fri Sep 28 19:37:46 CEST 2001 Paolo Molaro - - * interp.c: Implemented ldtoken, conv.ovf.i. Use MonoClass->byval_arg - (and remove related kludges). Don't choke on access to arrays of - references. Throw an exception when an internalcall or P/Invoke - function don't have an implementation. Throw and EngineException - for unimplemented opcodes. - -Tue Sep 25 11:12:35 CEST 2001 Paolo Molaro - - * interp.c: fixed get_virtual_method () to deal with interface - methods better. - -Mon Sep 24 18:50:25 CEST 2001 Paolo Molaro - - * interp.c: catch a few more error conditions with exceptions instead of - erroring out. - Don't use g_print() in stack traces because it doesn't work with - some float values. - When we call an instance method of a valuetype class, unbox the 'this' - argument if it is an object. - Use mono_ldstr () to implement the ldstr opcode: it takes care of - interning the string if necessary. - Implemented new opcodes: ckfinite, cgt.un, clt.un, ldvirtftn, ldarga. - Fixes to handle NaNs when comparing doubles. - Make sure the loaded assembly has an entry point defined. - Fixed portability bugs in neg and not opcodes. - -2001-09-24 Dietmar Maurer - - * interp.c (ves_exec_method): LDC_I4: 8bit constants are signed - (ves_exec_method): bug fix for NOT/NEG - (main): fix bug in parameter parsing - -2001-09-23 Dick Porter - - * Makefile.am (mint_LDADD): rename PTHREAD_LIBS to THREAD_LIBS - -2001-09-23 Dick Porter - - * interp.c (main): Do some thread setup and cleanup around the - call to ves_exec() - -2001-09-21 Dick Porter - - * Makefile.am (mint_LDADD): Added PTHREAD_LIBS to the link line - -Thu Sep 20 16:32:42 CEST 2001 Paolo Molaro - - * interp.c: implemented some more opcodes: calli, rem.un, - shr.un, conv.u, cpobj, stobj, conv.r.un, conv.ovf.i1.un, - conv.ovf.i2.un, conv.ovf.i4.un, conv.ovf.i8.un, conv.ovf.i.un, - conv.ovf.u1.un, conv.ovf.u2.un, conv.ovf.u4.un, conv.ovf.u8.un, - conv.ovf.u.un. - Fix some 64 bit issues in the array element access code and a small bug. - Throw an exception on index out of range instead of asserting. - Throw an exception on a NULL array instead of dying. - Stomped a memory corruption bug (.cctor methods were freed after - executing them, but they are stores in MonoClass now...). - Added a simple facility to invoke the debugger when a named - function is entered (use the cmdline option --debug method_name). - * interp.h: fix 64 bit issue. - -Tue Sep 18 13:21:33 CEST 2001 Paolo Molaro - - * interp.c: fix some 64 bit issues. Safer support for delegates. - -2001-09-12 Miguel de Icaza - - * interp.c (ves_exec_method): implement conv.u8 opcode. - -Mon Sep 10 20:20:36 CEST 2001 Paolo Molaro - - * interp.c: endian fixes, comments. - -Fri Sep 7 18:45:38 CEST 2001 Paolo Molaro - - * interp.c, interp.h: make ves_exec_method () and stackval_from_data () - non static. Implement a couple of runtime methods needed to - use delegates (ves_runtime_method ()). - Implemented ldftn opcode. - -Thu Sep 6 15:41:24 CEST 2001 Paolo Molaro - - * Makefile.am: link to libmonoarch. - * interp.h, interp.c: use mono_create_trampoline (). - Pass the command line arguments to Main (String[]) methods. - -2001-08-30 Dietmar Maurer - - * interp.c (ves_pinvoke_method): removed the libffi dependency - -2001-08-29 Dietmar Maurer - - * interp.c (ves_array_set): moved from icall.c - (ves_array_get): moved from icall.c - - * icall.c: moved to metadata/icall.c - -Wed Aug 29 12:46:06 CEST 2001 Paolo Molaro - - * interp.c: some small optimizations. Fixes to do signed - compares when needed. Change C++ comments into C. - Implemented cgt, clt. Added --opcode-count cmdline switch. - -2001-08-28 Dietmar Maurer - - * interp.c (ves_exec_method): better check for value types (get - the class to detect if we have a value type), implemented CEE_CONV_U1, - CEE_CONV_U2, CEE_CEQ - - -Mon Aug 27 21:30:30 CEST 2001 Paolo Molaro - - * interp.c: warn and exit when Main () expects the cmdline arguments - instead of creashing. - -Mon Aug 27 20:16:37 CEST 2001 Paolo Molaro - - * interp.c: merge isinst/castclass handling. Hopefully implement - the right semantics for handling callvirt correctly (changes - here and there to support it). Integrate bugfix from Dietmar quickly - so he needs to handle the cvs conflict:-) - -Mon Aug 27 12:20:32 CEST 2001 Paolo Molaro - - * interp.c: fix compilation and updates for changes in metadata/. - -2001-08-26 Miguel de Icaza - - * interp.c (main): Add option handling for the interpreter, - support the `--trace' option. - -Sun Aug 26 23:04:46 CEST 2001 Paolo Molaro - - * interp.c: get in a dummy virtual method dispatch. - Added support for int64, native int and native uint as arguments. - Added debug enter/leave for icall and pinvoke methods, too. - Implement opcodes conv.i, conv.i8, ldelema. - -Sun Aug 26 11:37:30 CEST 2001 Paolo Molaro - - * interp.h, interp.c: load also a MonoClass pointer when we load - an address on the stack. Implemented conv.i1, conv.i2, con.i4, - conv.u4, conv.r4, conv.r8. Print the arguments in the stack trace - and the name of the exception. - -Sat Aug 25 15:56:03 CEST 2001 Paolo Molaro - - * interp.c: Implemented some opcodes: starg.s, ldobj, isinst, - ldarg, starg, ldloc, ldloca, stloc, initobj, cpblk, sizeof. - -Sat Aug 25 12:57:36 CEST 2001 Paolo Molaro - - * interp.c: handle enumerations specially (not as valuetypes). - -Fri Aug 24 19:34:04 CEST 2001 Paolo Molaro - - * interp.h, interp.c: add support for valuetypes. - -Fri Aug 24 16:09:20 CEST 2001 Paolo Molaro - - * interp.c: updates for merge of MonoParam in MonoType. - -Thu Aug 23 12:04:34 CEST 2001 Paolo Molaro - - * interp.c: removed beforefieldinit check, it's a useless flag. - Added a couple more test cases to tests/ dir. - -2001-08-22 Miguel de Icaza - - * interp.c (usage): Add version information - (ves_pinvoke_method): Typo fix. - -Wed Aug 22 20:37:51 CEST 2001 Paolo Molaro - - * interp.c: simplified init_class (). Make sure a class - is fully initialized before executing a method in the class. - Search for the class constructor only on beforefieldinit classes. - Implement a bunch of opcodes: br, brfalse, brtrue, beq, bge, - bgt, blt, ble, bne.un, bge.un, bgt.un, ble.un, blt.un, stind.i, - ldflda, ldsflda, ldelem.i8, stelem.i8, leave. - -Wed Aug 22 16:34:03 CEST 2001 Paolo Molaro - - * interp.c: Updates for changes in metadata/. Better output in debug mode - and in the stack trace. Completed rethrow handling - -Tue Aug 21 18:56:19 CEST 2001 Paolo Molaro - - * interp.c: new macro INIT_FRAME() to properly - initialize a MonoInvocation. Fixed a couple of buglets in exception code: - increase stack pointer when pushing the exception for catch blocks, - initialize frame->ex_handler to NULL, correctly try all the - catch blocks (don't incorrectly fallback on filter handling). - Added a couple more checks where we may need to throw an - exception. Added more exception creation functions. - Changed stackval_from_data() to take the target stackval as - argument. Implemented a couple more opcodes. - * interp.h: prepare stackval for value type code. - -2001-08-21 Miguel de Icaza - - * Makefile.am (mint_LDADD): Renamed interpreter to mint. - -2001-08-21 Dietmar Maurer - - * interp.c (get_named_exception): use the right constructor. - -Mon Aug 20 18:58:36 CEST 2001 Paolo Molaro - - * interp.c: fix buglet with the leave.s opcode. - -2001-08-20 Dietmar Maurer - - * icall.c: changed everything to support the new calling convention - - * hacks.h: added some macros for FreeBSD - - * interp.c (get_named_exception): use mono_object_new instead of - newobj, initialize the stack before we call the constructor. - -Sat Aug 18 12:43:38 CEST 2001 Paolo Molaro - - * interp.c, interp.h: added support code to create exceptions. - Changed interncal calling convnetion over to MonoInvocation, to support - exceptions, walking the stack back and forward and passing the 'this' - pointer separately (remove the cludges required before to pass this on the - stack). Use alloca heavily for both local vars and a copy of the incoming - arguments. Init local vars to zero. - Simplify stackval_from_data() and stackval_to_data() to only take a pointer - instead of pointer + offset. - Implement a few exceptions-related opcodes and the code to run finally, fault and - catch blocks as well as a stack trace if no handler is found. - -2001-08-16 Alex Graveley - - * Makefile.am (mono_int_LDADD): Link with ../../libffi/libffi.a - instead of ../../libffi/.libs/libffi.a. - -2001-08-10 Dietmar Maurer - - * interp.c (ves_exec_method): impl CASTCLASS - - * icall.c: moved the internal call stuff to this file - - * interp.c (ves_exec_method): impl. BOX/UNBOX - (ves_icall_System_Array_GetValue): impl. - (ves_icall_System_Array_SetValue): impl. - added myself to Authors - -2001-08-09 Dietmar Maurer - - * implemented arrays, but you will need a modified version of - Array.cs to get arrays working (will commit soon) - - * interp.c (ves_icall_array_Set): impl. - (ves_icall_array_Get): impl. - (ves_icall_array_ctor): impl. - (ves_icall_System_Array_GetRank): impl. - (ves_icall_System_Array_GetLength): impl. - (ves_icall_System_Array_GetLowerBound): impl. - (mono_lookup_internal_call): impl. - -2001-08-06 Dietmar Maurer - - * interp.c (ves_exec_method): impl. NEWARR - (ves_exec_method): impl. most LDELEM/STELEM opcodes, LDLEN - (newarr): impl. - (mono_get_ansi_string): impl. - (mono_lookup_internal_call): impl. - (ves_exec_method): implemented internal calls - -2001-08-05 Dietmar Maurer - - * interp.c (ves_pinvoke_method): removed all static vars. - -2001-08-02 Dietmar Maurer - - * interp.c (ves_exec_method): found a way to do unordered - compares, implemented CEE_BNE_UN_S, CEE_BGE_UN_S, CEE_BGT_UN_S, - CEE_BLE_UN_S, CEE_BLT_UN_S - -Wed Aug 1 22:51:38 CEST 2001 Paolo Molaro - - * interp.c: handle also MONO_TYPE_CLASS to/from the stack. - Change locals to be a memory blob, instead of the structured - (but wrong) stackval. Implement bne.un.s opcode. Make the program - exit with the error code from Main(). - -2001-08-01 Dietmar Maurer - - * interp.c (ves_exec_method): implemented LDSTR - -2001-07-31 Miguel de Icaza - - * interp.c (GET_NATI): Switched from using nati_t to cli/types.h - m_i type. Maybe we should rename the types to be m_i_t instead of - m_i alone. - - Make the code compile after I broke it. - -Tue Jul 31 23:46:33 CEST 2001 Paolo Molaro - - * interp.c: fix cleanup. - * Makefile.am: don't link with disassembler library. - -2001-07-31 Miguel de Icaza - - (ves_exec_method): Cleanup of the source code. - -Tue Jul 31 20:13:59 CEST 2001 Paolo Molaro - - * interp.c: implement stind.*, ldind.*, ldloca.s opcodes. - Provide better tracing with DEBUG_INTERP. - -Tue Jul 31 17:52:53 CEST 2001 Paolo Molaro - - * interp.c: massive namespace cleanup. - -Mon Jul 30 20:09:58 CEST 2001 Paolo Molaro - - * interp.c: update to use mono_method->name. - -Fri Jul 27 20:54:00 CEST 2001 Paolo Molaro - - * interp.c: start implementing callvirt. Classes with - class constructors are properly initialized when needed. - Fix error introduced in version 1.17. - -Fri Jul 27 14:03:19 CEST 2001 Paolo Molaro - - * interp.c: implement static field loading and storing. - -2001-07-27 Dietmar Maurer - - * interp.c (ves_pinvoke_method): impl. - -Fri Jul 27 11:49:19 CEST 2001 Paolo Molaro - - * interp.c: Removed some debugging printouts. Made stackval_to_data - static. Handle also instance methods in CALL opcode. Fix ret to properly - deal with void functions. Fixed constructor to leave the object on - the stack. - -Thu Jul 26 13:24:51 CEST 2001 Paolo Molaro - - * interp.c: ves_exec_method () doesn't take a MonoImage arg - anymore. Use the method cache in MonoImage. Updates to - mache recent changes in metadata. - Fix newobj code to use new metadata features. Call the class - constructor after allocationg the object. Implemented load field - and store field opcodes (the support functions need to be finished). - -Tue Jul 24 16:51:09 CEST 2001 Paolo Molaro - - * interp.c, hacks.h: moved a few ugly macros out of the code. - Implemented switch opcode. - -2001-07-23 Miguel de Icaza - - * interp.c (newobj): Added function to handle newobj opcode. - -2001-07-18 Miguel de Icaza - - * interp.c (ves_exec_method): Make the interpreter abort with more - information than it currently does. - - Enable the slow processor, as it is easier to debug. - -Sun Jul 15 17:50:23 CEST 2001 Paolo Molaro - - * Started changelog. - * interp.c: use new mono_get_method () function to get the complete - info on a method invocation: we support now method invocation with - multiple (or zero) simple arguments and with or without a return value. - Implement also a couple more opcodes. diff --git a/mono/interpreter/Makefile.am b/mono/interpreter/Makefile.am deleted file mode 100644 index 4cea04452b..0000000000 --- a/mono/interpreter/Makefile.am +++ /dev/null @@ -1,59 +0,0 @@ -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - $(LIBGC_CPPFLAGS) \ - $(GLIB_CFLAGS) - -if HOST_WIN32 -export HOST_CC -# The mingw math.h has "extern inline" functions that dont appear in libs, so -# optimisation is required to actually inline them -AM_CFLAGS = -O -endif - -if INTERP_SUPPORTED -bin_PROGRAMS = mint - -lib_LTLIBRARIES = libmint.la - -man_MANS = mint.1 -endif - -mint_SOURCES = \ - main.c - -mint_LDADD = \ - libmint.la - -libmint_la_SOURCES = \ - hacks.h \ - interp.h \ - interp.c \ - mintops.h \ - mintops.def \ - mintops.c \ - transform.c - -libmintincludedir = $(includedir)/mono-$(API_VER)/mono/interpreter - -libmintinclude_HEADERS = \ - embed.h - -# This is needed for automake dependency generation -if INCLUDED_LIBGC -libgc_libs=../../libgc/libmonogc.la -else -libgc_libs=$(LIBGC_LIBS) -endif - -libmint_la_LIBADD = \ - ../arch/libmonoarch.la \ - ../metadata/libmonoruntime.la \ - ../io-layer/libwapi.la \ - ../utils/libmonoutils.la \ - $(libgc_libs) \ - $(GLIB_LIBS) \ - $(LIBICONV) \ - $(ICU_LIBS) \ - -lm - -EXTRA_DIST = $(man_MANS) diff --git a/mono/interpreter/Makefile.in b/mono/interpreter/Makefile.in deleted file mode 100644 index 1d5db63467..0000000000 --- a/mono/interpreter/Makefile.in +++ /dev/null @@ -1,913 +0,0 @@ -# Makefile.in generated by automake 1.14.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994-2013 Free Software Foundation, Inc. - -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ - - - -VPATH = @srcdir@ -am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' -am__make_running_with_option = \ - case $${target_option-} in \ - ?) ;; \ - *) echo "am__make_running_with_option: internal error: invalid" \ - "target option '$${target_option-}' specified" >&2; \ - exit 1;; \ - esac; \ - has_opt=no; \ - sane_makeflags=$$MAKEFLAGS; \ - if $(am__is_gnu_make); then \ - sane_makeflags=$$MFLAGS; \ - else \ - case $$MAKEFLAGS in \ - *\\[\ \ ]*) \ - bs=\\; \ - sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ - | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ - esac; \ - fi; \ - skip_next=no; \ - strip_trailopt () \ - { \ - flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ - }; \ - for flg in $$sane_makeflags; do \ - test $$skip_next = yes && { skip_next=no; continue; }; \ - case $$flg in \ - *=*|--*) continue;; \ - -*I) strip_trailopt 'I'; skip_next=yes;; \ - -*I?*) strip_trailopt 'I';; \ - -*O) strip_trailopt 'O'; skip_next=yes;; \ - -*O?*) strip_trailopt 'O';; \ - -*l) strip_trailopt 'l'; skip_next=yes;; \ - -*l?*) strip_trailopt 'l';; \ - -[dEDm]) skip_next=yes;; \ - -[JT]) skip_next=yes;; \ - esac; \ - case $$flg in \ - *$$target_option*) has_opt=yes; break;; \ - esac; \ - done; \ - test $$has_opt = yes -am__make_dryrun = (target_option=n; $(am__make_running_with_option)) -am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -build_triplet = @build@ -host_triplet = @host@ -target_triplet = @target@ -@INTERP_SUPPORTED_TRUE@bin_PROGRAMS = mint$(EXEEXT) -subdir = mono/interpreter -DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ - $(top_srcdir)/mkinstalldirs $(top_srcdir)/depcomp \ - $(libmintinclude_HEADERS) ChangeLog -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/m4/iconv.m4 \ - $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ - $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ - $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ - $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ - $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ - $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ - "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(libmintincludedir)" -LTLIBRARIES = $(lib_LTLIBRARIES) -am__DEPENDENCIES_1 = -@INCLUDED_LIBGC_FALSE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) -@INCLUDED_LIBGC_TRUE@am__DEPENDENCIES_2 = ../../libgc/libmonogc.la -libmint_la_DEPENDENCIES = ../arch/libmonoarch.la \ - ../metadata/libmonoruntime.la ../io-layer/libwapi.la \ - ../utils/libmonoutils.la $(am__DEPENDENCIES_2) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am_libmint_la_OBJECTS = interp.lo mintops.lo transform.lo -libmint_la_OBJECTS = $(am_libmint_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -@INTERP_SUPPORTED_TRUE@am_libmint_la_rpath = -rpath $(libdir) -PROGRAMS = $(bin_PROGRAMS) -am_mint_OBJECTS = main.$(OBJEXT) -mint_OBJECTS = $(am_mint_OBJECTS) -mint_DEPENDENCIES = libmint.la -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libmint_la_SOURCES) $(mint_SOURCES) -DIST_SOURCES = $(libmint_la_SOURCES) $(mint_SOURCES) -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -man1dir = $(mandir)/man1 -NROFF = nroff -MANS = $(man_MANS) -HEADERS = $(libmintinclude_HEADERS) -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) -# Read a list of newline-separated strings from the standard input, -# and print each of them once, without duplicates. Input order is -# *not* preserved. -am__uniquify_input = $(AWK) '\ - BEGIN { nonempty = 0; } \ - { items[$$0] = 1; nonempty = 1; } \ - END { if (nonempty) { for (i in items) print i; }; } \ -' -# Make sure the list of sources is unique. This is necessary because, -# e.g., the same source file might be shared among _SOURCES variables -# for different programs/libraries. -am__define_uniq_tagged_files = \ - list='$(am__tagged_files)'; \ - unique=`for i in $$list; do \ - if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ - done | $(am__uniquify_input)` -ETAGS = etags -CTAGS = ctags -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -AMTAR = @AMTAR@ -AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ -API_VER = @API_VER@ -AR = @AR@ -AS = @AS@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -BOEHM_DEFINES = @BOEHM_DEFINES@ -BUILD_EXEEXT = @BUILD_EXEEXT@ -BUILD_GLIB_CFLAGS = @BUILD_GLIB_CFLAGS@ -BUILD_GLIB_LIBS = @BUILD_GLIB_LIBS@ -CC = @CC@ -CCAS = @CCAS@ -CCASDEPMODE = @CCASDEPMODE@ -CCASFLAGS = @CCASFLAGS@ -CCDEPMODE = @CCDEPMODE@ -CC_FOR_BUILD = @CC_FOR_BUILD@ -CFLAGS = @CFLAGS@ -CFLAGS_FOR_BUILD = @CFLAGS_FOR_BUILD@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -DISABLE_SHARED_HANDLES = @DISABLE_SHARED_HANDLES@ -DLLTOOL = @DLLTOOL@ -DOLT_BASH = @DOLT_BASH@ -DSYMUTIL = @DSYMUTIL@ -DTRACE = @DTRACE@ -DTRACEFLAGS = @DTRACEFLAGS@ -DUMPBIN = @DUMPBIN@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -FGREP = @FGREP@ -GDKX11 = @GDKX11@ -GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ -GLIB_CFLAGS = @GLIB_CFLAGS@ -GLIB_LIBS = @GLIB_LIBS@ -GMODULE_CFLAGS = @GMODULE_CFLAGS@ -GMODULE_LIBS = @GMODULE_LIBS@ -GMSGFMT = @GMSGFMT@ -GMSGFMT_015 = @GMSGFMT_015@ -GREP = @GREP@ -GTKX11 = @GTKX11@ -HAVE_MSGFMT = @HAVE_MSGFMT@ -HOST_CC = @HOST_CC@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INTL = @INTL@ -LD = @LD@ -LDFLAGS = @LDFLAGS@ -LIBC = @LIBC@ -LIBGC_CPPFLAGS = @LIBGC_CPPFLAGS@ -LIBGC_LIBS = @LIBGC_LIBS@ -LIBGC_STATIC_LIBS = @LIBGC_STATIC_LIBS@ -LIBICONV = @LIBICONV@ -LIBMONO_LA = @LIBMONO_LA@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LIBTOOL = @LIBTOOL@ -LIPO = @LIPO@ -LLVM_CFLAGS = @LLVM_CFLAGS@ -LLVM_CONFIG = @LLVM_CONFIG@ -LLVM_CXXFLAGS = @LLVM_CXXFLAGS@ -LLVM_LDFLAGS = @LLVM_LDFLAGS@ -LLVM_LIBS = @LLVM_LIBS@ -LN_S = @LN_S@ -LTCOMPILE = @LTCOMPILE@ -LTCXXCOMPILE = @LTCXXCOMPILE@ -LTLIBICONV = @LTLIBICONV@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MANIFEST_TOOL = @MANIFEST_TOOL@ -MKDIR_P = @MKDIR_P@ -MONO_DL_NEED_USCORE = @MONO_DL_NEED_USCORE@ -MONO_NACL_ALIGN_MASK_OFF = @MONO_NACL_ALIGN_MASK_OFF@ -MSGFMT = @MSGFMT@ -MSGFMT_015 = @MSGFMT_015@ -MSGMERGE = @MSGMERGE@ -NM = @NM@ -NMEDIT = @NMEDIT@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OPROFILE_CFLAGS = @OPROFILE_CFLAGS@ -OPROFILE_LIBS = @OPROFILE_LIBS@ -OTOOL = @OTOOL@ -OTOOL64 = @OTOOL64@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -RANLIB = @RANLIB@ -SED = @SED@ -SET_MAKE = @SET_MAKE@ -SGEN_DEFINES = @SGEN_DEFINES@ -SHELL = @SHELL@ -SQLITE = @SQLITE@ -SQLITE3 = @SQLITE3@ -STRIP = @STRIP@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -WERROR_CFLAGS = @WERROR_CFLAGS@ -X11 = @X11@ -XATTR_LIB = @XATTR_LIB@ -XGETTEXT = @XGETTEXT@ -XGETTEXT_015 = @XGETTEXT_015@ -XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ -XINERAMA = @XINERAMA@ -XMKMF = @XMKMF@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_AR = @ac_ct_AR@ -ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -arch_target = @arch_target@ -bindir = @bindir@ -build = @build@ -build_alias = @build_alias@ -build_cpu = @build_cpu@ -build_os = @build_os@ -build_vendor = @build_vendor@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -docs_dir = @docs_dir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -export_ldflags = @export_ldflags@ -extra_runtime_ldflags = @extra_runtime_ldflags@ -host = @host@ -host_alias = @host_alias@ -host_cpu = @host_cpu@ -host_os = @host_os@ -host_vendor = @host_vendor@ -htmldir = @htmldir@ -ikvm_native_dir = @ikvm_native_dir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -libgc_dir = @libgc_dir@ -libgdiplus_install_loc = @libgdiplus_install_loc@ -libgdiplus_loc = @libgdiplus_loc@ -libmono_cflags = @libmono_cflags@ -libmono_ldflags = @libmono_ldflags@ -libsuffix = @libsuffix@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mcs_topdir = @mcs_topdir@ -mcs_topdir_from_srcdir = @mcs_topdir_from_srcdir@ -mkdir_p = @mkdir_p@ -mono_build_root = @mono_build_root@ -mono_cfg_dir = @mono_cfg_dir@ -mono_runtime = @mono_runtime@ -nacl_self_host = @nacl_self_host@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -reloc_libdir = @reloc_libdir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -subdirs = @subdirs@ -sysconfdir = @sysconfdir@ -target = @target@ -target_alias = @target_alias@ -target_cpu = @target_cpu@ -target_os = @target_os@ -target_vendor = @target_vendor@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -AM_CPPFLAGS = \ - -I$(top_srcdir) \ - $(LIBGC_CPPFLAGS) \ - $(GLIB_CFLAGS) - -# The mingw math.h has "extern inline" functions that dont appear in libs, so -# optimisation is required to actually inline them -@HOST_WIN32_TRUE@AM_CFLAGS = -O -@INTERP_SUPPORTED_TRUE@lib_LTLIBRARIES = libmint.la -@INTERP_SUPPORTED_TRUE@man_MANS = mint.1 -mint_SOURCES = \ - main.c - -mint_LDADD = \ - libmint.la - -libmint_la_SOURCES = \ - hacks.h \ - interp.h \ - interp.c \ - mintops.h \ - mintops.def \ - mintops.c \ - transform.c - -libmintincludedir = $(includedir)/mono-$(API_VER)/mono/interpreter -libmintinclude_HEADERS = \ - embed.h - -@INCLUDED_LIBGC_FALSE@libgc_libs = $(LIBGC_LIBS) - -# This is needed for automake dependency generation -@INCLUDED_LIBGC_TRUE@libgc_libs = ../../libgc/libmonogc.la -libmint_la_LIBADD = \ - ../arch/libmonoarch.la \ - ../metadata/libmonoruntime.la \ - ../io-layer/libwapi.la \ - ../utils/libmonoutils.la \ - $(libgc_libs) \ - $(GLIB_LIBS) \ - $(LIBICONV) \ - $(ICU_LIBS) \ - -lm - -EXTRA_DIST = $(man_MANS) -all: all-am - -.SUFFIXES: -.SUFFIXES: .c .lo .o .obj -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign mono/interpreter/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --foreign mono/interpreter/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): - -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ - } - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -libmint.la: $(libmint_la_OBJECTS) $(libmint_la_DEPENDENCIES) $(EXTRA_libmint_la_DEPENDENCIES) - $(AM_V_CCLD)$(LINK) $(am_libmint_la_rpath) $(libmint_la_OBJECTS) $(libmint_la_LIBADD) $(LIBS) -install-binPROGRAMS: $(bin_PROGRAMS) - @$(NORMAL_INSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ - fi; \ - for p in $$list; do echo "$$p $$p"; done | \ - sed 's/$(EXEEXT)$$//' | \ - while read p p1; do if test -f $$p \ - || test -f $$p1 \ - ; then echo "$$p"; echo "$$p"; else :; fi; \ - done | \ - sed -e 'p;s,.*/,,;n;h' \ - -e 's|.*|.|' \ - -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ - sed 'N;N;N;s,\n, ,g' | \ - $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ - { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ - if ($$2 == $$4) files[d] = files[d] " " $$1; \ - else { print "f", $$3 "/" $$4, $$1; } } \ - END { for (d in files) print "f", d, files[d] }' | \ - while read type dir files; do \ - if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ - test -z "$$files" || { \ - echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ - $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ - } \ - ; done - -uninstall-binPROGRAMS: - @$(NORMAL_UNINSTALL) - @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ - files=`for p in $$list; do echo "$$p"; done | \ - sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ - -e 's/$$/$(EXEEXT)/' \ - `; \ - test -n "$$list" || exit 0; \ - echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(bindir)" && rm -f $$files - -clean-binPROGRAMS: - @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list - -mint$(EXEEXT): $(mint_OBJECTS) $(mint_DEPENDENCIES) $(EXTRA_mint_DEPENDENCIES) - @rm -f mint$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(mint_OBJECTS) $(mint_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mintops.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/transform.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs -install-man1: $(man_MANS) - @$(NORMAL_INSTALL) - @list1=''; \ - list2='$(man_MANS)'; \ - test -n "$(man1dir)" \ - && test -n "`echo $$list1$$list2`" \ - || exit 0; \ - echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ - { for i in $$list1; do echo "$$i"; done; \ - if test -n "$$list2"; then \ - for i in $$list2; do echo "$$i"; done \ - | sed -n '/\.1[a-z]*$$/p'; \ - fi; \ - } | while read p; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; echo "$$p"; \ - done | \ - sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ - sed 'N;N;s,\n, ,g' | { \ - list=; while read file base inst; do \ - if test "$$base" = "$$inst"; then list="$$list $$file"; else \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ - fi; \ - done; \ - for i in $$list; do echo "$$i"; done | $(am__base_list) | \ - while read files; do \ - test -z "$$files" || { \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ - done; } - -uninstall-man1: - @$(NORMAL_UNINSTALL) - @list=''; test -n "$(man1dir)" || exit 0; \ - files=`{ for i in $$list; do echo "$$i"; done; \ - l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.1[a-z]*$$/p'; \ - } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) -install-libmintincludeHEADERS: $(libmintinclude_HEADERS) - @$(NORMAL_INSTALL) - @list='$(libmintinclude_HEADERS)'; test -n "$(libmintincludedir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(libmintincludedir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libmintincludedir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libmintincludedir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(libmintincludedir)" || exit $$?; \ - done - -uninstall-libmintincludeHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(libmintinclude_HEADERS)'; test -n "$(libmintincludedir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(libmintincludedir)'; $(am__uninstall_files_from_dir) - -ID: $(am__tagged_files) - $(am__define_uniq_tagged_files); mkid -fID $$unique -tags: tags-am -TAGS: tags - -tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - set x; \ - here=`pwd`; \ - $(am__define_uniq_tagged_files); \ - shift; \ - if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ - if test $$# -gt 0; then \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - "$$@" $$unique; \ - else \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$unique; \ - fi; \ - fi -ctags: ctags-am - -CTAGS: ctags -ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) - $(am__define_uniq_tagged_files); \ - test -z "$(CTAGS_ARGS)$$unique" \ - || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$unique - -GTAGS: - here=`$(am__cd) $(top_builddir) && pwd` \ - && $(am__cd) $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) "$$here" -cscopelist: cscopelist-am - -cscopelist-am: $(am__tagged_files) - list='$(am__tagged_files)'; \ - case "$(srcdir)" in \ - [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ - *) sdir=$(subdir)/$(srcdir) ;; \ - esac; \ - for i in $$list; do \ - if test -f "$$i"; then \ - echo "$(subdir)/$$i"; \ - else \ - echo "$$sdir/$$i"; \ - fi; \ - done >> $(top_builddir)/cscope.files - -distclean-tags: - -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS) $(HEADERS) -install-binPROGRAMS: install-libLTLIBRARIES - -installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(libmintincludedir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - if test -z '$(STRIP)'; then \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - install; \ - else \ - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ - fi -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ - clean-libtool mostlyclean-am - -distclean: distclean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-tags - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-libmintincludeHEADERS install-man - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: install-binPROGRAMS install-libLTLIBRARIES - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: install-man1 - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ - uninstall-libmintincludeHEADERS uninstall-man - -uninstall-man: uninstall-man1 - -.MAKE: install-am install-strip - -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ - clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \ - clean-libtool cscopelist-am ctags ctags-am distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-binPROGRAMS install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-libLTLIBRARIES \ - install-libmintincludeHEADERS install-man install-man1 \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ - pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ - uninstall-binPROGRAMS uninstall-libLTLIBRARIES \ - uninstall-libmintincludeHEADERS uninstall-man uninstall-man1 - - -@HOST_WIN32_TRUE@export HOST_CC - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/mono/interpreter/embed.h b/mono/interpreter/embed.h deleted file mode 100644 index b3a54490ee..0000000000 --- a/mono/interpreter/embed.h +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include - -int -mono_main (int argc, char* argv[]); - -MonoDomain * -mono_interp_init(const char *file); - -int -mono_interp_exec(MonoDomain *domain, MonoAssembly *assembly, int argc, char *argv[]); - -void -mono_interp_cleanup(MonoDomain *domain); - diff --git a/mono/interpreter/hacks.h b/mono/interpreter/hacks.h deleted file mode 100644 index 9697ccbad6..0000000000 --- a/mono/interpreter/hacks.h +++ /dev/null @@ -1,153 +0,0 @@ -/* we need some special math function */ -#ifndef _ISOC99_SOURCE -#define _ISOC99_SOURCE -#endif -#include - -/* which are not defined on FreeBSD */ -#ifdef __GNUC__ - -#ifndef isunordered -# define isunordered(u, v) \ - (__extension__ \ - ({ __typeof__(u) __u = (u); __typeof__(v) __v = (v); \ - isnan(__u) || isnan(__v); })) -#endif - -#ifndef islessgreater -# define islessgreater(x, u) \ - (__extension__ \ - ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered (__x, __y) && (__x < __y) || (__y < __x); })) -#endif - -#ifndef islessequal -# define islessequal(x, y) \ - (__extension__ \ - ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered(__x, __y) && __x <= __y; })) -#endif - -#ifndef isless -# define isless(x, y) \ - (__extension__ \ - ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered(__x, __y) && __x < __y; })) -#endif - -#ifndef isgreater -# define isgreater(x, y) \ - (__extension__ \ - ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y); \ - !isunordered(__x, __y) && __x > __y; })) -#endif - -#else - -/* isunordered seems to crash on HPUX when built 64 bits - so use generic implementation. -*/ -#if defined(__hpux) && SIZEOF_VOID_P == 8 -#undef isunordered -#undef islessgreater -#undef islessequal -#undef isless -#undef isgreater -#endif - -#ifndef isunordered -# define isunordered(u, v) (isnan(u) || isnan(v)) -#endif - -#ifndef islessgreater -# define islessgreater(x, u) (!isunordered (x, y) && (x < y) || (y < x)) -#endif - -#ifndef islessequal -# define islessequal(x, y) (!isunordered(x, y) && x <= y) -#endif - -#ifndef isless -# define isless(x, y) (!isunordered(x, y) && x < y) -#endif - -#ifndef isgreater -# define isgreater(x, y) (!isunordered(x, y) && x > y) -#endif - -#endif - -/* - * Attempt at using the goto label construct of GNU GCC: - * it turns out this does give some benefit: 5-15% speedup. - * Don't look at these macros, it hurts... - */ -#define GOTO_LABEL -#undef GOTO_LABEL -#ifdef GOTO_LABEL - -#define SWITCH(a) goto *goto_map [(a)]; -#define BREAK SWITCH(*ip) -#define CASE(l) l ## _LABEL: -#define DEFAULT \ - CEE_ILLEGAL_LABEL: \ - CEE_ENDMAC_LABEL: -#define SUB_SWITCH \ - CEE_PREFIX1_LABEL: \ - CEE_ARGLIST_LABEL: \ - CEE_CEQ_LABEL: \ - CEE_CGT_LABEL: \ - CEE_CGT_UN_LABEL: \ - CEE_CLT_LABEL: \ - CEE_CLT_UN_LABEL: \ - CEE_LDFTN_LABEL: \ - CEE_LDVIRTFTN_LABEL: \ - CEE_UNUSED56_LABEL: \ - CEE_LDARG_LABEL: \ - CEE_LDARGA_LABEL: \ - CEE_STARG_LABEL: \ - CEE_LDLOC_LABEL: \ - CEE_LDLOCA_LABEL: \ - CEE_STLOC_LABEL: \ - CEE_LOCALLOC_LABEL: \ - CEE_UNUSED57_LABEL: \ - CEE_ENDFILTER_LABEL: \ - CEE_UNALIGNED__LABEL: \ - CEE_VOLATILE__LABEL: \ - CEE_TAIL__LABEL: \ - CEE_INITOBJ_LABEL: \ - CEE_UNUSED68_LABEL: \ - CEE_CPBLK_LABEL: \ - CEE_INITBLK_LABEL: \ - CEE_UNUSED69_LABEL: \ - CEE_RETHROW_LABEL: \ - CEE_UNUSED_LABEL: \ - CEE_SIZEOF_LABEL: \ - CEE_REFANYTYPE_LABEL: \ - CEE_UNUSED52_LABEL: \ - CEE_UNUSED53_LABEL: \ - CEE_UNUSED54_LABEL: \ - CEE_UNUSED55_LABEL: \ - CEE_UNUSED70_LABEL: -#define GOTO_LABEL_VARS \ - const static void * const goto_map [] = {\ -#define OPDEF(a,b,c,d,e,f,g,h,i,j) \ \ - && a ## _LABEL, \ -#include "mono/cil/opcode.def" \ -#undef OPDEF \ - &&DUMMY_LABEL \ - }; \ - DUMMY_LABEL: - -#else - -#define SWITCH(a) switch(a) -#define BREAK break -#define CASE(l) case l: -#define DEFAULT \ - default: \ - g_error ("Unimplemented opcode: %x at 0x%x\n", *ip, ip-header->code); -#define SUB_SWITCH case 0xFE: -#define GOTO_LABEL_VARS - -#endif diff --git a/mono/interpreter/interp.c.REMOVED.git-id b/mono/interpreter/interp.c.REMOVED.git-id deleted file mode 100644 index 1f52f2e181..0000000000 --- a/mono/interpreter/interp.c.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -4525ff69ab35c533d92938550de86dddec4ed887 \ No newline at end of file diff --git a/mono/interpreter/interp.h b/mono/interpreter/interp.h deleted file mode 100644 index 0953e5a54c..0000000000 --- a/mono/interpreter/interp.h +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "config.h" - -enum { - VAL_I32 = 0, - VAL_DOUBLE = 1, - VAL_I64 = 2, - VAL_VALUET = 3, - VAL_POINTER = 4, - VAL_NATI = 0 + VAL_POINTER, - VAL_MP = 1 + VAL_POINTER, - VAL_TP = 2 + VAL_POINTER, - VAL_OBJ = 3 + VAL_POINTER -}; - -#if SIZEOF_VOID_P == 4 -typedef guint32 mono_u; -typedef gint32 mono_i; -#elif SIZEOF_VOID_P == 8 -typedef guint64 mono_u; -typedef gint64 mono_i; -#endif - -/* - * Value types are represented on the eval stack as pointers to the - * actual storage. The size field tells how much storage is allocated. - * A value type can't be larger than 16 MB. - */ -typedef struct { - union { - gint32 i; - gint64 l; - double f; - /* native size integer and pointer types */ - gpointer p; - mono_u nati; - gpointer vt; - } data; -#if defined(__ppc__) || defined(__powerpc__) - int pad; -#endif -} stackval; - -typedef struct _MonoInvocation MonoInvocation; - -typedef void (*MonoFunc) (void); -typedef void (*MonoPIFunc) (MonoFunc callme, void *retval, void *obj_this, stackval *arguments); - -/* - * Structure representing a method transformed for the interpreter - * This is domain specific - */ -typedef struct _RuntimeMethod -{ - /* NOTE: These first two elements (method and - next_jit_code_hash) must be in the same order and at the - same offset as in MonoJitInfo, because of the jit_code_hash - internal hash table in MonoDomain. */ - MonoMethod *method; - struct _RuntimeMethod *next_jit_code_hash; - guint32 locals_size; - guint32 args_size; - guint32 stack_size; - guint32 vt_stack_size; - guint32 alloca_size; - unsigned short *code; - unsigned short *new_body_start; /* after all STINARG instrs */ - MonoPIFunc func; - int num_clauses; - MonoExceptionClause *clauses; - void **data_items; - int transformed; - guint32 *arg_offsets; - guint32 *local_offsets; - unsigned int param_count; - unsigned int hasthis; - unsigned int valuetype; -} RuntimeMethod; - -struct _MonoInvocation { - MonoInvocation *parent; /* parent */ - RuntimeMethod *runtime_method; /* parent */ - MonoMethod *method; /* parent */ - stackval *retval; /* parent */ - void *obj; /* this - parent */ - char *args; - stackval *stack_args; /* parent */ - stackval *stack; - stackval *sp; /* For GC stack marking */ - /* exception info */ - unsigned char invoke_trap; - const unsigned short *ip; - MonoException *ex; - MonoExceptionClause *ex_handler; -}; - -typedef struct { - MonoDomain *domain; - MonoInvocation *base_frame; - MonoInvocation *current_frame; - MonoInvocation *env_frame; - jmp_buf *current_env; - unsigned char search_for_handler; - unsigned char managed_code; -} ThreadContext; - -void mono_init_icall (void); - -MonoException * -mono_interp_transform_method (RuntimeMethod *runtime_method, ThreadContext *context); - -MonoDelegate* -mono_interp_ftnptr_to_delegate (MonoClass *klass, gpointer ftn); - -void -mono_interp_transform_init (void); - -void inline stackval_from_data (MonoType *type, stackval *result, char *data, gboolean pinvoke); -void inline stackval_to_data (MonoType *type, stackval *val, char *data, gboolean pinvoke); -void ves_exec_method (MonoInvocation *frame); - -/* - * defined in an arch specific file. - */ -MonoPIFunc -mono_arch_create_trampoline (MonoMethodSignature *sig, gboolean string_ctor); - -RuntimeMethod * -mono_interp_get_runtime_method (MonoMethod *method); - -void *mono_arch_create_method_pointer (MonoMethod *method); - -extern int mono_interp_traceopt; diff --git a/mono/interpreter/main.c b/mono/interpreter/main.c deleted file mode 100644 index 70b5d96d1b..0000000000 --- a/mono/interpreter/main.c +++ /dev/null @@ -1,9 +0,0 @@ -#include "interp.h" -#include "embed.h" - -int -main (int argc, char* argv[]) -{ - return mono_main (argc, argv); -} - diff --git a/mono/interpreter/mintops.c b/mono/interpreter/mintops.c deleted file mode 100644 index 5b4d69269e..0000000000 --- a/mono/interpreter/mintops.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Utilities for handling interpreter VM instructions - * - * Authors: - * Bernie Solomon (bernard@ugsolutions.com) - * - */ -#include -#include -#include "mintops.h" - -#define OPDEF(a,b,c,d) \ - b, -const char *mono_interp_opname[] = { -#include "mintops.def" - "" -}; -#undef OPDEF - -#define OPDEF(a,b,c,d) \ - c, -unsigned char mono_interp_oplen[] = { -#include "mintops.def" - 0 -}; -#undef OPDEF - - -#define OPDEF(a,b,c,d) \ - d, -MintOpArgType mono_interp_opargtype[] = { -#include "mintops.def" - 0 -}; -#undef OPDEF - -const guint16 * -mono_interp_dis_mintop(const guint16 *base, const guint16 *ip) -{ - int len = mono_interp_oplen [*ip]; - guint32 token; - int target; - if (len < 0 || len > 10) { - g_print ("op %d len %d\n", *ip, len); - g_assert_not_reached (); - } else if (len == 0) { /* SWITCH */ - int n = READ32 (ip + 1); - len = 3 + n * 2; - } - - g_print ("IL_%04x: %-10s", ip - base, mono_interp_opname [*ip]); - switch (mono_interp_opargtype [*ip]) { - case MintOpNoArgs: - break; - case MintOpUShortInt: - g_print (" %u", * (guint16 *)(ip + 1)); - break; - case MintOpTwoShorts: - g_print (" %u,%u", * (guint16 *)(ip + 1), * (guint16 *)(ip + 2)); - break; - case MintOpShortAndInt: - g_print (" %u,%u", * (guint16 *)(ip + 1), (guint32)READ32(ip + 2)); - break; - case MintOpShortInt: - g_print (" %d", * (short *)(ip + 1)); - break; - case MintOpClassToken: - case MintOpMethodToken: - case MintOpFieldToken: - token = * (guint16 *)(ip + 1); - g_print (" %u", token); - break; - case MintOpInt: - g_print (" %d", (gint32)READ32 (ip + 1)); - break; - case MintOpLongInt: - g_print (" %lld", (gint64)READ64 (ip + 1)); - break; - case MintOpFloat: { - gint32 tmp = READ32 (ip + 1); - g_print (" %g", * (float *)&tmp); - break; - } - case MintOpDouble: { - gint64 tmp = READ64 (ip + 1); - g_print (" %g", * (double *)&tmp); - break; - } - case MintOpShortBranch: - target = ip + * (short *)(ip + 1) - base; - g_print (" IL_%04x", target); - break; - case MintOpBranch: - target = ip + (gint32)READ32 (ip + 1) - base; - g_print (" IL_%04x", target); - break; - case MintOpSwitch: { - const guint16 *p = ip + 1; - int sval = (gint32)READ32 (p); - int i; - p += 2; - g_print ("("); - for (i = 0; i < sval; ++i) { - int offset; - if (i > 0) - g_print (", "); - offset = (gint32)READ32 (p); - g_print ("IL_%04x", ip - base + 3 + 2 * sval + offset); - p += 2; - } - g_print (")"); - break; - } - default: - g_print("unknown arg type\n"); - } - - return ip + len; -} - diff --git a/mono/interpreter/mintops.def b/mono/interpreter/mintops.def deleted file mode 100644 index 550ba65562..0000000000 --- a/mono/interpreter/mintops.def +++ /dev/null @@ -1,510 +0,0 @@ -/* - * Definitions of VM instructions executed by interp.c - * - * Authors: - * Bernie Solomon (bernard@ugsolutions.com) - * - */ - -/* OPDEF (opsymbol, opstring, oplength, optype) */ - -OPDEF(MINT_NOP, "nop", 1, MintOpNoArgs) -OPDEF(MINT_BREAK, "break", 1, MintOpNoArgs) -OPDEF(MINT_LDNULL, "ldnull", 1, MintOpNoArgs) -OPDEF(MINT_DUP, "dup", 1, MintOpNoArgs) -OPDEF(MINT_DUP_VT, "dup.vt", 3, MintOpInt) -OPDEF(MINT_POP, "pop", 1, MintOpNoArgs) - -OPDEF(MINT_RET, "ret", 1, MintOpNoArgs) -OPDEF(MINT_RET_VOID, "ret.void", 1, MintOpNoArgs) -OPDEF(MINT_RET_VT, "ret.vt", 3, MintOpInt) - -OPDEF(MINT_VTRESULT, "vtresult", 4, MintOpShortAndInt) /*FIX should be unsigned*/ - -OPDEF(MINT_LDC_I4_M1, "ldc.i4.m1", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_0, "ldc.i4.0", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_1, "ldc.i4.1", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_2, "ldc.i4.2", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_3, "ldc.i4.3", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_4, "ldc.i4.4", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_5, "ldc.i4.5", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_6, "ldc.i4.6", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_7, "ldc.i4.7", 1, MintOpNoArgs) -OPDEF(MINT_LDC_I4_8, "ldc.i4.8", 1, MintOpNoArgs) - -OPDEF(MINT_LDC_I4_S, "ldc.i4.s", 2, MintOpShortInt) -OPDEF(MINT_LDC_I4, "ldc.i4", 3, MintOpInt) -OPDEF(MINT_LDC_I8, "ldc.i8", 5, MintOpLongInt) - -OPDEF(MINT_LDC_R4, "ldc.r4", 3, MintOpFloat) -OPDEF(MINT_LDC_R8, "ldc.r8", 5, MintOpDouble) - -OPDEF(MINT_LDARG_I1, "ldarg.i1", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_U1, "ldarg.u1", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_I2, "ldarg.i2", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_U2, "ldarg.u2", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_I4, "ldarg.i4", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_I8, "ldarg.i8", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_R4, "ldarg.r4", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_R8, "ldarg.r8", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_O, "ldarg.o", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_P, "ldarg.p", 2, MintOpUShortInt) -OPDEF(MINT_LDARG_VT, "ldarg.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_LDTHIS, "ldthis", 1, MintOpNoArgs) - -OPDEF(MINT_STARG_I1, "starg.i1", 2, MintOpUShortInt) -OPDEF(MINT_STARG_U1, "starg.u1", 2, MintOpUShortInt) -OPDEF(MINT_STARG_I2, "starg.i2", 2, MintOpUShortInt) -OPDEF(MINT_STARG_U2, "starg.u2", 2, MintOpUShortInt) -OPDEF(MINT_STARG_I4, "starg.i4", 2, MintOpUShortInt) -OPDEF(MINT_STARG_I8, "starg.i8", 2, MintOpUShortInt) -OPDEF(MINT_STARG_R4, "starg.r4", 2, MintOpUShortInt) -OPDEF(MINT_STARG_R8, "starg.r8", 2, MintOpUShortInt) -OPDEF(MINT_STARG_O, "starg.o", 2, MintOpUShortInt) -OPDEF(MINT_STARG_P, "starg.p", 2, MintOpUShortInt) -OPDEF(MINT_STARG_VT, "starg.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_STTHIS, "stthis", 1, MintOpNoArgs) - -OPDEF(MINT_STINARG_I1, "stinarg.i1", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_U1, "stinarg.u1", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_I2, "stinarg.i2", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_U2, "stinarg.u2", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_I4, "stinarg.i4", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_I8, "stinarg.i8", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_R4, "stinarg.r4", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_R8, "stinarg.r8", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_O, "stinarg.o", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_P, "stinarg.p", 2, MintOpUShortInt) -OPDEF(MINT_STINARG_VT, "stinarg.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_LDARGA, "ldarga", 2, MintOpUShortInt) -OPDEF(MINT_LDTHISA, "ldthisa", 1, MintOpNoArgs) - -OPDEF(MINT_LDFLD_I1, "ldfld.i1", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_U1, "ldfld.u1", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_I2, "ldfld.i2", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_U2, "ldfld.u2", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_I4, "ldfld.i4", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_I8, "ldfld.i8", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_R4, "ldfld.r4", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_R8, "ldfld.r8", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_O, "ldfld.o", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_P, "ldfld.p", 2, MintOpUShortInt) -OPDEF(MINT_LDFLD_VT, "ldfld.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_LDRMFLD, "ldrmfld", 2, MintOpFieldToken) -OPDEF(MINT_LDRMFLD_VT, "ldrmfld.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_LDFLDA, "ldflda", 2, MintOpUShortInt) - -OPDEF(MINT_STFLD_I1, "stfld.i1", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_U1, "stfld.u1", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_I2, "stfld.i2", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_U2, "stfld.u2", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_I4, "stfld.i4", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_I8, "stfld.i8", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_R4, "stfld.r4", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_R8, "stfld.r8", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_O, "stfld.o", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_P, "stfld.p", 2, MintOpUShortInt) -OPDEF(MINT_STFLD_VT, "stfld.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_STRMFLD, "strmfld", 2, MintOpFieldToken) -OPDEF(MINT_STRMFLD_VT, "strmfld.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_LDSFLD, "ldsfld", 3, MintOpTwoShorts) -OPDEF(MINT_LDSFLD_I4, "ldsfld.i4", 3, MintOpTwoShorts) -OPDEF(MINT_LDSFLD_O, "ldsfld.o", 3, MintOpTwoShorts) -OPDEF(MINT_LDSFLD_VT, "ldsfld.vt", 4, MintOpShortAndInt) -OPDEF(MINT_STSFLD, "stsfld", 2, MintOpUShortInt) -OPDEF(MINT_STSFLD_VT, "stsfld.vt", 4, MintOpShortAndInt) -OPDEF(MINT_LDSFLDA, "ldsflda", 2, MintOpUShortInt) - -OPDEF(MINT_LDLOC_I1, "ldloc.i1", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_U1, "ldloc.u1", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_I2, "ldloc.i2", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_U2, "ldloc.u2", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_I4, "ldloc.i4", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_I8, "ldloc.i8", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_R4, "ldloc.r4", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_R8, "ldloc.r8", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_O, "ldloc.o", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_P, "ldloc.p", 2, MintOpUShortInt) -OPDEF(MINT_LDLOC_VT, "ldloc.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_STLOC_I1, "stloc.i1", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_U1, "stloc.u1", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_I2, "stloc.i2", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_U2, "stloc.u2", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_I4, "stloc.i4", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_I8, "stloc.i8", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_R4, "stloc.r4", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_R8, "stloc.r8", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_O, "stloc.o", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_P, "stloc.p", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_VT, "stloc.vt", 4, MintOpShortAndInt) - -OPDEF(MINT_STLOC_NP_I4, "stloc.np.i4", 2, MintOpUShortInt) -OPDEF(MINT_STLOC_NP_O, "stloc.np.o", 2, MintOpUShortInt) - -OPDEF(MINT_LDLOCA_S, "ldloca.s", 2, MintOpUShortInt) - -OPDEF(MINT_LDIND_I1, "ldind.i1", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_U1, "ldind.u1", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_I2, "ldind.i2", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_U2, "ldind.u2", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_I4, "ldind.i4", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_U4, "ldind.u4", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_I8, "ldind.i8", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_I, "ldind.i", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_R4, "ldind.r4", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_R8, "ldind.r8", 1, MintOpNoArgs) -OPDEF(MINT_LDIND_REF, "ldind.ref", 1, MintOpNoArgs) -OPDEF(MINT_STIND_I1, "stind.i1", 1, MintOpNoArgs) -OPDEF(MINT_STIND_I2, "stind.i2", 1, MintOpNoArgs) -OPDEF(MINT_STIND_I4, "stind.i4", 1, MintOpNoArgs) -OPDEF(MINT_STIND_I8, "stind.i8", 1, MintOpNoArgs) -OPDEF(MINT_STIND_I, "stind.i", 1, MintOpNoArgs) -OPDEF(MINT_STIND_R4, "stind.r4", 1, MintOpNoArgs) -OPDEF(MINT_STIND_R8, "stind.r8", 1, MintOpNoArgs) -OPDEF(MINT_STIND_REF, "stind.ref", 1, MintOpNoArgs) - -OPDEF(MINT_BR, "br", 3, MintOpBranch) -OPDEF(MINT_LEAVE, "leave", 3, MintOpBranch) -OPDEF(MINT_BR_S, "br.s", 2, MintOpShortBranch) -OPDEF(MINT_LEAVE_S, "leave.s", 2, MintOpShortBranch) - -OPDEF(MINT_THROW, "throw", 1, MintOpNoArgs) -OPDEF(MINT_RETHROW, "rethrow", 1, MintOpNoArgs) -OPDEF(MINT_ENDFINALLY, "endfinally", 1, MintOpNoArgs) - -OPDEF(MINT_BRFALSE_I4, "brfalse.i4", 3, MintOpBranch) -OPDEF(MINT_BRFALSE_I8, "brfalse.i8", 3, MintOpBranch) -OPDEF(MINT_BRFALSE_R8, "brfalse.r8", 3, MintOpBranch) -OPDEF(MINT_BRTRUE_I4, "brtrue.i4", 3, MintOpBranch) -OPDEF(MINT_BRTRUE_I8, "brtrue.i8", 3, MintOpBranch) -OPDEF(MINT_BRTRUE_R8, "brtrue.r8", 3, MintOpBranch) - -OPDEF(MINT_BRFALSE_I4_S, "brfalse.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BRFALSE_I8_S, "brfalse.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BRFALSE_R8_S, "brfalse.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BRTRUE_I4_S, "brtrue.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BRTRUE_I8_S, "brtrue.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BRTRUE_R8_S, "brtrue.r8.s", 2, MintOpShortBranch) - -OPDEF(MINT_BEQ_I4, "beq.i4", 3, MintOpBranch) -OPDEF(MINT_BEQ_I8, "beq.i8", 3, MintOpBranch) -OPDEF(MINT_BEQ_R8, "beq.r8", 3, MintOpBranch) -OPDEF(MINT_BGE_I4, "bge.i4", 3, MintOpBranch) -OPDEF(MINT_BGE_I8, "bge.i8", 3, MintOpBranch) -OPDEF(MINT_BGE_R8, "bge.r8", 3, MintOpBranch) -OPDEF(MINT_BGT_I4, "bgt.i4", 3, MintOpBranch) -OPDEF(MINT_BGT_I8, "bgt.i8", 3, MintOpBranch) -OPDEF(MINT_BGT_R8, "bgt.r8", 3, MintOpBranch) -OPDEF(MINT_BLT_I4, "blt.i4", 3, MintOpBranch) -OPDEF(MINT_BLT_I8, "blt.i8", 3, MintOpBranch) -OPDEF(MINT_BLT_R8, "blt.r8", 3, MintOpBranch) -OPDEF(MINT_BLE_I4, "ble.i4", 3, MintOpBranch) -OPDEF(MINT_BLE_I8, "ble.i8", 3, MintOpBranch) -OPDEF(MINT_BLE_R8, "ble.r8", 3, MintOpBranch) - -OPDEF(MINT_BNE_UN_I4, "bne.un.i4", 3, MintOpBranch) -OPDEF(MINT_BNE_UN_I8, "bne.un.i8", 3, MintOpBranch) -OPDEF(MINT_BNE_UN_R8, "bne.un.r8", 3, MintOpBranch) -OPDEF(MINT_BGE_UN_I4, "bge.un.i4", 3, MintOpBranch) -OPDEF(MINT_BGE_UN_I8, "bge.un.i8", 3, MintOpBranch) -OPDEF(MINT_BGE_UN_R8, "bge.un.r8", 3, MintOpBranch) -OPDEF(MINT_BGT_UN_I4, "bgt.un.i4", 3, MintOpBranch) -OPDEF(MINT_BGT_UN_I8, "bgt.un.i8", 3, MintOpBranch) -OPDEF(MINT_BGT_UN_R8, "bgt.un.r8", 3, MintOpBranch) -OPDEF(MINT_BLE_UN_I4, "ble.un.i4", 3, MintOpBranch) -OPDEF(MINT_BLE_UN_I8, "ble.un.i8", 3, MintOpBranch) -OPDEF(MINT_BLE_UN_R8, "ble.un.r8", 3, MintOpBranch) -OPDEF(MINT_BLT_UN_I4, "blt.un.i4", 3, MintOpBranch) -OPDEF(MINT_BLT_UN_I8, "blt.un.i8", 3, MintOpBranch) -OPDEF(MINT_BLT_UN_R8, "blt.un.r8", 3, MintOpBranch) - -OPDEF(MINT_BEQ_I4_S, "beq.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BEQ_I8_S, "beq.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BEQ_R8_S, "beq.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BGE_I4_S, "bge.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BGE_I8_S, "bge.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BGE_R8_S, "bge.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BGT_I4_S, "bgt.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BGT_I8_S, "bgt.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BGT_R8_S, "bgt.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BLT_I4_S, "blt.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BLT_I8_S, "blt.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BLT_R8_S, "blt.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BLE_I4_S, "ble.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BLE_I8_S, "ble.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BLE_R8_S, "ble.r8.s", 2, MintOpShortBranch) - -OPDEF(MINT_BNE_UN_I4_S, "bne.un.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BNE_UN_I8_S, "bne.un.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BNE_UN_R8_S, "bne.un.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BGE_UN_I4_S, "bge.un.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BGE_UN_I8_S, "bge.un.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BGE_UN_R8_S, "bge.un.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BGT_UN_I4_S, "bgt.un.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BGT_UN_I8_S, "bgt.un.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BGT_UN_R8_S, "bgt.un.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BLE_UN_I4_S, "ble.un.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BLE_UN_I8_S, "ble.un.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BLE_UN_R8_S, "ble.un.r8.s", 2, MintOpShortBranch) -OPDEF(MINT_BLT_UN_I4_S, "blt.un.i4.s", 2, MintOpShortBranch) -OPDEF(MINT_BLT_UN_I8_S, "blt.un.i8.s", 2, MintOpShortBranch) -OPDEF(MINT_BLT_UN_R8_S, "blt.un.r8.s", 2, MintOpShortBranch) - -OPDEF(MINT_SWITCH, "switch", 0, MintOpSwitch) - -OPDEF(MINT_LDSTR, "ldstr", 2, MintOpMethodToken) /* not really */ - -OPDEF(MINT_CALL, "call", 2, MintOpMethodToken) -OPDEF(MINT_VCALL, "vcall", 2, MintOpMethodToken) -OPDEF(MINT_CALLVIRT, "callvirt", 2, MintOpMethodToken) -OPDEF(MINT_VCALLVIRT, "vcallvirt", 2, MintOpMethodToken) -OPDEF(MINT_CALLI, "calli", 2, MintOpMethodToken) -OPDEF(MINT_CALLI_NAT, "calli.nat", 2, MintOpMethodToken) -OPDEF(MINT_JMP, "jmp", 2, MintOpMethodToken) - -OPDEF(MINT_CALLINT, "callint", 1, MintOpNoArgs) -OPDEF(MINT_CALLRUN, "callrun", 1, MintOpNoArgs) - -OPDEF(MINT_NEWOBJ, "newobj", 2, MintOpMethodToken) -OPDEF(MINT_INITOBJ, "initobj", 3, MintOpInt) -OPDEF(MINT_CASTCLASS, "castclass", 2, MintOpClassToken) -OPDEF(MINT_ISINST, "isinst", 2, MintOpClassToken) -OPDEF(MINT_NEWARR, "newarr", 2, MintOpClassToken) -OPDEF(MINT_BOX, "box", 2, MintOpClassToken) -OPDEF(MINT_UNBOX, "unbox", 2, MintOpClassToken) -OPDEF(MINT_LDTOKEN, "ldtoken", 2, MintOpClassToken) /* not really */ -OPDEF(MINT_LDFTN, "ldftn", 2, MintOpMethodToken) -OPDEF(MINT_LDVIRTFTN, "ldvirtftn", 2, MintOpMethodToken) -OPDEF(MINT_LDOBJ, "ldobj", 2, MintOpClassToken) -OPDEF(MINT_STOBJ, "stobj", 2, MintOpClassToken) -OPDEF(MINT_STOBJ_VT, "stobj.vt", 2, MintOpClassToken) -OPDEF(MINT_CPBLK, "cpblk", 1, MintOpNoArgs) -OPDEF(MINT_INITBLK, "initblk", 1, MintOpNoArgs) -OPDEF(MINT_LOCALLOC, "localloc", 1, MintOpNoArgs) -OPDEF(MINT_INITLOCALS, "initlocals", 1, MintOpNoArgs) - -OPDEF(MINT_LDELEM_I, "ldelem.i", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_I1, "ldelem.i1", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_U1, "ldelem.u1", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_I2, "ldelem.i2", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_U2, "ldelem.u2", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_I4, "ldelem.i4", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_U4, "ldelem.u4", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_I8, "ldelem.i8", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_R4, "ldelem.r4", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_R8, "ldelem.r8", 1, MintOpNoArgs) -OPDEF(MINT_LDELEM_REF, "ldelem.ref", 1, MintOpNoArgs) - -OPDEF(MINT_LDELEMA, "ldelema", 2, MintOpClassToken) - -OPDEF(MINT_STELEM_I, "stelem.i", 1, MintOpNoArgs) -OPDEF(MINT_STELEM_I1, "stelem.i1", 1, MintOpNoArgs) -OPDEF(MINT_STELEM_I2, "stelem.i2", 1, MintOpNoArgs) -OPDEF(MINT_STELEM_I4, "stelem.i4", 1, MintOpNoArgs) -OPDEF(MINT_STELEM_I8, "stelem.i8", 1, MintOpNoArgs) -OPDEF(MINT_STELEM_R4, "stelem.r4", 1, MintOpNoArgs) -OPDEF(MINT_STELEM_R8, "stelem.r8", 1, MintOpNoArgs) -OPDEF(MINT_STELEM_REF, "stelem.ref", 1, MintOpNoArgs) - -OPDEF(MINT_LDLEN, "ldlen", 1, MintOpNoArgs) - -OPDEF(MINT_ADD_I4, "add.i4", 1, MintOpNoArgs) -OPDEF(MINT_ADD_I8, "add.i8", 1, MintOpNoArgs) -OPDEF(MINT_ADD_R8, "add.r8", 1, MintOpNoArgs) - -OPDEF(MINT_ADD1_I4, "add1.i4", 1, MintOpNoArgs) - -OPDEF(MINT_SUB_I4, "sub.i4", 1, MintOpNoArgs) -OPDEF(MINT_SUB_I8, "sub.i8", 1, MintOpNoArgs) -OPDEF(MINT_SUB_R8, "sub.r8", 1, MintOpNoArgs) - -OPDEF(MINT_SUB1_I4, "sub1.i4", 1, MintOpNoArgs) - -OPDEF(MINT_MUL_I4, "mul.i4", 1, MintOpNoArgs) -OPDEF(MINT_MUL_I8, "mul.i8", 1, MintOpNoArgs) -OPDEF(MINT_MUL_R8, "mul.r8", 1, MintOpNoArgs) - -OPDEF(MINT_DIV_I4, "div.i4", 1, MintOpNoArgs) -OPDEF(MINT_DIV_I8, "div.i8", 1, MintOpNoArgs) -OPDEF(MINT_DIV_R8, "div.r8", 1, MintOpNoArgs) - -OPDEF(MINT_DIV_UN_I4, "div.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_DIV_UN_I8, "div.un.i8", 1, MintOpNoArgs) - -OPDEF(MINT_ADD_OVF_I4, "add.ovf.i4", 1, MintOpNoArgs) -OPDEF(MINT_ADD_OVF_I8, "add.ovf.i8", 1, MintOpNoArgs) - -OPDEF(MINT_ADD_OVF_UN_I4, "add.ovf.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_ADD_OVF_UN_I8, "add.ovf.un.i8", 1, MintOpNoArgs) - -OPDEF(MINT_MUL_OVF_I4, "mul.ovf.i4", 1, MintOpNoArgs) -OPDEF(MINT_MUL_OVF_I8, "mul.ovf.i8", 1, MintOpNoArgs) - -OPDEF(MINT_MUL_OVF_UN_I4, "mul.ovf.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_MUL_OVF_UN_I8, "mul.ovf.un.i8", 1, MintOpNoArgs) - -OPDEF(MINT_SUB_OVF_I4, "sub.ovf.i4", 1, MintOpNoArgs) -OPDEF(MINT_SUB_OVF_I8, "sub.ovf.i8", 1, MintOpNoArgs) - -OPDEF(MINT_SUB_OVF_UN_I4, "sub.ovf.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_SUB_OVF_UN_I8, "sub.ovf.un.i8", 1, MintOpNoArgs) - -OPDEF(MINT_NEG_I4, "neg.i4", 1, MintOpNoArgs) -OPDEF(MINT_NEG_I8, "neg.i8", 1, MintOpNoArgs) -OPDEF(MINT_NEG_R8, "neg.r8", 1, MintOpNoArgs) - -OPDEF(MINT_NOT_I4, "not.i4", 1, MintOpNoArgs) -OPDEF(MINT_NOT_I8, "not.i8", 1, MintOpNoArgs) - -OPDEF(MINT_AND_I4, "and.i4", 1, MintOpNoArgs) -OPDEF(MINT_AND_I8, "and.i8", 1, MintOpNoArgs) - -OPDEF(MINT_OR_I4, "or.i4", 1, MintOpNoArgs) -OPDEF(MINT_OR_I8, "or.i8", 1, MintOpNoArgs) - -OPDEF(MINT_XOR_I4, "xor.i4", 1, MintOpNoArgs) -OPDEF(MINT_XOR_I8, "xor.i8", 1, MintOpNoArgs) - -OPDEF(MINT_REM_I4, "rem.i4", 1, MintOpNoArgs) -OPDEF(MINT_REM_I8, "rem.i8", 1, MintOpNoArgs) -OPDEF(MINT_REM_R8, "rem.r8", 1, MintOpNoArgs) - -OPDEF(MINT_REM_UN_I4, "rem.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_REM_UN_I8, "rem.un.i8", 1, MintOpNoArgs) - -OPDEF(MINT_SHR_UN_I4, "shr.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_SHR_UN_I8, "shr.un.i8", 1, MintOpNoArgs) -OPDEF(MINT_SHL_I4, "shl.i4", 1, MintOpNoArgs) -OPDEF(MINT_SHL_I8, "shl.i8", 1, MintOpNoArgs) -OPDEF(MINT_SHR_I4, "shr.i4", 1, MintOpNoArgs) -OPDEF(MINT_SHR_I8, "shr.i8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_R_UN_I4, "conv.r.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_R_UN_I8, "conv.r.un.i8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_I1_I4, "conv.i1.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_I1_I8, "conv.i1.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_I1_R8, "conv.i1.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_U1_I4, "conv.u1.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_U1_I8, "conv.u1.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_U1_R8, "conv.u1.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_I2_I4, "conv.i2.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_I2_I8, "conv.i2.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_I2_R8, "conv.i2.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_U2_I4, "conv.u2.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_U2_I8, "conv.u2.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_U2_R8, "conv.u2.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_I4_I8, "conv.i4.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_I4_R8, "conv.i4.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_U4_I8, "conv.u4.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_U4_R8, "conv.u4.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_I8_I4, "conv.i8.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_I8_U4, "conv.i8.u4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_I8_R8, "conv.i8.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_R4_I4, "conv.r4.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_R4_I8, "conv.r4.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_R4_R8, "conv.r4.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_R8_I4, "conv.r8.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_R8_I8, "conv.r8.i8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_I4_I8_SP, "conv.i4.i8.sp", 1, MintOpNoArgs) /* special for narrowing sp[-2] on 64 bits */ -OPDEF(MINT_CONV_I8_I4_SP, "conv.i8.i4.sp", 1, MintOpNoArgs) /* special for widening sp[-2] on 64 bits */ - -OPDEF(MINT_CONV_U8_I4, "conv.u8.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_U8_R8, "conv.u8.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_I1_I4, "conv.ovf.i1.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_I1_I8, "conv.ovf.i1.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_I1_R8, "conv.ovf.i1.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_U1_I4, "conv.ovf.u1.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_U1_I8, "conv.ovf.u1.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_U1_R8, "conv.ovf.u1.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_I2_I4, "conv.ovf.i2.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_I2_I8, "conv.ovf.i2.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_I2_R8, "conv.ovf.i2.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_U2_I4, "conv.ovf.u2.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_U2_I8, "conv.ovf.u2.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_U2_R8, "conv.ovf.u2.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_I4_U4, "conv.ovf.i4.u4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_I4_I8, "conv.ovf.i4.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_I4_R8, "conv.ovf.i4.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_I4_UN_I8, "conv.ovf.i4.un.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_I4_UN_R8, "conv.ovf.i4.un.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_U4_I4, "conv.ovf.u4.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_U4_I8, "conv.ovf.u4.i8", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_U4_R8, "conv.ovf.u4.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_I8_R8, "conv.ovf.i8.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_I8_UN_R8, "conv.ovf.i8.un.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CONV_OVF_U8_I4, "conv.ovf.u8.i4", 1, MintOpNoArgs) -OPDEF(MINT_CONV_OVF_U8_R8, "conv.ovf.u8.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CEQ_I4, "ceq.i4", 1, MintOpNoArgs) -OPDEF(MINT_CEQ_I8, "ceq.i8", 1, MintOpNoArgs) -OPDEF(MINT_CEQ_R8, "ceq.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CEQ0_I4, "ceq0.i4", 1, MintOpNoArgs) - -OPDEF(MINT_CGT_I4, "cgt.i4", 1, MintOpNoArgs) -OPDEF(MINT_CGT_I8, "cgt.i8", 1, MintOpNoArgs) -OPDEF(MINT_CGT_R8, "cgt.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CGT_UN_I4, "cgt.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_CGT_UN_I8, "cgt.un.i8", 1, MintOpNoArgs) -OPDEF(MINT_CGT_UN_R8, "cgt.un.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CLT_I4, "clt.i4", 1, MintOpNoArgs) -OPDEF(MINT_CLT_I8, "clt.i8", 1, MintOpNoArgs) -OPDEF(MINT_CLT_R8, "clt.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CLT_UN_I4, "clt.un.i4", 1, MintOpNoArgs) -OPDEF(MINT_CLT_UN_I8, "clt.un.i8", 1, MintOpNoArgs) -OPDEF(MINT_CLT_UN_R8, "clt.un.r8", 1, MintOpNoArgs) - -OPDEF(MINT_CKFINITE, "ckfinite", 1, MintOpNoArgs) - -OPDEF(MINT_CKNULL, "cknull", 1, MintOpNoArgs) - -OPDEF(MINT_GETCHR, "getchr", 1, MintOpNoArgs) -OPDEF(MINT_STRLEN, "strlen", 1, MintOpNoArgs) -OPDEF(MINT_ARRAY_RANK, "array_rank", 1, MintOpNoArgs) - -OPDEF(MINT_ICALL_V_V, "mono_icall_v_v", 2, MintOpClassToken) /* not really */ -OPDEF(MINT_ICALL_P_V, "mono_icall_p_v", 2, MintOpClassToken) -OPDEF(MINT_ICALL_P_P, "mono_icall_p_p", 2, MintOpClassToken) -OPDEF(MINT_ICALL_PP_V, "mono_icall_pp_v", 2, MintOpClassToken) -OPDEF(MINT_ICALL_PI_V, "mono_icall_pi_v", 2, MintOpClassToken) -OPDEF(MINT_ICALL_PP_P, "mono_icall_pp_p", 2, MintOpClassToken) -OPDEF(MINT_ICALL_PI_P, "mono_icall_pi_p", 2, MintOpClassToken) -OPDEF(MINT_ICALL_PPP_V, "mono_icall_ppp_v", 2, MintOpClassToken) -OPDEF(MINT_ICALL_PPI_V, "mono_icall_ppi_v", 2, MintOpClassToken) -OPDEF(MINT_MONO_LDPTR, "mono_ldptr", 2, MintOpClassToken) -OPDEF(MINT_MONO_NEWOBJ, "mono_newobj", 2, MintOpClassToken) -OPDEF(MINT_MONO_RETOBJ, "mono_retobj", 1, MintOpNoArgs) -OPDEF(MINT_MONO_FREE, "mono_free", 1, MintOpNoArgs) - - diff --git a/mono/interpreter/mintops.h b/mono/interpreter/mintops.h deleted file mode 100644 index e787526e2f..0000000000 --- a/mono/interpreter/mintops.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef __INTERPRETER_MINTOPS_H -#define __INTERPRETER_MINTOPS_H - -#include - -typedef enum -{ - MintOpNoArgs, - MintOpShortInt, - MintOpUShortInt, - MintOpInt, - MintOpLongInt, - MintOpFloat, - MintOpDouble, - MintOpBranch, - MintOpShortBranch, - MintOpSwitch, - MintOpMethodToken, - MintOpFieldToken, - MintOpClassToken, - MintOpTwoShorts, - MintOpShortAndInt -} MintOpArgType; - -#define OPDEF(a,b,c,d) \ - a, -enum { -#include "mintops.def" - MINT_LASTOP -}; -#undef OPDEF - -#if NO_UNALIGNED_ACCESS -# if G_BYTE_ORDER == G_LITTLE_ENDIAN -#define READ32(x) (((guint16 *)(x)) [0] | ((guint16 *)(x)) [1] << 16) -#define READ64(x) ((guint64)((guint16 *)(x)) [0] | \ - (guint64)((guint16 *)(x)) [1] << 16 | \ - (guint64)((guint16 *)(x)) [2] << 32 | \ - (guint64)((guint16 *)(x)) [3] << 48) -# else -#define READ32(x) (((guint16 *)(x)) [0] << 16 | ((guint16 *)(x)) [1]) -#define READ64(x) ((guint64)((guint16 *)(x)) [0] << 48 | \ - (guint64)((guint16 *)(x)) [1] << 32 | \ - (guint64)((guint16 *)(x)) [2] << 16 | \ - (guint64)((guint16 *)(x)) [3]) -# endif -#else /* unaligned access OK */ -#define READ32(x) (*(guint32 *)(x)) -#define READ64(x) (*(guint64 *)(x)) -#endif - -extern const char *mono_interp_opname[]; -extern unsigned char mono_interp_oplen[]; -extern MintOpArgType mono_interp_opargtype[]; -extern const guint16 *mono_interp_dis_mintop(const unsigned short *base, const guint16 *ip); - -#endif - diff --git a/mono/interpreter/transform.c b/mono/interpreter/transform.c deleted file mode 100644 index 2bd3f25818..0000000000 --- a/mono/interpreter/transform.c +++ /dev/null @@ -1,3049 +0,0 @@ -/* - * transform CIL into different opcodes for more - * efficient interpretation - * - * Written by Bernie Solomon (bernard@ugsolutions.com) - * Copyright (c) 2004. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define OPDEF(a,b,c,d,e,f,g,h,i,j) \ - a = i, - -enum { -#include "mono/cil/opcode.def" - CEE_LASTOP -}; -#undef OPDEF - -#include "mintops.h" -#include "interp.h" - -#define DEBUG 0 - -typedef struct -{ - MonoClass *klass; - unsigned char type; - unsigned char flags; -} StackInfo; - -typedef struct -{ - MonoMethod *method; - MonoMethodHeader *header; - RuntimeMethod *rtm; - const unsigned char *il_code; - const unsigned char *ip; - const unsigned char *last_ip; - const unsigned char *in_start; - int code_size; - int *in_offsets; - int *forward_refs; - StackInfo **stack_state; - int *stack_height; - int *vt_stack_size; - unsigned char *is_bb_start; - unsigned short *new_code; - unsigned short *new_code_end; - unsigned short *new_ip; - unsigned short *last_new_ip; - unsigned int max_code_size; - StackInfo *stack; - StackInfo *sp; - unsigned int max_stack_height; - unsigned int vt_sp; - unsigned int max_vt_sp; - int n_data_items; - int max_data_items; - void **data_items; - GHashTable *data_hash; -} TransformData; - -#define MINT_TYPE_I1 0 -#define MINT_TYPE_U1 1 -#define MINT_TYPE_I2 2 -#define MINT_TYPE_U2 3 -#define MINT_TYPE_I4 4 -#define MINT_TYPE_I8 5 -#define MINT_TYPE_R4 6 -#define MINT_TYPE_R8 7 -#define MINT_TYPE_O 8 -#define MINT_TYPE_P 9 -#define MINT_TYPE_VT 10 - -#define STACK_TYPE_I4 0 -#define STACK_TYPE_I8 1 -#define STACK_TYPE_R8 2 -#define STACK_TYPE_O 3 -#define STACK_TYPE_VT 4 -#define STACK_TYPE_MP 5 -#define STACK_TYPE_F 6 - -static const char *stack_type_string [] = { "I4", "I8", "R8", "O ", "VT", "MP", "F " }; - -#if SIZEOF_VOID_P == 8 -#define STACK_TYPE_I STACK_TYPE_I8 -#else -#define STACK_TYPE_I STACK_TYPE_I4 -#endif - -static int stack_type [] = { - STACK_TYPE_I4, /*I1*/ - STACK_TYPE_I4, /*U1*/ - STACK_TYPE_I4, /*I2*/ - STACK_TYPE_I4, /*U2*/ - STACK_TYPE_I4, /*I4*/ - STACK_TYPE_I8, /*I8*/ - STACK_TYPE_R8, /*R4*/ - STACK_TYPE_R8, /*R8*/ - STACK_TYPE_O, /*O*/ - STACK_TYPE_MP, /*P*/ - STACK_TYPE_VT -}; - -static void -grow_code (TransformData *td) -{ - unsigned int old_ip_offset = td->new_ip - td->new_code; - unsigned int old_last_ip_offset = td->last_new_ip - td->new_code; - g_assert (old_ip_offset <= td->max_code_size); - td->new_code = g_realloc (td->new_code, (td->max_code_size *= 2) * sizeof (td->new_code [0])); - td->new_code_end = td->new_code + td->max_code_size; - td->new_ip = td->new_code + old_ip_offset; - td->last_new_ip = td->new_code + old_last_ip_offset; -} - -#define ENSURE_CODE(td, n) \ - do { \ - if ((td)->new_ip + (n) > (td)->new_code_end) \ - grow_code (td); \ - } while (0) - -#define ADD_CODE(td, n) \ - do { \ - if ((td)->new_ip == (td)->new_code_end) \ - grow_code (td); \ - *(td)->new_ip++ = (n); \ - } while (0) - -#define CHECK_STACK(td, n) \ - do { \ - int stack_size = (td)->sp - (td)->stack; \ - if (stack_size < (n)) \ - g_warning ("%s.%s: not enough values (%d < %d) on stack at %04x", \ - (td)->method->klass->name, (td)->method->name, \ - stack_size, n, (td)->ip - (td)->il_code); \ - } while (0) - -#define ENSURE_I4(td, sp_off) \ - do { \ - if ((td)->sp [-sp_off].type == STACK_TYPE_I8) \ - ADD_CODE(td, sp_off == 1 ? MINT_CONV_I4_I8 : MINT_CONV_I4_I8_SP); \ - } while (0) - -static void -handle_branch(TransformData *td, int short_op, int long_op, int offset) -{ - int shorten_branch = 0; - int target = td->ip + offset - td->il_code; - if (target < 0 || target >= td->code_size) - g_assert_not_reached (); - if (offset > 0 && td->stack_height [target] < 0) { - td->stack_height [target] = td->sp - td->stack; - if (td->stack_height [target] > 0) - td->stack_state [target] = g_memdup (td->stack, td->stack_height [target] * sizeof (td->stack [0])); - td->vt_stack_size [target] = td->vt_sp; - } - if (offset < 0) { - offset = td->in_offsets [target] - (td->new_ip - td->new_code); - if (offset >= -32768) { - shorten_branch = 1; - } - } else { - int prev = td->forward_refs [target]; - td->forward_refs [td->ip - td->il_code] = prev; - td->forward_refs [target] = td->ip - td->il_code; - offset = 0; - if (td->header->code_size <= 25000) /* FIX to be precise somehow? */ - shorten_branch = 1; - } - if (shorten_branch) { - ADD_CODE(td, short_op); - ADD_CODE(td, offset); - } else { - ADD_CODE(td, long_op); - ADD_CODE(td, * (unsigned short *)(&offset)); - ADD_CODE(td, * ((unsigned short *)&offset + 1)); - } -} - -static void -one_arg_branch(TransformData *td, int mint_op, int offset) -{ - int type = td->sp [-1].type == STACK_TYPE_O || td->sp [-1].type == STACK_TYPE_MP ? STACK_TYPE_I : td->sp [-1].type; - int long_op = mint_op + type - STACK_TYPE_I4; - int short_op = long_op + MINT_BRFALSE_I4_S - MINT_BRFALSE_I4; - CHECK_STACK(td, 1); - --td->sp; - handle_branch (td, short_op, long_op, offset); -} - -static void -two_arg_branch(TransformData *td, int mint_op, int offset) -{ - int type1 = td->sp [-1].type == STACK_TYPE_O || td->sp [-1].type == STACK_TYPE_MP ? STACK_TYPE_I : td->sp [-1].type; - int type2 = td->sp [-2].type == STACK_TYPE_O || td->sp [-2].type == STACK_TYPE_MP ? STACK_TYPE_I : td->sp [-2].type; - int long_op = mint_op + type1 - STACK_TYPE_I4; - int short_op = long_op + MINT_BEQ_I4_S - MINT_BEQ_I4; - CHECK_STACK(td, 2); - if (type1 == STACK_TYPE_I4 && type2 == STACK_TYPE_I8) { - ADD_CODE(td, MINT_CONV_I8_I4); - td->in_offsets [td->ip - td->il_code]++; - } else if (type1 == STACK_TYPE_I8 && type2 == STACK_TYPE_I4) { - ADD_CODE(td, MINT_CONV_I8_I4_SP); - td->in_offsets [td->ip - td->il_code]++; - } else if (type1 != type2) { - g_warning("%s.%s: branch type mismatch %d %d", - td->method->klass->name, td->method->name, - td->sp [-1].type, td->sp [-2].type); - } - td->sp -= 2; - handle_branch (td, short_op, long_op, offset); -} - -static void -unary_arith_op(TransformData *td, int mint_op) -{ - int op = mint_op + td->sp [-1].type - STACK_TYPE_I4; - CHECK_STACK(td, 1); - ADD_CODE(td, op); -} - -static void -binary_arith_op(TransformData *td, int mint_op) -{ - int type1 = td->sp [-2].type; - int type2 = td->sp [-1].type; - int op; -#if SIZEOF_VOID_P == 8 - if ((type1 == STACK_TYPE_MP || type1 == STACK_TYPE_I8) && type2 == STACK_TYPE_I4) { - ADD_CODE(td, MINT_CONV_I8_I4); - type2 = STACK_TYPE_I8; - } - if (type1 == STACK_TYPE_I4 && (type2 == STACK_TYPE_MP || type2 == STACK_TYPE_I8)) { - ADD_CODE(td, MINT_CONV_I8_I4_SP); - type1 = STACK_TYPE_I8; - td->sp [-2].type = STACK_TYPE_I8; - } -#endif - if (type1 == STACK_TYPE_MP) - type1 = STACK_TYPE_I; - if (type2 == STACK_TYPE_MP) - type2 = STACK_TYPE_I; - if (type1 != type2) { - g_warning("%s.%s: %04x arith type mismatch %s %d %d", - td->method->klass->name, td->method->name, - td->ip - td->il_code, mono_interp_opname[mint_op], type1, type2); - } - op = mint_op + type1 - STACK_TYPE_I4; - CHECK_STACK(td, 2); - ADD_CODE(td, op); - --td->sp; -} - -static void -binary_int_op(TransformData *td, int mint_op) -{ - int op = mint_op + td->sp [-1].type - STACK_TYPE_I4; - CHECK_STACK(td, 2); - if (td->sp [-1].type != td->sp [-2].type) - g_warning("%s.%s: int type mismatch", td->method->klass->name, td->method->name); - ADD_CODE(td, op); - --td->sp; -} - -static void -shift_op(TransformData *td, int mint_op) -{ - int op = mint_op + td->sp [-2].type - STACK_TYPE_I4; - CHECK_STACK(td, 2); - if (td->sp [-1].type != STACK_TYPE_I4) { - g_warning("%s.%s: shift type mismatch %d", - td->method->klass->name, td->method->name, - td->sp [-2].type); - } - ADD_CODE(td, op); - --td->sp; -} - -static int -mint_type(MonoType *type) -{ - if (type->byref) - return MINT_TYPE_P; -enum_type: - switch (type->type) { - case MONO_TYPE_I1: - return MINT_TYPE_I1; - case MONO_TYPE_U1: - case MONO_TYPE_BOOLEAN: - return MINT_TYPE_U1; - case MONO_TYPE_I2: - return MINT_TYPE_I2; - case MONO_TYPE_U2: - case MONO_TYPE_CHAR: - return MINT_TYPE_U2; - case MONO_TYPE_I4: - case MONO_TYPE_U4: - return MINT_TYPE_I4; - case MONO_TYPE_I: - case MONO_TYPE_U: -#if SIZEOF_VOID_P == 4 - return MINT_TYPE_I4; -#else - return MINT_TYPE_I8; -#endif - case MONO_TYPE_PTR: - return MINT_TYPE_P; - case MONO_TYPE_R4: - return MINT_TYPE_R4; - case MONO_TYPE_I8: - case MONO_TYPE_U8: - return MINT_TYPE_I8; - case MONO_TYPE_R8: - return MINT_TYPE_R8; - case MONO_TYPE_STRING: - case MONO_TYPE_SZARRAY: - case MONO_TYPE_CLASS: - case MONO_TYPE_OBJECT: - case MONO_TYPE_ARRAY: - return MINT_TYPE_O; - case MONO_TYPE_VALUETYPE: - if (type->data.klass->enumtype) { - type = type->data.klass->enum_basetype; - goto enum_type; - } else - return MINT_TYPE_VT; - default: - g_warning ("got type 0x%02x", type->type); - g_assert_not_reached (); - } - return -1; -} - -static int -can_store (int stack_type, int var_type) -{ - if (stack_type == STACK_TYPE_O || stack_type == STACK_TYPE_MP) - stack_type = STACK_TYPE_I; - if (var_type == STACK_TYPE_O || var_type == STACK_TYPE_MP) - var_type = STACK_TYPE_I; - return stack_type == var_type; -} - -#define SET_SIMPLE_TYPE(s, ty) \ - do { \ - (s)->type = (ty); \ - (s)->flags = 0; \ - (s)->klass = NULL; \ - } while (0) - -#define SET_TYPE(s, ty, k) \ - do { \ - (s)->type = (ty); \ - (s)->flags = 0; \ - (s)->klass = k; \ - } while (0) - -#define PUSH_SIMPLE_TYPE(td, ty) \ - do { \ - int sp_height; \ - (td)->sp++; \ - sp_height = (td)->sp - (td)->stack; \ - if (sp_height > (td)->max_stack_height) \ - (td)->max_stack_height = sp_height; \ - SET_SIMPLE_TYPE((td)->sp - 1, ty); \ - } while (0) - -#define PUSH_TYPE(td, ty, k) \ - do { \ - int sp_height; \ - (td)->sp++; \ - sp_height = (td)->sp - (td)->stack; \ - if (sp_height > (td)->max_stack_height) \ - (td)->max_stack_height = sp_height; \ - SET_TYPE((td)->sp - 1, ty, k); \ - } while (0) - -#define PUSH_VT(td, size) \ - do { \ - (td)->vt_sp += ((size) + 7) & ~7; \ - if ((td)->vt_sp > (td)->max_vt_sp) \ - (td)->max_vt_sp = (td)->vt_sp; \ - } while (0) - -#define POP_VT(td, size) \ - do { \ - (td)->vt_sp -= ((size) + 7) & ~7; \ - } while (0) - -#if NO_UNALIGNED_ACCESS -#define WRITE32(td, v) \ - do { \ - ENSURE_CODE(td, 2); \ - * (guint16 *)((td)->new_ip) = * (guint16 *)(v); \ - * ((guint16 *)((td)->new_ip) + 1) = * ((guint16 *)(v) + 1); \ - (td)->new_ip += 2; \ - } while (0) - -#define WRITE64(td, v) \ - do { \ - ENSURE_CODE(td, 4); \ - * (guint16 *)((td)->new_ip) = * (guint16 *)(v); \ - * ((guint16 *)((td)->new_ip) + 1) = * ((guint16 *)(v) + 1); \ - * ((guint16 *)((td)->new_ip) + 2) = * ((guint16 *)(v) + 2); \ - * ((guint16 *)((td)->new_ip) + 3) = * ((guint16 *)(v) + 3); \ - (td)->new_ip += 4; \ - } while (0) -#else -#define WRITE32(td, v) \ - do { \ - ENSURE_CODE(td, 2); \ - * (guint32 *)((td)->new_ip) = * (guint32 *)(v); \ - (td)->new_ip += 2; \ - } while (0) - -#define WRITE64(td, v) \ - do { \ - ENSURE_CODE(td, 4); \ - * (guint64 *)((td)->new_ip) = * (guint64 *)(v); \ - (td)->new_ip += 4; \ - } while (0) - -#endif - -static void -load_arg(TransformData *td, int n) -{ - int mt; - MonoClass *klass = NULL; - if (n == 0 && mono_method_signature (td->method)->hasthis) { - if (td->method->klass->valuetype) - mt = MINT_TYPE_P; - else { - mt = MINT_TYPE_O; - klass = td->method->klass; - } - ADD_CODE(td, MINT_LDTHIS); - } else { - MonoType *type; - n -= mono_method_signature (td->method)->hasthis; - type = mono_method_signature (td->method)->params [n]; - mt = mint_type (type); - if (mt == MINT_TYPE_VT) { - gint32 size; - if (mono_method_signature (td->method)->pinvoke) - size = mono_class_native_size (type->data.klass, NULL); - else - size = mono_class_value_size (type->data.klass, NULL); - PUSH_VT(td, size); - ADD_CODE(td, MINT_LDARG_VT); - ADD_CODE(td, td->rtm->arg_offsets [n]); /* FIX for large offset */ - WRITE32(td, &size); - klass = type->data.klass; - } else { - ADD_CODE(td, MINT_LDARG_I1 + (mt - MINT_TYPE_I1)); - ADD_CODE(td, td->rtm->arg_offsets [n]); /* FIX for large offset */ - if (mt == MINT_TYPE_O) - klass = mono_class_from_mono_type (type); - } - } - PUSH_TYPE(td, stack_type[mt], klass); -} - -static void -store_arg(TransformData *td, int n) -{ - int mt; - CHECK_STACK (td, 1); - if (n == 0 && mono_method_signature (td->method)->hasthis) - ADD_CODE(td, MINT_STTHIS); - else { - MonoType *type; - n -= mono_method_signature (td->method)->hasthis; - type = mono_method_signature (td->method)->params [n]; - mt = mint_type (type); - if (mt == MINT_TYPE_VT) { - gint32 size; - if (mono_method_signature (td->method)->pinvoke) - size = mono_class_native_size (type->data.klass, NULL); - else - size = mono_class_value_size (type->data.klass, NULL); - ADD_CODE(td, MINT_STARG_VT); - ADD_CODE(td, n); - WRITE32(td, &size); - if (td->sp [-1].type == STACK_TYPE_VT) - POP_VT(td, size); - } else { - ADD_CODE(td, MINT_STARG_I1 + (mt - MINT_TYPE_I1)); - ADD_CODE(td, td->rtm->arg_offsets [n]); - } - } - --td->sp; -} - -static void -store_inarg(TransformData *td, int n) -{ - MonoType *type = mono_method_signature (td->method)->params [n]; - int mt = mint_type (type); - if (mt == MINT_TYPE_VT) { - gint32 size; - if (mono_method_signature (td->method)->pinvoke) - size = mono_class_native_size (type->data.klass, NULL); - else - size = mono_class_value_size (type->data.klass, NULL); - ADD_CODE(td, MINT_STINARG_VT); - ADD_CODE(td, n); - WRITE32(td, &size); - } else { - ADD_CODE(td, MINT_STINARG_I1 + (mt - MINT_TYPE_I1)); - ADD_CODE(td, n); - } -} - -static void -load_local(TransformData *td, int n) -{ - MonoType *type = td->header->locals [n]; - int mt = mint_type (type); - int offset = td->rtm->local_offsets [n]; - MonoClass *klass = NULL; - if (mt == MINT_TYPE_VT) { - gint32 size = mono_class_value_size (type->data.klass, NULL); - PUSH_VT(td, size); - ADD_CODE(td, MINT_LDLOC_VT); - ADD_CODE(td, offset); /*FIX for large offset */ - WRITE32(td, &size); - klass = type->data.klass; - } else { - if (mt == MINT_TYPE_I4 && !td->is_bb_start [td->in_start - td->il_code] && td->last_new_ip != NULL && - td->last_new_ip [0] == MINT_STLOC_I4 && td->last_new_ip [1] == offset) { - td->last_new_ip [0] = MINT_STLOC_NP_I4; - } else if (mt == MINT_TYPE_O && !td->is_bb_start [td->in_start - td->il_code] && td->last_new_ip != NULL && - td->last_new_ip [0] == MINT_STLOC_O && td->last_new_ip [1] == offset) { - td->last_new_ip [0] = MINT_STLOC_NP_O; - } else { - ADD_CODE(td, MINT_LDLOC_I1 + (mt - MINT_TYPE_I1)); - ADD_CODE(td, offset); /*FIX for large offset */ - } - if (mt == MINT_TYPE_O) - klass = mono_class_from_mono_type (type); - } - PUSH_TYPE(td, stack_type[mt], klass); -} - -static void -store_local(TransformData *td, int n) -{ - MonoType *type = td->header->locals [n]; - int mt = mint_type (type); - int offset = td->rtm->local_offsets [n]; - CHECK_STACK (td, 1); -#if SIZEOF_VOID_P == 8 - if (td->sp [-1].type == STACK_TYPE_I4 && stack_type [mt] == STACK_TYPE_I8) { - ADD_CODE(td, MINT_CONV_I8_I4); - td->sp [-1].type = STACK_TYPE_I8; - } -#endif - if (!can_store(td->sp [-1].type, stack_type [mt])) { - g_warning("%s.%s: Store local stack type mismatch %d %d", - td->method->klass->name, td->method->name, - stack_type [mt], td->sp [-1].type); - } - if (mt == MINT_TYPE_VT) { - gint32 size = mono_class_value_size (type->data.klass, NULL); - ADD_CODE(td, MINT_STLOC_VT); - ADD_CODE(td, offset); /*FIX for large offset */ - WRITE32(td, &size); - if (td->sp [-1].type == STACK_TYPE_VT) - POP_VT(td, size); - } else { - ADD_CODE(td, MINT_STLOC_I1 + (mt - MINT_TYPE_I1)); - ADD_CODE(td, offset); /*FIX for large offset */ - } - --td->sp; -} - -#define SIMPLE_OP(td, op) \ - do { \ - ADD_CODE(&td, op); \ - ++td.ip; \ - } while (0) - -static guint16 -get_data_item_index (TransformData *td, void *ptr) -{ - gpointer p = g_hash_table_lookup (td->data_hash, ptr); - guint index; - if (p != NULL) - return GPOINTER_TO_UINT (p) - 1; - if (td->max_data_items == td->n_data_items) { - td->max_data_items = td->n_data_items == 0 ? 16 : 2 * td->max_data_items; - td->data_items = g_realloc (td->data_items, td->max_data_items * sizeof(td->data_items [0])); - } - index = td->n_data_items; - td->data_items [index] = ptr; - ++td->n_data_items; - g_hash_table_insert (td->data_hash, ptr, GUINT_TO_POINTER (index + 1)); - return index; -} - -static void -generate(MonoMethod *method, RuntimeMethod *rtm, unsigned char *is_bb_start) -{ - MonoMethodHeader *header = mono_method_get_header (method); - MonoMethodSignature *signature = mono_method_signature (method); - MonoImage *image = method->klass->image; - MonoDomain *domain = mono_domain_get (); - MonoGenericContext *generic_context = NULL; - int offset, mt; - int i; - int i32; - MonoClass *klass; - MonoClassField *field; - const unsigned char *end; - int new_in_start_offset; - int body_start_offset; - int target; - guint32 token; - TransformData td; - int generating_code = 1; - - if (mono_method_signature (method)->is_inflated) - generic_context = ((MonoMethodInflated *) method)->context; - - memset(&td, 0, sizeof(td)); - td.method = method; - td.rtm = rtm; - td.is_bb_start = is_bb_start; - td.il_code = header->code; - td.code_size = header->code_size; - td.header = header; - td.max_code_size = td.code_size; - td.new_code = (unsigned short *)g_malloc(td.max_code_size * sizeof(gushort)); - td.new_code_end = td.new_code + td.max_code_size; - td.in_offsets = g_malloc0(header->code_size * sizeof(int)); - td.forward_refs = g_malloc(header->code_size * sizeof(int)); - td.stack_state = g_malloc0(header->code_size * sizeof(StackInfo *)); - td.stack_height = g_malloc(header->code_size * sizeof(int)); - td.vt_stack_size = g_malloc(header->code_size * sizeof(int)); - td.n_data_items = 0; - td.max_data_items = 0; - td.data_items = NULL; - td.data_hash = g_hash_table_new (NULL, NULL); - rtm->data_items = td.data_items; - for (i = 0; i < header->code_size; i++) { - td.forward_refs [i] = -1; - td.stack_height [i] = -1; - } - td.new_ip = td.new_code; - td.last_new_ip = NULL; - - td.stack = g_malloc0(header->max_stack * sizeof(td.stack[0])); - td.sp = td.stack; - td.max_stack_height = 0; - - for (i = 0; i < header->num_clauses; i++) { - MonoExceptionClause *c = header->clauses + i; - td.stack_height [c->handler_offset] = 0; - td.vt_stack_size [c->handler_offset] = 0; - td.is_bb_start [c->handler_offset] = 1; - if (c->flags == MONO_EXCEPTION_CLAUSE_NONE) { - td.stack_height [c->handler_offset] = 1; - td.stack_state [c->handler_offset] = g_malloc0(sizeof(StackInfo)); - td.stack_state [c->handler_offset][0].type = STACK_TYPE_O; - td.stack_state [c->handler_offset][0].klass = NULL; /*FIX*/ - } - } - - td.ip = header->code; - end = td.ip + header->code_size; - - if (mono_interp_traceopt) { - char *tmp = mono_disasm_code (NULL, method, td.ip, end); - char *name = mono_method_full_name (method, TRUE); - g_print ("Method %s, original code:\n", name); - g_print ("%s\n", tmp); - g_free (tmp); - g_free (name); - } - - for (i = 0; i < signature->param_count; i++) - store_inarg(&td, i); - - body_start_offset = td.new_ip - td.new_code; - - for (i = 0; i < header->num_locals; i++) { - int mt = mint_type(header->locals [i]); - if (mt == MINT_TYPE_VT || mt == MINT_TYPE_O) { - ADD_CODE(&td, MINT_INITLOCALS); - break; - } - } - - while (td.ip < end) { - int in_offset; - - g_assert (td.sp >= td.stack); - g_assert (td.vt_sp < 0x10000000); - in_offset = td.ip - header->code; - td.in_offsets [in_offset] = td.new_ip - td.new_code; - new_in_start_offset = td.new_ip - td.new_code; - td.in_start = td.ip; - while (td.forward_refs [in_offset] >= 0) { - int j = td.forward_refs [in_offset]; - int slot; - td.forward_refs [in_offset] = td.forward_refs [j]; - if (td.in_offsets [j] < 0) { - int old_switch_offset = -td.in_offsets [j]; - int new_switch_offset = td.in_offsets [old_switch_offset]; - int switch_case = (j - old_switch_offset - 5) / 4; - int n_cases = read32 (header->code + old_switch_offset + 1); - offset = (td.new_ip - td.new_code) - (new_switch_offset + 2 * n_cases + 3); - slot = new_switch_offset + 3 + 2 * switch_case; - td.new_code [slot] = * (unsigned short *)(&offset); - td.new_code [slot + 1] = * ((unsigned short *)&offset + 1); - } else { - int op = td.new_code [td.in_offsets [j]]; - if (mono_interp_opargtype [op] == MintOpShortBranch) { - offset = (td.new_ip - td.new_code) - td.in_offsets [j]; - g_assert (offset <= 32767); - slot = td.in_offsets [j] + 1; - td.new_code [slot] = offset; - } else { - offset = (td.new_ip - td.new_code) - td.in_offsets [j]; - slot = td.in_offsets [j] + 1; - td.new_code [slot] = * (unsigned short *)(&offset); - td.new_code [slot + 1] = * ((unsigned short *)&offset + 1); - } - } - } - if (td.stack_height [in_offset] >= 0) { - g_assert (is_bb_start [in_offset]); - if (td.stack_height [in_offset] > 0) - memcpy (td.stack, td.stack_state [in_offset], td.stack_height [in_offset] * sizeof(td.stack [0])); - td.sp = td.stack + td.stack_height [in_offset]; - td.vt_sp = td.vt_stack_size [in_offset]; - } - if (is_bb_start [in_offset]) { - generating_code = 1; - } - if (!generating_code) { - while (td.ip < end && !is_bb_start [td.ip - td.il_code]) - ++td.ip; - continue; - } - if (mono_interp_traceopt > 1) { - printf("IL_%04x %s %-10s -> IL_%04x, sp %d, %s %-12s vt_sp %u (max %u)\n", - td.ip - td.il_code, - td.is_bb_start [td.ip - td.il_code] == 3 ? "<>" : - td.is_bb_start [td.ip - td.il_code] == 2 ? "< " : - td.is_bb_start [td.ip - td.il_code] == 1 ? " >" : " ", - mono_opcode_name (*td.ip), td.new_ip - td.new_code, td.sp - td.stack, - td.sp > td.stack ? stack_type_string [td.sp [-1].type] : " ", - (td.sp > td.stack && (td.sp [-1].type == STACK_TYPE_O || td.sp [-1].type == STACK_TYPE_VT)) ? (td.sp [-1].klass == NULL ? "?" : td.sp [-1].klass->name) : "", - td.vt_sp, td.max_vt_sp); - } - switch (*td.ip) { - case CEE_NOP: - /* lose it */ - ++td.ip; - break; - case CEE_BREAK: - SIMPLE_OP(td, MINT_BREAK); - break; - case CEE_LDARG_0: - case CEE_LDARG_1: - case CEE_LDARG_2: - case CEE_LDARG_3: - load_arg (&td, *td.ip - CEE_LDARG_0); - ++td.ip; - break; - case CEE_LDLOC_0: - case CEE_LDLOC_1: - case CEE_LDLOC_2: - case CEE_LDLOC_3: - load_local (&td, *td.ip - CEE_LDLOC_0); - ++td.ip; - break; - case CEE_STLOC_0: - case CEE_STLOC_1: - case CEE_STLOC_2: - case CEE_STLOC_3: - store_local (&td, *td.ip - CEE_STLOC_0); - ++td.ip; - break; - case CEE_LDARG_S: - load_arg (&td, ((guint8 *)td.ip)[1]); - td.ip += 2; - break; - case CEE_LDARGA_S: { - int n = ((guint8 *)td.ip)[1]; - if (n == 0 && signature->hasthis) - ADD_CODE(&td, MINT_LDTHISA); - else { - ADD_CODE(&td, MINT_LDARGA); - ADD_CODE(&td, td.rtm->arg_offsets [n - signature->hasthis]); - } - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_MP); - td.ip += 2; - break; - } - case CEE_STARG_S: - store_arg (&td, ((guint8 *)td.ip)[1]); - td.ip += 2; - break; - case CEE_LDLOC_S: - load_local (&td, ((guint8 *)td.ip)[1]); - td.ip += 2; - break; - case CEE_LDLOCA_S: - ADD_CODE(&td, MINT_LDLOCA_S); - ADD_CODE(&td, td.rtm->local_offsets [((guint8 *)td.ip)[1]]); - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_MP); - td.ip += 2; - break; - case CEE_STLOC_S: - store_local (&td, ((guint8 *)td.ip)[1]); - td.ip += 2; - break; - case CEE_LDNULL: - SIMPLE_OP(td, MINT_LDNULL); - PUSH_TYPE(&td, STACK_TYPE_O, NULL); - break; - case CEE_LDC_I4_M1: - SIMPLE_OP(td, MINT_LDC_I4_M1); - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_I4); - break; - case CEE_LDC_I4_0: - if (!td.is_bb_start[td.ip + 1 - td.il_code] && td.ip [1] == 0xfe && td.ip [2] == CEE_CEQ && - td.sp > td.stack && td.sp [-1].type == STACK_TYPE_I4) { - SIMPLE_OP(td, MINT_CEQ0_I4); - td.ip += 2; - } else { - SIMPLE_OP(td, MINT_LDC_I4_0); - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_I4); - } - break; - case CEE_LDC_I4_1: - if (!td.is_bb_start[td.ip + 1 - td.il_code] && - (td.ip [1] == CEE_ADD || td.ip [1] == CEE_SUB) && td.sp [-1].type == STACK_TYPE_I4) { - ADD_CODE(&td, td.ip [1] == CEE_ADD ? MINT_ADD1_I4 : MINT_SUB1_I4); - td.ip += 2; - } else { - SIMPLE_OP(td, MINT_LDC_I4_1); - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_I4); - } - break; - case CEE_LDC_I4_2: - case CEE_LDC_I4_3: - case CEE_LDC_I4_4: - case CEE_LDC_I4_5: - case CEE_LDC_I4_6: - case CEE_LDC_I4_7: - case CEE_LDC_I4_8: - SIMPLE_OP(td, (*td.ip - CEE_LDC_I4_0) + MINT_LDC_I4_0); - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_I4); - break; - case CEE_LDC_I4_S: - ADD_CODE(&td, MINT_LDC_I4_S); - ADD_CODE(&td, ((gint8 *) td.ip) [1]); - td.ip += 2; - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_I4); - break; - case CEE_LDC_I4: - i32 = read32 (td.ip + 1); - ADD_CODE(&td, MINT_LDC_I4); - WRITE32(&td, &i32); - td.ip += 5; - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_I4); - break; - case CEE_LDC_I8: { - gint64 val = read64 (td.ip + 1); - ADD_CODE(&td, MINT_LDC_I8); - WRITE64(&td, &val); - td.ip += 9; - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_I8); - break; - } - case CEE_LDC_R4: { - float val; - readr4 (td.ip + 1, &val); - ADD_CODE(&td, MINT_LDC_R4); - WRITE32(&td, &val); - td.ip += 5; - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_R8); - break; - } - case CEE_LDC_R8: { - double val; - readr8 (td.ip + 1, &val); - ADD_CODE(&td, MINT_LDC_R8); - WRITE64(&td, &val); - td.ip += 9; - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_R8); - break; - } - case CEE_DUP: { - int type = td.sp [-1].type; - MonoClass *klass = td.sp [-1].klass; - if (td.sp [-1].type == STACK_TYPE_VT) { - gint32 size = mono_class_value_size (klass, NULL); - PUSH_VT(&td, size); - ADD_CODE(&td, MINT_DUP_VT); - WRITE32(&td, &size); - td.ip ++; - } else - SIMPLE_OP(td, MINT_DUP); - PUSH_TYPE(&td, type, klass); - break; - } - case CEE_POP: - CHECK_STACK(&td, 1); - SIMPLE_OP(td, MINT_POP); - if (td.sp [-1].type == STACK_TYPE_VT) { - int size = mono_class_value_size (td.sp [-1].klass, NULL); - size = (size + 7) & ~7; - ADD_CODE(&td, MINT_VTRESULT); - ADD_CODE(&td, 0); - WRITE32(&td, &size); - td.vt_sp -= size; - } - --td.sp; - break; - case CEE_JMP: { - MonoMethod *m; - if (td.sp > td.stack) - g_warning ("CEE_JMP: stack must be empty"); - token = read32 (td.ip + 1); - m = mono_get_method_full (image, token, NULL, generic_context); - ADD_CODE(&td, MINT_JMP); - ADD_CODE(&td, get_data_item_index (&td, mono_interp_get_runtime_method (m))); - td.ip += 5; - break; - } - case CEE_CALLVIRT: /* Fall through */ - case CEE_CALLI: /* Fall through */ - case CEE_CALL: { - MonoMethod *m; - MonoMethodSignature *csignature; - int virtual = *td.ip == CEE_CALLVIRT; - int calli = *td.ip == CEE_CALLI; - int i; - guint32 vt_stack_used = 0; - guint32 vt_res_size = 0; - int op = -1; - int native = 0; - int is_void = 0; - - token = read32 (td.ip + 1); - if (calli) { - CHECK_STACK(&td, 1); - native = (method->wrapper_type != MONO_WRAPPER_DELEGATE_INVOKE && td.sp [-1].type == STACK_TYPE_I); - --td.sp; - if (method->wrapper_type != MONO_WRAPPER_NONE) - csignature = (MonoMethodSignature *)mono_method_get_wrapper_data (method, token); - else - csignature = mono_metadata_parse_signature (image, token); - m = NULL; - } else { - if (method->wrapper_type == MONO_WRAPPER_NONE) - m = mono_get_method_full (image, token, NULL, generic_context); - else - m = (MonoMethod *)mono_method_get_wrapper_data (method, token); - csignature = mono_method_signature (m); - if (m->klass == mono_defaults.string_class) { - if (m->name [0] == 'g') { - if (strcmp (m->name, "get_Chars") == 0) - op = MINT_GETCHR; - else if (strcmp (m->name, "get_Length") == 0) - op = MINT_STRLEN; - } - } else if (m->klass == mono_defaults.array_class) { - if (strcmp (m->name, "get_Rank") == 0) - op = MINT_ARRAY_RANK; - else if (strcmp (m->name, "get_Length") == 0) - op = MINT_LDLEN; - } - } - CHECK_STACK(&td, csignature->param_count + csignature->hasthis); - if (!calli && (!virtual || (m->flags & METHOD_ATTRIBUTE_VIRTUAL) == 0) && - (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) == 0 && - (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) == 0) { - int called_inited = mono_class_vtable (domain, m->klass)->initialized; - MonoMethodHeader *mheader = mono_method_get_header (m); - - if (/*mono_metadata_signature_equal (method->signature, m->signature) */ method == m && *(td.ip + 5) == CEE_RET) { - int offset; - if (mono_interp_traceopt) - g_print ("Optimize tail call of %s.%s\n", m->klass->name, m->name); - for (i = csignature->param_count - 1; i >= 0; --i) - store_arg (&td, i + csignature->hasthis); - - if (csignature->hasthis) { - ADD_CODE(&td, MINT_STTHIS); - --td.sp; - } - ADD_CODE(&td, MINT_BR_S); - offset = body_start_offset - ((td.new_ip - 1) - td.new_code); - ADD_CODE(&td, offset); - if (!is_bb_start [td.ip + 5 - td.il_code]) - ++td.ip; /* gobble the CEE_RET if it isn't branched to */ - td.ip += 5; - break; - } else { - /* mheader might not exist if this is a delegate invoc, etc */ - if (mheader && *mheader->code == CEE_RET && called_inited) { - if (mono_interp_traceopt) - g_print ("Inline (empty) call of %s.%s\n", m->klass->name, m->name); - for (i = 0; i < csignature->param_count; i++) - ADD_CODE(&td, MINT_POP); /*FIX: vt */ - if (csignature->hasthis) { - if (virtual) - ADD_CODE(&td, MINT_CKNULL); - ADD_CODE(&td, MINT_POP); - } - td.sp -= csignature->param_count + csignature->hasthis; - td.ip += 5; - break; - } - } - } - if (method->wrapper_type == MONO_WRAPPER_NONE && m != NULL) { - if (m->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) - m = mono_marshal_get_native_wrapper (m); - if (!virtual && m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) - m = mono_marshal_get_synchronized_wrapper (m); - } - g_assert (csignature->call_convention == MONO_CALL_DEFAULT || csignature->call_convention == MONO_CALL_C); - td.sp -= csignature->param_count + csignature->hasthis; - for (i = 0; i < csignature->param_count; ++i) { - if (td.sp [i + csignature->hasthis].type == STACK_TYPE_VT) { - gint32 size; - if (csignature->pinvoke && method->wrapper_type != MONO_WRAPPER_NONE) - size = mono_class_native_size (csignature->params [i]->data.klass, NULL); - else - size = mono_class_value_size (csignature->params [i]->data.klass, NULL); - size = (size + 7) & ~7; - vt_stack_used += size; - } - } - - /* need to handle typedbyref ... */ - if (csignature->ret->type != MONO_TYPE_VOID) { - int mt = mint_type(csignature->ret); - MonoClass *klass = NULL; - if (mt == MINT_TYPE_VT) { - if (csignature->pinvoke && method->wrapper_type != MONO_WRAPPER_NONE) - vt_res_size = mono_class_native_size (csignature->ret->data.klass, NULL); - else - vt_res_size = mono_class_value_size (csignature->ret->data.klass, NULL); - PUSH_VT(&td, vt_res_size); - klass = csignature->ret->data.klass; - } else if (mt == MINT_TYPE_O) - klass = mono_class_from_mono_type (csignature->ret); - PUSH_TYPE(&td, stack_type[mt], klass); - } else - is_void = TRUE; - - if (op >= 0) { - ADD_CODE(&td, op); -#if SIZEOF_VOID_P == 8 - if (op == MINT_LDLEN) - ADD_CODE(&td, MINT_CONV_I4_I8); -#endif - } else { - if (calli) - ADD_CODE(&td, native ? MINT_CALLI_NAT : MINT_CALLI); - else if (virtual) - ADD_CODE(&td, is_void ? MINT_VCALLVIRT : MINT_CALLVIRT); - else - ADD_CODE(&td, is_void ? MINT_VCALL : MINT_CALL); - ADD_CODE(&td, get_data_item_index (&td, calli? (void *)csignature : (void *)mono_interp_get_runtime_method (m))); - } - td.ip += 5; - if (vt_stack_used != 0 || vt_res_size != 0) { - ADD_CODE(&td, MINT_VTRESULT); - ADD_CODE(&td, vt_res_size); - WRITE32(&td, &vt_stack_used); - td.vt_sp -= vt_stack_used; - } - break; - } - case CEE_RET: { - int vt_size = 0; - if (signature->ret->type != MONO_TYPE_VOID) { - --td.sp; - if (mint_type(signature->ret) == MINT_TYPE_VT) { - vt_size = mono_class_value_size (signature->ret->data.klass, NULL); - vt_size = (vt_size + 7) & ~7; - } - } - if (td.sp > td.stack) - g_warning ("%s.%s: CEE_RET: more values on stack: %d", td.method->klass->name, td.method->name, td.sp - td.stack); - if (td.vt_sp != vt_size) - g_warning ("%s.%s: CEE_RET: value type stack: %d", td.method->klass->name, td.method->name, td.vt_sp); - if (vt_size == 0) - SIMPLE_OP(td, signature->ret->type == MONO_TYPE_VOID ? MINT_RET_VOID : MINT_RET); - else { - ADD_CODE(&td, MINT_RET_VT); - WRITE32(&td, &vt_size); - ++td.ip; - } - generating_code = 0; - break; - } - case CEE_BR: - handle_branch (&td, MINT_BR_S, MINT_BR, 5 + read32 (td.ip + 1)); - td.ip += 5; - generating_code = 0; - break; - case CEE_BR_S: - handle_branch (&td, MINT_BR_S, MINT_BR, 2 + (gint8)td.ip [1]); - td.ip += 2; - generating_code = 0; - break; - case CEE_BRFALSE: - one_arg_branch (&td, MINT_BRFALSE_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BRFALSE_S: - one_arg_branch (&td, MINT_BRFALSE_I4, 2 + (gint8)td.ip [1]); - td.ip += 2; - break; - case CEE_BRTRUE: - one_arg_branch (&td, MINT_BRTRUE_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BRTRUE_S: - one_arg_branch (&td, MINT_BRTRUE_I4, 2 + (gint8)td.ip [1]); - td.ip += 2; - break; - case CEE_BEQ: - two_arg_branch (&td, MINT_BEQ_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BEQ_S: - two_arg_branch (&td, MINT_BEQ_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BGE: - two_arg_branch (&td, MINT_BGE_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BGE_S: - two_arg_branch (&td, MINT_BGE_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BGT: - two_arg_branch (&td, MINT_BGT_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BGT_S: - two_arg_branch (&td, MINT_BGT_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BLT: - two_arg_branch (&td, MINT_BLT_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BLT_S: - two_arg_branch (&td, MINT_BLT_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BLE: - two_arg_branch (&td, MINT_BLE_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BLE_S: - two_arg_branch (&td, MINT_BLE_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BNE_UN: - two_arg_branch (&td, MINT_BNE_UN_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BNE_UN_S: - two_arg_branch (&td, MINT_BNE_UN_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BGE_UN: - two_arg_branch (&td, MINT_BGE_UN_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BGE_UN_S: - two_arg_branch (&td, MINT_BGE_UN_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BGT_UN: - two_arg_branch (&td, MINT_BGT_UN_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BGT_UN_S: - two_arg_branch (&td, MINT_BGT_UN_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BLE_UN: - two_arg_branch (&td, MINT_BLE_UN_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BLE_UN_S: - two_arg_branch (&td, MINT_BLE_UN_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_BLT_UN: - two_arg_branch (&td, MINT_BLT_UN_I4, 5 + read32 (td.ip + 1)); - td.ip += 5; - break; - case CEE_BLT_UN_S: - two_arg_branch (&td, MINT_BLT_UN_I4, 2 + (gint8) td.ip [1]); - td.ip += 2; - break; - case CEE_SWITCH: { - guint32 n; - const unsigned char *next_ip; - const unsigned char *base_ip = td.ip; - unsigned short *next_new_ip; - ++td.ip; - n = read32 (td.ip); - ADD_CODE(&td, MINT_SWITCH); - ADD_CODE(&td, * (unsigned short *)(&n)); - ADD_CODE(&td, * ((unsigned short *)&n + 1)); - td.ip += 4; - next_ip = td.ip + n * 4; - next_new_ip = td.new_ip + n * 2; - for (i = 0; i < n; i++) { - offset = read32 (td.ip); - target = next_ip - td.il_code + offset; - if (offset < 0) - target = td.in_offsets [target] - (next_new_ip - td.new_code); - else { - int prev = td.forward_refs [target]; - td.forward_refs [td.ip - td.il_code] = prev; - td.forward_refs [target] = td.ip - td.il_code; - td.in_offsets [td.ip - td.il_code] = - (base_ip - td.il_code); - } - ADD_CODE(&td, * (unsigned short *)(&target)); - ADD_CODE(&td, * ((unsigned short *)&target + 1)); - td.ip += 4; - } - --td.sp; - break; - } - case CEE_LDIND_I1: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_I1); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDIND_U1: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_U1); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDIND_I2: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_I2); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDIND_U2: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_U2); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDIND_I4: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_I4); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDIND_U4: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_U4); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDIND_I8: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_I8); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I8); - break; - case CEE_LDIND_I: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_I); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I); - break; - case CEE_LDIND_R4: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_R4); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_R8); - break; - case CEE_LDIND_R8: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_R8); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_R8); - break; - case CEE_LDIND_REF: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDIND_REF); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_O); - break; - case CEE_STIND_REF: - CHECK_STACK (&td, 2); - SIMPLE_OP (td, MINT_STIND_REF); - td.sp -= 2; - break; - case CEE_STIND_I1: - CHECK_STACK (&td, 2); - SIMPLE_OP (td, MINT_STIND_I1); - td.sp -= 2; - break; - case CEE_STIND_I2: - CHECK_STACK (&td, 2); - SIMPLE_OP (td, MINT_STIND_I2); - td.sp -= 2; - break; - case CEE_STIND_I4: - CHECK_STACK (&td, 2); - SIMPLE_OP (td, MINT_STIND_I4); - td.sp -= 2; - break; - case CEE_STIND_I: - CHECK_STACK (&td, 2); - SIMPLE_OP (td, MINT_STIND_I); - td.sp -= 2; - break; - case CEE_STIND_I8: - CHECK_STACK (&td, 2); - SIMPLE_OP (td, MINT_STIND_I8); - td.sp -= 2; - break; - case CEE_STIND_R4: - CHECK_STACK (&td, 2); - SIMPLE_OP (td, MINT_STIND_R4); - td.sp -= 2; - break; - case CEE_STIND_R8: - CHECK_STACK (&td, 2); - SIMPLE_OP (td, MINT_STIND_R8); - td.sp -= 2; - break; - case CEE_ADD: - binary_arith_op(&td, MINT_ADD_I4); - ++td.ip; - break; - case CEE_SUB: - binary_arith_op(&td, MINT_SUB_I4); - ++td.ip; - break; - case CEE_MUL: - binary_arith_op(&td, MINT_MUL_I4); - ++td.ip; - break; - case CEE_DIV: - binary_arith_op(&td, MINT_DIV_I4); - ++td.ip; - break; - case CEE_DIV_UN: - binary_arith_op(&td, MINT_DIV_UN_I4); - ++td.ip; - break; - case CEE_REM: - binary_int_op (&td, MINT_REM_I4); - ++td.ip; - break; - case CEE_REM_UN: - binary_int_op (&td, MINT_REM_UN_I4); - ++td.ip; - break; - case CEE_AND: - binary_int_op (&td, MINT_AND_I4); - ++td.ip; - break; - case CEE_OR: - binary_int_op (&td, MINT_OR_I4); - ++td.ip; - break; - case CEE_XOR: - binary_int_op (&td, MINT_XOR_I4); - ++td.ip; - break; - case CEE_SHL: - shift_op (&td, MINT_SHL_I4); - ++td.ip; - break; - case CEE_SHR: - shift_op (&td, MINT_SHR_I4); - ++td.ip; - break; - case CEE_SHR_UN: - shift_op (&td, MINT_SHR_UN_I4); - ++td.ip; - break; - case CEE_NEG: - unary_arith_op (&td, MINT_NEG_I4); - ++td.ip; - break; - case CEE_NOT: - unary_arith_op (&td, MINT_NOT_I4); - ++td.ip; - break; - case CEE_CONV_U1: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_U1_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_U1_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_U1_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_I1: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_I1_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_I1_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_I1_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_U2: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_U2_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_U2_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_U2_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_I2: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_I2_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_I2_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_I2_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_U: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: -#if SIZEOF_VOID_P == 4 - ADD_CODE(&td, MINT_CONV_U4_R8); -#else - ADD_CODE(&td, MINT_CONV_U8_R8); -#endif - break; - case STACK_TYPE_I4: -#if SIZEOF_VOID_P == 8 - ADD_CODE(&td, MINT_CONV_U8_I4); -#endif - break; - case STACK_TYPE_I8: -#if SIZEOF_VOID_P == 4 - ADD_CODE(&td, MINT_CONV_U4_I8); -#endif - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I); - break; - case CEE_CONV_I: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: -#if SIZEOF_VOID_P == 8 - ADD_CODE(&td, MINT_CONV_I8_R8); -#else - ADD_CODE(&td, MINT_CONV_I4_R8); -#endif - break; - case STACK_TYPE_I4: -#if SIZEOF_VOID_P == 8 - ADD_CODE(&td, MINT_CONV_I8_I4); -#endif - break; - case STACK_TYPE_O: - break; - case STACK_TYPE_MP: - break; - case STACK_TYPE_I8: -#if SIZEOF_VOID_P == 4 - ADD_CODE(&td, MINT_CONV_I4_I8); -#endif - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I); - break; - case CEE_CONV_U4: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_U4_R8); - break; - case STACK_TYPE_I4: - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_U4_I8); - break; - case STACK_TYPE_MP: -#if SIZEOF_VOID_P == 8 - ADD_CODE(&td, MINT_CONV_U4_I8); -#endif - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_I4: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_I4_R8); - break; - case STACK_TYPE_I4: - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_I4_I8); - break; - case STACK_TYPE_MP: -#if SIZEOF_VOID_P == 8 - ADD_CODE(&td, MINT_CONV_I4_I8); -#endif - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_I8: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_I8_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_I8_I4); - break; - case STACK_TYPE_I8: - break; - case STACK_TYPE_MP: -#if SIZEOF_VOID_P == 4 - ADD_CODE(&td, MINT_CONV_I8_I4); -#endif - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I8); - break; - case CEE_CONV_R4: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_R4_R8); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_R4_I8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_R4_I4); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_R8); - break; - case CEE_CONV_R8: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_R8_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_R8_I8); - break; - case STACK_TYPE_R8: - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_R8); - break; - case CEE_CONV_U8: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_U8_I4); - break; - case STACK_TYPE_I8: - break; - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_U8_R8); - break; - case STACK_TYPE_MP: -#if SIZEOF_VOID_P == 4 - ADD_CODE(&td, MINT_CONV_U8_I4); -#endif - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I8); - break; -#if 0 - case CEE_CPOBJ: { - MonoClass *vtklass; - ++ip; - vtklass = mono_class_get_full (image, read32 (ip), generic_context); - ip += 4; - sp -= 2; - memcpy (sp [0].data.p, sp [1].data.p, mono_class_value_size (vtklass, NULL)); - break; - } -#endif - case CEE_LDOBJ: { - int size; - CHECK_STACK (&td, 1); - - token = read32 (td.ip + 1); - - if (method->wrapper_type != MONO_WRAPPER_NONE) - klass = (MonoClass *)mono_method_get_wrapper_data (method, token); - else - klass = mono_class_get_full (image, token, generic_context); - - ADD_CODE(&td, MINT_LDOBJ); - ADD_CODE(&td, get_data_item_index(&td, klass)); - if (klass->byval_arg.type == MONO_TYPE_VALUETYPE && !klass->byval_arg.data.klass->enumtype) { - size = mono_class_value_size (klass, NULL); - PUSH_VT(&td, size); - } - td.ip += 5; - SET_TYPE(td.sp - 1, stack_type[mint_type(&klass->byval_arg)], klass); - break; - } - case CEE_LDSTR: { - MonoString *s; - token = mono_metadata_token_index (read32 (td.ip + 1)); - td.ip += 5; - if (method->wrapper_type != MONO_WRAPPER_NONE) { - s = mono_string_new_wrapper( - mono_method_get_wrapper_data (method, token)); - } - else - s = mono_ldstr (domain, image, token); - ADD_CODE(&td, MINT_LDSTR); - ADD_CODE(&td, get_data_item_index (&td, s)); - PUSH_TYPE(&td, STACK_TYPE_O, mono_defaults.string_class); - break; - } - case CEE_NEWOBJ: { - MonoMethod *m; - MonoMethodSignature *csignature; - guint32 vt_stack_used = 0; - guint32 vt_res_size = 0; - - td.ip++; - token = read32 (td.ip); - td.ip += 4; - - if (method->wrapper_type != MONO_WRAPPER_NONE) - m = (MonoMethod *)mono_method_get_wrapper_data (method, token); - else - m = mono_get_method_full (image, token, NULL, generic_context); - - csignature = mono_method_signature (m); - klass = m->klass; - td.sp -= csignature->param_count; - ADD_CODE(&td, MINT_NEWOBJ); - ADD_CODE(&td, get_data_item_index (&td, mono_interp_get_runtime_method (m))); - if (klass->byval_arg.type == MONO_TYPE_VALUETYPE) { - vt_res_size = mono_class_value_size (klass, NULL); - PUSH_VT(&td, vt_res_size); - } - for (i = 0; i < csignature->param_count; ++i) { - int mt = mint_type(csignature->params [i]); - if (mt == MINT_TYPE_VT) { - gint32 size = mono_class_value_size (csignature->params [i]->data.klass, NULL); - size = (size + 7) & ~7; - vt_stack_used += size; - } - } - if (vt_stack_used != 0 || vt_res_size != 0) { - ADD_CODE(&td, MINT_VTRESULT); - ADD_CODE(&td, vt_res_size); - WRITE32(&td, &vt_stack_used); - td.vt_sp -= vt_stack_used; - } - PUSH_TYPE(&td, stack_type [mint_type (&klass->byval_arg)], klass); - break; - } - case CEE_CASTCLASS: - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - klass = mono_class_get_full (image, token, generic_context); - ADD_CODE(&td, MINT_CASTCLASS); - ADD_CODE(&td, get_data_item_index (&td, klass)); - td.sp [-1].klass = klass; - td.ip += 5; - break; - case CEE_ISINST: - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - klass = mono_class_get_full (image, token, generic_context); - ADD_CODE(&td, MINT_ISINST); - ADD_CODE(&td, get_data_item_index (&td, klass)); - td.ip += 5; - break; - case CEE_CONV_R_UN: - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_R_UN_I8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_R_UN_I4); - break; - default: - g_assert_not_reached (); - } - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_R8); - ++td.ip; - break; - case CEE_UNBOX: - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - - if (method->wrapper_type != MONO_WRAPPER_NONE) - klass = (MonoClass *)mono_method_get_wrapper_data (method, token); - else - klass = mono_class_get_full (image, token, generic_context); - - ADD_CODE(&td, MINT_UNBOX); - ADD_CODE(&td, get_data_item_index (&td, klass)); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_MP); - td.ip += 5; - break; - case CEE_THROW: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_THROW); - --td.sp; - generating_code = 0; - break; - case CEE_LDFLDA: - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - field = mono_field_from_token (image, token, &klass, generic_context); - mono_class_init (klass); - mt = mint_type(field->type); - ADD_CODE(&td, MINT_LDFLDA); - ADD_CODE(&td, klass->valuetype ? field->offset - sizeof(MonoObject) : field->offset); - td.ip += 5; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_MP); - break; - case CEE_LDFLD: { - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - field = mono_field_from_token (image, token, &klass, generic_context); - mono_class_init (klass); - mt = mint_type(field->type); - if (klass->marshalbyref) { - ADD_CODE(&td, mt == MINT_TYPE_VT ? MINT_LDRMFLD_VT : MINT_LDRMFLD); - ADD_CODE(&td, get_data_item_index (&td, field)); - } else { - ADD_CODE(&td, MINT_LDFLD_I1 + mt - MINT_TYPE_I1); - ADD_CODE(&td, klass->valuetype ? field->offset - sizeof(MonoObject) : field->offset); - } - klass = NULL; - if (mt == MINT_TYPE_VT) { - int size = mono_class_value_size (field->type->data.klass, NULL); - PUSH_VT(&td, size); - WRITE32(&td, &size); - klass = field->type->data.klass; - } else if (mt == MINT_TYPE_O) - klass = mono_class_from_mono_type (field->type); - td.ip += 5; - SET_TYPE(td.sp - 1, stack_type [mt], klass); - break; - } - case CEE_STFLD: - CHECK_STACK (&td, 2); - token = read32 (td.ip + 1); - field = mono_field_from_token (image, token, &klass, generic_context); - mono_class_init (klass); - mt = mint_type(field->type); - if (klass->marshalbyref) { - ADD_CODE(&td, mt == MINT_TYPE_VT ? MINT_STRMFLD_VT : MINT_STRMFLD); - ADD_CODE(&td, get_data_item_index (&td, field)); - } else { - ADD_CODE(&td, MINT_STFLD_I1 + mt - MINT_TYPE_I1); - ADD_CODE(&td, klass->valuetype ? field->offset - sizeof(MonoObject) : field->offset); - } - if (mt == MINT_TYPE_VT) { - int size = mono_class_value_size (field->type->data.klass, NULL); - POP_VT(&td, size); - WRITE32(&td, &size); - } - td.ip += 5; - td.sp -= 2; - break; - case CEE_LDSFLDA: - token = read32 (td.ip + 1); - field = mono_field_from_token (image, token, &klass, generic_context); - ADD_CODE(&td, MINT_LDSFLDA); - ADD_CODE(&td, get_data_item_index (&td, field)); - td.ip += 5; - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_MP); - break; - case CEE_LDSFLD: - token = read32 (td.ip + 1); - field = mono_field_from_token (image, token, &klass, generic_context); - mt = mint_type(field->type); - ADD_CODE(&td, mt == MINT_TYPE_VT ? MINT_LDSFLD_VT : MINT_LDSFLD); - ADD_CODE(&td, get_data_item_index (&td, field)); - klass = NULL; - if (mt == MINT_TYPE_VT) { - int size = mono_class_value_size (field->type->data.klass, NULL); - PUSH_VT(&td, size); - WRITE32(&td, &size); - klass = field->type->data.klass; - } else { - if (mt == MINT_TYPE_O) - klass = mono_class_from_mono_type (field->type); - if (!domain->special_static_fields || !g_hash_table_lookup (domain->special_static_fields, field)) { - if (mt == MINT_TYPE_O) - td.new_ip [-2] = MINT_LDSFLD_O; - else if (mt == MINT_TYPE_I4) - td.new_ip [-2] = MINT_LDSFLD_I4; - } - ADD_CODE(&td, get_data_item_index (&td, mono_class_vtable (domain, field->parent))); - } - td.ip += 5; - PUSH_TYPE(&td, stack_type [mt], klass); - break; - case CEE_STSFLD: - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - field = mono_field_from_token (image, token, &klass, generic_context); - mt = mint_type(field->type); - ADD_CODE(&td, mt == MINT_TYPE_VT ? MINT_STSFLD_VT : MINT_STSFLD); - ADD_CODE(&td, get_data_item_index (&td, field)); - if (mt == MINT_TYPE_VT) { - int size = mono_class_value_size (field->type->data.klass, NULL); - POP_VT(&td, size); - WRITE32(&td, &size); - } - td.ip += 5; - --td.sp; - break; - case CEE_STOBJ: { - int size; - token = read32 (td.ip + 1); - - if (method->wrapper_type != MONO_WRAPPER_NONE) - klass = (MonoClass *)mono_method_get_wrapper_data (method, token); - else - klass = mono_class_get_full (image, token, generic_context); - - ADD_CODE(&td, td.sp [-1].type == STACK_TYPE_VT ? MINT_STOBJ_VT : MINT_STOBJ); - ADD_CODE(&td, get_data_item_index (&td, klass)); - if (td.sp [-1].type == STACK_TYPE_VT) { - size = mono_class_value_size (klass, NULL); - size = (size + 7) & ~7; - td.vt_sp -= size; - } - td.ip += 5; - td.sp -= 2; - break; - } - case CEE_CONV_OVF_I_UN: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: -#if SIZEOF_VOID_P == 8 - ADD_CODE(&td, MINT_CONV_OVF_I8_UN_R8); -#else - ADD_CODE(&td, MINT_CONV_OVF_I4_UN_R8); -#endif - break; - case STACK_TYPE_I8: - /*FIX*/ - break; - case STACK_TYPE_I4: -#if SIZEOF_VOID_P == 8 - ADD_CODE(&td, MINT_CONV_I8_U4); -#endif - break; - default: - g_assert_not_reached (); - break; - } - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I8); - ++td.ip; - break; - case CEE_CONV_OVF_I8_UN: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_I8_UN_R8); - break; - case STACK_TYPE_I8: - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_I8_U4); - break; - default: - g_assert_not_reached (); - break; - } - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I8); - ++td.ip; - break; - case CEE_BOX: { - int size; - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - if (method->wrapper_type != MONO_WRAPPER_NONE) - klass = (MonoClass *)mono_method_get_wrapper_data (method, token); - else - klass = mono_class_get_full (image, token, generic_context); - g_assert (klass->valuetype); - if (klass->byval_arg.type == MONO_TYPE_VALUETYPE && !klass->enumtype) { - size = mono_class_value_size (klass, NULL); - size = (size + 7) & ~7; - td.vt_sp -= size; - } - ADD_CODE(&td, MINT_BOX); - ADD_CODE(&td, get_data_item_index (&td, klass)); - SET_TYPE(td.sp - 1, STACK_TYPE_O, klass); - td.ip += 5; - break; - } - case CEE_NEWARR: - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - - if (method->wrapper_type != MONO_WRAPPER_NONE) - klass = (MonoClass *)mono_method_get_wrapper_data (method, token); - else - klass = mono_class_get_full (image, token, generic_context); - - ADD_CODE(&td, MINT_NEWARR); - ADD_CODE(&td, get_data_item_index (&td, klass)); - SET_TYPE(td.sp - 1, STACK_TYPE_O, klass); - td.ip += 5; - break; - case CEE_LDLEN: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_LDLEN); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I); - break; - case CEE_LDELEMA: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - token = read32 (td.ip + 1); - - if (method->wrapper_type != MONO_WRAPPER_NONE) - klass = (MonoClass *)mono_method_get_wrapper_data (method, token); - else - klass = mono_class_get_full (image, token, generic_context); - - ADD_CODE(&td, MINT_LDELEMA); - ADD_CODE(&td, get_data_item_index (&td, klass)); - td.ip += 5; - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_MP); - break; - case CEE_LDELEM_I1: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_I1); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDELEM_U1: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_U1); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDELEM_I2: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_I2); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDELEM_U2: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_U2); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDELEM_I4: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_I4); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDELEM_U4: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_U4); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_LDELEM_I8: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_I8); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I8); - break; - case CEE_LDELEM_I: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_I); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I); - break; - case CEE_LDELEM_R4: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_R4); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_R8); - break; - case CEE_LDELEM_R8: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_R8); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_R8); - break; - case CEE_LDELEM_REF: - CHECK_STACK (&td, 2); - ENSURE_I4 (&td, 1); - SIMPLE_OP (td, MINT_LDELEM_REF); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_O); - break; - case CEE_STELEM_I: - CHECK_STACK (&td, 3); - ENSURE_I4 (&td, 2); - SIMPLE_OP (td, MINT_STELEM_I); - td.sp -= 3; - break; - case CEE_STELEM_I1: - CHECK_STACK (&td, 3); - ENSURE_I4 (&td, 2); - SIMPLE_OP (td, MINT_STELEM_I1); - td.sp -= 3; - break; - case CEE_STELEM_I2: - CHECK_STACK (&td, 3); - ENSURE_I4 (&td, 2); - SIMPLE_OP (td, MINT_STELEM_I2); - td.sp -= 3; - break; - case CEE_STELEM_I4: - CHECK_STACK (&td, 3); - ENSURE_I4 (&td, 2); - SIMPLE_OP (td, MINT_STELEM_I4); - td.sp -= 3; - break; - case CEE_STELEM_I8: - CHECK_STACK (&td, 3); - ENSURE_I4 (&td, 2); - SIMPLE_OP (td, MINT_STELEM_I8); - td.sp -= 3; - break; - case CEE_STELEM_R4: - CHECK_STACK (&td, 3); - ENSURE_I4 (&td, 2); - SIMPLE_OP (td, MINT_STELEM_R4); - td.sp -= 3; - break; - case CEE_STELEM_R8: - CHECK_STACK (&td, 3); - ENSURE_I4 (&td, 2); - SIMPLE_OP (td, MINT_STELEM_R8); - td.sp -= 3; - break; - case CEE_STELEM_REF: - CHECK_STACK (&td, 3); - ENSURE_I4 (&td, 2); - SIMPLE_OP (td, MINT_STELEM_REF); - td.sp -= 3; - break; -#if 0 - case CEE_LDELEM: - case CEE_STELEM: - case CEE_UNBOX_ANY: - - case CEE_CONV_OVF_U1: - - case CEE_CONV_OVF_I8: - -#if SIZEOF_VOID_P == 8 - case CEE_CONV_OVF_U: -#endif - case CEE_REFANYVAL: ves_abort(); break; -#endif - case CEE_CKFINITE: - CHECK_STACK (&td, 1); - SIMPLE_OP (td, MINT_CKFINITE); - break; - case CEE_CONV_OVF_I1: - case CEE_CONV_OVF_I1_UN: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_I1_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_OVF_I1_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_OVF_I1_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_OVF_U1: - case CEE_CONV_OVF_U1_UN: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_U1_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_OVF_U1_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_OVF_U1_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_OVF_I2: - case CEE_CONV_OVF_I2_UN: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_I2_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_OVF_I2_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_OVF_I2_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; - case CEE_CONV_OVF_U2_UN: - case CEE_CONV_OVF_U2: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_U2_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_OVF_U2_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_OVF_U2_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; -#if SIZEOF_VOID_P == 4 - case CEE_CONV_OVF_I: -#endif - case CEE_CONV_OVF_I4: - case CEE_CONV_OVF_I4_UN: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_I4_R8); - break; - case STACK_TYPE_I4: - if (*td.ip == CEE_CONV_OVF_I4_UN) - ADD_CODE(&td, MINT_CONV_OVF_I4_U4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_OVF_I4_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; -#if SIZEOF_VOID_P == 4 - case CEE_CONV_OVF_U: -#endif - case CEE_CONV_OVF_U4: - case CEE_CONV_OVF_U4_UN: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_U4_R8); - break; - case STACK_TYPE_I4: - if (*td.ip != CEE_CONV_OVF_U4_UN) - ADD_CODE(&td, MINT_CONV_OVF_U4_I4); - break; - case STACK_TYPE_I8: - ADD_CODE(&td, MINT_CONV_OVF_U4_I8); - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - break; -#if SIZEOF_VOID_P == 8 - case CEE_CONV_OVF_I: -#endif - case CEE_CONV_OVF_I8: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_I8_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_I8_I4); - break; - case STACK_TYPE_I8: - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I8); - break; -#if SIZEOF_VOID_P == 8 - case CEE_CONV_OVF_U: -#endif - case CEE_CONV_OVF_U8: - CHECK_STACK (&td, 1); - switch (td.sp [-1].type) { - case STACK_TYPE_R8: - ADD_CODE(&td, MINT_CONV_OVF_U8_R8); - break; - case STACK_TYPE_I4: - ADD_CODE(&td, MINT_CONV_OVF_U8_I4); - break; - case STACK_TYPE_I8: - break; - default: - g_assert_not_reached (); - } - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I8); - break; - case CEE_LDTOKEN: { - int size; - gpointer handle; - token = read32 (td.ip + 1); - handle = mono_ldtoken (image, token, &klass, generic_context); - mt = mint_type(&klass->byval_arg); - g_assert (mt == MINT_TYPE_VT); - size = mono_class_value_size (klass, NULL); - g_assert (size == sizeof(gpointer)); - PUSH_VT(&td, sizeof(gpointer)); - ADD_CODE(&td, MINT_LDTOKEN); - ADD_CODE(&td, get_data_item_index (&td, handle)); - PUSH_SIMPLE_TYPE(&td, stack_type [mt]); - td.ip += 5; - break; - } - case CEE_ADD_OVF: - binary_arith_op(&td, MINT_ADD_OVF_I4); - ++td.ip; - break; - case CEE_ADD_OVF_UN: - binary_arith_op(&td, MINT_ADD_OVF_UN_I4); - ++td.ip; - break; - case CEE_MUL_OVF: - binary_arith_op(&td, MINT_MUL_OVF_I4); - ++td.ip; - break; - case CEE_MUL_OVF_UN: - binary_arith_op(&td, MINT_MUL_OVF_UN_I4); - ++td.ip; - break; - case CEE_SUB_OVF: - binary_arith_op(&td, MINT_SUB_OVF_I4); - ++td.ip; - break; - case CEE_SUB_OVF_UN: - binary_arith_op(&td, MINT_SUB_OVF_UN_I4); - ++td.ip; - break; - case CEE_ENDFINALLY: - SIMPLE_OP (td, MINT_ENDFINALLY); - generating_code = 0; - break; - case CEE_LEAVE: - td.sp = td.stack; - handle_branch (&td, MINT_LEAVE_S, MINT_LEAVE, 5 + read32 (td.ip + 1)); - td.ip += 5; - generating_code = 0; - break; - case CEE_LEAVE_S: - td.sp = td.stack; - handle_branch (&td, MINT_LEAVE_S, MINT_LEAVE, 2 + (gint8)td.ip [1]); - td.ip += 2; - generating_code = 0; - break; - case CEE_UNUSED41: - ++td.ip; - switch (*td.ip) { - case CEE_MONO_ICALL: { - guint32 token; - gpointer func; - MonoJitICallInfo *info; - - token = read32 (td.ip + 1); - td.ip += 5; - func = mono_method_get_wrapper_data (method, token); - info = mono_find_jit_icall_by_addr (func); - g_assert (info); - - CHECK_STACK (&td, info->sig->param_count); - switch (info->sig->param_count) { - case 0: - if (MONO_TYPE_IS_VOID (info->sig->ret)) - ADD_CODE (&td,MINT_ICALL_V_V); - else - g_assert_not_reached(); - break; - case 1: - if (MONO_TYPE_IS_VOID (info->sig->ret)) - ADD_CODE (&td,MINT_ICALL_P_V); - else - ADD_CODE (&td,MINT_ICALL_P_P); - break; - case 2: - if (MONO_TYPE_IS_VOID (info->sig->ret)) { - if (info->sig->params [1]->type == MONO_TYPE_I4) - ADD_CODE (&td,MINT_ICALL_PI_V); - else - ADD_CODE (&td,MINT_ICALL_PP_V); - } else { - if (info->sig->params [1]->type == MONO_TYPE_I4) - ADD_CODE (&td,MINT_ICALL_PI_P); - else - ADD_CODE (&td,MINT_ICALL_PP_P); - } - break; - case 3: - g_assert (MONO_TYPE_IS_VOID (info->sig->ret)); - if (info->sig->params [2]->type == MONO_TYPE_I4) - ADD_CODE (&td,MINT_ICALL_PPI_V); - else - ADD_CODE (&td,MINT_ICALL_PPP_V); - break; - default: - g_assert_not_reached (); - } - if (func == mono_ftnptr_to_delegate) - func = mono_interp_ftnptr_to_delegate; - ADD_CODE(&td, get_data_item_index (&td, func)); - td.sp -= info->sig->param_count; - - if (!MONO_TYPE_IS_VOID (info->sig->ret)) { - td.sp ++; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I); - } - break; - } - case CEE_MONO_VTADDR: { - int size; - CHECK_STACK (&td, 1); - if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) - size = mono_class_native_size(td.sp [-1].klass, NULL); - else - size = mono_class_value_size(td.sp [-1].klass, NULL); - size = (size + 7) & ~7; - ADD_CODE(&td, MINT_VTRESULT); - ADD_CODE(&td, 0); - WRITE32(&td, &size); - td.vt_sp -= size; - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_MP); - break; - } - case CEE_MONO_LDPTR: - case CEE_MONO_CLASSCONST: - token = read32 (td.ip + 1); - td.ip += 5; - ADD_CODE(&td, MINT_MONO_LDPTR); - ADD_CODE(&td, get_data_item_index (&td, mono_method_get_wrapper_data (method, token))); - td.sp [0].type = STACK_TYPE_I; - ++td.sp; - break; - case CEE_MONO_OBJADDR: - CHECK_STACK (&td, 1); - ++td.ip; - td.sp[-1].type = STACK_TYPE_MP; - /* do nothing? */ - break; - case CEE_MONO_NEWOBJ: - token = read32 (td.ip + 1); - td.ip += 5; - ADD_CODE(&td, MINT_MONO_NEWOBJ); - ADD_CODE(&td, get_data_item_index (&td, mono_method_get_wrapper_data (method, token))); - td.sp [0].type = STACK_TYPE_O; - ++td.sp; - break; - case CEE_MONO_RETOBJ: - CHECK_STACK (&td, 1); - token = read32 (td.ip + 1); - td.ip += 5; - ADD_CODE(&td, MINT_MONO_RETOBJ); - td.sp--; - - klass = (MonoClass *)mono_method_get_wrapper_data (method, token); - - /*stackval_from_data (signature->ret, frame->retval, sp->data.vt, signature->pinvoke);*/ - - if (td.sp > td.stack) - g_warning ("CEE_MONO_RETOBJ: more values on stack: %d", td.sp-td.stack); - break; - case CEE_MONO_LDNATIVEOBJ: - token = read32 (td.ip + 1); - td.ip += 5; - klass = (MonoClass *)mono_method_get_wrapper_data (method, token); - g_assert(klass->valuetype); - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_MP); - break; - case CEE_MONO_SAVE_LMF: - case CEE_MONO_RESTORE_LMF: - case CEE_MONO_NOT_TAKEN: - ++td.ip; - break; - default: - g_error ("transform.c: Unimplemented opcode: 0xF0 %02x at 0x%x\n", *td.ip, td.ip-header->code); - } - break; -#if 0 - case CEE_PREFIX7: - case CEE_PREFIX6: - case CEE_PREFIX5: - case CEE_PREFIX4: - case CEE_PREFIX3: - case CEE_PREFIX2: - case CEE_PREFIXREF: ves_abort(); break; -#endif - /* - * Note: Exceptions thrown when executing a prefixed opcode need - * to take into account the number of prefix bytes (usually the - * throw point is just (ip - n_prefix_bytes). - */ - case CEE_PREFIX1: - ++td.ip; - switch (*td.ip) { -#if 0 - case CEE_ARGLIST: ves_abort(); break; -#endif - case CEE_CEQ: - CHECK_STACK(&td, 2); - if (td.sp [-1].type == STACK_TYPE_O || td.sp [-1].type == STACK_TYPE_MP) - ADD_CODE(&td, MINT_CEQ_I4 + STACK_TYPE_I - STACK_TYPE_I4); - else - ADD_CODE(&td, MINT_CEQ_I4 + td.sp [-1].type - STACK_TYPE_I4); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - ++td.ip; - break; - case CEE_CGT: - CHECK_STACK(&td, 2); - if (td.sp [-1].type == STACK_TYPE_O || td.sp [-1].type == STACK_TYPE_MP) - ADD_CODE(&td, MINT_CGT_I4 + STACK_TYPE_I - STACK_TYPE_I4); - else - ADD_CODE(&td, MINT_CGT_I4 + td.sp [-1].type - STACK_TYPE_I4); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - ++td.ip; - break; - case CEE_CGT_UN: - CHECK_STACK(&td, 2); - if (td.sp [-1].type == STACK_TYPE_O || td.sp [-1].type == STACK_TYPE_MP) - ADD_CODE(&td, MINT_CGT_UN_I4 + STACK_TYPE_I - STACK_TYPE_I4); - else - ADD_CODE(&td, MINT_CGT_UN_I4 + td.sp [-1].type - STACK_TYPE_I4); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - ++td.ip; - break; - case CEE_CLT: - CHECK_STACK(&td, 2); - if (td.sp [-1].type == STACK_TYPE_O || td.sp [-1].type == STACK_TYPE_MP) - ADD_CODE(&td, MINT_CLT_I4 + STACK_TYPE_I - STACK_TYPE_I4); - else - ADD_CODE(&td, MINT_CLT_I4 + td.sp [-1].type - STACK_TYPE_I4); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - ++td.ip; - break; - case CEE_CLT_UN: - CHECK_STACK(&td, 2); - if (td.sp [-1].type == STACK_TYPE_O || td.sp [-1].type == STACK_TYPE_MP) - ADD_CODE(&td, MINT_CLT_UN_I4 + STACK_TYPE_I - STACK_TYPE_I4); - else - ADD_CODE(&td, MINT_CLT_UN_I4 + td.sp [-1].type - STACK_TYPE_I4); - --td.sp; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I4); - ++td.ip; - break; - case CEE_LDVIRTFTN: /* fallthrough */ - case CEE_LDFTN: { - MonoMethod *m; - if (*td.ip == CEE_LDVIRTFTN) { - CHECK_STACK (&td, 1); - --td.sp; - } - token = read32 (td.ip + 1); - if (method->wrapper_type != MONO_WRAPPER_NONE) - m = (MonoMethod *)mono_method_get_wrapper_data (method, token); - else - m = mono_get_method_full (image, token, NULL, generic_context); - - if (method->wrapper_type == MONO_WRAPPER_NONE && m->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) - m = mono_marshal_get_synchronized_wrapper (m); - - ADD_CODE(&td, *td.ip == CEE_LDFTN ? MINT_LDFTN : MINT_LDVIRTFTN); - ADD_CODE(&td, get_data_item_index (&td, mono_interp_get_runtime_method (m))); - td.ip += 5; - PUSH_SIMPLE_TYPE (&td, STACK_TYPE_F); - break; - } - case CEE_LDARG: - load_arg (&td, read16 (td.ip + 1)); - td.ip += 3; - break; - case CEE_LDARGA: { - int n = read16 (td.ip + 1); - if (n == 0 && signature->hasthis) - ADD_CODE(&td, MINT_LDTHISA); - else { - ADD_CODE(&td, MINT_LDARGA); - ADD_CODE(&td, td.rtm->arg_offsets [n - signature->hasthis]); /* FIX for large offsets */ - } - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_MP); - td.ip += 3; - break; - } - case CEE_STARG: - store_arg (&td, read16 (td.ip + 1)); - td.ip += 3; - break; - case CEE_LDLOC: - load_local (&td, read16 (td.ip + 1)); - td.ip += 3; - break; - case CEE_LDLOCA: - ADD_CODE(&td, MINT_LDLOCA_S); - ADD_CODE(&td, td.rtm->local_offsets [read16 (td.ip + 1)]); - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_MP); - td.ip += 3; - break; - case CEE_STLOC: - store_local (&td, read16 (td.ip + 1)); - td.ip += 3; - break; - case CEE_LOCALLOC: - CHECK_STACK (&td, 1); -#if SIZEOF_VOID_P == 8 - if (td.sp [-1].type == STACK_TYPE_I8) - ADD_CODE(&td, MINT_CONV_I4_I8); -#endif - ADD_CODE(&td, MINT_LOCALLOC); - if (td.sp != td.stack + 1) - g_warning("CEE_LOCALLOC: stack not empty"); - ++td.ip; - SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_MP); - break; -#if 0 - case CEE_UNUSED57: ves_abort(); break; - case CEE_ENDFILTER: ves_abort(); break; -#endif - case CEE_UNALIGNED_: - ++td.ip; - /* FIX: should do something? */; - break; - case CEE_VOLATILE_: - ++td.ip; - /* FIX: should do something? */; - break; - case CEE_TAIL_: - ++td.ip; - /* FIX: should do something? */; - break; - case CEE_INITOBJ: - CHECK_STACK(&td, 1); - token = read32 (td.ip + 1); - klass = mono_class_get_full (image, token, generic_context); - ADD_CODE(&td, MINT_INITOBJ); - i32 = mono_class_value_size (klass, NULL); - WRITE32(&td, &i32); - td.ip += 5; - --td.sp; - break; - case CEE_CPBLK: - CHECK_STACK(&td, 3); - /* FIX? convert length to I8? */ - ADD_CODE(&td, MINT_CPBLK); - td.sp -= 3; - ++td.ip; - break; -#if 0 - case CEE_CONSTRAINED_: { - guint32 token; - /* FIXME: implement */ - ++ip; - token = read32 (ip); - ip += 4; - break; - } -#endif - case CEE_INITBLK: - CHECK_STACK(&td, 3); - ADD_CODE(&td, MINT_INITBLK); - td.sp -= 3; - break; -#if 0 - case CEE_NO_: - /* FIXME: implement */ - ip += 2; - break; -#endif - case CEE_RETHROW: - SIMPLE_OP (td, MINT_RETHROW); - generating_code = 0; - break; - case CEE_SIZEOF: { - guint32 align; - gint32 size; - token = read32 (td.ip + 1); - td.ip += 5; - if (mono_metadata_token_table (token) == MONO_TABLE_TYPESPEC) { - MonoType *type = mono_type_create_from_typespec (image, token); - size = mono_type_size (type, &align); - } else { - MonoClass *szclass = mono_class_get_full (image, token, generic_context); - mono_class_init (szclass); -#if 0 - if (!szclass->valuetype) - THROW_EX (mono_exception_from_name (mono_defaults.corlib, "System", "InvalidProgramException"), ip - 5); -#endif - size = mono_class_value_size (szclass, &align); - } - ADD_CODE(&td, MINT_LDC_I4); - WRITE32(&td, &size); - PUSH_SIMPLE_TYPE(&td, STACK_TYPE_I4); - break; - } -#if 0 - case CEE_REFANYTYPE: ves_abort(); break; -#endif - default: - g_error ("transform.c: Unimplemented opcode: 0xFE %02x at 0x%x\n", *td.ip, td.ip-header->code); - } - break; - default: - g_error ("transform.c: Unimplemented opcode: %02x at 0x%x\n", *td.ip, td.ip-header->code); - } - - if (td.new_ip - td.new_code != new_in_start_offset) - td.last_new_ip = td.new_code + new_in_start_offset; - else if (td.is_bb_start [td.in_start - td.il_code]) - td.is_bb_start [td.ip - td.il_code] = 1; - - td.last_ip = td.in_start; - } - - if (mono_interp_traceopt) { - const guint16 *p = td.new_code; - printf("Runtime method: %p, VT stack size: %d\n", rtm, td.max_vt_sp); - printf("Calculated stack size: %d, stated size: %d\n", td.max_stack_height, header->max_stack); - while (p < td.new_ip) { - p = mono_interp_dis_mintop(td.new_code, p); - printf("\n"); - } - } - - rtm->clauses = mono_mempool_alloc (domain->mp, header->num_clauses * sizeof(MonoExceptionClause)); - memcpy (rtm->clauses, header->clauses, header->num_clauses * sizeof(MonoExceptionClause)); - rtm->code = mono_mempool_alloc (domain->mp, (td.new_ip - td.new_code) * sizeof(gushort)); - memcpy (rtm->code, td.new_code, (td.new_ip - td.new_code) * sizeof(gushort)); - g_free (td.new_code); - rtm->new_body_start = rtm->code + body_start_offset; - rtm->num_clauses = header->num_clauses; - for (i = 0; i < header->num_clauses; i++) { - MonoExceptionClause *c = rtm->clauses + i; - int end_off = c->try_offset + c->try_len; - c->try_offset = td.in_offsets [c->try_offset]; - c->try_len = td.in_offsets [end_off] - c->try_offset; - end_off = c->handler_offset + c->handler_len; - c->handler_offset = td.in_offsets [c->handler_offset]; - c->handler_len = td.in_offsets [end_off] - c->handler_offset; - } - rtm->vt_stack_size = td.max_vt_sp; - rtm->alloca_size = rtm->locals_size + rtm->args_size + rtm->vt_stack_size + rtm->stack_size; - rtm->data_items = mono_mempool_alloc (domain->mp, td.n_data_items * sizeof (td.data_items [0])); - memcpy (rtm->data_items, td.data_items, td.n_data_items * sizeof (td.data_items [0])); - g_free (td.in_offsets); - g_free (td.forward_refs); - for (i = 0; i < header->code_size; ++i) - g_free (td.stack_state [i]); - g_free (td.stack_state); - g_free (td.stack_height); - g_free (td.vt_stack_size); - g_free (td.data_items); - g_hash_table_destroy (td.data_hash); -} - -static mono_mutex_t calc_section; - -void -mono_interp_transform_init (void) -{ - mono_mutex_init_recursive(&calc_section); -} - -MonoException * -mono_interp_transform_method (RuntimeMethod *runtime_method, ThreadContext *context) -{ - int i, align, size, offset; - MonoMethod *method = runtime_method->method; - MonoImage *image = method->klass->image; - MonoMethodHeader *header = mono_method_get_header (method); - MonoMethodSignature *signature = mono_method_signature (method); - register const unsigned char *ip, *end; - const MonoOpcode *opcode; - MonoMethod *m; - MonoClass *class; - MonoDomain *domain = mono_domain_get (); - unsigned char *is_bb_start; - int in; - MonoVTable *method_class_vt; - int backwards; - MonoGenericContext *generic_context = NULL; - - method_class_vt = mono_class_vtable (domain, runtime_method->method->klass); - if (!method_class_vt->initialized) { - jmp_buf env; - MonoInvocation *last_env_frame = context->env_frame; - jmp_buf *old_env = context->current_env; - - if (setjmp(env)) { - MonoException *failed = context->env_frame->ex; - context->env_frame->ex = NULL; - context->env_frame = last_env_frame; - context->current_env = old_env; - return failed; - } - context->env_frame = context->current_frame; - context->current_env = &env; - mono_runtime_class_init (method_class_vt); - context->env_frame = last_env_frame; - context->current_env = old_env; - } - - mono_profiler_method_jit (method); /* sort of... */ - - if (mono_method_signature (method)->is_inflated) - generic_context = ((MonoMethodInflated *) method)->context; - - if (method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)) { - MonoMethod *nm = NULL; - mono_mutex_lock(&calc_section); - if (runtime_method->transformed) { - mono_mutex_unlock(&calc_section); - mono_profiler_method_end_jit (method, MONO_PROFILE_OK); - return NULL; - } - - /* assumes all internal calls with an array this are built in... */ - if (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL && - (! mono_method_signature (method)->hasthis || method->klass->rank == 0)) { - runtime_method->code = g_malloc(sizeof(short)); - runtime_method->code[0] = MINT_CALLINT; - if (((MonoMethodPInvoke*) method)->addr == NULL) - ((MonoMethodPInvoke*) method)->addr = mono_lookup_internal_call (method); - runtime_method->func = mono_arch_create_trampoline (mono_method_signature (method), method->string_ctor); - } else { - const char *name = method->name; - if (method->klass->parent == mono_defaults.multicastdelegate_class) { - if (*name == 'I' && (strcmp (name, "Invoke") == 0)) { - nm = mono_marshal_get_delegate_invoke (method); - } else if (*name == 'B' && (strcmp (name, "BeginInvoke") == 0)) { - nm = mono_marshal_get_delegate_begin_invoke (method); - } else if (*name == 'E' && (strcmp (name, "EndInvoke") == 0)) { - nm = mono_marshal_get_delegate_end_invoke (method); - } - } - if (nm == NULL) { - runtime_method->code = g_malloc(sizeof(short)); - runtime_method->code[0] = MINT_CALLRUN; - } - } - if (nm == NULL) { - runtime_method->stack_size = sizeof (stackval); /* for tracing */ - runtime_method->alloca_size = runtime_method->stack_size; - runtime_method->transformed = TRUE; - mono_mutex_unlock(&calc_section); - mono_profiler_method_end_jit (method, MONO_PROFILE_OK); - return NULL; - } - method = nm; - header = mono_method_get_header (nm); - mono_mutex_unlock(&calc_section); - } - g_assert ((signature->param_count + signature->hasthis) < 1000); - g_assert (header->max_stack < 10000); - /* intern the strings in the method. */ - ip = header->code; - end = ip + header->code_size; - - is_bb_start = g_malloc0(header->code_size); - is_bb_start [0] = 1; - while (ip < end) { - in = *ip; - if (in == 0xfe) { - ip++; - in = *ip + 256; - } - else if (in == 0xf0) { - ip++; - in = *ip + MONO_CEE_MONO_ICALL; - } - opcode = &mono_opcodes [in]; - switch (opcode->argument) { - case MonoInlineNone: - ++ip; - break; - case MonoInlineString: - if (method->wrapper_type == MONO_WRAPPER_NONE) - mono_ldstr (domain, image, mono_metadata_token_index (read32 (ip + 1))); - ip += 5; - break; - case MonoInlineType: - if (method->wrapper_type == MONO_WRAPPER_NONE) { - class = mono_class_get_full (image, read32 (ip + 1), generic_context); - mono_class_init (class); - /* quick fix to not do this for the fake ptr classes - probably should not be getting the vtable at all here */ - if (!(class->flags & TYPE_ATTRIBUTE_INTERFACE) && class->interface_offsets != NULL) - mono_class_vtable (domain, class); - } - ip += 5; - break; - case MonoInlineMethod: - if (method->wrapper_type == MONO_WRAPPER_NONE && *ip != CEE_CALLI) { - m = mono_get_method_full (image, read32 (ip + 1), NULL, generic_context); - if (m == NULL) { - g_free (is_bb_start); - return mono_get_exception_missing_method (); - } - mono_class_init (m->klass); - if (!(m->klass->flags & TYPE_ATTRIBUTE_INTERFACE)) - mono_class_vtable (domain, m->klass); - } - ip += 5; - break; - case MonoInlineField: - case MonoInlineSig: - case MonoInlineI: - case MonoInlineTok: - case MonoShortInlineR: - ip += 5; - break; - case MonoInlineBrTarget: - offset = read32 (ip + 1); - ip += 5; - backwards = offset < 0; - offset += ip - header->code; - g_assert (offset >= 0 && offset < header->code_size); - is_bb_start [offset] |= backwards ? 2 : 1; - break; - case MonoShortInlineBrTarget: - offset = ((gint8 *)ip) [1]; - ip += 2; - backwards = offset < 0; - offset += ip - header->code; - g_assert (offset >= 0 && offset < header->code_size); - is_bb_start [offset] |= backwards ? 2 : 1; - break; - case MonoInlineVar: - ip += 3; - break; - case MonoShortInlineVar: - case MonoShortInlineI: - ip += 2; - break; - case MonoInlineSwitch: { - guint32 n; - const unsigned char *next_ip; - ++ip; - n = read32 (ip); - ip += 4; - next_ip = ip + 4 * n; - for (i = 0; i < n; i++) { - offset = read32 (ip); - backwards = offset < 0; - offset += next_ip - header->code; - g_assert (offset >= 0 && offset < header->code_size); - is_bb_start [offset] |= backwards ? 2 : 1; - ip += 4; - } - break; - } - case MonoInlineR: - case MonoInlineI8: - ip += 9; - break; - default: - g_assert_not_reached (); - } - } - - /* the rest needs to be locked so it is only done once */ - mono_mutex_lock(&calc_section); - if (runtime_method->transformed) { - mono_mutex_unlock(&calc_section); - g_free (is_bb_start); - mono_profiler_method_end_jit (method, MONO_PROFILE_OK); - return NULL; - } - - runtime_method->local_offsets = g_malloc (header->num_locals * sizeof(guint32)); - runtime_method->stack_size = (sizeof (stackval) + 2) * header->max_stack; /* + 1 for returns of called functions + 1 for 0-ing in trace*/ - runtime_method->stack_size = (runtime_method->stack_size + 7) & ~7; - offset = 0; - for (i = 0; i < header->num_locals; ++i) { - size = mono_type_size (header->locals [i], &align); - offset += align - 1; - offset &= ~(align - 1); - runtime_method->local_offsets [i] = offset; - offset += size; - } - offset = (offset + 7) & ~7; - runtime_method->locals_size = offset; - g_assert (runtime_method->locals_size < 65536); - offset = 0; - runtime_method->arg_offsets = g_malloc(signature->param_count * sizeof(guint32)); - for (i = 0; i < signature->param_count; ++i) { - if (signature->pinvoke) { - size = mono_type_native_stack_size (signature->params [i], &align); - align = 8; - } - else - size = mono_type_stack_size (signature->params [i], &align); - offset += align - 1; - offset &= ~(align - 1); - runtime_method->arg_offsets [i] = offset; - offset += size; - } - offset = (offset + 7) & ~7; - runtime_method->args_size = offset; - g_assert (runtime_method->args_size < 10000); - - generate(method, runtime_method, is_bb_start); - - g_free (is_bb_start); - - mono_profiler_method_end_jit (method, MONO_PROFILE_OK); - runtime_method->transformed = TRUE; - mono_mutex_unlock(&calc_section); - - return NULL; -} - diff --git a/mono/io-layer/handles.c b/mono/io-layer/handles.c index 8cd74e9ff3..3173399092 100644 --- a/mono/io-layer/handles.c +++ b/mono/io-layer/handles.c @@ -29,6 +29,9 @@ # include #endif #include +#ifdef HAVE_SYS_RESOURCE_H +# include +#endif #include #include @@ -39,6 +42,7 @@ #include #include +#include #undef DEBUG_REFS #if 0 @@ -213,6 +217,21 @@ static void handle_cleanup (void) g_free (_wapi_private_handles [i]); } +int +wapi_getdtablesize (void) +{ +#ifdef HAVE_GETRLIMIT + struct rlimit limit; + int res; + + res = getrlimit (RLIMIT_NOFILE, &limit); + g_assert (res == 0); + return limit.rlim_cur; +#else + return getdtablesize (); +#endif +} + /* * wapi_init: * @@ -223,8 +242,8 @@ wapi_init (void) { g_assert ((sizeof (handle_ops) / sizeof (handle_ops[0])) == WAPI_HANDLE_COUNT); - - _wapi_fd_reserve = getdtablesize(); + + _wapi_fd_reserve = wapi_getdtablesize (); /* This is needed by the code in _wapi_handle_new_internal */ _wapi_fd_reserve = (_wapi_fd_reserve + (_WAPI_HANDLE_INITIAL_COUNT - 1)) & ~(_WAPI_HANDLE_INITIAL_COUNT - 1); @@ -266,13 +285,14 @@ wapi_init (void) _wapi_global_signal_cond = &_WAPI_PRIVATE_HANDLES (GPOINTER_TO_UINT (_wapi_global_signal_handle)).signal_cond; _wapi_global_signal_mutex = &_WAPI_PRIVATE_HANDLES (GPOINTER_TO_UINT (_wapi_global_signal_handle)).signal_mutex; + wapi_processes_init (); - /* Using g_atexit here instead of an explicit function call in + /* Using atexit here instead of an explicit function call in * a cleanup routine lets us cope when a third-party library * calls exit (eg if an X client loses the connection to its * server.) */ - g_atexit (handle_cleanup); + mono_atexit (handle_cleanup); } void @@ -1841,65 +1861,6 @@ void _wapi_handle_check_share (struct _WapiFileShare *share_info, int fd) } } - for (i = 0; i < _WAPI_HANDLE_INITIAL_COUNT; i++) { - struct _WapiHandleShared *shared; - struct _WapiHandle_process *process_handle; - - shared = &_wapi_shared_layout->handles[i]; - - if (shared->type == WAPI_HANDLE_PROCESS) { - DIR *fd_dir; - struct dirent *fd_entry; - char subdir[_POSIX_PATH_MAX]; - - process_handle = &shared->u.process; - pid = process_handle->id; - - /* Look in /proc//fd/ but ignore - * /proc//fd/, as we have the - * file open too - */ - g_snprintf (subdir, _POSIX_PATH_MAX, "/proc/%d/fd", - pid); - - fd_dir = opendir (subdir); - if (fd_dir == NULL) { - continue; - } - - DEBUG ("%s: Looking in %s", __func__, subdir); - - proc_fds = TRUE; - - while ((fd_entry = readdir (fd_dir)) != NULL) { - char path[_POSIX_PATH_MAX]; - struct stat link_stat; - - if (!strcmp (fd_entry->d_name, ".") || - !strcmp (fd_entry->d_name, "..") || - (pid == self && - fd == atoi (fd_entry->d_name))) { - continue; - } - - g_snprintf (path, _POSIX_PATH_MAX, - "/proc/%d/fd/%s", pid, - fd_entry->d_name); - - stat (path, &link_stat); - if (link_stat.st_dev == share_info->device && - link_stat.st_ino == share_info->inode) { - DEBUG ("%s: Found it at %s", - __func__, path); - - found = TRUE; - } - } - - closedir (fd_dir); - } - } - if (proc_fds == FALSE) { _wapi_handle_check_share_by_pid (share_info); } else if (found == FALSE) { diff --git a/mono/io-layer/handles.h b/mono/io-layer/handles.h index 04444d0ae8..31cab7bdb9 100644 --- a/mono/io-layer/handles.h +++ b/mono/io-layer/handles.h @@ -20,6 +20,8 @@ extern gboolean DuplicateHandle (gpointer srcprocess, gpointer src, gpointer tar extern void wapi_init (void); extern void wapi_cleanup (void); +int wapi_getdtablesize (void); + G_END_DECLS #endif /* _WAPI_HANDLES_H_ */ diff --git a/mono/io-layer/io-layer.h b/mono/io-layer/io-layer.h index 394799bc86..6b21f056ca 100755 --- a/mono/io-layer/io-layer.h +++ b/mono/io-layer/io-layer.h @@ -21,9 +21,9 @@ * Declare as __GetProcessId for unsupported targets. */ #define GetProcessId __GetProcessId #endif -#include #include #include +#include /* * The mingw version says: * /usr/i686-pc-mingw32/sys-root/mingw/include/ws2tcpip.h:38:2: error: #error "ws2tcpip.h is not compatible with winsock.h. Include winsock2.h instead." diff --git a/mono/io-layer/io.c.REMOVED.git-id b/mono/io-layer/io.c.REMOVED.git-id index 9e31f3e576..62a2c3de85 100644 --- a/mono/io-layer/io.c.REMOVED.git-id +++ b/mono/io-layer/io.c.REMOVED.git-id @@ -1 +1 @@ -169cb07617adb06ac4bcb88ea5cc6fd59adad7b6 \ No newline at end of file +03672d4197efd1f5439337d506be2a9cdb2a815e \ No newline at end of file diff --git a/mono/io-layer/process-private.h b/mono/io-layer/process-private.h index c3e6988732..1da7f472f0 100644 --- a/mono/io-layer/process-private.h +++ b/mono/io-layer/process-private.h @@ -16,18 +16,24 @@ /* There doesn't seem to be a defined symbol for this */ #define _WAPI_PROCESS_CURRENT (gpointer)0xFFFFFFFF +/* + * Handles > _WAPI_PROCESS_UNHANDLED are pseudo handles which represent processes + * not started by the runtime. + */ /* This marks a system process that we don't have a handle on */ /* FIXME: Cope with PIDs > sizeof guint */ #define _WAPI_PROCESS_UNHANDLED (1 << (8*sizeof(pid_t)-1)) #define _WAPI_PROCESS_UNHANDLED_PID_MASK (-1 & ~_WAPI_PROCESS_UNHANDLED) +#define WAPI_IS_PSEUDO_PROCESS_HANDLE(handle) ((GPOINTER_TO_UINT(handle) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) +#define WAPI_PID_TO_HANDLE(pid) GINT_TO_POINTER (_WAPI_PROCESS_UNHANDLED + (pid)) +#define WAPI_HANDLE_TO_PID(handle) (GPOINTER_TO_UINT ((handle)) - _WAPI_PROCESS_UNHANDLED) +void wapi_processes_init (void); extern gpointer _wapi_process_duplicate (void); extern void wapi_processes_cleanup (void); extern struct _WapiHandleOps _wapi_process_ops; -#define _WAPI_PROC_NAME_MAX_LEN _POSIX_PATH_MAX - /* * MonoProcess describes processes we create. * It contains a semaphore that can be waited on in order to wait @@ -42,8 +48,7 @@ struct MonoProcess { gint32 handle_count; /* the number of handles to this mono_process instance */ /* we keep a ref to the creating _WapiHandle_process handle until * the process has exited, so that the information there isn't lost. - * If we put the information there in this structure, it won't be - * available to other processes when using shared handles. */ + */ gpointer handle; struct MonoProcess *next; }; @@ -52,8 +57,6 @@ struct MonoProcess { /* * _WapiHandle_process is a structure containing all the required information * for process handling. - * The mono_process field is only present if this process has created - * the corresponding process. */ struct _WapiHandle_process { @@ -62,12 +65,13 @@ struct _WapiHandle_process gpointer main_thread; WapiFileTime create_time; WapiFileTime exit_time; - gchar proc_name[_WAPI_PROC_NAME_MAX_LEN]; + char *proc_name; size_t min_working_set; size_t max_working_set; gboolean exited; - pid_t self; /* mono_process is shared among processes, but only usable in the process that created it */ struct MonoProcess *mono_process; }; +typedef struct _WapiHandle_process WapiHandle_process; + #endif /* _WAPI_PROCESS_PRIVATE_H_ */ diff --git a/mono/io-layer/processes.c b/mono/io-layer/processes.c index c65bf23813..3c0531f3de 100644 --- a/mono/io-layer/processes.c +++ b/mono/io-layer/processes.c @@ -86,7 +86,7 @@ * arm-apple-darwin9. We'll manually define the symbol on Apple as it does * in fact exist on all implementations (so far) */ -gchar ***_NSGetEnviron(void); +char ***_NSGetEnviron(void); #define environ (*_NSGetEnviron()) #else extern char **environ; @@ -142,22 +142,25 @@ static volatile gint32 mono_processes_cleaning_up = 0; static mono_mutex_t mono_processes_mutex; static void mono_processes_cleanup (void); -static mono_once_t process_current_once=MONO_ONCE_INIT; -static gpointer current_process=NULL; +static gpointer current_process; static char *cli_launcher; -static mono_once_t process_ops_once=MONO_ONCE_INIT; - -static void process_ops_init (void) +static WapiHandle_process * +lookup_process_handle (gpointer handle) { - _wapi_handle_register_capabilities (WAPI_HANDLE_PROCESS, - WAPI_HANDLE_CAP_WAIT | - WAPI_HANDLE_CAP_SPECIAL_WAIT); + WapiHandle_process *process_data; + gboolean ret; + + ret = _wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS, + (gpointer *)&process_data); + if (!ret) + return NULL; + return process_data; } - /* Check if a pid is valid - i.e. if a process exists with this pid. */ -static gboolean is_pid_valid (pid_t pid) +static gboolean +is_pid_valid (pid_t pid) { gboolean result = FALSE; @@ -169,7 +172,7 @@ static gboolean is_pid_valid (pid_t pid) if (get_team_info ((team_id)pid, &teamInfo) == B_OK) result = TRUE; #else - gchar *dir = g_strdup_printf ("/proc/%d", pid); + char *dir = g_strdup_printf ("/proc/%d", pid); if (!access (dir, F_OK)) result = TRUE; g_free (dir); @@ -178,7 +181,8 @@ static gboolean is_pid_valid (pid_t pid) return result; } -static void process_set_defaults (struct _WapiHandle_process *process_handle) +static void +process_set_defaults (WapiHandle_process *process_handle) { /* These seem to be the defaults on w2k */ process_handle->min_working_set = 204800; @@ -233,42 +237,6 @@ utf16_concat (const gunichar2 *first, ...) return ret; } -#ifdef PLATFORM_MACOSX - -/* 0 = no detection; -1 = not 10.5 or higher; 1 = 10.5 or higher */ -static int osx_10_5_or_higher; - -static void -detect_osx_10_5_or_higher (void) -{ - struct utsname u; - char *p; - int v; - - if (uname (&u) != 0){ - osx_10_5_or_higher = 1; - return; - } - - p = u.release; - v = atoi (p); - - if (v < 9) - osx_10_5_or_higher = -1; - else - osx_10_5_or_higher = 1; -} - -static gboolean -is_macos_10_5_or_higher (void) -{ - if (osx_10_5_or_higher == 0) - detect_osx_10_5_or_higher (); - - return (osx_10_5_or_higher == 1); -} -#endif - static const gunichar2 utf16_space_bytes [2] = { 0x20, 0 }; static const gunichar2 *utf16_space = utf16_space_bytes; static const gunichar2 utf16_quote_bytes [2] = { 0x22, 0 }; @@ -279,7 +247,7 @@ static const gunichar2 *utf16_quote = utf16_quote_bytes; void print_utf16 (gunichar2 *str) { - gchar *res; + char *res; res = g_utf16_to_utf8 (str, -1, NULL, NULL, NULL); g_print ("%s\n", res); @@ -288,7 +256,8 @@ print_utf16 (gunichar2 *str) #endif /* Implemented as just a wrapper around CreateProcess () */ -gboolean ShellExecuteEx (WapiShellExecuteInfo *sei) +gboolean +ShellExecuteEx (WapiShellExecuteInfo *sei) { gboolean ret; WapiProcessInformation process_info; @@ -299,13 +268,12 @@ gboolean ShellExecuteEx (WapiShellExecuteInfo *sei) * that */ SetLastError (ERROR_INVALID_PARAMETER); - return (FALSE); + return FALSE; } - if (sei->lpFile == NULL) { + if (sei->lpFile == NULL) /* w2k returns TRUE for this, for some reason. */ - return (TRUE); - } + return TRUE; /* Put both executable and parameters into the second argument * to CreateProcess (), so it searches $PATH. The conversion @@ -313,9 +281,9 @@ gboolean ShellExecuteEx (WapiShellExecuteInfo *sei) * g_strdup_printf () equivalent for gunichar2 :-( */ args = utf16_concat (utf16_quote, sei->lpFile, utf16_quote, sei->lpParameters == NULL ? NULL : utf16_space, sei->lpParameters, NULL); - if (args == NULL){ + if (args == NULL) { SetLastError (ERROR_INVALID_DATA); - return (FALSE); + return FALSE; } ret = CreateProcess (NULL, args, NULL, NULL, TRUE, CREATE_UNICODE_ENVIRONMENT, NULL, @@ -346,7 +314,7 @@ gboolean ShellExecuteEx (WapiShellExecuteInfo *sei) handler = g_find_program_in_path ("kfmclient"); if (handler == NULL){ handler_utf16 = (gunichar2 *) -1; - return (FALSE); + return FALSE; } else { /* kfmclient needs exec argument */ char *old = handler; @@ -370,7 +338,7 @@ gboolean ShellExecuteEx (WapiShellExecuteInfo *sei) sei->lpFile, utf16_quote, sei->lpParameters == NULL ? NULL : utf16_space, sei->lpParameters, NULL); - if (args == NULL){ + if (args == NULL) { SetLastError (ERROR_INVALID_DATA); return FALSE; } @@ -378,7 +346,7 @@ gboolean ShellExecuteEx (WapiShellExecuteInfo *sei) CREATE_UNICODE_ENVIRONMENT, NULL, sei->lpDirectory, NULL, &process_info); g_free (args); - if (!ret){ + if (!ret) { if (GetLastError () != ERROR_OUTOFMEMORY) SetLastError (ERROR_INVALID_DATA); return FALSE; @@ -388,17 +356,16 @@ gboolean ShellExecuteEx (WapiShellExecuteInfo *sei) process_info.hProcess = NULL; } - if (sei->fMask & SEE_MASK_NOCLOSEPROCESS) { + if (sei->fMask & SEE_MASK_NOCLOSEPROCESS) sei->hProcess = process_info.hProcess; - } else { + else CloseHandle (process_info.hProcess); - } - return (ret); + return ret; } static gboolean -is_managed_binary (const gchar *filename) +is_managed_binary (const char *filename) { int original_errno = errno; #if defined(HAVE_LARGE_FILE_SUPPORT) && defined(O_LARGEFILE) @@ -505,17 +472,18 @@ leave: return managed; } -gboolean CreateProcessWithLogonW (const gunichar2 *username, - const gunichar2 *domain, - const gunichar2 *password, - const guint32 logonFlags, - const gunichar2 *appname, - const gunichar2 *cmdline, - guint32 create_flags, - gpointer env, - const gunichar2 *cwd, - WapiStartupInfo *startup, - WapiProcessInformation *process_info) +gboolean +CreateProcessWithLogonW (const gunichar2 *username, + const gunichar2 *domain, + const gunichar2 *password, + const guint32 logonFlags, + const gunichar2 *appname, + const gunichar2 *cmdline, + guint32 create_flags, + gpointer env, + const gunichar2 *cwd, + WapiStartupInfo *startup, + WapiProcessInformation *process_info) { /* FIXME: use user information */ return CreateProcess (appname, cmdline, NULL, NULL, FALSE, create_flags, env, cwd, startup, process_info); @@ -535,17 +503,15 @@ is_executable (const char *prog) } static void -switchDirectorySeparators(gchar *path) +switch_dir_separators (char *path) { size_t i, pathLength = strlen(path); /* Turn all the slashes round the right way, except for \' */ /* There are probably other characters that need to be excluded as well. */ - for (i = 0; i < pathLength; i++) - { - if (path[i] == '\\' && i < pathLength - 1 && path[i+1] != '\'' ) { + for (i = 0; i < pathLength; i++) { + if (path[i] == '\\' && i < pathLength - 1 && path[i+1] != '\'' ) path[i] = '/'; - } } } @@ -557,11 +523,12 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, WapiStartupInfo *startup, WapiProcessInformation *process_info) { - gchar *cmd=NULL, *prog = NULL, *full_prog = NULL, *args = NULL, *args_after_prog = NULL, *dir = NULL, **env_strings = NULL, **argv = NULL; + char *cmd = NULL, *prog = NULL, *full_prog = NULL, *args = NULL, *args_after_prog = NULL; + char *dir = NULL, **env_strings = NULL, **argv = NULL; guint32 i, env_count = 0; gboolean ret = FALSE; gpointer handle; - struct _WapiHandle_process process_handle = {0}, *process_handle_data; + WapiHandle_process process_handle = {0}, *process_handle_data; GError *gerr = NULL; int in_fd, out_fd, err_fd; pid_t pid; @@ -570,10 +537,9 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, int dummy; struct MonoProcess *mono_process; gboolean fork_failed = FALSE; - - mono_once (&process_ops_once, process_ops_init); + mono_once (&process_sig_chld_once, process_add_sigchld_handler); - + /* appname and cmdline specify the executable and its args: * * If appname is not NULL, it is the name of the executable. @@ -610,7 +576,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, goto free_strings; } - switchDirectorySeparators(cmd); + switch_dir_separators(cmd); } if (cmdline != NULL) { @@ -633,13 +599,13 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, } /* Turn all the slashes round the right way */ - switchDirectorySeparators(dir); + switch_dir_separators(dir); } /* We can't put off locating the executable any longer :-( */ if (cmd != NULL) { - gchar *unquoted; + char *unquoted; if (g_ascii_isalpha (cmd[0]) && (cmd[1] == ':')) { /* Strip off the drive letter. I can't * believe that CP/M holdover is still @@ -684,7 +650,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, args_after_prog = args; } else { - gchar *token = NULL; + char *token = NULL; char quote; /* Dig out the first token from args, taking quotation @@ -747,7 +713,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, /* Turn all the slashes round the right way. Only for * the prg. name */ - switchDirectorySeparators(token); + switch_dir_separators(token); if (g_ascii_isalpha (token[0]) && (token[1] == ':')) { /* Strip off the drive letter. I can't @@ -770,7 +736,6 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, SetLastError (ERROR_FILE_NOT_FOUND); goto free_strings; } - } else { char *curdir = g_get_current_dir (); @@ -846,7 +811,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, } if (args_after_prog != NULL && *args_after_prog) { - gchar *qprog; + char *qprog; qprog = g_shell_quote (prog); full_prog = g_strconcat (qprog, " ", args_after_prog, NULL); @@ -873,8 +838,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, err_fd = GPOINTER_TO_UINT (GetStdHandle (STD_ERROR_HANDLE)); } - g_strlcpy (process_handle.proc_name, prog, - _WAPI_PROC_NAME_MAX_LEN - 1); + process_handle.proc_name = g_strdup (prog); process_set_defaults (&process_handle); @@ -895,7 +859,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, * environment variables in the new process. Otherwise the * new process inherits the same environment. */ - if (new_environ != NULL) { + if (new_environ) { gunichar2 *new_environp; /* Count the number of strings */ @@ -910,7 +874,7 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, /* +2: one for the process handle value, and the last * one is NULL */ - env_strings = g_new0 (gchar *, env_count + 2); + env_strings = g_new0 (char *, env_count + 2); /* Copy each environ string into 'strings' turning it * into utf8 (or the requested encoding) at the same @@ -926,14 +890,13 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, } } } else { - for (i = 0; environ[i] != NULL; i++) { + for (i = 0; environ[i] != NULL; i++) env_count++; - } /* +2: one for the process handle value, and the last * one is NULL */ - env_strings = g_new0 (gchar *, env_count + 2); + env_strings = g_new0 (char *, env_count + 2); /* Copy each environ string into 'strings' turning it * into utf8 (or the requested encoding) at the same @@ -945,18 +908,6 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, env_count++; } } - /* pass process handle info to the child, so it doesn't have - * to do an expensive search over the whole list - */ - if (env_strings != NULL) { - struct _WapiHandleUnshared *handle_data; - struct _WapiHandle_shared_ref *ref; - - handle_data = &_WAPI_PRIVATE_HANDLES(GPOINTER_TO_UINT(handle)); - ref = &handle_data->u.shared; - - env_strings[env_count] = g_strdup_printf ("_WAPI_PROCESS_HANDLE_OFFSET=%d", ref->offset); - } /* Create a pipe to make sure the child doesn't exit before * we can add the process to the linked list of mono_processes */ @@ -1000,20 +951,17 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, } /* Close all file descriptors */ - for (i = getdtablesize () - 1; i > 2; i--) { + for (i = wapi_getdtablesize () - 1; i > 2; i--) close (i); - } #ifdef DEBUG_ENABLED DEBUG ("%s: exec()ing [%s] in dir [%s]", __func__, cmd, - dir==NULL?".":dir); - for (i = 0; argv[i] != NULL; i++) { + dir == NULL?".":dir); + for (i = 0; argv[i] != NULL; i++) g_message ("arg %d: [%s]", i, argv[i]); - } - for (i = 0; env_strings[i] != NULL; i++) { + for (i = 0; env_strings[i] != NULL; i++) g_message ("env %d: [%s]", i, env_strings[i]); - } #endif /* set cwd */ @@ -1030,9 +978,8 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, } /* parent */ - ret = _wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS, - (gpointer *)&process_handle_data); - if (ret == FALSE) { + process_handle_data = lookup_process_handle (handle); + if (!process_handle_data) { g_warning ("%s: error looking up process handle %p", __func__, handle); _wapi_handle_unref (handle); @@ -1057,7 +1004,6 @@ gboolean CreateProcess (const gunichar2 *appname, const gunichar2 *cmdline, _wapi_handle_ref (handle); mono_process->handle = handle; - process_handle_data->self = _wapi_getpid (); process_handle_data->mono_process = mono_process; mono_mutex_lock (&mono_processes_mutex); @@ -1091,27 +1037,20 @@ cleanup: } free_strings: - if (cmd != NULL) { + if (cmd) g_free (cmd); - } - if (full_prog != NULL) { + if (full_prog) g_free (full_prog); - } - if (prog != NULL) { + if (prog) g_free (prog); - } - if (args != NULL) { + if (args) g_free (args); - } - if (dir != NULL) { + if (dir) g_free (dir); - } - if(env_strings != NULL) { + if (env_strings) g_strfreev (env_strings); - } - if (argv != NULL) { + if (argv) g_strfreev (argv); - } DEBUG ("%s: returning handle %p for pid %d", __func__, handle, pid); @@ -1119,98 +1058,39 @@ free_strings: /* Check if something needs to be cleaned up. */ mono_processes_cleanup (); - return(ret); + return ret; } -static void process_set_name (struct _WapiHandle_process *process_handle) +static void +process_set_name (WapiHandle_process *process_handle) { - gchar *progname, *utf8_progname, *slash; + char *progname, *utf8_progname, *slash; - progname=g_get_prgname (); - utf8_progname=mono_utf8_from_external (progname); + progname = g_get_prgname (); + utf8_progname = mono_utf8_from_external (progname); DEBUG ("%s: using [%s] as prog name", __func__, progname); - if(utf8_progname!=NULL) { - slash=strrchr (utf8_progname, '/'); - if(slash!=NULL) { - g_strlcpy (process_handle->proc_name, slash+1, - _WAPI_PROC_NAME_MAX_LEN - 1); - } else { - g_strlcpy (process_handle->proc_name, utf8_progname, - _WAPI_PROC_NAME_MAX_LEN - 1); - } - + if (utf8_progname) { + slash = strrchr (utf8_progname, '/'); + if (slash) + process_handle->proc_name = g_strdup (slash+1); + else + process_handle->proc_name = g_strdup (utf8_progname); g_free (utf8_progname); } } -extern void _wapi_time_t_to_filetime (time_t timeval, WapiFileTime *filetime); - -#if !GLIB_CHECK_VERSION (2,4,0) -#define g_setenv(a,b,c) setenv(a,b,c) -#define g_unsetenv(a) unsetenv(a) -#endif - -static void process_set_current (void) +void +wapi_processes_init (void) { pid_t pid = _wapi_getpid (); - const char *handle_env; - struct _WapiHandle_process process_handle = {0}; + WapiHandle_process process_handle = {0}; + + _wapi_handle_register_capabilities (WAPI_HANDLE_PROCESS, + WAPI_HANDLE_CAP_WAIT | + WAPI_HANDLE_CAP_SPECIAL_WAIT); - mono_once (&process_ops_once, process_ops_init); - - handle_env = g_getenv ("_WAPI_PROCESS_HANDLE_OFFSET"); - g_unsetenv ("_WAPI_PROCESS_HANDLE_OFFSET"); - - if (handle_env != NULL) { - struct _WapiHandle_process *process_handlep; - gchar *procname = NULL; - gboolean ok; - - current_process = _wapi_handle_new_from_offset (WAPI_HANDLE_PROCESS, atoi (handle_env), TRUE); - - DEBUG ("%s: Found my process handle: %p (offset %d 0x%x)", - __func__, current_process, atoi (handle_env), - atoi (handle_env)); - - ok = _wapi_lookup_handle (current_process, WAPI_HANDLE_PROCESS, - (gpointer *)&process_handlep); - if (ok) { - /* This test will probably break on linuxthreads, but - * that should be ancient history on all distros we - * care about by now - */ - if (process_handlep->id == pid) { - procname = process_handlep->proc_name; - if (!strcmp (procname, "mono")) { - /* Set a better process name */ - DEBUG ("%s: Setting better process name", __func__); - - process_set_name (process_handlep); - } else { - DEBUG ("%s: Leaving process name: %s", __func__, procname); - } - - return; - } - - /* Wrong pid, so drop this handle and fall through to - * create a new one - */ - _wapi_handle_unref (current_process); - } - } - - /* We get here if the handle wasn't specified in the - * environment, or if the process ID was wrong, or if the - * handle lookup failed (eg if the parent process forked and - * quit immediately, and deleted the shared data before the - * child got a chance to attach it.) - */ - - DEBUG ("%s: Need to create my own process handle", __func__); - process_handle.id = pid; process_set_defaults (&process_handle); @@ -1218,273 +1098,60 @@ static void process_set_current (void) current_process = _wapi_handle_new (WAPI_HANDLE_PROCESS, &process_handle); - if (current_process == _WAPI_HANDLE_INVALID) { - g_warning ("%s: error creating process handle", __func__); - return; - } + g_assert (current_process); } -gpointer _wapi_process_duplicate () +gpointer +_wapi_process_duplicate (void) { - mono_once (&process_current_once, process_set_current); - _wapi_handle_ref (current_process); - return(current_process); + return current_process; } /* Returns a pseudo handle that doesn't need to be closed afterwards */ -gpointer GetCurrentProcess (void) +gpointer +GetCurrentProcess (void) { - mono_once (&process_current_once, process_set_current); - - return(_WAPI_PROCESS_CURRENT); + return _WAPI_PROCESS_CURRENT; } -guint32 GetProcessId (gpointer handle) +guint32 +GetProcessId (gpointer handle) { - struct _WapiHandle_process *process_handle; - gboolean ok; + WapiHandle_process *process_handle; - if ((GPOINTER_TO_UINT (handle) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) { + if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle)) /* This is a pseudo handle */ - return(GPOINTER_TO_UINT (handle) & _WAPI_PROCESS_UNHANDLED_PID_MASK); - } + return WAPI_HANDLE_TO_PID (handle); - ok = _wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS, - (gpointer *)&process_handle); - if (ok == FALSE) { + process_handle = lookup_process_handle (handle); + if (!process_handle) { SetLastError (ERROR_INVALID_HANDLE); - return (0); + return 0; } - return (process_handle->id); + return process_handle->id; } -guint32 GetCurrentProcessId (void) +static gboolean +process_open_compare (gpointer handle, gpointer user_data) { - mono_once (&process_current_once, process_set_current); - - return (GetProcessId (current_process)); -} + pid_t wanted_pid; + WapiHandle_process *process_handle; + pid_t checking_pid; -/* Returns the process id as a convenience to the functions that call this */ -static pid_t signal_process_if_gone (gpointer handle) -{ - struct _WapiHandle_process *process_handle; - gboolean ok; + g_assert (!WAPI_IS_PSEUDO_PROCESS_HANDLE (handle)); - g_assert ((GPOINTER_TO_UINT (handle) & _WAPI_PROCESS_UNHANDLED) != _WAPI_PROCESS_UNHANDLED); - - /* Make sure the process is signalled if it has exited - if - * the parent process didn't wait for it then it won't be - */ - ok = _wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS, - (gpointer *)&process_handle); - if (ok == FALSE) { - /* It's possible that the handle has vanished during - * the _wapi_search_handle before it gets here, so - * don't spam the console with warnings. - */ -/* g_warning ("%s: error looking up process handle %p", - __func__, handle);*/ - - return (0); - } + process_handle = lookup_process_handle (handle); + g_assert (process_handle); DEBUG ("%s: looking at process %d", __func__, process_handle->id); - if (kill (process_handle->id, 0) == -1 && - (errno == ESRCH || - errno == EPERM)) { - /* The process is dead, (EPERM tells us a new process - * has that ID, but as it's owned by someone else it - * can't be the one listed in our shared memory file) - */ - _wapi_shared_handle_set_signal_state (handle, TRUE); - } + checking_pid = process_handle->id; - return (process_handle->id); -} - -#ifdef UNUSED_CODE -static gboolean process_enum (gpointer handle, gpointer user_data) -{ - GArray *processes=user_data; - pid_t pid = signal_process_if_gone (handle); - int i; - - if (pid == 0) { - return (FALSE); - } - - /* Ignore processes that have already exited (ie they are signalled) */ - if (_wapi_handle_issignalled (handle) == FALSE) { - DEBUG ("%s: process %d added to array", __func__, pid); - - /* This ensures that duplicates aren't returned (see - * the comment above _wapi_search_handle () for why - * it's needed - */ - for (i = 0; i < processes->len; i++) { - if (g_array_index (processes, pid_t, i) == pid) { - /* We've already got this one, return - * FALSE to keep searching - */ - return (FALSE); - } - } - - g_array_append_val (processes, pid); - } - - /* Return false to keep searching */ - return(FALSE); -} -#endif /* UNUSED_CODE */ - -#if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) - -gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed) -{ - guint32 count, fit, i, j; - gint32 err; - gboolean done; - size_t proclength, size; -#if defined(__OpenBSD__) - struct kinfo_proc *result; - int name[6]; - name[0] = CTL_KERN; - name[1] = KERN_PROC; - name[2] = KERN_PROC_ALL; - name[3] = 0; - name[4] = sizeof(struct kinfo_proc); - name[5] = 0; -#else - struct kinfo_proc *result; - static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 }; -#endif - - mono_once (&process_current_once, process_set_current); - - result = NULL; - done = FALSE; - - do { - proclength = 0; -#if defined(__OpenBSD__) - size = (sizeof(name) / sizeof(*name)); -#else - size = (sizeof(name) / sizeof(*name)) - 1; -#endif - err = sysctl ((int *)name, size, NULL, &proclength, NULL, 0); - - if (err == 0) { - result = malloc (proclength); - - if (result == NULL) - return FALSE; - -#if defined(__OpenBSD__) - name[5] = (int)(proclength / sizeof(struct kinfo_proc)); -#endif - - err = sysctl ((int *) name, size, result, &proclength, NULL, 0); - - if (err == 0) - done = TRUE; - else { - free (result); - result = NULL; - } - } - } while (err == 0 && !done); - - if (err != 0) { - if (result != NULL) { - free (result); - result = NULL; - } - return(FALSE); - } - - count = proclength / sizeof(struct kinfo_proc); - - fit = len / sizeof(guint32); - for (i = 0, j = 0; j< fit && i < count; i++) { -#if defined(__OpenBSD__) - pids [j++] = result [i].p_pid; -#else - if (result[i].kp_proc.p_pid > 0) /* Pid 0 not supported */ - pids [j++] = result [i].kp_proc.p_pid; -#endif - } - free (result); - result = NULL; - *needed = j * sizeof(guint32); - - return(TRUE); -} -#elif defined(__HAIKU__) - -gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed) -{ - guint32 fit, i = 0; - int32 cookie = 0; - team_info teamInfo; - - mono_once (&process_current_once, process_set_current); - - fit = len / sizeof (guint32); - while (get_next_team_info (&cookie, &teamInfo) == B_OK && i < fit) { - pids [i++] = teamInfo.team; - } - *needed = i * sizeof (guint32); - - return TRUE; -} -#else -gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed) -{ - guint32 fit, i; - DIR *dir; - struct dirent *entry; - - mono_once (&process_current_once, process_set_current); - - dir = opendir ("/proc"); - if (dir == NULL) { - return(FALSE); - } - - i = 0; - fit = len / sizeof (guint32); - while(i < fit && (entry = readdir (dir)) != NULL) { - pid_t pid; - char *endptr; - - if (!isdigit (entry->d_name[0])) - continue; - - pid = (pid_t) strtol (entry->d_name, &endptr, 10); - if (*endptr == '\0') - pids [i++] = (guint32) pid; - } - closedir (dir); - *needed = i * sizeof(guint32); - - return(TRUE); -} -#endif - -static gboolean process_open_compare (gpointer handle, gpointer user_data) -{ - pid_t wanted_pid; - pid_t checking_pid = signal_process_if_gone (handle); - - if (checking_pid == 0) { - return(FALSE); - } + if (checking_pid == 0) + return FALSE; wanted_pid = GPOINTER_TO_UINT (user_data); @@ -1493,37 +1160,34 @@ static gboolean process_open_compare (gpointer handle, gpointer user_data) * unsignalled */ if (checking_pid == wanted_pid && - _wapi_handle_issignalled (handle) == FALSE) { + !_wapi_handle_issignalled (handle)) { /* If the handle is blown away in the window between * returning TRUE here and _wapi_search_handle pinging * the timestamp, the search will continue */ - return(TRUE); + return TRUE; } else { - return(FALSE); + return FALSE; } } -gboolean CloseProcess(gpointer handle) +gboolean +CloseProcess (gpointer handle) { - if ((GPOINTER_TO_UINT (handle) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) { - /* This is a pseudo handle */ - return(TRUE); - } - + if (WAPI_IS_PSEUDO_PROCESS_HANDLE (handle)) + return TRUE; return CloseHandle (handle); } /* * The caller owns the returned handle and must call CloseProcess () on it to clean it up. */ -gpointer OpenProcess (guint32 req_access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, guint32 pid) +gpointer +OpenProcess (guint32 req_access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, guint32 pid) { /* Find the process handle that corresponds to pid */ gpointer handle = NULL; - mono_once (&process_current_once, process_set_current); - DEBUG ("%s: looking for process %d", __func__, pid); handle = _wapi_search_handle (WAPI_HANDLE_PROCESS, @@ -1534,34 +1198,31 @@ gpointer OpenProcess (guint32 req_access G_GNUC_UNUSED, gboolean inherit G_GNUC_ /* Return a pseudo handle for processes we * don't have handles for */ - return GINT_TO_POINTER (_WAPI_PROCESS_UNHANDLED + pid); + return WAPI_PID_TO_HANDLE (pid); } else { DEBUG ("%s: Can't find pid %d", __func__, pid); SetLastError (ERROR_PROC_NOT_FOUND); - return(NULL); + return NULL; } } /* _wapi_search_handle () already added a ref */ - return(handle); + return handle; } -gboolean GetExitCodeProcess (gpointer process, guint32 *code) +gboolean +GetExitCodeProcess (gpointer process, guint32 *code) { - struct _WapiHandle_process *process_handle; - gboolean ok; + WapiHandle_process *process_handle; guint32 pid = -1; - mono_once (&process_current_once, process_set_current); - - if(code==NULL) { - return(FALSE); - } + if (!code) + return FALSE; - pid = GPOINTER_TO_UINT (process) - _WAPI_PROCESS_UNHANDLED; - if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) { + if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) { + pid = WAPI_HANDLE_TO_PID (process); /* This is a pseudo handle, so we don't know what the * exit code was, but we can check whether it's alive or not */ @@ -1573,12 +1234,11 @@ gboolean GetExitCodeProcess (gpointer process, guint32 *code) } } - ok=_wapi_lookup_handle (process, WAPI_HANDLE_PROCESS, - (gpointer *)&process_handle); - if(ok==FALSE) { + process_handle = lookup_process_handle (process); + if (!process_handle) { DEBUG ("%s: Can't find process %p", __func__, process); - return(FALSE); + return FALSE; } /* A process handle is only signalled if the process has exited @@ -1589,53 +1249,46 @@ gboolean GetExitCodeProcess (gpointer process, guint32 *code) */ process_wait (process, 0, TRUE); - if (_wapi_handle_issignalled (process) == TRUE) { + if (_wapi_handle_issignalled (process)) *code = process_handle->exitstatus; - } else { + else *code = STILL_ACTIVE; - } - return(TRUE); + return TRUE; } -gboolean GetProcessTimes (gpointer process, WapiFileTime *create_time, - WapiFileTime *exit_time, WapiFileTime *kernel_time, - WapiFileTime *user_time) +gboolean +GetProcessTimes (gpointer process, WapiFileTime *create_time, + WapiFileTime *exit_time, WapiFileTime *kernel_time, + WapiFileTime *user_time) { - struct _WapiHandle_process *process_handle; - gboolean ok; + WapiHandle_process *process_handle; gboolean ku_times_set = FALSE; - mono_once (&process_current_once, process_set_current); - - if(create_time==NULL || exit_time==NULL || kernel_time==NULL || - user_time==NULL) { + if (create_time == NULL || exit_time == NULL || kernel_time == NULL || + user_time == NULL) /* Not sure if w32 allows NULLs here or not */ - return(FALSE); - } + return FALSE; - if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) { + if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) /* This is a pseudo handle, so just fail for now */ - return(FALSE); - } + return FALSE; - ok=_wapi_lookup_handle (process, WAPI_HANDLE_PROCESS, - (gpointer *)&process_handle); - if(ok==FALSE) { + process_handle = lookup_process_handle (process); + if (!process_handle) { DEBUG ("%s: Can't find process %p", __func__, process); - return(FALSE); + return FALSE; } - *create_time=process_handle->create_time; + *create_time = process_handle->create_time; /* A process handle is only signalled if the process has * exited. Otherwise exit_time isn't set */ - if(_wapi_handle_issignalled (process)==TRUE) { - *exit_time=process_handle->exit_time; - } + if (_wapi_handle_issignalled (process)) + *exit_time = process_handle->exit_time; #ifdef HAVE_GETRUSAGE if (process_handle->id == getpid ()) { @@ -1655,18 +1308,18 @@ gboolean GetProcessTimes (gpointer process, WapiFileTime *create_time, memset (user_time, 0, sizeof (WapiFileTime)); } - return(TRUE); + return TRUE; } typedef struct { gpointer address_start; gpointer address_end; - gchar *perms; + char *perms; gpointer address_offset; dev_t device; ino_t inode; - gchar *filename; + char *filename; } WapiProcModule; static void free_procmodule (WapiProcModule *mod) @@ -1843,9 +1496,9 @@ static GSList *load_modules (FILE *fp) { GSList *ret = NULL; WapiProcModule *mod; - gchar buf[MAXPATHLEN + 1], *p, *endp; - gchar *start_start, *end_start, *prot_start, *offset_start; - gchar *maj_dev_start, *min_dev_start, *inode_start, prot_buf[5]; + char buf[MAXPATHLEN + 1], *p, *endp; + char *start_start, *end_start, *prot_start, *offset_start; + char *maj_dev_start, *min_dev_start, *inode_start, prot_buf[5]; gpointer address_start, address_end, address_offset; guint32 maj_dev, min_dev; ino_t inode; @@ -1959,7 +1612,7 @@ static GSList *load_modules (FILE *fp) } #endif -static gboolean match_procname_to_modulename (gchar *procname, gchar *modulename) +static gboolean match_procname_to_modulename (char *procname, char *modulename) { char* lastsep = NULL; char* lastsep2 = NULL; @@ -2006,13 +1659,13 @@ static FILE * open_process_map (int pid, const char *mode) { FILE *fp = NULL; - const gchar *proc_path[] = { + const char *proc_path[] = { "/proc/%d/maps", /* GNU/Linux */ "/proc/%d/map", /* FreeBSD */ NULL }; int i; - gchar *filename; + char *filename; for (i = 0; fp == NULL && proc_path [i]; i++) { filename = g_strdup_printf (proc_path[i], pid); @@ -2027,8 +1680,7 @@ open_process_map (int pid, const char *mode) gboolean EnumProcessModules (gpointer process, gpointer *modules, guint32 size, guint32 *needed) { - struct _WapiHandle_process *process_handle; - gboolean ok; + WapiHandle_process *process_handle; #if !defined(__OpenBSD__) && !defined(PLATFORM_MACOSX) FILE *fp; #endif @@ -2037,7 +1689,7 @@ gboolean EnumProcessModules (gpointer process, gpointer *modules, guint32 count, avail = size / sizeof(gpointer); int i; pid_t pid; - gchar *proc_name = NULL; + char *proc_name = NULL; /* Store modules in an array of pointers (main module as * modules[0]), using the load address for each module as a @@ -2048,72 +1700,76 @@ gboolean EnumProcessModules (gpointer process, gpointer *modules, * implement /dev/kmem reading or whatever other horrid * technique is needed. */ - if (size < sizeof(gpointer)) { - return(FALSE); - } + if (size < sizeof(gpointer)) + return FALSE; - if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) { - /* This is a pseudo handle */ - pid = (pid_t)(GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED_PID_MASK); + if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) { + pid = WAPI_HANDLE_TO_PID (process); } else { - ok = _wapi_lookup_handle (process, WAPI_HANDLE_PROCESS, - (gpointer *)&process_handle); - if (ok == FALSE) { + process_handle = lookup_process_handle (process); + if (!process_handle) { DEBUG ("%s: Can't find process %p", __func__, process); - return(FALSE); + return FALSE; } pid = process_handle->id; proc_name = process_handle->proc_name; } #if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__HAIKU__) - { - mods = load_modules (); + mods = load_modules (); + if (!proc_name) { + modules[0] = NULL; + *needed = sizeof(gpointer); + return TRUE; + } #else - if ((fp = open_process_map (pid, "r")) == NULL) { + fp = open_process_map (pid, "r"); + if (!fp) { /* No /proc//maps so just return the main module * shortcut for now */ modules[0] = NULL; *needed = sizeof(gpointer); - } else { - mods = load_modules (fp); - fclose (fp); -#endif - count = g_slist_length (mods); - - /* count + 1 to leave slot 0 for the main module */ - *needed = sizeof(gpointer) * (count + 1); - - /* Use the NULL shortcut, as the first line in - * /proc//maps isn't the executable, and we need - * that first in the returned list. Check the module name - * to see if it ends with the proc name and substitute - * the first entry with it. FIXME if this turns out to - * be a problem. - */ - modules[0] = NULL; - for (i = 0; i < (avail - 1) && i < count; i++) { - module = (WapiProcModule *)g_slist_nth_data (mods, i); - if (modules[0] != NULL) - modules[i] = module->address_start; - else if (match_procname_to_modulename (proc_name, module->filename)) - modules[0] = module->address_start; - else - modules[i + 1] = module->address_start; - } - - for (i = 0; i < count; i++) { - free_procmodule (g_slist_nth_data (mods, i)); - } - g_slist_free (mods); + return TRUE; } + mods = load_modules (fp); + fclose (fp); +#endif + count = g_slist_length (mods); + + /* count + 1 to leave slot 0 for the main module */ + *needed = sizeof(gpointer) * (count + 1); - return(TRUE); + /* + * Use the NULL shortcut, as the first line in + * /proc//maps isn't the executable, and we need + * that first in the returned list. Check the module name + * to see if it ends with the proc name and substitute + * the first entry with it. FIXME if this turns out to + * be a problem. + */ + modules[0] = NULL; + for (i = 0; i < (avail - 1) && i < count; i++) { + module = (WapiProcModule *)g_slist_nth_data (mods, i); + if (modules[0] != NULL) + modules[i] = module->address_start; + else if (match_procname_to_modulename (proc_name, module->filename)) + modules[0] = module->address_start; + else + modules[i + 1] = module->address_start; + } + + for (i = 0; i < count; i++) { + free_procmodule (g_slist_nth_data (mods, i)); + } + g_slist_free (mods); + + return TRUE; } -static gchar *get_process_name_from_proc (pid_t pid) +static char * +get_process_name_from_proc (pid_t pid) { #if defined(__OpenBSD__) int mib [6]; @@ -2127,10 +1783,10 @@ static gchar *get_process_name_from_proc (pid_t pid) #endif #else FILE *fp; - gchar *filename = NULL; + char *filename = NULL; #endif - gchar buf[256]; - gchar *ret = NULL; + char buf[256]; + char *ret = NULL; #if defined(PLATFORM_SOLARIS) filename = g_strdup_printf ("/proc/%d/psinfo", pid); @@ -2239,7 +1895,7 @@ retry: filename = g_strdup_printf ("/proc/%d/stat", pid); if ((fp = fopen (filename, "r")) != NULL) { if (fgets (buf, 256, fp) != NULL) { - gchar *start, *end; + char *start, *end; start = strchr (buf, '('); if (start != NULL) { @@ -2266,11 +1922,11 @@ retry: * Return the full path of the executable of the process PID, or NULL if it cannot be determined. * Returns malloc-ed memory. */ -gchar* +char* wapi_process_get_path (pid_t pid) { #if defined(PLATFORM_MACOSX) && !defined(__mono_ppc__) && defined(TARGET_OSX) - gchar buf [PROC_PIDPATHINFO_MAXSIZE]; + char buf [PROC_PIDPATHINFO_MAXSIZE]; int res; res = proc_pidpath (pid, buf, sizeof (buf)); @@ -2296,15 +1952,15 @@ wapi_process_set_cli_launcher (char *path) cli_launcher = path ? g_strdup (path) : NULL; } -static guint32 get_module_name (gpointer process, gpointer module, - gunichar2 *basename, guint32 size, - gboolean base) +static guint32 +get_module_name (gpointer process, gpointer module, + gunichar2 *basename, guint32 size, + gboolean base) { - struct _WapiHandle_process *process_handle; - gboolean ok; + WapiHandle_process *process_handle; pid_t pid; gunichar2 *procname; - gchar *procname_ext = NULL; + char *procname_ext = NULL; glong len; gsize bytes; #if !defined(__OpenBSD__) && !defined(PLATFORM_MACOSX) @@ -2314,31 +1970,27 @@ static guint32 get_module_name (gpointer process, gpointer module, WapiProcModule *found_module; guint32 count; int i; - gchar *proc_name = NULL; + char *proc_name = NULL; - mono_once (&process_current_once, process_set_current); - DEBUG ("%s: Getting module base name, process handle %p module %p", __func__, process, module); - size = size*sizeof(gunichar2); /* adjust for unicode characters */ + size = size * sizeof (gunichar2); /* adjust for unicode characters */ - if (basename == NULL || size == 0) { - return(0); - } + if (basename == NULL || size == 0) + return 0; - if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) { + if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) { /* This is a pseudo handle */ - pid = (pid_t)(GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED_PID_MASK); + pid = (pid_t)WAPI_HANDLE_TO_PID (process); proc_name = get_process_name_from_proc (pid); } else { - ok = _wapi_lookup_handle (process, WAPI_HANDLE_PROCESS, - (gpointer *)&process_handle); - if (ok == FALSE) { + process_handle = lookup_process_handle (process); + if (!process_handle) { DEBUG ("%s: Can't find process %p", __func__, process); - return(0); + return 0; } pid = process_handle->id; proc_name = g_strdup (process_handle->proc_name); @@ -2346,10 +1998,10 @@ static guint32 get_module_name (gpointer process, gpointer module, /* Look up the address in /proc//maps */ #if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__HAIKU__) - { - mods = load_modules (); + mods = load_modules (); #else - if ((fp = open_process_map (pid, "r")) == NULL) { + fp = open_process_map (pid, "r"); + if (fp == NULL) { if (errno == EACCES && module == NULL && base == TRUE) { procname_ext = get_process_name_from_proc (pid); } else { @@ -2357,47 +2009,45 @@ static guint32 get_module_name (gpointer process, gpointer module, * for now */ g_free (proc_name); - return(0); + return 0; } } else { mods = load_modules (fp); fclose (fp); + } #endif - count = g_slist_length (mods); + count = g_slist_length (mods); - /* If module != NULL compare the address. - * If module == NULL we are looking for the main module. - * The best we can do for now check it the module name end with the process name. - */ - for (i = 0; i < count; i++) { - found_module = (WapiProcModule *)g_slist_nth_data (mods, i); - if (procname_ext == NULL && - ((module == NULL && match_procname_to_modulename (proc_name, found_module->filename)) || - (module != NULL && found_module->address_start == module))) { - if (base) { - procname_ext = g_path_get_basename (found_module->filename); - } else { - procname_ext = g_strdup (found_module->filename); - } - } - - free_procmodule (found_module); + /* If module != NULL compare the address. + * If module == NULL we are looking for the main module. + * The best we can do for now check it the module name end with the process name. + */ + for (i = 0; i < count; i++) { + found_module = (WapiProcModule *)g_slist_nth_data (mods, i); + if (procname_ext == NULL && + ((module == NULL && match_procname_to_modulename (proc_name, found_module->filename)) || + (module != NULL && found_module->address_start == module))) { + if (base) + procname_ext = g_path_get_basename (found_module->filename); + else + procname_ext = g_strdup (found_module->filename); } - if (procname_ext == NULL) - { - /* If it's *still* null, we might have hit the - * case where reading /proc/$pid/maps gives an - * empty file for this user. - */ - procname_ext = get_process_name_from_proc (pid); - } - - g_slist_free (mods); - g_free (proc_name); + free_procmodule (found_module); } - if (procname_ext != NULL) { + if (procname_ext == NULL) { + /* If it's *still* null, we might have hit the + * case where reading /proc/$pid/maps gives an + * empty file for this user. + */ + procname_ext = get_process_name_from_proc (pid); + } + + g_slist_free (mods); + g_free (proc_name); + + if (procname_ext) { DEBUG ("%s: Process name is [%s]", __func__, procname_ext); @@ -2405,7 +2055,7 @@ static guint32 get_module_name (gpointer process, gpointer module, if (procname == NULL) { /* bugger */ g_free (procname_ext); - return(0); + return 0; } len = (bytes / 2); @@ -2427,29 +2077,31 @@ static guint32 get_module_name (gpointer process, gpointer module, g_free (procname); g_free (procname_ext); - return(len); + return len; } - return(0); + return 0; } -guint32 GetModuleBaseName (gpointer process, gpointer module, - gunichar2 *basename, guint32 size) +guint32 +GetModuleBaseName (gpointer process, gpointer module, + gunichar2 *basename, guint32 size) { - return(get_module_name (process, module, basename, size, TRUE)); + return get_module_name (process, module, basename, size, TRUE); } -guint32 GetModuleFileNameEx (gpointer process, gpointer module, - gunichar2 *filename, guint32 size) +guint32 +GetModuleFileNameEx (gpointer process, gpointer module, + gunichar2 *filename, guint32 size) { - return(get_module_name (process, module, filename, size, FALSE)); + return get_module_name (process, module, filename, size, FALSE); } -gboolean GetModuleInformation (gpointer process, gpointer module, - WapiModuleInfo *modinfo, guint32 size) +gboolean +GetModuleInformation (gpointer process, gpointer module, + WapiModuleInfo *modinfo, guint32 size) { - struct _WapiHandle_process *process_handle; - gboolean ok; + WapiHandle_process *process_handle; pid_t pid; #if !defined(__OpenBSD__) && !defined(PLATFORM_MACOSX) FILE *fp; @@ -2459,37 +2111,31 @@ gboolean GetModuleInformation (gpointer process, gpointer module, guint32 count; int i; gboolean ret = FALSE; - gchar *proc_name = NULL; - - mono_once (&process_current_once, process_set_current); + char *proc_name = NULL; DEBUG ("%s: Getting module info, process handle %p module %p", __func__, process, module); - if (modinfo == NULL || size < sizeof(WapiModuleInfo)) { - return(FALSE); - } + if (modinfo == NULL || size < sizeof (WapiModuleInfo)) + return FALSE; - if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) { - /* This is a pseudo handle */ - pid = (pid_t)(GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED_PID_MASK); + if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) { + pid = (pid_t)WAPI_HANDLE_TO_PID (process); proc_name = get_process_name_from_proc (pid); } else { - ok = _wapi_lookup_handle (process, WAPI_HANDLE_PROCESS, - (gpointer *)&process_handle); - if (ok == FALSE) { + process_handle = lookup_process_handle (process); + if (!process_handle) { DEBUG ("%s: Can't find process %p", __func__, process); - return(FALSE); + return FALSE; } pid = process_handle->id; proc_name = g_strdup (process_handle->proc_name); } #if defined(PLATFORM_MACOSX) || defined(__OpenBSD__) || defined(__HAIKU__) - { - mods = load_modules (); + mods = load_modules (); #else /* Look up the address in /proc//maps */ if ((fp = open_process_map (pid, "r")) == NULL) { @@ -2497,22 +2143,22 @@ gboolean GetModuleInformation (gpointer process, gpointer module, * for now */ g_free (proc_name); - return(FALSE); - } else { - mods = load_modules (fp); - fclose (fp); + return FALSE; + } + mods = load_modules (fp); + fclose (fp); #endif - count = g_slist_length (mods); + count = g_slist_length (mods); - /* If module != NULL compare the address. - * If module == NULL we are looking for the main module. - * The best we can do for now check it the module name end with the process name. - */ - for (i = 0; i < count; i++) { + /* If module != NULL compare the address. + * If module == NULL we are looking for the main module. + * The best we can do for now check it the module name end with the process name. + */ + for (i = 0; i < count; i++) { found_module = (WapiProcModule *)g_slist_nth_data (mods, i); - if ( ret == FALSE && - ((module == NULL && match_procname_to_modulename (proc_name, found_module->filename)) || - (module != NULL && found_module->address_start == module))) { + if (ret == FALSE && + ((module == NULL && match_procname_to_modulename (proc_name, found_module->filename)) || + (module != NULL && found_module->address_start == module))) { modinfo->lpBaseOfDll = found_module->address_start; modinfo->SizeOfImage = (gsize)(found_module->address_end) - (gsize)(found_module->address_start); modinfo->EntryPoint = found_module->address_offset; @@ -2520,94 +2166,79 @@ gboolean GetModuleInformation (gpointer process, gpointer module, } free_procmodule (found_module); - } - - g_slist_free (mods); - g_free (proc_name); } - return(ret); + g_slist_free (mods); + g_free (proc_name); + + return ret; } -gboolean GetProcessWorkingSetSize (gpointer process, size_t *min, size_t *max) +gboolean +GetProcessWorkingSetSize (gpointer process, size_t *min, size_t *max) { - struct _WapiHandle_process *process_handle; - gboolean ok; + WapiHandle_process *process_handle; - mono_once (&process_current_once, process_set_current); - - if(min==NULL || max==NULL) { + if (min == NULL || max == NULL) /* Not sure if w32 allows NULLs here or not */ - return(FALSE); - } + return FALSE; - if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) { - /* This is a pseudo handle, so just fail for now - */ - return(FALSE); - } + if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) + /* This is a pseudo handle, so just fail for now */ + return FALSE; - ok=_wapi_lookup_handle (process, WAPI_HANDLE_PROCESS, - (gpointer *)&process_handle); - if(ok==FALSE) { + process_handle = lookup_process_handle (process); + if (!process_handle) { DEBUG ("%s: Can't find process %p", __func__, process); - return(FALSE); + return FALSE; } - *min=process_handle->min_working_set; - *max=process_handle->max_working_set; + *min = process_handle->min_working_set; + *max = process_handle->max_working_set; - return(TRUE); + return TRUE; } -gboolean SetProcessWorkingSetSize (gpointer process, size_t min, size_t max) +gboolean +SetProcessWorkingSetSize (gpointer process, size_t min, size_t max) { - struct _WapiHandle_process *process_handle; - gboolean ok; + WapiHandle_process *process_handle; - mono_once (&process_current_once, process_set_current); - - if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) { + if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) /* This is a pseudo handle, so just fail for now */ - return(FALSE); - } + return FALSE; - ok=_wapi_lookup_handle (process, WAPI_HANDLE_PROCESS, - (gpointer *)&process_handle); - if(ok==FALSE) { + process_handle = lookup_process_handle (process); + if (!process_handle) { DEBUG ("%s: Can't find process %p", __func__, process); - return(FALSE); + return FALSE; } - process_handle->min_working_set=min; - process_handle->max_working_set=max; + process_handle->min_working_set = min; + process_handle->max_working_set = max; - return(TRUE); + return TRUE; } gboolean TerminateProcess (gpointer process, gint32 exitCode) { - struct _WapiHandle_process *process_handle; - gboolean ok; + WapiHandle_process *process_handle; int signo; int ret; pid_t pid; - if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) { + if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) { /* This is a pseudo handle */ - pid = (pid_t)(GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED_PID_MASK); + pid = (pid_t)WAPI_HANDLE_TO_PID (process); } else { - ok = _wapi_lookup_handle (process, WAPI_HANDLE_PROCESS, - (gpointer *) &process_handle); - - if (ok == FALSE) { - DEBUG ("%s: Can't find process %p", __func__, - process); + process_handle = lookup_process_handle (process); + if (!process_handle) { + DEBUG ("%s: Can't find process %p", __func__, process); SetLastError (ERROR_INVALID_HANDLE); return FALSE; } @@ -2639,19 +2270,16 @@ guint32 GetPriorityClass (gpointer process) { #ifdef HAVE_GETPRIORITY - struct _WapiHandle_process *process_handle; - gboolean ok; + WapiHandle_process *process_handle; int ret; pid_t pid; - if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) { + if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) { /* This is a pseudo handle */ - pid = (pid_t)(GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED_PID_MASK); + pid = (pid_t)WAPI_HANDLE_TO_PID (process); } else { - ok = _wapi_lookup_handle (process, WAPI_HANDLE_PROCESS, - (gpointer *) &process_handle); - - if (!ok) { + process_handle = lookup_process_handle (process); + if (!process_handle) { SetLastError (ERROR_INVALID_HANDLE); return FALSE; } @@ -2699,20 +2327,17 @@ gboolean SetPriorityClass (gpointer process, guint32 priority_class) { #ifdef HAVE_SETPRIORITY - struct _WapiHandle_process *process_handle; - gboolean ok; + WapiHandle_process *process_handle; int ret; int prio; pid_t pid; - if ((GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) { + if (WAPI_IS_PSEUDO_PROCESS_HANDLE (process)) { /* This is a pseudo handle */ - pid = (pid_t)(GPOINTER_TO_UINT (process) & _WAPI_PROCESS_UNHANDLED_PID_MASK); + pid = (pid_t)WAPI_HANDLE_TO_PID (process); } else { - ok = _wapi_lookup_handle (process, WAPI_HANDLE_PROCESS, - (gpointer *) &process_handle); - - if (!ok) { + process_handle = lookup_process_handle (process); + if (!process_handle) { SetLastError (ERROR_INVALID_HANDLE); return FALSE; } @@ -2796,6 +2421,12 @@ mono_processes_cleanup (void) mp = mp->next; } + /* + * Remove processes which exited from the mono_processes list. + * We need to synchronize with the sigchld handler here, which runs + * asynchronously. The handler requires that the mono_processes list + * remain valid. + */ mp = mono_processes; spin = 0; while (mp != NULL) { @@ -2807,6 +2438,10 @@ mono_processes_cleanup (void) /* We've found a candidate */ mono_mutex_lock (&mono_processes_mutex); + /* + * This code can run parallel with the sigchld handler, but the + * modifications it makes are safe. + */ if (candidate == NULL) { /* unlink it */ if (mp == mono_processes) { @@ -2857,12 +2492,14 @@ mono_processes_cleanup (void) static void process_close (gpointer handle, gpointer data) { - struct _WapiHandle_process *process_handle; + WapiHandle_process *process_handle; DEBUG ("%s", __func__); - process_handle = (struct _WapiHandle_process *) data; - if (process_handle->mono_process && process_handle->self == _wapi_getpid ()) + process_handle = (WapiHandle_process *) data; + g_free (process_handle->proc_name); + process_handle->proc_name = NULL; + if (process_handle->mono_process) InterlockedDecrement (&process_handle->mono_process->handle_count); mono_processes_cleanup (); } @@ -2874,9 +2511,7 @@ MONO_SIGNAL_HANDLER_FUNC (static, mono_sigchld_signal_handler, (int _dummy, sigi int pid; struct MonoProcess *p; -#if DEBUG - fprintf (stdout, "SIG CHILD handler for pid: %i\n", info->si_pid); -#endif + DEBUG ("SIG CHILD handler for pid: %i\n", info->si_pid); InterlockedIncrement (&mono_processes_read_lock); @@ -2888,9 +2523,7 @@ MONO_SIGNAL_HANDLER_FUNC (static, mono_sigchld_signal_handler, (int _dummy, sigi if (pid <= 0) break; -#if DEBUG - fprintf (stdout, "child ended: %i", pid); -#endif + DEBUG ("child ended: %i", pid); p = mono_processes; while (p != NULL) { if (p->pid == pid) { @@ -2905,14 +2538,13 @@ MONO_SIGNAL_HANDLER_FUNC (static, mono_sigchld_signal_handler, (int _dummy, sigi InterlockedDecrement (&mono_processes_read_lock); -#if DEBUG - fprintf (stdout, "SIG CHILD handler: done looping."); -#endif + DEBUG ("SIG CHILD handler: done looping."); } #endif -static void process_add_sigchld_handler (void) +static void +process_add_sigchld_handler (void) { #if HAVE_SIGACTION struct sigaction sa; @@ -2925,23 +2557,15 @@ static void process_add_sigchld_handler (void) #endif } -static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertable) +static guint32 +process_wait (gpointer handle, guint32 timeout, gboolean alertable) { - struct _WapiHandle_process *process_handle; - gboolean ok; + WapiHandle_process *process_handle; pid_t pid, ret; int status; guint32 start; guint32 now; struct MonoProcess *mp; - gboolean spin; - gpointer current_thread; - - current_thread = wapi_get_current_thread_handle (); - if (current_thread == NULL) { - SetLastError (ERROR_INVALID_HANDLE); - return WAIT_FAILED; - } /* FIXME: We can now easily wait on processes that aren't our own children, * but WaitFor*Object won't call us for pseudo handles. */ @@ -2949,8 +2573,8 @@ static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertabl DEBUG ("%s (%p, %u)", __func__, handle, timeout); - ok = _wapi_lookup_handle (handle, WAPI_HANDLE_PROCESS, (gpointer *)&process_handle); - if (ok == FALSE) { + process_handle = lookup_process_handle (handle); + if (!process_handle) { g_warning ("%s: error looking up process handle %p", __func__, handle); return WAIT_FAILED; } @@ -2968,48 +2592,33 @@ static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertabl /* We don't need to lock mono_processes here, the entry * has a handle_count > 0 which means it will not be freed. */ mp = process_handle->mono_process; - if (mp && process_handle->self != _wapi_getpid ()) { - /* mono_process points to memory in another process' address space: we can't use it */ - mp = NULL; - } + g_assert (mp); start = mono_msec_ticks (); now = start; - spin = mp == NULL; while (1) { - if (mp != NULL) { - /* We have a semaphore we can wait on */ - if (timeout != INFINITE) { - DEBUG ("%s (%p, %u): waiting on semaphore for %li ms...", - __func__, handle, timeout, (timeout - (now - start))); + if (timeout != INFINITE) { + DEBUG ("%s (%p, %u): waiting on semaphore for %li ms...", + __func__, handle, timeout, (timeout - (now - start))); - ret = MONO_SEM_TIMEDWAIT_ALERTABLE (&mp->exit_sem, (timeout - (now - start)), alertable); - } else { - DEBUG ("%s (%p, %u): waiting on semaphore forever...", - __func__, handle, timeout); - ret = MONO_SEM_WAIT_ALERTABLE (&mp->exit_sem, alertable); - } - - if (ret == -1 && errno != EINTR && errno != ETIMEDOUT) { - DEBUG ("%s (%p, %u): sem_timedwait failure: %s", - __func__, handle, timeout, g_strerror (errno)); - /* Should we return a failure here? */ - } - - if (ret == 0) { - /* Success, process has exited */ - MONO_SEM_POST (&mp->exit_sem); - break; - } + ret = MONO_SEM_TIMEDWAIT_ALERTABLE (&mp->exit_sem, (timeout - (now - start)), alertable); } else { - /* We did not create this process, so we can't waidpid / sem_wait it. - * We need to poll for the pid existence */ - DEBUG ("%s (%p, %u): polling on pid...", __func__, handle, timeout); - if (!is_pid_valid (pid)) { - /* Success, process has exited */ - break; - } + DEBUG ("%s (%p, %u): waiting on semaphore forever...", + __func__, handle, timeout); + ret = MONO_SEM_WAIT_ALERTABLE (&mp->exit_sem, alertable); + } + + if (ret == -1 && errno != EINTR && errno != ETIMEDOUT) { + DEBUG ("%s (%p, %u): sem_timedwait failure: %s", + __func__, handle, timeout, g_strerror (errno)); + /* Should we return a failure here? */ + } + + if (ret == 0) { + /* Success, process has exited */ + MONO_SEM_POST (&mp->exit_sem); + break; } if (timeout == 0) { @@ -3022,14 +2631,8 @@ static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertabl DEBUG ("%s (%p, %u): WAIT_TIMEOUT", __func__, handle, timeout); return WAIT_TIMEOUT; } - - if (spin) { - /* "timeout - (now - start)" will not underflow, since timeout is always >=0, - * and we passed the check just above */ - _wapi_handle_spin (MIN (100, timeout - (now - start))); - } - if (alertable && _wapi_thread_apc_pending (current_thread)) { + if (alertable && _wapi_thread_cur_apc_pending ()) { DEBUG ("%s (%p, %u): WAIT_IO_COMPLETION", __func__, handle, timeout); return WAIT_IO_COMPLETION; } @@ -3042,11 +2645,10 @@ static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertabl g_assert (ret == 0); status = mp ? mp->status : 0; - if (WIFSIGNALED (status)) { + if (WIFSIGNALED (status)) process_handle->exitstatus = 128 + WTERMSIG (status); - } else { + else process_handle->exitstatus = WEXITSTATUS (status); - } _wapi_time_t_to_filetime (time (NULL), &process_handle->exit_time); process_handle->exited = TRUE; @@ -3054,7 +2656,7 @@ static guint32 process_wait (gpointer handle, guint32 timeout, gboolean alertabl DEBUG ("%s (%p, %u): Setting pid %d signalled, exit status %d", __func__, handle, timeout, process_handle->id, process_handle->exitstatus); - _wapi_shared_handle_set_signal_state (handle, TRUE); + _wapi_handle_set_signal_state (handle, TRUE, TRUE); _wapi_handle_unlock_shared_handles (); diff --git a/mono/io-layer/processes.h b/mono/io-layer/processes.h index 8e4c0aa558..c2b78d4438 100644 --- a/mono/io-layer/processes.h +++ b/mono/io-layer/processes.h @@ -10,6 +10,9 @@ #ifndef _WAPI_PROCESSES_H_ #define _WAPI_PROCESSES_H_ +#ifdef HAVE_UNISTD_H +#include +#endif #include #include @@ -188,8 +191,6 @@ extern gboolean CreateProcessWithLogonW (const gunichar2 *username, extern gpointer GetCurrentProcess (void); extern guint32 GetProcessId (gpointer handle); -extern guint32 GetCurrentProcessId (void); -extern gboolean EnumProcesses (guint32 *pids, guint32 len, guint32 *needed); extern gboolean CloseProcess (gpointer handle); extern gpointer OpenProcess (guint32 access, gboolean inherit, guint32 pid); extern gboolean GetExitCodeProcess (gpointer process, guint32 *code); diff --git a/mono/io-layer/shared.c b/mono/io-layer/shared.c index 1800f9b74a..f8539039ca 100644 --- a/mono/io-layer/shared.c +++ b/mono/io-layer/shared.c @@ -44,8 +44,6 @@ static mono_mutex_t noshm_sems[_WAPI_SHARED_SEM_COUNT]; -gboolean _wapi_shm_disabled = TRUE; - static gpointer wapi_storage [16]; static void @@ -152,12 +150,13 @@ _wapi_shm_detach (_wapi_shm_t type) } gboolean -_wapi_shm_enabled (void) +_wapi_shm_enabled_internal (void) { return FALSE; } -#else +#else /* DISABLE_SHARED_HANDLES */ + /* * Use POSIX shared memory if possible, it is simpler, and it has the advantage that * writes to the shared area does not need to be written to disk, avoiding spinning up @@ -167,6 +166,8 @@ _wapi_shm_enabled (void) #define USE_SHM 1 #endif +static gboolean _wapi_shm_disabled = TRUE; + static gchar * _wapi_shm_base_name (_wapi_shm_t type) { @@ -404,7 +405,7 @@ try_again: } gboolean -_wapi_shm_enabled (void) +_wapi_shm_enabled_internal (void) { static gboolean env_checked; diff --git a/mono/io-layer/shared.h b/mono/io-layer/shared.h index b175b6e306..5f66a732e6 100644 --- a/mono/io-layer/shared.h +++ b/mono/io-layer/shared.h @@ -17,15 +17,23 @@ typedef enum { WAPI_SHM_FILESHARE } _wapi_shm_t; -extern gboolean _wapi_shm_disabled; - extern gpointer _wapi_shm_attach (_wapi_shm_t type); extern void _wapi_shm_detach (_wapi_shm_t type); -extern gboolean _wapi_shm_enabled (void); +extern gboolean _wapi_shm_enabled_internal (void); extern void _wapi_shm_semaphores_init (void); extern void _wapi_shm_semaphores_remove (void); extern int _wapi_shm_sem_lock (int sem); extern int _wapi_shm_sem_trylock (int sem); extern int _wapi_shm_sem_unlock (int sem); +static inline gboolean +_wapi_shm_enabled (void) +{ +#ifdef DISABLE_SHARED_HANDLES + return FALSE; +#else + return _wapi_shm_enabled_internal (); +#endif +} + #endif /* _WAPI_SHARED_H_ */ diff --git a/mono/io-layer/wapi-private.h b/mono/io-layer/wapi-private.h index f982d86060..34de2f0fd9 100644 --- a/mono/io-layer/wapi-private.h +++ b/mono/io-layer/wapi-private.h @@ -42,8 +42,7 @@ typedef enum { extern const char *_wapi_handle_typename[]; -#define _WAPI_SHARED_HANDLE(type) (type == WAPI_HANDLE_PROCESS || \ - type == WAPI_HANDLE_NAMEDMUTEX || \ +#define _WAPI_SHARED_HANDLE(type) (type == WAPI_HANDLE_NAMEDMUTEX || \ type == WAPI_HANDLE_NAMEDSEM || \ type == WAPI_HANDLE_NAMEDEVENT) @@ -136,6 +135,7 @@ struct _WapiHandleUnshared struct _WapiHandle_sem sem; struct _WapiHandle_socket sock; struct _WapiHandle_thread thread; + struct _WapiHandle_process process; struct _WapiHandle_shared_ref shared; } u; }; @@ -149,7 +149,6 @@ struct _WapiHandleShared union { - struct _WapiHandle_process process; struct _WapiHandle_namedmutex namedmutex; struct _WapiHandle_namedsem namedsem; struct _WapiHandle_namedevent namedevent; diff --git a/mono/metadata/Makefile.am b/mono/metadata/Makefile.am index f0c175f08e..335484ae67 100644 --- a/mono/metadata/Makefile.am +++ b/mono/metadata/Makefile.am @@ -124,6 +124,7 @@ common_sources = \ icall.c \ icall-def.h \ image.c \ + jit-info.c \ loader.c \ locales.c \ locales.h \ @@ -222,9 +223,6 @@ sgen_sources = \ sgen-gc.c \ sgen-internal.c \ sgen-marksweep.c \ - sgen-marksweep-fixed.c \ - sgen-marksweep-par.c \ - sgen-marksweep-fixed-par.c \ sgen-los.c \ sgen-protocol.c \ sgen-bridge.c \ @@ -239,6 +237,8 @@ sgen_sources = \ sgen-archdep.h \ sgen-cardtable.c \ sgen-cardtable.h \ + sgen-pointer-queue.c \ + sgen-pointer-queue.h \ sgen-pinning.c \ sgen-pinning.h \ sgen-pinning-stats.c \ @@ -269,7 +269,8 @@ sgen_sources = \ sgen-layout-stats.c \ sgen-layout-stats.h \ sgen-qsort.c \ - sgen-qsort.h + sgen-qsort.h \ + sgen-tagged-pointer.h libmonoruntime_la_SOURCES = $(common_sources) $(gc_dependent_sources) $(null_gc_sources) $(boehm_sources) libmonoruntime_la_CFLAGS = $(BOEHM_DEFINES) diff --git a/mono/metadata/Makefile.in.REMOVED.git-id b/mono/metadata/Makefile.in.REMOVED.git-id index 106bed143d..6157fcf8fa 100644 --- a/mono/metadata/Makefile.in.REMOVED.git-id +++ b/mono/metadata/Makefile.in.REMOVED.git-id @@ -1 +1 @@ -3b9662818ee7d2d392b131d660e23415e5166e46 \ No newline at end of file +5fd9a5981c3a85d1f2ce8e1f06445b0565d05037 \ No newline at end of file diff --git a/mono/metadata/appdomain.c b/mono/metadata/appdomain.c index 45b9a606ab..c46bdfa2db 100644 --- a/mono/metadata/appdomain.c +++ b/mono/metadata/appdomain.c @@ -2415,6 +2415,7 @@ mono_domain_try_unload (MonoDomain *domain, MonoObject **exc) unload_data *thread_data; MonoNativeThreadId tid; MonoDomain *caller_domain = mono_domain_get (); + char *name; /* printf ("UNLOAD STARTING FOR %s (%p) IN THREAD 0x%x.\n", domain->friendly_name, domain, GetCurrentThreadId ()); */ @@ -2466,7 +2467,10 @@ mono_domain_try_unload (MonoDomain *domain, MonoObject **exc) thread_handle = mono_threads_create_thread ((LPTHREAD_START_ROUTINE)unload_thread_main, thread_data, 0, CREATE_SUSPENDED, &tid); if (thread_handle == NULL) return; + name = g_strdup_printf ("Unload thread for domain %x", domain); + mono_thread_info_set_name (tid, name); mono_thread_info_resume (tid); + g_free (name); /* Wait for the thread */ while (!thread_data->done && WaitForSingleObjectEx (thread_handle, INFINITE, TRUE) == WAIT_IO_COMPLETION) { diff --git a/mono/metadata/boehm-gc.c b/mono/metadata/boehm-gc.c index 3320820f87..f6c9cc876d 100644 --- a/mono/metadata/boehm-gc.c +++ b/mono/metadata/boehm-gc.c @@ -1291,6 +1291,18 @@ mono_gc_get_los_limit (void) return G_MAXINT; } +void +mono_gc_set_string_length (MonoString *str, gint32 new_length) +{ + mono_unichar2 *new_end = str->chars + new_length; + + /* zero the discarded string. This null-delimits the string and allows + * the space to be reclaimed by SGen. */ + + memset (new_end, 0, (str->length - new_length + 1) * sizeof (mono_unichar2)); + str->length = new_length; +} + gboolean mono_gc_user_markers_supported (void) { diff --git a/mono/metadata/class-internals.h b/mono/metadata/class-internals.h index ab4a5cb578..2bf904143f 100644 --- a/mono/metadata/class-internals.h +++ b/mono/metadata/class-internals.h @@ -208,8 +208,8 @@ enum { MONO_EXCEPTION_GENERIC_SHARING_FAILED = 11, MONO_EXCEPTION_BAD_IMAGE = 12, MONO_EXCEPTION_OBJECT_SUPPLIED = 13, /*The exception object is already created.*/ - MONO_EXCEPTION_OUT_OF_MEMORY = 14 - /* add other exception type */ + MONO_EXCEPTION_OUT_OF_MEMORY = 14, + MONO_EXCEPTION_INLINE_FAILED = 15 }; /* This struct collects the info needed for the runtime use of a class, @@ -1228,13 +1228,9 @@ MONO_API MonoGenericContainer * mono_metadata_load_generic_params (MonoImage *image, guint32 token, MonoGenericContainer *parent_container); -MONO_API void -mono_metadata_load_generic_param_constraints (MonoImage *image, guint32 token, - MonoGenericContainer *container); - -gboolean -mono_metadata_load_generic_param_constraints_full (MonoImage *image, guint32 token, - MonoGenericContainer *container) MONO_INTERNAL; +MONO_API gboolean +mono_metadata_load_generic_param_constraints_checked (MonoImage *image, guint32 token, + MonoGenericContainer *container, MonoError *error); MonoMethodSignature* mono_create_icall_signature (const char *sigstr) MONO_INTERNAL; @@ -1298,7 +1294,7 @@ MONO_API gboolean mono_class_is_valid_enum (MonoClass *klass); MonoType * -mono_type_get_full (MonoImage *image, guint32 type_token, MonoGenericContext *context) MONO_INTERNAL; +mono_type_get_checked (MonoImage *image, guint32 type_token, MonoGenericContext *context, MonoError *error) MONO_INTERNAL; gboolean mono_generic_class_is_generic_type_definition (MonoGenericClass *gklass) MONO_INTERNAL; @@ -1386,4 +1382,16 @@ mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bfla char* mono_class_full_name (MonoClass *klass) MONO_INTERNAL; +MonoClass* +mono_class_inflate_generic_class_checked (MonoClass *gklass, MonoGenericContext *context, MonoError *error) MONO_INTERNAL; + +MonoClass * +mono_class_get_checked (MonoImage *image, guint32 type_token, MonoError *error) MONO_INTERNAL; + +MonoClass * +mono_class_get_and_inflate_typespec_checked (MonoImage *image, guint32 type_token, MonoGenericContext *context, MonoError *error) MONO_INTERNAL; + +MonoClass * +mono_class_from_name_case_checked (MonoImage *image, const char* name_space, const char *name, MonoError *error) MONO_INTERNAL; + #endif /* __MONO_METADATA_CLASS_INTERBALS_H__ */ diff --git a/mono/metadata/class.c.REMOVED.git-id b/mono/metadata/class.c.REMOVED.git-id index b80fd8bc6a..1f2a97b9f6 100644 --- a/mono/metadata/class.c.REMOVED.git-id +++ b/mono/metadata/class.c.REMOVED.git-id @@ -1 +1 @@ -d438803266c9de14353e3f53d8573be775264e57 \ No newline at end of file +e9ff58249ef34610b39221c1f0cb51752a500f00 \ No newline at end of file diff --git a/mono/metadata/class.h b/mono/metadata/class.h index a65bd4565e..d9f315139b 100644 --- a/mono/metadata/class.h +++ b/mono/metadata/class.h @@ -4,6 +4,7 @@ #include #include #include +#include MONO_BEGIN_DECLS @@ -37,6 +38,9 @@ mono_class_get_method_from_name_flags (MonoClass *klass, const char *name, int p MONO_API MonoClass * mono_class_from_typeref (MonoImage *image, uint32_t type_token); +MONO_API MonoClass * +mono_class_from_typeref_checked (MonoImage *image, uint32_t type_token, MonoError *error); + MONO_API MonoClass * mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *image, mono_bool is_mvar); diff --git a/mono/metadata/cominterop.c b/mono/metadata/cominterop.c index b3ed7197d4..6b98212f4c 100644 --- a/mono/metadata/cominterop.c +++ b/mono/metadata/cominterop.c @@ -2068,8 +2068,17 @@ mono_marshal_free_ccw (MonoObject* object) MonoObject* handle_target = mono_gchandle_get_target (ccw_iter->gc_handle); /* Looks like the GC NULLs the weakref handle target before running the - * finalizer. So if we get a NULL target, destroy the CCW as well. */ - if (!handle_target || handle_target == object) { + * finalizer. So if we get a NULL target, destroy the CCW as well. + * Unless looking up the object from the CCW shows it not the right object. + */ + gboolean destroy_ccw = !handle_target || handle_target == object; + if (!handle_target) { + MonoCCWInterface* ccw_entry = g_hash_table_lookup (ccw_iter->vtable_hash, mono_class_get_iunknown_class ()); + if (!(ccw_entry && object == cominterop_get_ccw_object (ccw_entry, FALSE))) + destroy_ccw = FALSE; + } + + if (destroy_ccw) { /* remove all interfaces */ g_hash_table_foreach_remove (ccw_iter->vtable_hash, mono_marshal_free_ccw_entry, NULL); g_hash_table_destroy (ccw_iter->vtable_hash); diff --git a/mono/metadata/console-unix.c b/mono/metadata/console-unix.c index 6a70b35008..1de9a002e0 100644 --- a/mono/metadata/console-unix.c +++ b/mono/metadata/console-unix.c @@ -35,6 +35,7 @@ #include #include #include +#include /* On solaris, curses.h must come before both termios.h and term.h */ #ifdef HAVE_CURSES_H @@ -277,7 +278,7 @@ mono_console_handle_async_ops (void) static gboolean in_sigint; -MONO_SIGNAL_HANDLER_FUNC (static, sigint_handler, (int signo)) +MONO_SIG_HANDLER_FUNC (static, sigint_handler) { int save_errno; MONO_ARCH_SAVE_REGS; @@ -295,7 +296,7 @@ MONO_SIGNAL_HANDLER_FUNC (static, sigint_handler, (int signo)) static struct sigaction save_sigcont, save_sigint, save_sigwinch; -MONO_SIGNAL_HANDLER_FUNC (static, sigcont_handler, (int signo, void *the_siginfo, void *data)) +MONO_SIG_HANDLER_FUNC (static, sigcont_handler) { int unused; // Ignore error, there is not much we can do in the sigcont handler. @@ -308,10 +309,10 @@ MONO_SIGNAL_HANDLER_FUNC (static, sigcont_handler, (int signo, void *the_siginfo if (save_sigcont.sa_sigaction != NULL && save_sigcont.sa_sigaction != (void *)SIG_DFL && save_sigcont.sa_sigaction != (void *)SIG_IGN) - (*save_sigcont.sa_sigaction) (signo, the_siginfo, data); + (*save_sigcont.sa_sigaction) (MONO_SIG_HANDLER_PARAMS); } -MONO_SIGNAL_HANDLER_FUNC (static, sigwinch_handler, (int signo, void *the_siginfo, void *data)) +MONO_SIG_HANDLER_FUNC (static, sigwinch_handler) { int dims = terminal_get_dimensions (); if (dims != -1) @@ -321,7 +322,7 @@ MONO_SIGNAL_HANDLER_FUNC (static, sigwinch_handler, (int signo, void *the_siginf if (save_sigwinch.sa_sigaction != NULL && save_sigwinch.sa_sigaction != (void *)SIG_DFL && save_sigwinch.sa_sigaction != (void *)SIG_IGN) - (*save_sigwinch.sa_sigaction) (signo, the_siginfo, data); + (*save_sigwinch.sa_sigaction) (MONO_SIG_HANDLER_PARAMS); } /* @@ -502,7 +503,7 @@ ves_icall_System_ConsoleDriver_TtySetup (MonoString *keypad, MonoString *teardow if (teardown != NULL) teardown_str = mono_string_to_utf8 (teardown); - atexit (tty_teardown); + mono_atexit (tty_teardown); } return TRUE; diff --git a/mono/metadata/culture-info-tables.h.REMOVED.git-id b/mono/metadata/culture-info-tables.h.REMOVED.git-id index 825f7a0685..d842c05b05 100644 --- a/mono/metadata/culture-info-tables.h.REMOVED.git-id +++ b/mono/metadata/culture-info-tables.h.REMOVED.git-id @@ -1 +1 @@ -5df6721ed4dbe1151f1cf9e6af83f95d03eb116e \ No newline at end of file +bdbeb1daf6b9fcfd947ee467885762fa09a739b8 \ No newline at end of file diff --git a/mono/metadata/decimal.c b/mono/metadata/decimal.c index 39d226d3b2..3bbd005803 100644 --- a/mono/metadata/decimal.c +++ b/mono/metadata/decimal.c @@ -577,7 +577,7 @@ my_g_bit_nth_msf (gsize mask) if (_BitScanReverse (&bIndex, mask)) return bIndex; return -1; -#elif defined(__x86_64__) && defined(_MSC_VER) +#elif defined(_M_X64) && defined(_MSC_VER) unsigned long bIndex = 0; if (_BitScanReverse64 (&bIndex, mask)) return bIndex; @@ -597,7 +597,7 @@ my_g_bit_nth_msf (gsize mask) i = sizeof (gsize) * 8; while (i > 0) { i --; - if (mask & (1UL << i)) + if (mask & (1ULL << i)) return i; } return -1; diff --git a/mono/metadata/domain-internals.h b/mono/metadata/domain-internals.h index 24989f49af..065e0458fa 100644 --- a/mono/metadata/domain-internals.h +++ b/mono/metadata/domain-internals.h @@ -188,6 +188,14 @@ typedef struct { gboolean cas_method_permitonly:1; } MonoMethodCasInfo; +typedef enum { + JIT_INFO_NONE = 0, + JIT_INFO_HAS_CAS_INFO = (1 << 0), + JIT_INFO_HAS_GENERIC_JIT_INFO = (1 << 1), + JIT_INFO_HAS_TRY_BLOCK_HOLES = (1 << 2), + JIT_INFO_HAS_ARCH_EH_INFO = (1 << 3) +} MonoJitInfoFlags; + struct _MonoJitInfo { /* NOTE: These first two elements (method and next_jit_code_hash) must be in the same order and at the @@ -456,6 +464,19 @@ mono_cleanup (void) MONO_INTERNAL; void mono_close_exe_image (void) MONO_INTERNAL; +int +mono_jit_info_size (MonoJitInfoFlags flags, int num_clauses, int num_holes) MONO_INTERNAL; + +void +mono_jit_info_init (MonoJitInfo *ji, MonoMethod *method, guint8 *code, int code_size, + MonoJitInfoFlags flags, int num_clauses, int num_holes) MONO_INTERNAL; + +MonoJitInfoTable * +mono_jit_info_table_new (MonoDomain *domain) MONO_INTERNAL; + +void +mono_jit_info_table_free (MonoJitInfoTable *table) MONO_INTERNAL; + void mono_jit_info_table_add (MonoDomain *domain, MonoJitInfo *ji) MONO_INTERNAL; diff --git a/mono/metadata/domain.c b/mono/metadata/domain.c old mode 100644 new mode 100755 index b1b912f4e9..e30c0345c0 --- a/mono/metadata/domain.c +++ b/mono/metadata/domain.c @@ -116,8 +116,6 @@ typedef struct { static const MonoRuntimeInfo *current_runtime = NULL; -static MonoJitInfoFindInAot jit_info_find_in_aot_func = NULL; - /* This is the list of runtime versions supported by this JIT. */ static const MonoRuntimeInfo supported_runtimes[] = { @@ -160,876 +158,16 @@ gint32 mono_domain_get_tls_offset (void) { int offset = -1; + +#ifdef HOST_WIN32 + if (appdomain_thread_id) + offset = appdomain_thread_id; +#else MONO_THREAD_VAR_OFFSET (tls_appdomain, offset); -/* __asm ("jmp 1f; .section writetext, \"awx\"; 1: movl $tls_appdomain@ntpoff, %0; jmp 2f; .previous; 2:" - : "=r" (offset));*/ +#endif return offset; } -#define JIT_INFO_TABLE_FILL_RATIO_NOM 3 -#define JIT_INFO_TABLE_FILL_RATIO_DENOM 4 -#define JIT_INFO_TABLE_FILLED_NUM_ELEMENTS (MONO_JIT_INFO_TABLE_CHUNK_SIZE * JIT_INFO_TABLE_FILL_RATIO_NOM / JIT_INFO_TABLE_FILL_RATIO_DENOM) - -#define JIT_INFO_TABLE_LOW_WATERMARK(n) ((n) / 2) -#define JIT_INFO_TABLE_HIGH_WATERMARK(n) ((n) * 5 / 6) - -#define JIT_INFO_TOMBSTONE_MARKER ((MonoMethod*)NULL) -#define IS_JIT_INFO_TOMBSTONE(ji) ((ji)->d.method == JIT_INFO_TOMBSTONE_MARKER) - -#define JIT_INFO_TABLE_HAZARD_INDEX 0 -#define JIT_INFO_HAZARD_INDEX 1 - -static int -jit_info_table_num_elements (MonoJitInfoTable *table) -{ - int i; - int num_elements = 0; - - for (i = 0; i < table->num_chunks; ++i) { - MonoJitInfoTableChunk *chunk = table->chunks [i]; - int chunk_num_elements = chunk->num_elements; - int j; - - for (j = 0; j < chunk_num_elements; ++j) { - if (!IS_JIT_INFO_TOMBSTONE (chunk->data [j])) - ++num_elements; - } - } - - return num_elements; -} - -static MonoJitInfoTableChunk* -jit_info_table_new_chunk (void) -{ - MonoJitInfoTableChunk *chunk = g_new0 (MonoJitInfoTableChunk, 1); - chunk->refcount = 1; - - return chunk; -} - -static MonoJitInfoTable * -jit_info_table_new (MonoDomain *domain) -{ - MonoJitInfoTable *table = g_malloc0 (MONO_SIZEOF_JIT_INFO_TABLE + sizeof (MonoJitInfoTableChunk*)); - - table->domain = domain; - table->num_chunks = 1; - table->chunks [0] = jit_info_table_new_chunk (); - - return table; -} - -static void -jit_info_table_free (MonoJitInfoTable *table) -{ - int i; - int num_chunks = table->num_chunks; - MonoDomain *domain = table->domain; - - mono_domain_lock (domain); - - table->domain->num_jit_info_tables--; - if (table->domain->num_jit_info_tables <= 1) { - GSList *list; - - for (list = table->domain->jit_info_free_queue; list; list = list->next) - g_free (list->data); - - g_slist_free (table->domain->jit_info_free_queue); - table->domain->jit_info_free_queue = NULL; - } - - /* At this point we assume that there are no other threads - still accessing the table, so we don't have to worry about - hazardous pointers. */ - - for (i = 0; i < num_chunks; ++i) { - MonoJitInfoTableChunk *chunk = table->chunks [i]; - int num_elements; - int j; - - if (--chunk->refcount > 0) - continue; - - num_elements = chunk->num_elements; - for (j = 0; j < num_elements; ++j) { - MonoJitInfo *ji = chunk->data [j]; - - if (IS_JIT_INFO_TOMBSTONE (ji)) - g_free (ji); - } - - g_free (chunk); - } - - mono_domain_unlock (domain); - - g_free (table); -} - -/* The jit_info_table is sorted in ascending order by the end - * addresses of the compiled methods. The reason why we have to do - * this is that once we introduce tombstones, it becomes possible for - * code ranges to overlap, and if we sort by code start and insert at - * the back of the table, we cannot guarantee that we won't overlook - * an entry. - * - * There are actually two possible ways to do the sorting and - * inserting which work with our lock-free mechanism: - * - * 1. Sort by start address and insert at the front. When looking for - * an entry, find the last one with a start address lower than the one - * you're looking for, then work your way to the front of the table. - * - * 2. Sort by end address and insert at the back. When looking for an - * entry, find the first one with an end address higher than the one - * you're looking for, then work your way to the end of the table. - * - * We chose the latter out of convenience. - */ -static int -jit_info_table_index (MonoJitInfoTable *table, gint8 *addr) -{ - int left = 0, right = table->num_chunks; - - g_assert (left < right); - - do { - int pos = (left + right) / 2; - MonoJitInfoTableChunk *chunk = table->chunks [pos]; - - if (addr < chunk->last_code_end) - right = pos; - else - left = pos + 1; - } while (left < right); - g_assert (left == right); - - if (left >= table->num_chunks) - return table->num_chunks - 1; - return left; -} - -static int -jit_info_table_chunk_index (MonoJitInfoTableChunk *chunk, MonoThreadHazardPointers *hp, gint8 *addr) -{ - int left = 0, right = chunk->num_elements; - - while (left < right) { - int pos = (left + right) / 2; - MonoJitInfo *ji = get_hazardous_pointer((gpointer volatile*)&chunk->data [pos], hp, JIT_INFO_HAZARD_INDEX); - gint8 *code_end = (gint8*)ji->code_start + ji->code_size; - - if (addr < code_end) - right = pos; - else - left = pos + 1; - } - g_assert (left == right); - - return left; -} - -static MonoJitInfo* -jit_info_table_find (MonoJitInfoTable *table, MonoThreadHazardPointers *hp, gint8 *addr) -{ - MonoJitInfo *ji; - int chunk_pos, pos; - - chunk_pos = jit_info_table_index (table, (gint8*)addr); - g_assert (chunk_pos < table->num_chunks); - - pos = jit_info_table_chunk_index (table->chunks [chunk_pos], hp, (gint8*)addr); - - /* We now have a position that's very close to that of the - first element whose end address is higher than the one - we're looking for. If we don't have the exact position, - then we have a position below that one, so we'll just - search upward until we find our element. */ - do { - MonoJitInfoTableChunk *chunk = table->chunks [chunk_pos]; - - while (pos < chunk->num_elements) { - ji = get_hazardous_pointer ((gpointer volatile*)&chunk->data [pos], hp, JIT_INFO_HAZARD_INDEX); - - ++pos; - - if (IS_JIT_INFO_TOMBSTONE (ji)) { - mono_hazard_pointer_clear (hp, JIT_INFO_HAZARD_INDEX); - continue; - } - if ((gint8*)addr >= (gint8*)ji->code_start - && (gint8*)addr < (gint8*)ji->code_start + ji->code_size) { - mono_hazard_pointer_clear (hp, JIT_INFO_HAZARD_INDEX); - return ji; - } - - /* If we find a non-tombstone element which is already - beyond what we're looking for, we have to end the - search. */ - if ((gint8*)addr < (gint8*)ji->code_start) - goto not_found; - } - - ++chunk_pos; - pos = 0; - } while (chunk_pos < table->num_chunks); - - not_found: - if (hp) - mono_hazard_pointer_clear (hp, JIT_INFO_HAZARD_INDEX); - return NULL; -} - -/* - * mono_jit_info_table_find_internal: - * - * If TRY_AOT is FALSE, avoid loading information for missing methods from AOT images, which is currently not async safe. - * In this case, only those AOT methods will be found whose jit info is already loaded. - * ASYNC SAFETY: When called in an async context (mono_thread_info_is_async_context ()), this is async safe. - * In this case, the returned MonoJitInfo might not have metadata information, in particular, - * mono_jit_info_get_method () could fail. - */ -MonoJitInfo* -mono_jit_info_table_find_internal (MonoDomain *domain, char *addr, gboolean try_aot) -{ - MonoJitInfoTable *table; - MonoJitInfo *ji, *module_ji; - MonoThreadHazardPointers *hp = mono_hazard_pointer_get (); - - ++mono_stats.jit_info_table_lookup_count; - - /* First we have to get the domain's jit_info_table. This is - complicated by the fact that a writer might substitute a - new table and free the old one. What the writer guarantees - us is that it looks at the hazard pointers after it has - changed the jit_info_table pointer. So, if we guard the - table by a hazard pointer and make sure that the pointer is - still there after we've made it hazardous, we don't have to - worry about the writer freeing the table. */ - table = get_hazardous_pointer ((gpointer volatile*)&domain->jit_info_table, hp, JIT_INFO_TABLE_HAZARD_INDEX); - - ji = jit_info_table_find (table, hp, (gint8*)addr); - if (hp) - mono_hazard_pointer_clear (hp, JIT_INFO_TABLE_HAZARD_INDEX); - if (ji) - return ji; - - /* Maybe its an AOT module */ - if (try_aot && mono_root_domain && mono_root_domain->aot_modules) { - table = get_hazardous_pointer ((gpointer volatile*)&mono_root_domain->aot_modules, hp, JIT_INFO_TABLE_HAZARD_INDEX); - module_ji = jit_info_table_find (table, hp, (gint8*)addr); - if (module_ji) - ji = jit_info_find_in_aot_func (domain, module_ji->d.image, addr); - if (hp) - mono_hazard_pointer_clear (hp, JIT_INFO_TABLE_HAZARD_INDEX); - } - - return ji; -} - -MonoJitInfo* -mono_jit_info_table_find (MonoDomain *domain, char *addr) -{ - return mono_jit_info_table_find_internal (domain, addr, TRUE); -} - -static G_GNUC_UNUSED void -jit_info_table_check (MonoJitInfoTable *table) -{ - int i; - - for (i = 0; i < table->num_chunks; ++i) { - MonoJitInfoTableChunk *chunk = table->chunks [i]; - int j; - - g_assert (chunk->refcount > 0 /* && chunk->refcount <= 8 */); - if (chunk->refcount > 10) - printf("warning: chunk refcount is %d\n", chunk->refcount); - g_assert (chunk->num_elements <= MONO_JIT_INFO_TABLE_CHUNK_SIZE); - - for (j = 0; j < chunk->num_elements; ++j) { - MonoJitInfo *this = chunk->data [j]; - MonoJitInfo *next; - - g_assert ((gint8*)this->code_start + this->code_size <= chunk->last_code_end); - - if (j < chunk->num_elements - 1) - next = chunk->data [j + 1]; - else if (i < table->num_chunks - 1) { - int k; - - for (k = i + 1; k < table->num_chunks; ++k) - if (table->chunks [k]->num_elements > 0) - break; - - if (k >= table->num_chunks) - return; - - g_assert (table->chunks [k]->num_elements > 0); - next = table->chunks [k]->data [0]; - } else - return; - - g_assert ((gint8*)this->code_start + this->code_size <= (gint8*)next->code_start + next->code_size); - } - } -} - -static MonoJitInfoTable* -jit_info_table_realloc (MonoJitInfoTable *old) -{ - int i; - int num_elements = jit_info_table_num_elements (old); - int required_size; - int num_chunks; - int new_chunk, new_element; - MonoJitInfoTable *new; - - /* number of needed places for elements needed */ - required_size = (int)((long)num_elements * JIT_INFO_TABLE_FILL_RATIO_DENOM / JIT_INFO_TABLE_FILL_RATIO_NOM); - num_chunks = (required_size + MONO_JIT_INFO_TABLE_CHUNK_SIZE - 1) / MONO_JIT_INFO_TABLE_CHUNK_SIZE; - if (num_chunks == 0) { - g_assert (num_elements == 0); - return jit_info_table_new (old->domain); - } - g_assert (num_chunks > 0); - - new = g_malloc (MONO_SIZEOF_JIT_INFO_TABLE + sizeof (MonoJitInfoTableChunk*) * num_chunks); - new->domain = old->domain; - new->num_chunks = num_chunks; - - for (i = 0; i < num_chunks; ++i) - new->chunks [i] = jit_info_table_new_chunk (); - - new_chunk = 0; - new_element = 0; - for (i = 0; i < old->num_chunks; ++i) { - MonoJitInfoTableChunk *chunk = old->chunks [i]; - int chunk_num_elements = chunk->num_elements; - int j; - - for (j = 0; j < chunk_num_elements; ++j) { - if (!IS_JIT_INFO_TOMBSTONE (chunk->data [j])) { - g_assert (new_chunk < num_chunks); - new->chunks [new_chunk]->data [new_element] = chunk->data [j]; - if (++new_element >= JIT_INFO_TABLE_FILLED_NUM_ELEMENTS) { - new->chunks [new_chunk]->num_elements = new_element; - ++new_chunk; - new_element = 0; - } - } - } - } - - if (new_chunk < num_chunks) { - g_assert (new_chunk == num_chunks - 1); - new->chunks [new_chunk]->num_elements = new_element; - g_assert (new->chunks [new_chunk]->num_elements > 0); - } - - for (i = 0; i < num_chunks; ++i) { - MonoJitInfoTableChunk *chunk = new->chunks [i]; - MonoJitInfo *ji = chunk->data [chunk->num_elements - 1]; - - new->chunks [i]->last_code_end = (gint8*)ji->code_start + ji->code_size; - } - - return new; -} - -static void -jit_info_table_split_chunk (MonoJitInfoTableChunk *chunk, MonoJitInfoTableChunk **new1p, MonoJitInfoTableChunk **new2p) -{ - MonoJitInfoTableChunk *new1 = jit_info_table_new_chunk (); - MonoJitInfoTableChunk *new2 = jit_info_table_new_chunk (); - - g_assert (chunk->num_elements == MONO_JIT_INFO_TABLE_CHUNK_SIZE); - - new1->num_elements = MONO_JIT_INFO_TABLE_CHUNK_SIZE / 2; - new2->num_elements = MONO_JIT_INFO_TABLE_CHUNK_SIZE - new1->num_elements; - - memcpy ((void*)new1->data, (void*)chunk->data, sizeof (MonoJitInfo*) * new1->num_elements); - memcpy ((void*)new2->data, (void*)(chunk->data + new1->num_elements), sizeof (MonoJitInfo*) * new2->num_elements); - - new1->last_code_end = (gint8*)new1->data [new1->num_elements - 1]->code_start - + new1->data [new1->num_elements - 1]->code_size; - new2->last_code_end = (gint8*)new2->data [new2->num_elements - 1]->code_start - + new2->data [new2->num_elements - 1]->code_size; - - *new1p = new1; - *new2p = new2; -} - -static MonoJitInfoTable* -jit_info_table_copy_and_split_chunk (MonoJitInfoTable *table, MonoJitInfoTableChunk *chunk) -{ - MonoJitInfoTable *new_table = g_malloc (MONO_SIZEOF_JIT_INFO_TABLE - + sizeof (MonoJitInfoTableChunk*) * (table->num_chunks + 1)); - int i, j; - - new_table->domain = table->domain; - new_table->num_chunks = table->num_chunks + 1; - - j = 0; - for (i = 0; i < table->num_chunks; ++i) { - if (table->chunks [i] == chunk) { - jit_info_table_split_chunk (chunk, &new_table->chunks [j], &new_table->chunks [j + 1]); - j += 2; - } else { - new_table->chunks [j] = table->chunks [i]; - ++new_table->chunks [j]->refcount; - ++j; - } - } - - g_assert (j == new_table->num_chunks); - - return new_table; -} - -static MonoJitInfoTableChunk* -jit_info_table_purify_chunk (MonoJitInfoTableChunk *old) -{ - MonoJitInfoTableChunk *new = jit_info_table_new_chunk (); - int i, j; - - j = 0; - for (i = 0; i < old->num_elements; ++i) { - if (!IS_JIT_INFO_TOMBSTONE (old->data [i])) - new->data [j++] = old->data [i]; - } - - new->num_elements = j; - if (new->num_elements > 0) - new->last_code_end = (gint8*)new->data [j - 1]->code_start + new->data [j - 1]->code_size; - else - new->last_code_end = old->last_code_end; - - return new; -} - -static MonoJitInfoTable* -jit_info_table_copy_and_purify_chunk (MonoJitInfoTable *table, MonoJitInfoTableChunk *chunk) -{ - MonoJitInfoTable *new_table = g_malloc (MONO_SIZEOF_JIT_INFO_TABLE - + sizeof (MonoJitInfoTableChunk*) * table->num_chunks); - int i, j; - - new_table->domain = table->domain; - new_table->num_chunks = table->num_chunks; - - j = 0; - for (i = 0; i < table->num_chunks; ++i) { - if (table->chunks [i] == chunk) - new_table->chunks [j++] = jit_info_table_purify_chunk (table->chunks [i]); - else { - new_table->chunks [j] = table->chunks [i]; - ++new_table->chunks [j]->refcount; - ++j; - } - } - - g_assert (j == new_table->num_chunks); - - return new_table; -} - -/* As we add an element to the table the case can arise that the chunk - * to which we need to add is already full. In that case we have to - * allocate a new table and do something about that chunk. We have - * several strategies: - * - * If the number of elements in the table is below the low watermark - * or above the high watermark, we reallocate the whole table. - * Otherwise we only concern ourselves with the overflowing chunk: - * - * If there are no tombstones in the chunk then we split the chunk in - * two, each half full. - * - * If the chunk does contain tombstones, we just make a new copy of - * the chunk without the tombstones, which will have room for at least - * the one element we have to add. - */ -static MonoJitInfoTable* -jit_info_table_chunk_overflow (MonoJitInfoTable *table, MonoJitInfoTableChunk *chunk) -{ - int num_elements = jit_info_table_num_elements (table); - int i; - - if (num_elements < JIT_INFO_TABLE_LOW_WATERMARK (table->num_chunks * MONO_JIT_INFO_TABLE_CHUNK_SIZE) - || num_elements > JIT_INFO_TABLE_HIGH_WATERMARK (table->num_chunks * MONO_JIT_INFO_TABLE_CHUNK_SIZE)) { - //printf ("reallocing table\n"); - return jit_info_table_realloc (table); - } - - /* count the number of non-tombstone elements in the chunk */ - num_elements = 0; - for (i = 0; i < chunk->num_elements; ++i) { - if (!IS_JIT_INFO_TOMBSTONE (chunk->data [i])) - ++num_elements; - } - - if (num_elements == MONO_JIT_INFO_TABLE_CHUNK_SIZE) { - //printf ("splitting chunk\n"); - return jit_info_table_copy_and_split_chunk (table, chunk); - } - - //printf ("purifying chunk\n"); - return jit_info_table_copy_and_purify_chunk (table, chunk); -} - -/* We add elements to the table by first making space for them by - * shifting the elements at the back to the right, one at a time. - * This results in duplicate entries during the process, but during - * all the time the table is in a sorted state. Also, when an element - * is replaced by another one, the element that replaces it has an end - * address that is equal to or lower than that of the replaced - * element. That property is necessary to guarantee that when - * searching for an element we end up at a position not higher than - * the one we're looking for (i.e. we either find the element directly - * or we end up to the left of it). - */ -static void -jit_info_table_add (MonoDomain *domain, MonoJitInfoTable *volatile *table_ptr, MonoJitInfo *ji) -{ - MonoJitInfoTable *table; - MonoJitInfoTableChunk *chunk; - int chunk_pos, pos; - int num_elements; - int i; - - table = *table_ptr; - - restart: - chunk_pos = jit_info_table_index (table, (gint8*)ji->code_start + ji->code_size); - g_assert (chunk_pos < table->num_chunks); - chunk = table->chunks [chunk_pos]; - - if (chunk->num_elements >= MONO_JIT_INFO_TABLE_CHUNK_SIZE) { - MonoJitInfoTable *new_table = jit_info_table_chunk_overflow (table, chunk); - - /* Debugging code, should be removed. */ - //jit_info_table_check (new_table); - - *table_ptr = new_table; - mono_memory_barrier (); - domain->num_jit_info_tables++; - mono_thread_hazardous_free_or_queue (table, (MonoHazardousFreeFunc)jit_info_table_free, TRUE, FALSE); - table = new_table; - - goto restart; - } - - /* Debugging code, should be removed. */ - //jit_info_table_check (table); - - num_elements = chunk->num_elements; - - pos = jit_info_table_chunk_index (chunk, NULL, (gint8*)ji->code_start + ji->code_size); - - /* First we need to size up the chunk by one, by copying the - last item, or inserting the first one, if the table is - empty. */ - if (num_elements > 0) - chunk->data [num_elements] = chunk->data [num_elements - 1]; - else - chunk->data [0] = ji; - mono_memory_write_barrier (); - chunk->num_elements = ++num_elements; - - /* Shift the elements up one by one. */ - for (i = num_elements - 2; i >= pos; --i) { - mono_memory_write_barrier (); - chunk->data [i + 1] = chunk->data [i]; - } - - /* Now we have room and can insert the new item. */ - mono_memory_write_barrier (); - chunk->data [pos] = ji; - - /* Set the high code end address chunk entry. */ - chunk->last_code_end = (gint8*)chunk->data [chunk->num_elements - 1]->code_start - + chunk->data [chunk->num_elements - 1]->code_size; - - /* Debugging code, should be removed. */ - //jit_info_table_check (table); -} - -void -mono_jit_info_table_add (MonoDomain *domain, MonoJitInfo *ji) -{ - g_assert (ji->d.method != NULL); - - mono_domain_lock (domain); - - ++mono_stats.jit_info_table_insert_count; - - jit_info_table_add (domain, &domain->jit_info_table, ji); - - mono_domain_unlock (domain); -} - -static MonoJitInfo* -mono_jit_info_make_tombstone (MonoJitInfo *ji) -{ - MonoJitInfo *tombstone = g_new0 (MonoJitInfo, 1); - - tombstone->code_start = ji->code_start; - tombstone->code_size = ji->code_size; - tombstone->d.method = JIT_INFO_TOMBSTONE_MARKER; - - return tombstone; -} - -/* - * LOCKING: domain lock - */ -static void -mono_jit_info_free_or_queue (MonoDomain *domain, MonoJitInfo *ji) -{ - if (domain->num_jit_info_tables <= 1) { - /* Can it actually happen that we only have one table - but ji is still hazardous? */ - mono_thread_hazardous_free_or_queue (ji, g_free, TRUE, FALSE); - } else { - domain->jit_info_free_queue = g_slist_prepend (domain->jit_info_free_queue, ji); - } -} - -static void -jit_info_table_remove (MonoJitInfoTable *table, MonoJitInfo *ji) -{ - MonoJitInfoTableChunk *chunk; - gpointer start = ji->code_start; - int chunk_pos, pos; - - chunk_pos = jit_info_table_index (table, start); - g_assert (chunk_pos < table->num_chunks); - - pos = jit_info_table_chunk_index (table->chunks [chunk_pos], NULL, start); - - do { - chunk = table->chunks [chunk_pos]; - - while (pos < chunk->num_elements) { - if (chunk->data [pos] == ji) - goto found; - - g_assert (IS_JIT_INFO_TOMBSTONE (chunk->data [pos])); - g_assert ((guint8*)chunk->data [pos]->code_start + chunk->data [pos]->code_size - <= (guint8*)ji->code_start + ji->code_size); - - ++pos; - } - - ++chunk_pos; - pos = 0; - } while (chunk_pos < table->num_chunks); - - found: - g_assert (chunk->data [pos] == ji); - - chunk->data [pos] = mono_jit_info_make_tombstone (ji); - - /* Debugging code, should be removed. */ - //jit_info_table_check (table); -} - -void -mono_jit_info_table_remove (MonoDomain *domain, MonoJitInfo *ji) -{ - MonoJitInfoTable *table; - - mono_domain_lock (domain); - table = domain->jit_info_table; - - ++mono_stats.jit_info_table_remove_count; - - jit_info_table_remove (table, ji); - - mono_jit_info_free_or_queue (domain, ji); - - mono_domain_unlock (domain); -} - -void -mono_jit_info_add_aot_module (MonoImage *image, gpointer start, gpointer end) -{ - MonoJitInfo *ji; - - g_assert (mono_root_domain); - mono_domain_lock (mono_root_domain); - - /* - * We reuse MonoJitInfoTable to store AOT module info, - * this gives us async-safe lookup. - */ - if (!mono_root_domain->aot_modules) { - mono_root_domain->num_jit_info_tables ++; - mono_root_domain->aot_modules = jit_info_table_new (mono_root_domain); - } - - ji = g_new0 (MonoJitInfo, 1); - ji->d.image = image; - ji->code_start = start; - ji->code_size = (guint8*)end - (guint8*)start; - jit_info_table_add (mono_root_domain, &mono_root_domain->aot_modules, ji); - - mono_domain_unlock (mono_root_domain); -} - -void -mono_install_jit_info_find_in_aot (MonoJitInfoFindInAot func) -{ - jit_info_find_in_aot_func = func; -} - -gpointer -mono_jit_info_get_code_start (MonoJitInfo* ji) -{ - return ji->code_start; -} - -int -mono_jit_info_get_code_size (MonoJitInfo* ji) -{ - return ji->code_size; -} - -MonoMethod* -mono_jit_info_get_method (MonoJitInfo* ji) -{ - g_assert (!ji->async); - return ji->d.method; -} - -static gpointer -jit_info_key_extract (gpointer value) -{ - MonoJitInfo *info = (MonoJitInfo*)value; - - return info->d.method; -} - -static gpointer* -jit_info_next_value (gpointer value) -{ - MonoJitInfo *info = (MonoJitInfo*)value; - - return (gpointer*)&info->next_jit_code_hash; -} - -void -mono_jit_code_hash_init (MonoInternalHashTable *jit_code_hash) -{ - mono_internal_hash_table_init (jit_code_hash, - mono_aligned_addr_hash, - jit_info_key_extract, - jit_info_next_value); -} - -MonoGenericJitInfo* -mono_jit_info_get_generic_jit_info (MonoJitInfo *ji) -{ - if (ji->has_generic_jit_info) - return (MonoGenericJitInfo*)&ji->clauses [ji->num_clauses]; - else - return NULL; -} - -/* - * mono_jit_info_get_generic_sharing_context: - * @ji: a jit info - * - * Returns the jit info's generic sharing context, or NULL if it - * doesn't have one. - */ -MonoGenericSharingContext* -mono_jit_info_get_generic_sharing_context (MonoJitInfo *ji) -{ - MonoGenericJitInfo *gi = mono_jit_info_get_generic_jit_info (ji); - - if (gi) - return gi->generic_sharing_context; - else - return NULL; -} - -/* - * mono_jit_info_set_generic_sharing_context: - * @ji: a jit info - * @gsctx: a generic sharing context - * - * Sets the jit info's generic sharing context. The jit info must - * have memory allocated for the context. - */ -void -mono_jit_info_set_generic_sharing_context (MonoJitInfo *ji, MonoGenericSharingContext *gsctx) -{ - MonoGenericJitInfo *gi = mono_jit_info_get_generic_jit_info (ji); - - g_assert (gi); - - gi->generic_sharing_context = gsctx; -} - -MonoTryBlockHoleTableJitInfo* -mono_jit_info_get_try_block_hole_table_info (MonoJitInfo *ji) -{ - if (ji->has_try_block_holes) { - char *ptr = (char*)&ji->clauses [ji->num_clauses]; - if (ji->has_generic_jit_info) - ptr += sizeof (MonoGenericJitInfo); - return (MonoTryBlockHoleTableJitInfo*)ptr; - } else { - return NULL; - } -} - -static int -try_block_hole_table_size (MonoJitInfo *ji) -{ - MonoTryBlockHoleTableJitInfo *table; - - table = mono_jit_info_get_try_block_hole_table_info (ji); - g_assert (table); - return sizeof (MonoTryBlockHoleTableJitInfo) + table->num_holes * sizeof (MonoTryBlockHoleJitInfo); -} - -MonoArchEHJitInfo* -mono_jit_info_get_arch_eh_info (MonoJitInfo *ji) -{ - if (ji->has_arch_eh_info) { - char *ptr = (char*)&ji->clauses [ji->num_clauses]; - if (ji->has_generic_jit_info) - ptr += sizeof (MonoGenericJitInfo); - if (ji->has_try_block_holes) - ptr += try_block_hole_table_size (ji); - return (MonoArchEHJitInfo*)ptr; - } else { - return NULL; - } -} - -MonoMethodCasInfo* -mono_jit_info_get_cas_info (MonoJitInfo *ji) -{ - if (ji->has_cas_info) { - char *ptr = (char*)&ji->clauses [ji->num_clauses]; - if (ji->has_generic_jit_info) - ptr += sizeof (MonoGenericJitInfo); - if (ji->has_try_block_holes) - ptr += try_block_hole_table_size (ji); - if (ji->has_arch_eh_info) - ptr += sizeof (MonoArchEHJitInfo); - return (MonoMethodCasInfo*)ptr; - } else { - return NULL; - } -} - #define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1)) #define ALIGN_PTR_TO(ptr,align) (gpointer)((((gssize)(ptr)) + (align - 1)) & (~(align - 1))) @@ -1302,7 +440,7 @@ mono_domain_create (void) mono_jit_code_hash_init (&domain->jit_code_hash); domain->ldstr_table = mono_g_hash_table_new_type ((GHashFunc)mono_string_hash, (GCompareFunc)mono_string_equal, MONO_HASH_KEY_VALUE_GC); domain->num_jit_info_tables = 1; - domain->jit_info_table = jit_info_table_new (domain); + domain->jit_info_table = mono_jit_info_table_new (domain); domain->jit_info_free_queue = NULL; domain->finalizable_objects_hash = g_hash_table_new (mono_aligned_addr_hash, NULL); domain->ftnptrs_hash = g_hash_table_new (mono_aligned_addr_hash, NULL); @@ -2094,9 +1232,9 @@ mono_domain_free (MonoDomain *domain, gboolean force) */ mono_thread_hazardous_try_free_all (); if (domain->aot_modules) - jit_info_table_free (domain->aot_modules); + mono_jit_info_table_free (domain->aot_modules); g_assert (domain->num_jit_info_tables == 1); - jit_info_table_free (domain->jit_info_table); + mono_jit_info_table_free (domain->jit_info_table); domain->jit_info_table = NULL; g_assert (!domain->jit_info_free_queue); diff --git a/mono/metadata/exception.c b/mono/metadata/exception.c index 24bfd6ed5b..cf42445fa7 100644 --- a/mono/metadata/exception.c +++ b/mono/metadata/exception.c @@ -87,10 +87,12 @@ mono_exception_from_name_domain (MonoDomain *domain, MonoImage *image, MonoException * mono_exception_from_token (MonoImage *image, guint32 token) { + MonoError error; MonoClass *klass; MonoObject *o; - klass = mono_class_get (image, token); + klass = mono_class_get_checked (image, token, &error); + g_assert (mono_error_ok (&error)); /* FIXME handle the error. */ o = mono_object_new (mono_domain_get (), klass); g_assert (o != NULL); @@ -197,7 +199,9 @@ MonoException * mono_exception_from_token_two_strings (MonoImage *image, guint32 token, MonoString *a1, MonoString *a2) { - MonoClass *klass = mono_class_get (image, token); + MonoError error; + MonoClass *klass = mono_class_get_checked (image, token, &error); + g_assert (mono_error_ok (&error)); /* FIXME handle the error. */ return create_exception_two_strings (klass, a1, a2); } diff --git a/mono/metadata/gc-internal.h b/mono/metadata/gc-internal.h index f2e59acb84..7b8836363f 100644 --- a/mono/metadata/gc-internal.h +++ b/mono/metadata/gc-internal.h @@ -13,7 +13,6 @@ #include #include #include -#include #include typedef struct { @@ -21,14 +20,7 @@ typedef struct { int major_gc_count; long long minor_gc_time; long long major_gc_time; -#ifdef HEAVY_STATISTICS - unsigned long long gray_queue_section_alloc; - unsigned long long gray_queue_section_free; - unsigned long long gray_queue_enqueue_fast_path; - unsigned long long gray_queue_dequeue_fast_path; - unsigned long long gray_queue_enqueue_slow_path; - unsigned long long gray_queue_dequeue_slow_path; -#endif + long long major_gc_time_concurrent; } GCStats; #define mono_domain_finalizers_lock(domain) mono_mutex_lock (&(domain)->finalizable_objects_hash_lock); @@ -337,6 +329,8 @@ void mono_gc_set_skip_thread (gboolean skip) MONO_INTERNAL; */ gboolean mono_gc_is_disabled (void) MONO_INTERNAL; +void mono_gc_set_string_length (MonoString *str, gint32 new_length) MONO_INTERNAL; + #if defined(__MACH__) void mono_gc_register_mach_exception_thread (pthread_t thread) MONO_INTERNAL; pthread_t mono_gc_get_mach_exception_thread (void) MONO_INTERNAL; diff --git a/mono/metadata/gc.c b/mono/metadata/gc.c index 03b182b99f..4e025385b7 100644 --- a/mono/metadata/gc.c +++ b/mono/metadata/gc.c @@ -1154,14 +1154,7 @@ mono_gc_init (void) mono_counters_register ("Major GC collections", MONO_COUNTER_GC | MONO_COUNTER_INT, &gc_stats.major_gc_count); mono_counters_register ("Minor GC time", MONO_COUNTER_GC | MONO_COUNTER_LONG | MONO_COUNTER_TIME, &gc_stats.minor_gc_time); mono_counters_register ("Major GC time", MONO_COUNTER_GC | MONO_COUNTER_LONG | MONO_COUNTER_TIME, &gc_stats.major_gc_time); -#ifdef HEAVY_STATISTICS - mono_counters_register ("Gray Queue alloc section", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &gc_stats.gray_queue_section_alloc); - mono_counters_register ("Gray Queue free section", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &gc_stats.gray_queue_section_free); - mono_counters_register ("Gray Queue enqueue fast path", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &gc_stats.gray_queue_enqueue_fast_path); - mono_counters_register ("Gray Queue dequeue fast path", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &gc_stats.gray_queue_dequeue_fast_path); - mono_counters_register ("Gray Queue enqueue slow path", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &gc_stats.gray_queue_enqueue_slow_path); - mono_counters_register ("Gray Queue dequeue slow path", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &gc_stats.gray_queue_dequeue_slow_path); -#endif + mono_counters_register ("Major GC time concurrent", MONO_COUNTER_GC | MONO_COUNTER_LONG | MONO_COUNTER_TIME, &gc_stats.major_gc_time_concurrent); mono_gc_base_init (); @@ -1231,7 +1224,7 @@ mono_gc_cleanup (void) ret = WaitForSingleObjectEx (gc_thread->handle, INFINITE, TRUE); g_assert (ret == WAIT_OBJECT_0); - mono_thread_join ((gpointer)gc_thread->tid); + mono_thread_join (MONO_UINT_TO_NATIVE_THREAD_ID (gc_thread->tid)); } } gc_thread = NULL; diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h index 103eb3c423..257b8332f5 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -797,6 +797,7 @@ ICALL(STRING_8a, "GetLOSLimit", ves_icall_System_String_GetLOSLimit) ICALL(STRING_9, "InternalAllocateStr", ves_icall_System_String_InternalAllocateStr) ICALL(STRING_10, "InternalIntern", ves_icall_System_String_InternalIntern) ICALL(STRING_11, "InternalIsInterned", ves_icall_System_String_InternalIsInterned) +ICALL(STRING_12, "InternalSetLength", ves_icall_System_String_InternalSetLength) ICALL_TYPE(TENC, "System.Text.Encoding", TENC_1) ICALL(TENC_1, "InternalCodePage", ves_icall_System_Text_Encoding_InternalCodePage) diff --git a/mono/metadata/icall.c.REMOVED.git-id b/mono/metadata/icall.c.REMOVED.git-id index 12f3d61b20..9ed4225504 100644 --- a/mono/metadata/icall.c.REMOVED.git-id +++ b/mono/metadata/icall.c.REMOVED.git-id @@ -1 +1 @@ -ddec8e4305301db4d3a6aafc7b3c908d6eb14c3a \ No newline at end of file +763b2f638bff16a7463b9ef207bf0ce2e33a2706 \ No newline at end of file diff --git a/mono/metadata/jit-info.c b/mono/metadata/jit-info.c new file mode 100644 index 0000000000..cc0b76622f --- /dev/null +++ b/mono/metadata/jit-info.c @@ -0,0 +1,946 @@ +/* + * jit-info.c: MonoJitInfo functionality + * + * Author: + * Dietmar Maurer (dietmar@ximian.com) + * Patrik Torstensson + * + * Copyright 2001-2003 Ximian, Inc (http://www.ximian.com) + * Copyright 2004-2009 Novell, Inc (http://www.novell.com) + * Copyright 2011-2012 Xamarin, Inc (http://www.xamarin.com) + */ + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static MonoJitInfoFindInAot jit_info_find_in_aot_func = NULL; + +#define JIT_INFO_TABLE_FILL_RATIO_NOM 3 +#define JIT_INFO_TABLE_FILL_RATIO_DENOM 4 +#define JIT_INFO_TABLE_FILLED_NUM_ELEMENTS (MONO_JIT_INFO_TABLE_CHUNK_SIZE * JIT_INFO_TABLE_FILL_RATIO_NOM / JIT_INFO_TABLE_FILL_RATIO_DENOM) + +#define JIT_INFO_TABLE_LOW_WATERMARK(n) ((n) / 2) +#define JIT_INFO_TABLE_HIGH_WATERMARK(n) ((n) * 5 / 6) + +#define JIT_INFO_TOMBSTONE_MARKER ((MonoMethod*)NULL) +#define IS_JIT_INFO_TOMBSTONE(ji) ((ji)->d.method == JIT_INFO_TOMBSTONE_MARKER) + +#define JIT_INFO_TABLE_HAZARD_INDEX 0 +#define JIT_INFO_HAZARD_INDEX 1 + +static int +jit_info_table_num_elements (MonoJitInfoTable *table) +{ + int i; + int num_elements = 0; + + for (i = 0; i < table->num_chunks; ++i) { + MonoJitInfoTableChunk *chunk = table->chunks [i]; + int chunk_num_elements = chunk->num_elements; + int j; + + for (j = 0; j < chunk_num_elements; ++j) { + if (!IS_JIT_INFO_TOMBSTONE (chunk->data [j])) + ++num_elements; + } + } + + return num_elements; +} + +static MonoJitInfoTableChunk* +jit_info_table_new_chunk (void) +{ + MonoJitInfoTableChunk *chunk = g_new0 (MonoJitInfoTableChunk, 1); + chunk->refcount = 1; + + return chunk; +} + +MonoJitInfoTable * +mono_jit_info_table_new (MonoDomain *domain) +{ + MonoJitInfoTable *table = g_malloc0 (MONO_SIZEOF_JIT_INFO_TABLE + sizeof (MonoJitInfoTableChunk*)); + + table->domain = domain; + table->num_chunks = 1; + table->chunks [0] = jit_info_table_new_chunk (); + + return table; +} + +void +mono_jit_info_table_free (MonoJitInfoTable *table) +{ + int i; + int num_chunks = table->num_chunks; + MonoDomain *domain = table->domain; + + mono_domain_lock (domain); + + table->domain->num_jit_info_tables--; + if (table->domain->num_jit_info_tables <= 1) { + GSList *list; + + for (list = table->domain->jit_info_free_queue; list; list = list->next) + g_free (list->data); + + g_slist_free (table->domain->jit_info_free_queue); + table->domain->jit_info_free_queue = NULL; + } + + /* At this point we assume that there are no other threads + still accessing the table, so we don't have to worry about + hazardous pointers. */ + + for (i = 0; i < num_chunks; ++i) { + MonoJitInfoTableChunk *chunk = table->chunks [i]; + int num_elements; + int j; + + if (--chunk->refcount > 0) + continue; + + num_elements = chunk->num_elements; + for (j = 0; j < num_elements; ++j) { + MonoJitInfo *ji = chunk->data [j]; + + if (IS_JIT_INFO_TOMBSTONE (ji)) + g_free (ji); + } + + g_free (chunk); + } + + mono_domain_unlock (domain); + + g_free (table); +} + +/* The jit_info_table is sorted in ascending order by the end + * addresses of the compiled methods. The reason why we have to do + * this is that once we introduce tombstones, it becomes possible for + * code ranges to overlap, and if we sort by code start and insert at + * the back of the table, we cannot guarantee that we won't overlook + * an entry. + * + * There are actually two possible ways to do the sorting and + * inserting which work with our lock-free mechanism: + * + * 1. Sort by start address and insert at the front. When looking for + * an entry, find the last one with a start address lower than the one + * you're looking for, then work your way to the front of the table. + * + * 2. Sort by end address and insert at the back. When looking for an + * entry, find the first one with an end address higher than the one + * you're looking for, then work your way to the end of the table. + * + * We chose the latter out of convenience. + */ +static int +jit_info_table_index (MonoJitInfoTable *table, gint8 *addr) +{ + int left = 0, right = table->num_chunks; + + g_assert (left < right); + + do { + int pos = (left + right) / 2; + MonoJitInfoTableChunk *chunk = table->chunks [pos]; + + if (addr < chunk->last_code_end) + right = pos; + else + left = pos + 1; + } while (left < right); + g_assert (left == right); + + if (left >= table->num_chunks) + return table->num_chunks - 1; + return left; +} + +static int +jit_info_table_chunk_index (MonoJitInfoTableChunk *chunk, MonoThreadHazardPointers *hp, gint8 *addr) +{ + int left = 0, right = chunk->num_elements; + + while (left < right) { + int pos = (left + right) / 2; + MonoJitInfo *ji = get_hazardous_pointer((gpointer volatile*)&chunk->data [pos], hp, JIT_INFO_HAZARD_INDEX); + gint8 *code_end = (gint8*)ji->code_start + ji->code_size; + + if (addr < code_end) + right = pos; + else + left = pos + 1; + } + g_assert (left == right); + + return left; +} + +static MonoJitInfo* +jit_info_table_find (MonoJitInfoTable *table, MonoThreadHazardPointers *hp, gint8 *addr) +{ + MonoJitInfo *ji; + int chunk_pos, pos; + + chunk_pos = jit_info_table_index (table, (gint8*)addr); + g_assert (chunk_pos < table->num_chunks); + + pos = jit_info_table_chunk_index (table->chunks [chunk_pos], hp, (gint8*)addr); + + /* We now have a position that's very close to that of the + first element whose end address is higher than the one + we're looking for. If we don't have the exact position, + then we have a position below that one, so we'll just + search upward until we find our element. */ + do { + MonoJitInfoTableChunk *chunk = table->chunks [chunk_pos]; + + while (pos < chunk->num_elements) { + ji = get_hazardous_pointer ((gpointer volatile*)&chunk->data [pos], hp, JIT_INFO_HAZARD_INDEX); + + ++pos; + + if (IS_JIT_INFO_TOMBSTONE (ji)) { + mono_hazard_pointer_clear (hp, JIT_INFO_HAZARD_INDEX); + continue; + } + if ((gint8*)addr >= (gint8*)ji->code_start + && (gint8*)addr < (gint8*)ji->code_start + ji->code_size) { + mono_hazard_pointer_clear (hp, JIT_INFO_HAZARD_INDEX); + return ji; + } + + /* If we find a non-tombstone element which is already + beyond what we're looking for, we have to end the + search. */ + if ((gint8*)addr < (gint8*)ji->code_start) + goto not_found; + } + + ++chunk_pos; + pos = 0; + } while (chunk_pos < table->num_chunks); + + not_found: + if (hp) + mono_hazard_pointer_clear (hp, JIT_INFO_HAZARD_INDEX); + return NULL; +} + +/* + * mono_jit_info_table_find_internal: + * + * If TRY_AOT is FALSE, avoid loading information for missing methods from AOT images, which is currently not async safe. + * In this case, only those AOT methods will be found whose jit info is already loaded. + * ASYNC SAFETY: When called in an async context (mono_thread_info_is_async_context ()), this is async safe. + * In this case, the returned MonoJitInfo might not have metadata information, in particular, + * mono_jit_info_get_method () could fail. + */ +MonoJitInfo* +mono_jit_info_table_find_internal (MonoDomain *domain, char *addr, gboolean try_aot) +{ + MonoJitInfoTable *table; + MonoJitInfo *ji, *module_ji; + MonoThreadHazardPointers *hp = mono_hazard_pointer_get (); + + ++mono_stats.jit_info_table_lookup_count; + + /* First we have to get the domain's jit_info_table. This is + complicated by the fact that a writer might substitute a + new table and free the old one. What the writer guarantees + us is that it looks at the hazard pointers after it has + changed the jit_info_table pointer. So, if we guard the + table by a hazard pointer and make sure that the pointer is + still there after we've made it hazardous, we don't have to + worry about the writer freeing the table. */ + table = get_hazardous_pointer ((gpointer volatile*)&domain->jit_info_table, hp, JIT_INFO_TABLE_HAZARD_INDEX); + + ji = jit_info_table_find (table, hp, (gint8*)addr); + if (hp) + mono_hazard_pointer_clear (hp, JIT_INFO_TABLE_HAZARD_INDEX); + if (ji) + return ji; + + /* Maybe its an AOT module */ + if (try_aot && mono_get_root_domain () && mono_get_root_domain ()->aot_modules) { + table = get_hazardous_pointer ((gpointer volatile*)&mono_get_root_domain ()->aot_modules, hp, JIT_INFO_TABLE_HAZARD_INDEX); + module_ji = jit_info_table_find (table, hp, (gint8*)addr); + if (module_ji) + ji = jit_info_find_in_aot_func (domain, module_ji->d.image, addr); + if (hp) + mono_hazard_pointer_clear (hp, JIT_INFO_TABLE_HAZARD_INDEX); + } + + return ji; +} + +MonoJitInfo* +mono_jit_info_table_find (MonoDomain *domain, char *addr) +{ + return mono_jit_info_table_find_internal (domain, addr, TRUE); +} + +static G_GNUC_UNUSED void +jit_info_table_check (MonoJitInfoTable *table) +{ + int i; + + for (i = 0; i < table->num_chunks; ++i) { + MonoJitInfoTableChunk *chunk = table->chunks [i]; + int j; + + g_assert (chunk->refcount > 0 /* && chunk->refcount <= 8 */); + if (chunk->refcount > 10) + printf("warning: chunk refcount is %d\n", chunk->refcount); + g_assert (chunk->num_elements <= MONO_JIT_INFO_TABLE_CHUNK_SIZE); + + for (j = 0; j < chunk->num_elements; ++j) { + MonoJitInfo *this = chunk->data [j]; + MonoJitInfo *next; + + g_assert ((gint8*)this->code_start + this->code_size <= chunk->last_code_end); + + if (j < chunk->num_elements - 1) + next = chunk->data [j + 1]; + else if (i < table->num_chunks - 1) { + int k; + + for (k = i + 1; k < table->num_chunks; ++k) + if (table->chunks [k]->num_elements > 0) + break; + + if (k >= table->num_chunks) + return; + + g_assert (table->chunks [k]->num_elements > 0); + next = table->chunks [k]->data [0]; + } else + return; + + g_assert ((gint8*)this->code_start + this->code_size <= (gint8*)next->code_start + next->code_size); + } + } +} + +static MonoJitInfoTable* +jit_info_table_realloc (MonoJitInfoTable *old) +{ + int i; + int num_elements = jit_info_table_num_elements (old); + int required_size; + int num_chunks; + int new_chunk, new_element; + MonoJitInfoTable *new; + + /* number of needed places for elements needed */ + required_size = (int)((long)num_elements * JIT_INFO_TABLE_FILL_RATIO_DENOM / JIT_INFO_TABLE_FILL_RATIO_NOM); + num_chunks = (required_size + MONO_JIT_INFO_TABLE_CHUNK_SIZE - 1) / MONO_JIT_INFO_TABLE_CHUNK_SIZE; + if (num_chunks == 0) { + g_assert (num_elements == 0); + return mono_jit_info_table_new (old->domain); + } + g_assert (num_chunks > 0); + + new = g_malloc (MONO_SIZEOF_JIT_INFO_TABLE + sizeof (MonoJitInfoTableChunk*) * num_chunks); + new->domain = old->domain; + new->num_chunks = num_chunks; + + for (i = 0; i < num_chunks; ++i) + new->chunks [i] = jit_info_table_new_chunk (); + + new_chunk = 0; + new_element = 0; + for (i = 0; i < old->num_chunks; ++i) { + MonoJitInfoTableChunk *chunk = old->chunks [i]; + int chunk_num_elements = chunk->num_elements; + int j; + + for (j = 0; j < chunk_num_elements; ++j) { + if (!IS_JIT_INFO_TOMBSTONE (chunk->data [j])) { + g_assert (new_chunk < num_chunks); + new->chunks [new_chunk]->data [new_element] = chunk->data [j]; + if (++new_element >= JIT_INFO_TABLE_FILLED_NUM_ELEMENTS) { + new->chunks [new_chunk]->num_elements = new_element; + ++new_chunk; + new_element = 0; + } + } + } + } + + if (new_chunk < num_chunks) { + g_assert (new_chunk == num_chunks - 1); + new->chunks [new_chunk]->num_elements = new_element; + g_assert (new->chunks [new_chunk]->num_elements > 0); + } + + for (i = 0; i < num_chunks; ++i) { + MonoJitInfoTableChunk *chunk = new->chunks [i]; + MonoJitInfo *ji = chunk->data [chunk->num_elements - 1]; + + new->chunks [i]->last_code_end = (gint8*)ji->code_start + ji->code_size; + } + + return new; +} + +static void +jit_info_table_split_chunk (MonoJitInfoTableChunk *chunk, MonoJitInfoTableChunk **new1p, MonoJitInfoTableChunk **new2p) +{ + MonoJitInfoTableChunk *new1 = jit_info_table_new_chunk (); + MonoJitInfoTableChunk *new2 = jit_info_table_new_chunk (); + + g_assert (chunk->num_elements == MONO_JIT_INFO_TABLE_CHUNK_SIZE); + + new1->num_elements = MONO_JIT_INFO_TABLE_CHUNK_SIZE / 2; + new2->num_elements = MONO_JIT_INFO_TABLE_CHUNK_SIZE - new1->num_elements; + + memcpy ((void*)new1->data, (void*)chunk->data, sizeof (MonoJitInfo*) * new1->num_elements); + memcpy ((void*)new2->data, (void*)(chunk->data + new1->num_elements), sizeof (MonoJitInfo*) * new2->num_elements); + + new1->last_code_end = (gint8*)new1->data [new1->num_elements - 1]->code_start + + new1->data [new1->num_elements - 1]->code_size; + new2->last_code_end = (gint8*)new2->data [new2->num_elements - 1]->code_start + + new2->data [new2->num_elements - 1]->code_size; + + *new1p = new1; + *new2p = new2; +} + +static MonoJitInfoTable* +jit_info_table_copy_and_split_chunk (MonoJitInfoTable *table, MonoJitInfoTableChunk *chunk) +{ + MonoJitInfoTable *new_table = g_malloc (MONO_SIZEOF_JIT_INFO_TABLE + + sizeof (MonoJitInfoTableChunk*) * (table->num_chunks + 1)); + int i, j; + + new_table->domain = table->domain; + new_table->num_chunks = table->num_chunks + 1; + + j = 0; + for (i = 0; i < table->num_chunks; ++i) { + if (table->chunks [i] == chunk) { + jit_info_table_split_chunk (chunk, &new_table->chunks [j], &new_table->chunks [j + 1]); + j += 2; + } else { + new_table->chunks [j] = table->chunks [i]; + ++new_table->chunks [j]->refcount; + ++j; + } + } + + g_assert (j == new_table->num_chunks); + + return new_table; +} + +static MonoJitInfoTableChunk* +jit_info_table_purify_chunk (MonoJitInfoTableChunk *old) +{ + MonoJitInfoTableChunk *new = jit_info_table_new_chunk (); + int i, j; + + j = 0; + for (i = 0; i < old->num_elements; ++i) { + if (!IS_JIT_INFO_TOMBSTONE (old->data [i])) + new->data [j++] = old->data [i]; + } + + new->num_elements = j; + if (new->num_elements > 0) + new->last_code_end = (gint8*)new->data [j - 1]->code_start + new->data [j - 1]->code_size; + else + new->last_code_end = old->last_code_end; + + return new; +} + +static MonoJitInfoTable* +jit_info_table_copy_and_purify_chunk (MonoJitInfoTable *table, MonoJitInfoTableChunk *chunk) +{ + MonoJitInfoTable *new_table = g_malloc (MONO_SIZEOF_JIT_INFO_TABLE + + sizeof (MonoJitInfoTableChunk*) * table->num_chunks); + int i, j; + + new_table->domain = table->domain; + new_table->num_chunks = table->num_chunks; + + j = 0; + for (i = 0; i < table->num_chunks; ++i) { + if (table->chunks [i] == chunk) + new_table->chunks [j++] = jit_info_table_purify_chunk (table->chunks [i]); + else { + new_table->chunks [j] = table->chunks [i]; + ++new_table->chunks [j]->refcount; + ++j; + } + } + + g_assert (j == new_table->num_chunks); + + return new_table; +} + +/* As we add an element to the table the case can arise that the chunk + * to which we need to add is already full. In that case we have to + * allocate a new table and do something about that chunk. We have + * several strategies: + * + * If the number of elements in the table is below the low watermark + * or above the high watermark, we reallocate the whole table. + * Otherwise we only concern ourselves with the overflowing chunk: + * + * If there are no tombstones in the chunk then we split the chunk in + * two, each half full. + * + * If the chunk does contain tombstones, we just make a new copy of + * the chunk without the tombstones, which will have room for at least + * the one element we have to add. + */ +static MonoJitInfoTable* +jit_info_table_chunk_overflow (MonoJitInfoTable *table, MonoJitInfoTableChunk *chunk) +{ + int num_elements = jit_info_table_num_elements (table); + int i; + + if (num_elements < JIT_INFO_TABLE_LOW_WATERMARK (table->num_chunks * MONO_JIT_INFO_TABLE_CHUNK_SIZE) + || num_elements > JIT_INFO_TABLE_HIGH_WATERMARK (table->num_chunks * MONO_JIT_INFO_TABLE_CHUNK_SIZE)) { + //printf ("reallocing table\n"); + return jit_info_table_realloc (table); + } + + /* count the number of non-tombstone elements in the chunk */ + num_elements = 0; + for (i = 0; i < chunk->num_elements; ++i) { + if (!IS_JIT_INFO_TOMBSTONE (chunk->data [i])) + ++num_elements; + } + + if (num_elements == MONO_JIT_INFO_TABLE_CHUNK_SIZE) { + //printf ("splitting chunk\n"); + return jit_info_table_copy_and_split_chunk (table, chunk); + } + + //printf ("purifying chunk\n"); + return jit_info_table_copy_and_purify_chunk (table, chunk); +} + +/* We add elements to the table by first making space for them by + * shifting the elements at the back to the right, one at a time. + * This results in duplicate entries during the process, but during + * all the time the table is in a sorted state. Also, when an element + * is replaced by another one, the element that replaces it has an end + * address that is equal to or lower than that of the replaced + * element. That property is necessary to guarantee that when + * searching for an element we end up at a position not higher than + * the one we're looking for (i.e. we either find the element directly + * or we end up to the left of it). + */ +static void +jit_info_table_add (MonoDomain *domain, MonoJitInfoTable *volatile *table_ptr, MonoJitInfo *ji) +{ + MonoJitInfoTable *table; + MonoJitInfoTableChunk *chunk; + int chunk_pos, pos; + int num_elements; + int i; + + table = *table_ptr; + + restart: + chunk_pos = jit_info_table_index (table, (gint8*)ji->code_start + ji->code_size); + g_assert (chunk_pos < table->num_chunks); + chunk = table->chunks [chunk_pos]; + + if (chunk->num_elements >= MONO_JIT_INFO_TABLE_CHUNK_SIZE) { + MonoJitInfoTable *new_table = jit_info_table_chunk_overflow (table, chunk); + + /* Debugging code, should be removed. */ + //jit_info_table_check (new_table); + + *table_ptr = new_table; + mono_memory_barrier (); + domain->num_jit_info_tables++; + mono_thread_hazardous_free_or_queue (table, (MonoHazardousFreeFunc)mono_jit_info_table_free, TRUE, FALSE); + table = new_table; + + goto restart; + } + + /* Debugging code, should be removed. */ + //jit_info_table_check (table); + + num_elements = chunk->num_elements; + + pos = jit_info_table_chunk_index (chunk, NULL, (gint8*)ji->code_start + ji->code_size); + + /* First we need to size up the chunk by one, by copying the + last item, or inserting the first one, if the table is + empty. */ + if (num_elements > 0) + chunk->data [num_elements] = chunk->data [num_elements - 1]; + else + chunk->data [0] = ji; + mono_memory_write_barrier (); + chunk->num_elements = ++num_elements; + + /* Shift the elements up one by one. */ + for (i = num_elements - 2; i >= pos; --i) { + mono_memory_write_barrier (); + chunk->data [i + 1] = chunk->data [i]; + } + + /* Now we have room and can insert the new item. */ + mono_memory_write_barrier (); + chunk->data [pos] = ji; + + /* Set the high code end address chunk entry. */ + chunk->last_code_end = (gint8*)chunk->data [chunk->num_elements - 1]->code_start + + chunk->data [chunk->num_elements - 1]->code_size; + + /* Debugging code, should be removed. */ + //jit_info_table_check (table); +} + +void +mono_jit_info_table_add (MonoDomain *domain, MonoJitInfo *ji) +{ + g_assert (ji->d.method != NULL); + + mono_domain_lock (domain); + + ++mono_stats.jit_info_table_insert_count; + + jit_info_table_add (domain, &domain->jit_info_table, ji); + + mono_domain_unlock (domain); +} + +static MonoJitInfo* +mono_jit_info_make_tombstone (MonoJitInfo *ji) +{ + MonoJitInfo *tombstone = g_new0 (MonoJitInfo, 1); + + tombstone->code_start = ji->code_start; + tombstone->code_size = ji->code_size; + tombstone->d.method = JIT_INFO_TOMBSTONE_MARKER; + + return tombstone; +} + +/* + * LOCKING: domain lock + */ +static void +mono_jit_info_free_or_queue (MonoDomain *domain, MonoJitInfo *ji) +{ + if (domain->num_jit_info_tables <= 1) { + /* Can it actually happen that we only have one table + but ji is still hazardous? */ + mono_thread_hazardous_free_or_queue (ji, g_free, TRUE, FALSE); + } else { + domain->jit_info_free_queue = g_slist_prepend (domain->jit_info_free_queue, ji); + } +} + +static void +jit_info_table_remove (MonoJitInfoTable *table, MonoJitInfo *ji) +{ + MonoJitInfoTableChunk *chunk; + gpointer start = ji->code_start; + int chunk_pos, pos; + + chunk_pos = jit_info_table_index (table, start); + g_assert (chunk_pos < table->num_chunks); + + pos = jit_info_table_chunk_index (table->chunks [chunk_pos], NULL, start); + + do { + chunk = table->chunks [chunk_pos]; + + while (pos < chunk->num_elements) { + if (chunk->data [pos] == ji) + goto found; + + g_assert (IS_JIT_INFO_TOMBSTONE (chunk->data [pos])); + g_assert ((guint8*)chunk->data [pos]->code_start + chunk->data [pos]->code_size + <= (guint8*)ji->code_start + ji->code_size); + + ++pos; + } + + ++chunk_pos; + pos = 0; + } while (chunk_pos < table->num_chunks); + + found: + g_assert (chunk->data [pos] == ji); + + chunk->data [pos] = mono_jit_info_make_tombstone (ji); + + /* Debugging code, should be removed. */ + //jit_info_table_check (table); +} + +void +mono_jit_info_table_remove (MonoDomain *domain, MonoJitInfo *ji) +{ + MonoJitInfoTable *table; + + mono_domain_lock (domain); + table = domain->jit_info_table; + + ++mono_stats.jit_info_table_remove_count; + + jit_info_table_remove (table, ji); + + mono_jit_info_free_or_queue (domain, ji); + + mono_domain_unlock (domain); +} + +void +mono_jit_info_add_aot_module (MonoImage *image, gpointer start, gpointer end) +{ + MonoJitInfo *ji; + MonoDomain *domain = mono_get_root_domain (); + + g_assert (domain); + mono_domain_lock (domain); + + /* + * We reuse MonoJitInfoTable to store AOT module info, + * this gives us async-safe lookup. + */ + if (!domain->aot_modules) { + domain->num_jit_info_tables ++; + domain->aot_modules = mono_jit_info_table_new (domain); + } + + ji = g_new0 (MonoJitInfo, 1); + ji->d.image = image; + ji->code_start = start; + ji->code_size = (guint8*)end - (guint8*)start; + jit_info_table_add (domain, &domain->aot_modules, ji); + + mono_domain_unlock (domain); +} + +void +mono_install_jit_info_find_in_aot (MonoJitInfoFindInAot func) +{ + jit_info_find_in_aot_func = func; +} + +int +mono_jit_info_size (MonoJitInfoFlags flags, int num_clauses, int num_holes) +{ + int size = MONO_SIZEOF_JIT_INFO; + + size += num_clauses * sizeof (MonoJitExceptionInfo); + if (flags & JIT_INFO_HAS_CAS_INFO) + size += sizeof (MonoMethodCasInfo); + if (flags & JIT_INFO_HAS_GENERIC_JIT_INFO) + size += sizeof (MonoGenericJitInfo); + if (flags & JIT_INFO_HAS_TRY_BLOCK_HOLES) + size += sizeof (MonoTryBlockHoleTableJitInfo) + num_holes * sizeof (MonoTryBlockHoleJitInfo); + if (flags & JIT_INFO_HAS_ARCH_EH_INFO) + size += sizeof (MonoArchEHJitInfo); + return size; +} + +void +mono_jit_info_init (MonoJitInfo *ji, MonoMethod *method, guint8 *code, int code_size, + MonoJitInfoFlags flags, int num_clauses, int num_holes) +{ + ji->d.method = method; + ji->code_start = code; + ji->code_size = code_size; + ji->num_clauses = num_clauses; + if (flags & JIT_INFO_HAS_CAS_INFO) + ji->has_cas_info = 1; + if (flags & JIT_INFO_HAS_GENERIC_JIT_INFO) + ji->has_generic_jit_info = 1; + if (flags & JIT_INFO_HAS_TRY_BLOCK_HOLES) + ji->has_try_block_holes = 1; + if (flags & JIT_INFO_HAS_ARCH_EH_INFO) + ji->has_arch_eh_info = 1; +} + +gpointer +mono_jit_info_get_code_start (MonoJitInfo* ji) +{ + return ji->code_start; +} + +int +mono_jit_info_get_code_size (MonoJitInfo* ji) +{ + return ji->code_size; +} + +MonoMethod* +mono_jit_info_get_method (MonoJitInfo* ji) +{ + g_assert (!ji->async); + return ji->d.method; +} + +static gpointer +jit_info_key_extract (gpointer value) +{ + MonoJitInfo *info = (MonoJitInfo*)value; + + return info->d.method; +} + +static gpointer* +jit_info_next_value (gpointer value) +{ + MonoJitInfo *info = (MonoJitInfo*)value; + + return (gpointer*)&info->next_jit_code_hash; +} + +void +mono_jit_code_hash_init (MonoInternalHashTable *jit_code_hash) +{ + mono_internal_hash_table_init (jit_code_hash, + mono_aligned_addr_hash, + jit_info_key_extract, + jit_info_next_value); +} + +MonoGenericJitInfo* +mono_jit_info_get_generic_jit_info (MonoJitInfo *ji) +{ + if (ji->has_generic_jit_info) + return (MonoGenericJitInfo*)&ji->clauses [ji->num_clauses]; + else + return NULL; +} + +/* + * mono_jit_info_get_generic_sharing_context: + * @ji: a jit info + * + * Returns the jit info's generic sharing context, or NULL if it + * doesn't have one. + */ +MonoGenericSharingContext* +mono_jit_info_get_generic_sharing_context (MonoJitInfo *ji) +{ + MonoGenericJitInfo *gi = mono_jit_info_get_generic_jit_info (ji); + + if (gi) + return gi->generic_sharing_context; + else + return NULL; +} + +/* + * mono_jit_info_set_generic_sharing_context: + * @ji: a jit info + * @gsctx: a generic sharing context + * + * Sets the jit info's generic sharing context. The jit info must + * have memory allocated for the context. + */ +void +mono_jit_info_set_generic_sharing_context (MonoJitInfo *ji, MonoGenericSharingContext *gsctx) +{ + MonoGenericJitInfo *gi = mono_jit_info_get_generic_jit_info (ji); + + g_assert (gi); + + gi->generic_sharing_context = gsctx; +} + +MonoTryBlockHoleTableJitInfo* +mono_jit_info_get_try_block_hole_table_info (MonoJitInfo *ji) +{ + if (ji->has_try_block_holes) { + char *ptr = (char*)&ji->clauses [ji->num_clauses]; + if (ji->has_generic_jit_info) + ptr += sizeof (MonoGenericJitInfo); + return (MonoTryBlockHoleTableJitInfo*)ptr; + } else { + return NULL; + } +} + +static int +try_block_hole_table_size (MonoJitInfo *ji) +{ + MonoTryBlockHoleTableJitInfo *table; + + table = mono_jit_info_get_try_block_hole_table_info (ji); + g_assert (table); + return sizeof (MonoTryBlockHoleTableJitInfo) + table->num_holes * sizeof (MonoTryBlockHoleJitInfo); +} + +MonoArchEHJitInfo* +mono_jit_info_get_arch_eh_info (MonoJitInfo *ji) +{ + if (ji->has_arch_eh_info) { + char *ptr = (char*)&ji->clauses [ji->num_clauses]; + if (ji->has_generic_jit_info) + ptr += sizeof (MonoGenericJitInfo); + if (ji->has_try_block_holes) + ptr += try_block_hole_table_size (ji); + return (MonoArchEHJitInfo*)ptr; + } else { + return NULL; + } +} + +MonoMethodCasInfo* +mono_jit_info_get_cas_info (MonoJitInfo *ji) +{ + if (ji->has_cas_info) { + char *ptr = (char*)&ji->clauses [ji->num_clauses]; + if (ji->has_generic_jit_info) + ptr += sizeof (MonoGenericJitInfo); + if (ji->has_try_block_holes) + ptr += try_block_hole_table_size (ji); + if (ji->has_arch_eh_info) + ptr += sizeof (MonoArchEHJitInfo); + return (MonoMethodCasInfo*)ptr; + } else { + return NULL; + } +} diff --git a/mono/metadata/loader.c b/mono/metadata/loader.c index aa24aa88bf..ea521d5520 100644 --- a/mono/metadata/loader.c +++ b/mono/metadata/loader.c @@ -395,9 +395,9 @@ find_cached_memberref_sig (MonoImage *image, guint32 sig_idx) { gpointer res; - mono_loader_lock (); + mono_image_lock (image); res = g_hash_table_lookup (image->memberref_signatures, GUINT_TO_POINTER (sig_idx)); - mono_loader_unlock (); + mono_image_unlock (image); return res; } @@ -407,7 +407,7 @@ cache_memberref_sig (MonoImage *image, guint32 sig_idx, gpointer sig) { gpointer prev_sig; - mono_loader_lock (); + mono_image_lock (image); prev_sig = g_hash_table_lookup (image->memberref_signatures, GUINT_TO_POINTER (sig_idx)); if (prev_sig) { /* Somebody got in before us */ @@ -418,8 +418,7 @@ cache_memberref_sig (MonoImage *image, guint32 sig_idx, gpointer sig) /* An approximation based on glib 2.18 */ memberref_sig_cache_size += sizeof (gpointer) * 4; } - - mono_loader_unlock (); + mono_image_unlock (image); return sig; } @@ -437,6 +436,7 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass, const char *fname; const char *ptr; guint32 idx = mono_metadata_token_index (token); + MonoError error; mono_metadata_decode_row (&tables [MONO_TABLE_MEMBERREF], idx-1, cols, MONO_MEMBERREF_SIZE); nindex = cols [MONO_MEMBERREF_CLASS] >> MONO_MEMBERREF_PARENT_BITS; @@ -452,15 +452,29 @@ field_from_memberref (MonoImage *image, guint32 token, MonoClass **retklass, switch (class) { case MONO_MEMBERREF_PARENT_TYPEDEF: class_table = MONO_TOKEN_TYPE_DEF; - klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | nindex); + klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | nindex, &error); + if (!mono_error_ok (&error)) { + /*FIXME don't swallow the error message*/ + mono_error_cleanup (&error); + } + break; case MONO_MEMBERREF_PARENT_TYPEREF: class_table = MONO_TOKEN_TYPE_REF; - klass = mono_class_from_typeref (image, MONO_TOKEN_TYPE_REF | nindex); + klass = mono_class_from_typeref_checked (image, MONO_TOKEN_TYPE_REF | nindex, &error); + if (!mono_error_ok (&error)) { + /*FIXME don't swallow the error message*/ + mono_error_cleanup (&error); + } + break; case MONO_MEMBERREF_PARENT_TYPESPEC: class_table = MONO_TOKEN_TYPE_SPEC; - klass = mono_class_get_full (image, MONO_TOKEN_TYPE_SPEC | nindex, context); + klass = mono_class_get_and_inflate_typespec_checked (image, MONO_TOKEN_TYPE_SPEC | nindex, context, &error); + if (!mono_error_ok (&error)) { + /*FIXME don't swallow the error message*/ + mono_error_cleanup (&error); + } break; default: /*FIXME this must set a loader error!*/ @@ -513,6 +527,7 @@ MonoClassField* mono_field_from_token (MonoImage *image, guint32 token, MonoClass **retklass, MonoGenericContext *context) { + MonoError error; MonoClass *k; guint32 type; MonoClassField *field; @@ -543,9 +558,12 @@ mono_field_from_token (MonoImage *image, guint32 token, MonoClass **retklass, type = mono_metadata_typedef_from_field (image, mono_metadata_token_index (token)); if (!type) return NULL; - k = mono_class_get (image, MONO_TOKEN_TYPE_DEF | type); - if (!k) + k = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | type, &error); + if (!k) { + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /*FIXME don't swallow the error message*/ return NULL; + } mono_class_init (k); if (retklass) *retklass = k; @@ -941,6 +959,7 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp const char *mname; MonoMethodSignature *sig; const char *ptr; + MonoError error; mono_metadata_decode_row (&tables [MONO_TABLE_MEMBERREF], idx-1, cols, 3); nindex = cols [MONO_MEMBERREF_CLASS] >> MONO_MEMBERREF_PARENT_BITS; @@ -960,12 +979,10 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp switch (class) { case MONO_MEMBERREF_PARENT_TYPEREF: - klass = mono_class_from_typeref (image, MONO_TOKEN_TYPE_REF | nindex); + klass = mono_class_from_typeref_checked (image, MONO_TOKEN_TYPE_REF | nindex, &error); if (!klass) { - char *name = mono_class_name_from_token (image, MONO_TOKEN_TYPE_REF | nindex); - g_warning ("Missing method %s in assembly %s, type %s", mname, image->name, name); - mono_loader_set_error_type_load (name, image->assembly_name); - g_free (name); + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /* FIXME Don't swallow the error */ return NULL; } break; @@ -973,22 +990,18 @@ method_from_memberref (MonoImage *image, guint32 idx, MonoGenericContext *typesp /* * Parse the TYPESPEC in the parent's context. */ - klass = mono_class_get_full (image, MONO_TOKEN_TYPE_SPEC | nindex, typespec_context); + klass = mono_class_get_and_inflate_typespec_checked (image, MONO_TOKEN_TYPE_SPEC | nindex, typespec_context, &error); if (!klass) { - char *name = mono_class_name_from_token (image, MONO_TOKEN_TYPE_SPEC | nindex); - g_warning ("Missing method %s in assembly %s, type %s", mname, image->name, name); - mono_loader_set_error_type_load (name, image->assembly_name); - g_free (name); + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /*FIXME don't swallow the error message*/ return NULL; } break; case MONO_MEMBERREF_PARENT_TYPEDEF: - klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | nindex); + klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | nindex, &error); if (!klass) { - char *name = mono_class_name_from_token (image, MONO_TOKEN_TYPE_DEF | nindex); - g_warning ("Missing method %s in assembly %s, type %s", mname, image->name, name); - mono_loader_set_error_type_load (name, image->assembly_name); - g_free (name); + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /*FIXME don't swallow the error message*/ return NULL; } break; @@ -1230,27 +1243,29 @@ mono_dllmap_insert (MonoImage *assembly, const char *dll, const char *func, cons mono_loader_init (); - mono_loader_lock (); - if (!assembly) { entry = g_malloc0 (sizeof (MonoDllMap)); entry->dll = dll? g_strdup (dll): NULL; entry->target = tdll? g_strdup (tdll): NULL; entry->func = func? g_strdup (func): NULL; entry->target_func = tfunc? g_strdup (tfunc): NULL; + + mono_loader_lock (); entry->next = global_dll_map; global_dll_map = entry; + mono_loader_unlock (); } else { entry = mono_image_alloc0 (assembly, sizeof (MonoDllMap)); entry->dll = dll? mono_image_strdup (assembly, dll): NULL; entry->target = tdll? mono_image_strdup (assembly, tdll): NULL; entry->func = func? mono_image_strdup (assembly, func): NULL; entry->target_func = tfunc? mono_image_strdup (assembly, tfunc): NULL; + + mono_image_lock (assembly); entry->next = assembly->dll_map; assembly->dll_map = entry; + mono_image_unlock (assembly); } - - mono_loader_unlock (); } static void @@ -1369,14 +1384,14 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char mono_dllmap_lookup (image, orig_scope, import, &new_scope, &import); if (!module) { - mono_loader_lock (); + mono_image_lock (image); if (!image->pinvoke_scopes) { image->pinvoke_scopes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); image->pinvoke_scope_filenames = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); } module = g_hash_table_lookup (image->pinvoke_scopes, new_scope); found_name = g_hash_table_lookup (image->pinvoke_scope_filenames, new_scope); - mono_loader_unlock (); + mono_image_unlock (image); if (module) cached = TRUE; if (found_name) @@ -1542,12 +1557,12 @@ mono_lookup_pinvoke_call (MonoMethod *method, const char **exc_class, const char if (!cached) { mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, "DllImport loaded library '%s'.", found_name); - mono_loader_lock (); + mono_image_lock (image); if (!g_hash_table_lookup (image->pinvoke_scopes, new_scope)) { g_hash_table_insert (image->pinvoke_scopes, g_strdup (new_scope), module); g_hash_table_insert (image->pinvoke_scope_filenames, g_strdup (new_scope), g_strdup (found_name)); } - mono_loader_unlock (); + mono_image_unlock (image); } mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_DLLIMPORT, @@ -1676,6 +1691,7 @@ static MonoMethod * mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass, MonoGenericContext *context, gboolean *used_context) { + MonoError error; MonoMethod *result; int table = mono_metadata_token_table (token); int idx = mono_metadata_token_index (token); @@ -1717,6 +1733,18 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass, return NULL; } + if (!klass) { + guint32 type = mono_metadata_typedef_from_method (image, token); + if (!type) + return NULL; + klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF | type, &error); + if (klass == NULL) { + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /*FIXME don't swallow the error message*/ + return NULL; + } + } + mono_metadata_decode_row (&image->tables [MONO_TABLE_METHOD], idx - 1, cols, 6); if ((cols [2] & METHOD_ATTRIBUTE_PINVOKE_IMPL) || @@ -1729,15 +1757,6 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass, mono_stats.method_count ++; - if (!klass) { /*FIXME put this before the image alloc*/ - guint32 type = mono_metadata_typedef_from_method (image, token); - if (!type) - return NULL; - klass = mono_class_get (image, MONO_TOKEN_TYPE_DEF | type); - if (klass == NULL) - return NULL; - } - result->slot = -1; result->klass = klass; result->flags = cols [2]; @@ -1758,11 +1777,15 @@ mono_get_method_from_token (MonoImage *image, guint32 token, MonoClass *klass, if (*sig & 0x10) generic_container = mono_metadata_load_generic_params (image, token, container); if (generic_container) { + MonoError error; result->is_generic = TRUE; generic_container->owner.method = result; /*FIXME put this before the image alloc*/ - if (!mono_metadata_load_generic_param_constraints_full (image, token, generic_container)) + if (!mono_metadata_load_generic_param_constraints_checked (image, token, generic_container, &error)) { + mono_loader_set_error_from_mono_error (&error); + mono_error_cleanup (&error); /*FIXME don't swallow the error message*/ return NULL; + } container = generic_container; } @@ -1917,17 +1940,11 @@ MonoMethod * mono_get_method_constrained_with_method (MonoImage *image, MonoMethod *method, MonoClass *constrained_class, MonoGenericContext *context) { - MonoMethod *result; - g_assert (method); - mono_loader_lock (); - - result = get_method_constrained (image, method, constrained_class, context); - - mono_loader_unlock (); - return result; + return get_method_constrained (image, method, constrained_class, context); } + /** * mono_get_method_constrained: * @@ -1943,17 +1960,12 @@ mono_get_method_constrained (MonoImage *image, guint32 token, MonoClass *constra { MonoMethod *result; - mono_loader_lock (); - *cil_method = mono_get_method_from_token (image, token, NULL, context, NULL); - if (!*cil_method) { - mono_loader_unlock (); + if (!*cil_method) return NULL; - } result = get_method_constrained (image, *cil_method, constrained_class, context); - mono_loader_unlock (); return result; } @@ -2266,16 +2278,49 @@ mono_stack_walk_no_il (MonoStackWalk func, gpointer user_data) mono_get_eh_callbacks ()->mono_walk_stack_with_ctx (stack_walk_adapter, NULL, MONO_UNWIND_DEFAULT, &ud); } +typedef struct { + MonoStackWalkAsyncSafe func; + gpointer user_data; +} AsyncStackWalkUserData; + + +static gboolean +async_stack_walk_adapter (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer data) +{ + AsyncStackWalkUserData *d = data; + + switch (frame->type) { + case FRAME_TYPE_DEBUGGER_INVOKE: + case FRAME_TYPE_MANAGED_TO_NATIVE: + return FALSE; + case FRAME_TYPE_MANAGED: + if (!frame->ji) + return FALSE; + if (frame->ji->async) + return d->func (NULL, frame->domain, frame->ji->code_start, frame->native_offset, d->user_data); + else + return d->func (mono_jit_info_get_method (frame->ji), frame->domain, frame->ji->code_start, frame->native_offset, d->user_data); + break; + default: + g_assert_not_reached (); + return FALSE; + } +} + + /* * mono_stack_walk_async_safe: * * Async safe version callable from signal handlers. */ void -mono_stack_walk_async_safe (MonoStackWalk func, gpointer user_data) +mono_stack_walk_async_safe (MonoStackWalkAsyncSafe func, void *initial_sig_context, void *user_data) { - StackWalkUserData ud = { func, user_data }; - mono_get_eh_callbacks ()->mono_walk_stack_with_ctx (stack_walk_adapter, NULL, MONO_UNWIND_NONE, &ud); + MonoContext ctx; + AsyncStackWalkUserData ud = { func, user_data }; + + mono_sigctx_to_monoctx (initial_sig_context, &ctx); + mono_get_eh_callbacks ()->mono_walk_stack_with_ctx (async_stack_walk_adapter, NULL, MONO_UNWIND_SIGNAL_SAFE, &ud); } static gboolean @@ -2382,7 +2427,7 @@ mono_method_signature_checked (MonoMethod *m, MonoError *error) const char *sig; gboolean can_cache_signature; MonoGenericContainer *container; - MonoMethodSignature *signature = NULL; + MonoMethodSignature *signature = NULL, *sig2; guint32 sig_offset; /* We need memory barriers below because of the double-checked locking pattern */ @@ -2392,34 +2437,31 @@ mono_method_signature_checked (MonoMethod *m, MonoError *error) if (m->signature) return m->signature; - mono_loader_lock (); - - if (m->signature) { - mono_loader_unlock (); - return m->signature; - } + img = m->klass->image; if (m->is_inflated) { MonoMethodInflated *imethod = (MonoMethodInflated *) m; /* the lock is recursive */ signature = mono_method_signature (imethod->declaring); signature = inflate_generic_signature_checked (imethod->declaring->klass->image, signature, mono_method_get_context (m), error); - if (!mono_error_ok (error)) { - mono_loader_unlock (); + if (!mono_error_ok (error)) return NULL; - } inflated_signatures_size += mono_metadata_signature_size (signature); + mono_image_lock (img); + mono_memory_barrier (); - m->signature = signature; - mono_loader_unlock (); + if (!m->signature) + m->signature = signature; + + mono_image_unlock (img); + return m->signature; } g_assert (mono_metadata_token_table (m->token) == MONO_TABLE_METHOD); idx = mono_metadata_token_index (m->token); - img = m->klass->image; sig = mono_metadata_blob_heap (img, sig_offset = mono_metadata_decode_row_col (&img->tables [MONO_TABLE_METHOD], idx - 1, MONO_METHOD_SIGNATURE)); @@ -2436,28 +2478,33 @@ mono_method_signature_checked (MonoMethod *m, MonoError *error) if (mono_metadata_method_has_param_attrs (img, idx)) can_cache_signature = FALSE; - if (can_cache_signature) + if (can_cache_signature) { + mono_image_lock (img); signature = g_hash_table_lookup (img->method_signatures, sig); + mono_image_unlock (img); + } if (!signature) { const char *sig_body; /*TODO we should cache the failure result somewhere*/ - if (!mono_verifier_verify_method_signature (img, sig_offset, error)) { - mono_loader_unlock (); + if (!mono_verifier_verify_method_signature (img, sig_offset, error)) return NULL; - } size = mono_metadata_decode_blob_size (sig, &sig_body); signature = mono_metadata_parse_method_signature_full (img, container, idx, sig_body, NULL); if (!signature) { mono_error_set_from_loader_error (error); - mono_loader_unlock (); return NULL; } - if (can_cache_signature) - g_hash_table_insert (img->method_signatures, (gpointer)sig, signature); + if (can_cache_signature) { + mono_image_lock (img); + sig2 = g_hash_table_lookup (img->method_signatures, sig); + if (!sig2) + g_hash_table_insert (img->method_signatures, (gpointer)sig, signature); + mono_image_unlock (img); + } signatures_size += mono_metadata_signature_size (signature); } @@ -2465,17 +2512,14 @@ mono_method_signature_checked (MonoMethod *m, MonoError *error) /* Verify metadata consistency */ if (signature->generic_param_count) { if (!container || !container->is_method) { - mono_loader_unlock (); mono_error_set_method_load (error, m->klass, m->name, "Signature claims method has generic parameters, but generic_params table says it doesn't for method 0x%08x from image %s", idx, img->name); return NULL; } if (container->type_argc != signature->generic_param_count) { - mono_loader_unlock (); mono_error_set_method_load (error, m->klass, m->name, "Inconsistent generic parameter count. Signature says %d, generic_params table says %d for method 0x%08x from image %s", signature->generic_param_count, container->type_argc, idx, img->name); return NULL; } } else if (container && container->is_method && container->type_argc) { - mono_loader_unlock (); mono_error_set_method_load (error, m->klass, m->name, "generic_params table claims method has generic parameters, but signature says it doesn't for method 0x%08x from image %s", idx, img->name); return NULL; } @@ -2506,17 +2550,20 @@ mono_method_signature_checked (MonoMethod *m, MonoError *error) case PINVOKE_ATTRIBUTE_CALL_CONV_GENERIC: case PINVOKE_ATTRIBUTE_CALL_CONV_GENERICINST: default: - mono_loader_unlock (); mono_error_set_method_load (error, m->klass, m->name, "unsupported calling convention : 0x%04x for method 0x%08x from image %s", piinfo->piflags, idx, img->name); return NULL; } signature->call_convention = conv; } - mono_memory_barrier (); - m->signature = signature; + mono_image_lock (img); + + mono_memory_barrier (); + if (!m->signature) + m->signature = signature; + + mono_image_unlock (img); - mono_loader_unlock (); return m->signature; } @@ -2573,26 +2620,32 @@ mono_method_get_header (MonoMethod *method) 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)) return NULL; + img = method->klass->image; + if (method->is_inflated) { MonoMethodInflated *imethod = (MonoMethodInflated *) method; - MonoMethodHeader *header; + MonoMethodHeader *header, *iheader; - mono_loader_lock (); + header = mono_method_get_header (imethod->declaring); + if (!header) + return NULL; + + iheader = inflate_generic_header (header, mono_method_get_context (method)); + mono_metadata_free_mh (header); + + mono_image_lock (img); if (imethod->header) { - mono_loader_unlock (); + mono_metadata_free_mh (iheader); + mono_image_unlock (img); return imethod->header; } - header = mono_method_get_header (imethod->declaring); - if (!header) { - mono_loader_unlock (); - return NULL; - } + mono_memory_barrier (); + imethod->header = iheader; + + mono_image_unlock (img); - imethod->header = inflate_generic_header (header, mono_method_get_context (method)); - mono_loader_unlock (); - mono_metadata_free_mh (header); return imethod->header; } @@ -2608,7 +2661,6 @@ mono_method_get_header (MonoMethod *method) */ g_assert (mono_metadata_token_table (method->token) == MONO_TABLE_METHOD); idx = mono_metadata_token_index (method->token); - img = method->klass->image; rva = mono_metadata_decode_row_col (&img->tables [MONO_TABLE_METHOD], idx - 1, MONO_METHOD_RVA); if (!mono_verifier_verify_method_header (img, rva, NULL)) @@ -2642,7 +2694,8 @@ mono_method_get_flags (MonoMethod *method, guint32 *iflags) * Find the method index in the metadata methodDef table. */ guint32 -mono_method_get_index (MonoMethod *method) { +mono_method_get_index (MonoMethod *method) +{ MonoClass *klass = method->klass; int i; @@ -2666,4 +2719,3 @@ mono_method_get_index (MonoMethod *method) { } return 0; } - diff --git a/mono/metadata/loader.h b/mono/metadata/loader.h index ae0ca44177..74d82817bb 100644 --- a/mono/metadata/loader.h +++ b/mono/metadata/loader.h @@ -90,8 +90,9 @@ mono_stack_walk (MonoStackWalk func, void* user_data); MONO_API void mono_stack_walk_no_il (MonoStackWalk func, void* user_data); +typedef mono_bool (*MonoStackWalkAsyncSafe) (MonoMethod *method, MonoDomain *domain, void *base_address, int offset, void* data); MONO_API void -mono_stack_walk_async_safe (MonoStackWalk func, void* user_data); +mono_stack_walk_async_safe (MonoStackWalkAsyncSafe func, void *initial_sig_context, void* user_data); MONO_END_DECLS diff --git a/mono/metadata/marshal.c.REMOVED.git-id b/mono/metadata/marshal.c.REMOVED.git-id index 65b82513e9..31fec80fcb 100644 --- a/mono/metadata/marshal.c.REMOVED.git-id +++ b/mono/metadata/marshal.c.REMOVED.git-id @@ -1 +1 @@ -88bbaeb7a029b8f56d130d32b6b724a303ef6bf6 \ No newline at end of file +0c8fe33f219deadaed0965bed82c58d1a3c880ba \ No newline at end of file diff --git a/mono/metadata/metadata-internals.h b/mono/metadata/metadata-internals.h index 8ee78a211d..c738d53654 100644 --- a/mono/metadata/metadata-internals.h +++ b/mono/metadata/metadata-internals.h @@ -228,7 +228,7 @@ struct _MonoImage { MonoConcurrentHashTable *field_cache; /*protected by the image lock*/ /* indexed by typespec tokens. */ - GHashTable *typespec_cache; + GHashTable *typespec_cache; /* protected by the image lock */ /* indexed by token */ GHashTable *memberref_signatures; GHashTable *helper_signatures; @@ -317,6 +317,7 @@ struct _MonoImage { MonoDllMap *dll_map; /* interfaces IDs from this image */ + /* protected by the classes lock */ MonoBitSet *interface_bitset; /* when the image is being closed, this is abused as a list of @@ -534,6 +535,7 @@ typedef struct { */ GSList *apps; GSList *assemblies; + char *aot_options; } MonoAotCacheConfig; #define MONO_SIZEOF_METHOD_SIGNATURE (sizeof (struct _MonoMethodSignature) - MONO_ZERO_LEN_ARRAY * SIZEOF_VOID_P) @@ -799,6 +801,8 @@ MonoMethod *mono_get_method_constrained_with_method (MonoImage *image, MonoMetho void mono_type_set_alignment (MonoTypeEnum type, int align) MONO_INTERNAL; MonoAotCacheConfig *mono_get_aot_cache_config (void) MONO_INTERNAL; +MonoType * +mono_type_create_from_typespec_checked (MonoImage *image, guint32 type_spec, MonoError *error) MONO_INTERNAL; #endif /* __MONO_METADATA_INTERNALS_H__ */ diff --git a/mono/metadata/metadata.c.REMOVED.git-id b/mono/metadata/metadata.c.REMOVED.git-id index 4fe0ef620c..34236abc95 100644 --- a/mono/metadata/metadata.c.REMOVED.git-id +++ b/mono/metadata/metadata.c.REMOVED.git-id @@ -1 +1 @@ -091ab5046e3c2b45db4e17c1e1559f5e8f41c57b \ No newline at end of file +6b598020f031767fa058d2d195344f146200aaab \ No newline at end of file diff --git a/mono/metadata/mono-config.c b/mono/metadata/mono-config.c index 1e85012dd0..c9e9e030b8 100644 --- a/mono/metadata/mono-config.c +++ b/mono/metadata/mono-config.c @@ -375,7 +375,6 @@ aot_cache_start (gpointer user_data, for (i = 0; attribute_names [i]; ++i) { if (!strcmp (attribute_names [i], "app")) { config->apps = g_slist_prepend (config->apps, g_strdup (attribute_values [i])); - return; } } @@ -391,6 +390,8 @@ aot_cache_start (gpointer user_data, config->assemblies = g_slist_prepend (config->assemblies, g_strdup (part)); } g_strfreev (parts); + } else if (!strcmp (attribute_names [i], "options")) { + config->aot_options = g_strdup (attribute_values [i]); } } } diff --git a/mono/metadata/mono-wsq.c b/mono/metadata/mono-wsq.c index 7a9d2258d1..859fb69c55 100644 --- a/mono/metadata/mono-wsq.c +++ b/mono/metadata/mono-wsq.c @@ -24,6 +24,7 @@ struct _MonoWSQ { volatile gint tail; MonoArray *queue; gint32 mask; + gint32 suspended; MonoSemType lock; }; @@ -61,6 +62,7 @@ mono_wsq_create () wsq = g_new0 (MonoWSQ, 1); wsq->mask = INITIAL_LENGTH - 1; + wsq->suspended = 0; MONO_GC_REGISTER_ROOT_SINGLE (wsq->queue); root = mono_get_root_domain (); wsq->queue = mono_array_new_cached (root, mono_defaults.object_class, INITIAL_LENGTH); @@ -72,6 +74,12 @@ mono_wsq_create () return wsq; } +gboolean +mono_wsq_suspend (MonoWSQ *wsq) +{ + return InterlockedCompareExchange (&wsq->suspended, 1, 0) == 0; +} + void mono_wsq_destroy (MonoWSQ *wsq) { @@ -112,6 +120,11 @@ mono_wsq_local_push (void *obj) return FALSE; } + if (wsq->suspended) { + WSQ_DEBUG ("local_push: wsq suspended\n"); + return FALSE; + } + tail = wsq->tail; if (tail < wsq->head + wsq->mask) { mono_array_setref (wsq->queue, tail & wsq->mask, (MonoObject *) obj); diff --git a/mono/metadata/mono-wsq.h b/mono/metadata/mono-wsq.h index 7208dadb6b..ccb064d4f1 100644 --- a/mono/metadata/mono-wsq.h +++ b/mono/metadata/mono-wsq.h @@ -20,6 +20,7 @@ gboolean mono_wsq_local_push (void *obj) MONO_INTERNAL; gboolean mono_wsq_local_pop (void **ptr) MONO_INTERNAL; void mono_wsq_try_steal (MonoWSQ *wsq, void **ptr, guint32 ms_timeout) MONO_INTERNAL; gint mono_wsq_count (MonoWSQ *wsq) MONO_INTERNAL; +gboolean mono_wsq_suspend (MonoWSQ *wsq) MONO_INTERNAL; G_END_DECLS diff --git a/mono/metadata/object.c.REMOVED.git-id b/mono/metadata/object.c.REMOVED.git-id index 8bc6153aea..4980ab7386 100644 --- a/mono/metadata/object.c.REMOVED.git-id +++ b/mono/metadata/object.c.REMOVED.git-id @@ -1 +1 @@ -daa72aec6f298e8bebbbc05346e545ca83e0c665 \ No newline at end of file +a2aa759293b742fa9fb342ecee505d4949476464 \ No newline at end of file diff --git a/mono/metadata/process.c b/mono/metadata/process.c index c9e0f8bf63..d7cc110aec 100644 --- a/mono/metadata/process.c +++ b/mono/metadata/process.c @@ -23,18 +23,7 @@ #include #include #include -#ifndef HAVE_GETPROCESSID -#if defined(_MSC_VER) || defined(HAVE_WINTERNL_H) -#include -#ifndef NT_SUCCESS -#define NT_SUCCESS(status) ((NTSTATUS) (status) >= 0) -#endif /* !NT_SUCCESS */ -#else /* ! (defined(_MSC_VER) || defined(HAVE_WINTERNL_H)) */ -#include -#include -#endif /* (defined(_MSC_VER) || defined(HAVE_WINTERNL_H)) */ -#endif /* !HAVE_GETPROCESSID */ -/* FIXME: fix this code to not depend so much on the inetrnals */ +/* FIXME: fix this code to not depend so much on the internals */ #include #define LOGDEBUG(...) @@ -60,11 +49,12 @@ HANDLE ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid) return(handle); } -guint32 ves_icall_System_Diagnostics_Process_GetPid_internal (void) +guint32 +ves_icall_System_Diagnostics_Process_GetPid_internal (void) { MONO_ARCH_SAVE_REGS; - return(GetCurrentProcessId ()); + return mono_process_current_pid (); } void ves_icall_System_Diagnostics_Process_Process_free_internal (MonoObject *this, @@ -525,76 +515,6 @@ complete_path (const gunichar2 *appname, gchar **completed) return TRUE; } -#ifndef HAVE_GETPROCESSID -/* Run-time GetProcessId detection for Windows */ -#ifdef TARGET_WIN32 -#define HAVE_GETPROCESSID - -typedef DWORD (WINAPI *GETPROCESSID_PROC) (HANDLE); -typedef DWORD (WINAPI *NTQUERYINFORMATIONPROCESS_PROC) (HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG); -typedef DWORD (WINAPI *RTLNTSTATUSTODOSERROR_PROC) (NTSTATUS); - -static DWORD WINAPI GetProcessId_detect (HANDLE process); - -static GETPROCESSID_PROC GetProcessId = &GetProcessId_detect; -static NTQUERYINFORMATIONPROCESS_PROC NtQueryInformationProcess_proc = NULL; -static RTLNTSTATUSTODOSERROR_PROC RtlNtStatusToDosError_proc = NULL; - -static DWORD WINAPI GetProcessId_ntdll (HANDLE process) -{ - PROCESS_BASIC_INFORMATION pi; - NTSTATUS status; - - status = NtQueryInformationProcess_proc (process, ProcessBasicInformation, &pi, sizeof (pi), NULL); - if (NT_SUCCESS (status)) { - return pi.UniqueProcessId; - } else { - SetLastError (RtlNtStatusToDosError_proc (status)); - return 0; - } -} - -static DWORD WINAPI GetProcessId_stub (HANDLE process) -{ - SetLastError (ERROR_CALL_NOT_IMPLEMENTED); - return 0; -} - -static DWORD WINAPI GetProcessId_detect (HANDLE process) -{ - HMODULE module_handle; - GETPROCESSID_PROC GetProcessId_kernel; - - /* Windows XP SP1 and above have GetProcessId API */ - module_handle = GetModuleHandle (L"kernel32.dll"); - if (module_handle != NULL) { - GetProcessId_kernel = (GETPROCESSID_PROC) GetProcAddress (module_handle, "GetProcessId"); - if (GetProcessId_kernel != NULL) { - GetProcessId = GetProcessId_kernel; - return GetProcessId (process); - } - } - - /* Windows 2000 and above have deprecated NtQueryInformationProcess API */ - module_handle = GetModuleHandle (L"ntdll.dll"); - if (module_handle != NULL) { - NtQueryInformationProcess_proc = (NTQUERYINFORMATIONPROCESS_PROC) GetProcAddress (module_handle, "NtQueryInformationProcess"); - if (NtQueryInformationProcess_proc != NULL) { - RtlNtStatusToDosError_proc = (RTLNTSTATUSTODOSERROR_PROC) GetProcAddress (module_handle, "RtlNtStatusToDosError"); - if (RtlNtStatusToDosError_proc != NULL) { - GetProcessId = &GetProcessId_ntdll; - return GetProcessId (process); - } - } - } - - /* Fall back to ERROR_CALL_NOT_IMPLEMENTED */ - GetProcessId = &GetProcessId_stub; - return GetProcessId (process); -} -#endif /* HOST_WIN32 */ -#endif /* !HAVE_GETPROCESSID */ - MonoBoolean ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoProcessStartInfo *proc_start_info, MonoProcInfo *process_info) { SHELLEXECUTEINFO shellex = {0}; @@ -891,14 +811,33 @@ MonoString *ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE pr /* Returns an array of pids */ MonoArray *ves_icall_System_Diagnostics_Process_GetProcesses_internal (void) { +#if !defined(HOST_WIN32) + MonoArray *procs; + gpointer *pidarray; + int i, count; + + MONO_ARCH_SAVE_REGS; + + pidarray = mono_process_list (&count); + if (!pidarray) + mono_raise_exception (mono_get_exception_not_supported ("This system does not support EnumProcesses")); + procs = mono_array_new (mono_domain_get (), mono_get_int32_class (), count); + if (sizeof (guint32) == sizeof (gpointer)) { + memcpy (mono_array_addr (procs, guint32, 0), pidarray, count); + } else { + for (i = 0; i < count; ++i) + *(mono_array_addr (procs, guint32, i)) = GPOINTER_TO_UINT (pidarray [i]); + } + g_free (pidarray); + + return procs; +#else MonoArray *procs; gboolean ret; DWORD needed; - guint32 count; + int count; guint32 *pids; - MONO_ARCH_SAVE_REGS; - count = 512; do { pids = g_new0 (guint32, count); @@ -926,6 +865,7 @@ MonoArray *ves_icall_System_Diagnostics_Process_GetProcesses_internal (void) pids = NULL; return procs; +#endif } MonoBoolean ves_icall_System_Diagnostics_Process_GetWorkingSet_internal (HANDLE process, guint32 *min, guint32 *max) diff --git a/mono/metadata/profiler-private.h b/mono/metadata/profiler-private.h index 18ec96b7ae..ed8a32f44f 100644 --- a/mono/metadata/profiler-private.h +++ b/mono/metadata/profiler-private.h @@ -77,5 +77,8 @@ void mono_profiler_code_buffer_new (gpointer buffer, int size, MonoProfilerCodeB void mono_profiler_runtime_initialized (void) MONO_INTERNAL; +int64_t mono_profiler_get_sampling_rate (void) MONO_INTERNAL; +MonoProfileSamplingMode mono_profiler_get_sampling_mode (void) MONO_INTERNAL; + #endif /* __MONO_PROFILER_PRIVATE_H__ */ diff --git a/mono/metadata/profiler.c b/mono/metadata/profiler.c index 53f8ff0c90..dccf093071 100644 --- a/mono/metadata/profiler.c +++ b/mono/metadata/profiler.c @@ -273,6 +273,28 @@ mono_profiler_install_monitor (MonoProfileMonitorFunc callback) prof_list->monitor_event_cb = callback; } +static MonoProfileSamplingMode sampling_mode = MONO_PROFILER_STAT_MODE_PROCESS; +static int64_t sampling_frequency = 1000; //1ms + +/** + * mono_profiler_set_statistical_mode: + * @mode the sampling mode used. + * @sample_frequency_is_us the sampling frequency in microseconds. + * + * Set the sampling parameters for the profiler. Sampling mode affects the effective sampling rate as in samples/s you'll witness. + * The default sampling mode is process mode, which only reports samples when there's activity in the process. + * + * Sampling frequency should be interpreted as a suggestion that can't always be honored due to how most kernels expose alarms. + * + * Said that, when using statistical sampling, always assume variable rate sampling as all sort of external factors can interfere. + */ +void +mono_profiler_set_statistical_mode (MonoProfileSamplingMode mode, int64_t sampling_frequency_is_us) +{ + sampling_mode = mode; + sampling_frequency = sampling_frequency_is_us; +} + void mono_profiler_install_statistical (MonoProfileStatFunc callback) { @@ -281,6 +303,18 @@ mono_profiler_install_statistical (MonoProfileStatFunc callback) prof_list->statistical_cb = callback; } +int64_t +mono_profiler_get_sampling_rate (void) +{ + return sampling_frequency; +} + +MonoProfileSamplingMode +mono_profiler_get_sampling_mode (void) +{ + return sampling_mode; +} + void mono_profiler_install_statistical_call_chain (MonoProfileStatCallChainFunc callback, int call_chain_depth, MonoProfilerCallChainStrategy call_chain_strategy) { if (!prof_list) diff --git a/mono/metadata/profiler.h b/mono/metadata/profiler.h index c7b8f6d8a8..408cac8ba3 100644 --- a/mono/metadata/profiler.h +++ b/mono/metadata/profiler.h @@ -193,6 +193,15 @@ MONO_API void mono_profiler_install_iomap (MonoProfileIomapFunc callback); MONO_API void mono_profiler_load (const char *desc); +typedef enum { + /* Elapsed time is tracked by user+kernel time of the process - this is the default*/ + MONO_PROFILER_STAT_MODE_PROCESS = 0, + /* Elapsed time is tracked by wallclock time */ + MONO_PROFILER_STAT_MODE_REAL = 1, +} MonoProfileSamplingMode; + +MONO_API void mono_profiler_set_statistical_mode (MonoProfileSamplingMode mode, int64_t sampling_frequency_is_us); + MONO_END_DECLS #endif /* __MONO_PROFILER_H__ */ diff --git a/mono/metadata/reflection.c.REMOVED.git-id b/mono/metadata/reflection.c.REMOVED.git-id index 116f3fd5ff..9cdd010b3c 100644 --- a/mono/metadata/reflection.c.REMOVED.git-id +++ b/mono/metadata/reflection.c.REMOVED.git-id @@ -1 +1 @@ -c74c30e0e62ae6289c8922f58177dc8367b2a9bf \ No newline at end of file +6614b01e1e9863aec5a44153b0f9b5c85365b290 \ No newline at end of file diff --git a/mono/metadata/row-indexes.h b/mono/metadata/row-indexes.h index 4b4ca6dbc9..74fbf6b35c 100644 --- a/mono/metadata/row-indexes.h +++ b/mono/metadata/row-indexes.h @@ -419,6 +419,16 @@ enum { MONO_CUSTOM_ATTR_TYPE_MASK = 7 }; +enum { + MONO_RESOLUTION_SCOPE_MODULE, + MONO_RESOLUTION_SCOPE_MODULEREF, + MONO_RESOLUTION_SCOPE_ASSEMBLYREF, + MONO_RESOLUTION_SCOPE_TYPEREF, + MONO_RESOLUTION_SCOPE_BITS = 2, + MONO_RESOLUTION_SCOPE_MASK = 3 +}; + +/* Kept for compatibility since this is a public header file */ enum { MONO_RESOLTION_SCOPE_MODULE, MONO_RESOLTION_SCOPE_MODULEREF, diff --git a/mono/metadata/security.c b/mono/metadata/security.c index c61eab99f7..65a562da72 100644 --- a/mono/metadata/security.c +++ b/mono/metadata/security.c @@ -701,9 +701,10 @@ IsUserProtected (gunichar2 *path) gboolean success = FALSE; PACL pDACL = NULL; PSID pEveryoneSid = NULL; + PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL; DWORD dwRes = GetNamedSecurityInfoW (path, SE_FILE_OBJECT, - DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL, NULL, NULL); + DACL_SECURITY_INFORMATION, NULL, NULL, &pDACL, NULL, &pSecurityDescriptor); if (dwRes != ERROR_SUCCESS) return FALSE; @@ -720,8 +721,8 @@ IsUserProtected (gunichar2 *path) /* Note: we don't need to check our own access - we'll know soon enough when reading the file */ - if (pDACL) - LocalFree (pDACL); + if (pSecurityDescriptor) + LocalFree (pSecurityDescriptor); return success; } diff --git a/mono/metadata/sgen-alloc.c b/mono/metadata/sgen-alloc.c index d9a52e9b19..80fc8252db 100644 --- a/mono/metadata/sgen-alloc.c +++ b/mono/metadata/sgen-alloc.c @@ -189,9 +189,12 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size) void **p; char *new_next; TLAB_ACCESS_INIT; + size_t real_size = size; + + CANARIFY_SIZE(size); HEAVY_STAT (++stat_objects_alloced); - if (size <= SGEN_MAX_SMALL_OBJ_SIZE) + if (real_size <= SGEN_MAX_SMALL_OBJ_SIZE) HEAVY_STAT (stat_bytes_alloced += size); else HEAVY_STAT (stat_bytes_alloced_los += size); @@ -207,7 +210,7 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size) if (collect_before_allocs) { if (((current_alloc % collect_before_allocs) == 0) && nursery_section) { sgen_perform_collection (0, GENERATION_NURSERY, "collect-before-alloc-triggered", TRUE); - if (!degraded_mode && sgen_can_alloc_size (size) && size <= SGEN_MAX_SMALL_OBJ_SIZE) { + if (!degraded_mode && sgen_can_alloc_size (size) && real_size <= SGEN_MAX_SMALL_OBJ_SIZE) { // FIXME: g_assert_not_reached (); } @@ -229,8 +232,8 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size) * specially by the world-stopping code. */ - if (size > SGEN_MAX_SMALL_OBJ_SIZE) { - p = sgen_los_alloc_large_inner (vtable, size); + if (real_size > SGEN_MAX_SMALL_OBJ_SIZE) { + p = sgen_los_alloc_large_inner (vtable, ALIGN_UP (real_size)); } else { /* tlab_next and tlab_temp_end are TLS vars so accessing them might be expensive */ @@ -247,6 +250,7 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size) * visible before the vtable store. */ + CANARIFY_ALLOC(p,real_size); SGEN_LOG (6, "Allocated object %p, vtable: %p (%s), size: %zd", p, vtable, vtable->klass->name, size); binary_protocol_alloc (p , vtable, size); if (G_UNLIKELY (MONO_GC_NURSERY_OBJ_ALLOC_ENABLED ())) @@ -290,7 +294,7 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size) do { p = sgen_nursery_alloc (size); if (!p) { - sgen_ensure_free_space (size); + sgen_ensure_free_space (real_size); if (degraded_mode) return alloc_degraded (vtable, size, FALSE); else @@ -347,13 +351,14 @@ mono_gc_alloc_obj_nolock (MonoVTable *vtable, size_t size) TLAB_TEMP_END = MIN (TLAB_REAL_END, TLAB_NEXT + SGEN_SCAN_START_SIZE); SGEN_LOG (5, "Expanding local alloc: %p-%p", TLAB_NEXT, TLAB_TEMP_END); } + CANARIFY_ALLOC(p,real_size); } if (G_LIKELY (p)) { SGEN_LOG (6, "Allocated object %p, vtable: %p (%s), size: %zd", p, vtable, vtable->klass->name, size); binary_protocol_alloc (p, vtable, size); if (G_UNLIKELY (MONO_GC_MAJOR_OBJ_ALLOC_LARGE_ENABLED ()|| MONO_GC_NURSERY_OBJ_ALLOC_ENABLED ())) { - if (size > SGEN_MAX_SMALL_OBJ_SIZE) + if (real_size > SGEN_MAX_SMALL_OBJ_SIZE) MONO_GC_MAJOR_OBJ_ALLOC_LARGE ((mword)p, size, vtable->klass->name_space, vtable->klass->name); else MONO_GC_NURSERY_OBJ_ALLOC ((mword)p, size, vtable->klass->name_space, vtable->klass->name); @@ -370,12 +375,15 @@ mono_gc_try_alloc_obj_nolock (MonoVTable *vtable, size_t size) void **p; char *new_next; TLAB_ACCESS_INIT; + size_t real_size = size; + + CANARIFY_SIZE(size); size = ALIGN_UP (size); - SGEN_ASSERT (9, size >= sizeof (MonoObject), "Object too small"); + SGEN_ASSERT (9, real_size >= sizeof (MonoObject), "Object too small"); g_assert (vtable->gc_descr); - if (size > SGEN_MAX_SMALL_OBJ_SIZE) + if (real_size > SGEN_MAX_SMALL_OBJ_SIZE) return NULL; if (G_UNLIKELY (size > tlab_size)) { @@ -440,6 +448,7 @@ mono_gc_try_alloc_obj_nolock (MonoVTable *vtable, size_t size) HEAVY_STAT (++stat_objects_alloced); HEAVY_STAT (stat_bytes_alloced += size); + CANARIFY_ALLOC(p,real_size); SGEN_LOG (6, "Allocated object %p, vtable: %p (%s), size: %zd", p, vtable, vtable->klass->name, size); binary_protocol_alloc (p, vtable, size); if (G_UNLIKELY (MONO_GC_NURSERY_OBJ_ALLOC_ENABLED ())) diff --git a/mono/metadata/sgen-archdep.h b/mono/metadata/sgen-archdep.h index b86ec318c7..420dc96e47 100644 --- a/mono/metadata/sgen-archdep.h +++ b/mono/metadata/sgen-archdep.h @@ -21,7 +21,14 @@ #ifndef __MONO_SGENARCHDEP_H__ #define __MONO_SGENARCHDEP_H__ -#include +#include + +/* + * Define either USE_MONO_CTX, or + * ARCH_SIGCTX_SP/ARCH_SIGCTX_IP/ARCH_STORE_REGS/ARCH_COPY_SIGCTX_REGS. + * Define ARCH_NUM_REGS to be the number of general registers in MonoContext, or the + * number of registers stored by ARCH_STORE_REGS. + */ #if defined(MONO_CROSS_COMPILE) @@ -35,35 +42,23 @@ #elif defined(TARGET_X86) -#include - #define REDZONE_SIZE 0 #define ARCH_NUM_REGS 8 -#ifdef MONO_ARCH_HAS_MONO_CONTEXT -#define USE_MONO_CTX -#else +#ifndef MONO_ARCH_HAS_MONO_CONTEXT #error 0 #endif -/*FIXME, move this to mono-sigcontext as this is generaly useful.*/ -#define ARCH_SIGCTX_SP(ctx) (UCONTEXT_REG_ESP ((ctx))) -#define ARCH_SIGCTX_IP(ctx) (UCONTEXT_REG_EIP ((ctx))) +#define USE_MONO_CTX #elif defined(TARGET_AMD64) -#include - #define REDZONE_SIZE 128 #define ARCH_NUM_REGS 16 #define USE_MONO_CTX -/*FIXME, move this to mono-sigcontext as this is generaly useful.*/ -#define ARCH_SIGCTX_SP(ctx) (UCONTEXT_REG_RSP (ctx)) -#define ARCH_SIGCTX_IP(ctx) (UCONTEXT_REG_RIP (ctx)) - #elif defined(TARGET_POWERPC) #define REDZONE_SIZE 224 @@ -99,39 +94,9 @@ /* We dont store ip, sp */ #define ARCH_NUM_REGS 14 -#define ARCH_STORE_REGS(ptr) \ - __asm__ __volatile__( \ - "push {lr}\n" \ - "mov lr, %0\n" \ - "stmia lr!, {r0-r12}\n" \ - "pop {lr}\n" \ - : \ - : "r" (ptr) \ - ) - -#define ARCH_SIGCTX_SP(ctx) (UCONTEXT_REG_SP((ctx))) -#define ARCH_SIGCTX_IP(ctx) (UCONTEXT_REG_PC((ctx))) -#define ARCH_COPY_SIGCTX_REGS(a,ctx) do { \ - ((a)[0]) = (gpointer) (UCONTEXT_REG_R0((ctx))); \ - ((a)[1]) = (gpointer) (UCONTEXT_REG_R1((ctx))); \ - ((a)[2]) = (gpointer) (UCONTEXT_REG_R2((ctx))); \ - ((a)[3]) = (gpointer) (UCONTEXT_REG_R3((ctx))); \ - ((a)[4]) = (gpointer) (UCONTEXT_REG_R4((ctx))); \ - ((a)[5]) = (gpointer) (UCONTEXT_REG_R5((ctx))); \ - ((a)[6]) = (gpointer) (UCONTEXT_REG_R6((ctx))); \ - ((a)[7]) = (gpointer) (UCONTEXT_REG_R7((ctx))); \ - ((a)[8]) = (gpointer) (UCONTEXT_REG_R8((ctx))); \ - ((a)[9]) = (gpointer) (UCONTEXT_REG_R9((ctx))); \ - ((a)[10]) = (gpointer) (UCONTEXT_REG_R10((ctx))); \ - ((a)[11]) = (gpointer) (UCONTEXT_REG_R11((ctx))); \ - ((a)[12]) = (gpointer) (UCONTEXT_REG_R12((ctx))); \ - ((a)[13]) = (gpointer) (UCONTEXT_REG_LR((ctx))); \ - } while (0) #elif defined(TARGET_ARM64) -#include - #ifdef __linux__ #define REDZONE_SIZE 0 #elif defined(__APPLE__) @@ -142,12 +107,6 @@ #define USE_MONO_CTX #define ARCH_NUM_REGS 31 -#define ARCH_STORE_REGS(ptr) do { g_assert_not_reached (); } while (0) - -#define ARCH_SIGCTX_SP(ctx) UCONTEXT_REG_SP (ctx) -#define ARCH_SIGCTX_IP(ctx) UCONTEXT_REG_PC (ctx) -#define ARCH_COPY_SIGCTX_REGS(a,ctx) do { g_assert_not_reached (); } while (0) - #elif defined(__mips__) #define REDZONE_SIZE 0 @@ -155,23 +114,12 @@ #define USE_MONO_CTX #define ARCH_NUM_REGS 32 -/* - * These casts are necessary since glibc always makes the - * gregs 64-bit values in userland. - */ -#define ARCH_SIGCTX_SP(ctx) ((gsize) UCONTEXT_GREGS((ctx))[29]) -#define ARCH_SIGCTX_IP(ctx) ((gsize) UCONTEXT_REG_PC((ctx))) - #elif defined(__s390x__) #define REDZONE_SIZE 0 -#include - #define USE_MONO_CTX #define ARCH_NUM_REGS 16 -#define ARCH_SIGCTX_SP(ctx) ((UCONTEXT_GREGS((ctx))) [15]) -#define ARCH_SIGCTX_IP(ctx) ((ucontext_t *) (ctx))->uc_mcontext.psw.addr #elif defined(__sparc__) diff --git a/mono/metadata/sgen-cardtable.c b/mono/metadata/sgen-cardtable.c index aab3bcb615..6dd91e2444 100644 --- a/mono/metadata/sgen-cardtable.c +++ b/mono/metadata/sgen-cardtable.c @@ -455,6 +455,9 @@ sgen_card_table_finish_scan_remsets (void *start_nursery, void *end_nursery, Sge guint8* mono_gc_get_card_table (int *shift_bits, gpointer *mask) { +#ifndef MANAGED_WBARRIER + return NULL; +#else if (!sgen_cardtable) return NULL; @@ -466,6 +469,7 @@ mono_gc_get_card_table (int *shift_bits, gpointer *mask) #endif return sgen_cardtable; +#endif } gboolean @@ -475,22 +479,6 @@ mono_gc_card_table_nursery_check (void) } #if 0 -static void -collect_faulted_cards (void) -{ -#define CARD_PAGES (CARD_COUNT_IN_BYTES / 4096) - int i, count = 0; - unsigned char faulted [CARD_PAGES] = { 0 }; - mincore (sgen_cardtable, CARD_COUNT_IN_BYTES, faulted); - - for (i = 0; i < CARD_PAGES; ++i) { - if (faulted [i]) - ++count; - } - - printf ("TOTAL card pages %d faulted %d\n", CARD_PAGES, count); -} - void sgen_card_table_dump_obj_card (char *object, size_t size, void *dummy) { @@ -683,9 +671,9 @@ LOOP_HEAD: HEAVY_STAT (++bloby_objects); if (cards) { if (sgen_card_table_is_range_marked (cards, (mword)obj, block_obj_size)) - sgen_get_current_object_ops ()->scan_object (obj, queue); + sgen_get_current_object_ops ()->scan_object (obj, sgen_obj_get_descriptor (obj), queue); } else if (sgen_card_table_region_begin_scanning ((mword)obj, block_obj_size)) { - sgen_get_current_object_ops ()->scan_object (obj, queue); + sgen_get_current_object_ops ()->scan_object (obj, sgen_obj_get_descriptor (obj), queue); } binary_protocol_card_scan (obj, sgen_safe_object_get_size ((MonoObject*)obj)); diff --git a/mono/metadata/sgen-conf.h b/mono/metadata/sgen-conf.h index 009d0f66ee..babee94026 100644 --- a/mono/metadata/sgen-conf.h +++ b/mono/metadata/sgen-conf.h @@ -41,6 +41,12 @@ typedef guint64 mword; */ // #define HEAVY_STATISTICS +#ifdef HEAVY_STATISTICS +#define HEAVY_STAT(x) x +#else +#define HEAVY_STAT(x) +#endif + /* * Define this to allow the user to change the nursery size by * specifying its value in the MONO_GC_PARAMS environmental diff --git a/mono/metadata/sgen-copy-object.h b/mono/metadata/sgen-copy-object.h index dec0d073fe..21331c18f0 100644 --- a/mono/metadata/sgen-copy-object.h +++ b/mono/metadata/sgen-copy-object.h @@ -18,6 +18,9 @@ * License 2.0 along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "mono/utils/mono-compiler.h" + extern long long stat_copy_object_called_nursery; extern long long stat_objects_copied_nursery; @@ -31,13 +34,9 @@ extern long long stat_slots_allocated_in_vain; * This function can be used even if the vtable of obj is not valid * anymore, which is the case in the parallel collector. */ -static inline void +static MONO_ALWAYS_INLINE void par_copy_object_no_checks (char *destination, MonoVTable *vt, void *obj, mword objsize, SgenGrayQueue *queue) { -#ifdef __GNUC__ - static const void *copy_labels [] = { &&LAB_0, &&LAB_1, &&LAB_2, &&LAB_3, &&LAB_4, &&LAB_5, &&LAB_6, &&LAB_7, &&LAB_8 }; -#endif - SGEN_ASSERT (9, vt->klass->inited, "vtable %p for class %s:%s was not initialized", vt, vt->klass->name_space, vt->klass->name); SGEN_LOG (9, " (to %p, %s size: %lu)", destination, ((MonoObject*)obj)->vtable->klass->name, (unsigned long)objsize); binary_protocol_copy (obj, destination, vt, objsize); @@ -50,35 +49,8 @@ par_copy_object_no_checks (char *destination, MonoVTable *vt, void *obj, mword o } #endif -#ifdef __GNUC__ - if (objsize <= sizeof (gpointer) * 8) { - mword *dest = (mword*)destination; - goto *copy_labels [objsize / sizeof (gpointer)]; - LAB_8: - (dest) [7] = ((mword*)obj) [7]; - LAB_7: - (dest) [6] = ((mword*)obj) [6]; - LAB_6: - (dest) [5] = ((mword*)obj) [5]; - LAB_5: - (dest) [4] = ((mword*)obj) [4]; - LAB_4: - (dest) [3] = ((mword*)obj) [3]; - LAB_3: - (dest) [2] = ((mword*)obj) [2]; - LAB_2: - (dest) [1] = ((mword*)obj) [1]; - LAB_1: - ; - LAB_0: - ; - } else { - /*can't trust memcpy doing word copies */ - mono_gc_memmove_aligned (destination + sizeof (mword), (char*)obj + sizeof (mword), objsize - sizeof (mword)); - } -#else - mono_gc_memmove_aligned (destination + sizeof (mword), (char*)obj + sizeof (mword), objsize - sizeof (mword)); -#endif + memcpy (destination + sizeof (mword), (char*)obj + sizeof (mword), objsize - sizeof (mword)); + /* adjust array->bounds */ SGEN_ASSERT (9, vt->gc_descr, "vtable %p for class %s:%s has no gc descriptor", vt, vt->klass->name_space, vt->klass->name); @@ -92,18 +64,14 @@ par_copy_object_no_checks (char *destination, MonoVTable *vt, void *obj, mword o obj = destination; if (queue) { SGEN_LOG (9, "Enqueuing gray object %p (%s)", obj, sgen_safe_name (obj)); - GRAY_OBJECT_ENQUEUE (queue, obj); + GRAY_OBJECT_ENQUEUE (queue, obj, sgen_vtable_get_descriptor (vt)); } } /* * This can return OBJ itself on OOM. */ -#ifdef _MSC_VER -static __declspec(noinline) void* -#else -static G_GNUC_UNUSED void* __attribute__((noinline)) -#endif +static MONO_NEVER_INLINE void* copy_object_no_checks (void *obj, SgenGrayQueue *queue) { MonoVTable *vt = ((MonoObject*)obj)->vtable; diff --git a/mono/metadata/sgen-debug.c b/mono/metadata/sgen-debug.c index 1387676c75..113078c183 100644 --- a/mono/metadata/sgen-debug.c +++ b/mono/metadata/sgen-debug.c @@ -174,7 +174,8 @@ static gboolean missing_remsets; static void check_consistency_callback (char *start, size_t size, void *dummy) { - GCVTable *vt = (GCVTable*)LOAD_VTABLE (start); + MonoVTable *vt = (MonoVTable*)LOAD_VTABLE (start); + mword desc = sgen_vtable_get_descriptor (vt); SGEN_LOG (8, "Scanning object %p, vtable: %p (%s)", start, vt, vt->klass->name); #include "sgen-scan-object.h" @@ -230,7 +231,8 @@ static void check_mod_union_callback (char *start, size_t size, void *dummy) { gboolean in_los = (gboolean) (size_t) dummy; - GCVTable *vt = (GCVTable*)LOAD_VTABLE (start); + MonoVTable *vt = (MonoVTable*)LOAD_VTABLE (start); + mword desc = sgen_vtable_get_descriptor (vt); guint8 *cards; SGEN_LOG (8, "Scanning object %p, vtable: %p (%s)", start, vt, vt->klass->name); @@ -269,6 +271,8 @@ sgen_check_mod_union_consistency (void) static void check_major_refs_callback (char *start, size_t size, void *dummy) { + mword desc = sgen_obj_get_descriptor (start); + #include "sgen-scan-object.h" } @@ -296,9 +300,13 @@ sgen_check_major_refs (void) void check_object (char *start) { + mword desc; + if (!start) return; + desc = sgen_obj_get_descriptor (start); + #include "sgen-scan-object.h" } @@ -425,6 +433,7 @@ static void verify_object_pointers_callback (char *start, size_t size, void *data) { gboolean allow_missing_pinned = (gboolean) (size_t) data; + mword desc = sgen_obj_get_descriptor (start); #include "sgen-scan-object.h" } @@ -548,6 +557,7 @@ static void check_marked_callback (char *start, size_t size, void *dummy) { gboolean is_los = (gboolean) (size_t) dummy; + mword desc; if (is_los) { if (!sgen_los_object_is_pinned (start)) @@ -557,6 +567,8 @@ check_marked_callback (char *start, size_t size, void *dummy) return; } + desc = sgen_obj_get_descriptor (start); + #include "sgen-scan-object.h" } @@ -608,6 +620,7 @@ scan_object_for_specific_ref (char *start, MonoObject *key) start = forwarded; if (scan_object_for_specific_ref_precise) { + mword desc = sgen_obj_get_descriptor (start); #include "sgen-scan-object.h" } else { mword *words = (mword*)start; @@ -896,7 +909,9 @@ check_reference_for_xdomain (gpointer *ptr, char *obj, MonoDomain *domain) static void scan_object_for_xdomain_refs (char *start, mword size, void *data) { - MonoDomain *domain = ((MonoObject*)start)->vtable->domain; + MonoVTable *vt = (MonoVTable*)SGEN_LOAD_VTABLE (start); + MonoDomain *domain = vt->domain; + mword desc = sgen_vtable_get_descriptor (vt); #include "sgen-scan-object.h" } diff --git a/mono/metadata/sgen-descriptor.c b/mono/metadata/sgen-descriptor.c index c578a91cfb..6da8f7290d 100644 --- a/mono/metadata/sgen-descriptor.c +++ b/mono/metadata/sgen-descriptor.c @@ -43,6 +43,7 @@ #define _XOPEN_SOURCE #endif +#include "utils/mono-counters.h" #include "metadata/sgen-gc.h" #define MAX_USER_DESCRIPTORS 16 @@ -58,6 +59,9 @@ static MonoGCRootMarkFunc user_descriptors [MAX_USER_DESCRIPTORS]; static int user_descriptors_next = 0; static void *all_ref_root_descrs [32]; +#ifdef HEAVY_STATISTICS +static long long stat_scanned_count_per_descriptor [DESC_TYPE_MAX]; +#endif static int alloc_complex_descriptor (gsize *bitmap, int numbits) @@ -348,4 +352,28 @@ sgen_get_user_descriptor_func (mword desc) return user_descriptors [desc >> ROOT_DESC_TYPE_SHIFT]; } +#ifdef HEAVY_STATISTICS +void +sgen_descriptor_count_scanned_object (mword desc) +{ + int type = desc & 7; + SGEN_ASSERT (0, type, "Descriptor type can't be zero"); + ++stat_scanned_count_per_descriptor [type - 1]; +} +#endif + +void +sgen_init_descriptors (void) +{ +#ifdef HEAVY_STATISTICS + mono_counters_register ("# scanned RUN_LENGTH", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_scanned_count_per_descriptor [DESC_TYPE_RUN_LENGTH - 1]); + mono_counters_register ("# scanned SMALL_BITMAP", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_scanned_count_per_descriptor [DESC_TYPE_SMALL_BITMAP - 1]); + mono_counters_register ("# scanned COMPLEX", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_scanned_count_per_descriptor [DESC_TYPE_COMPLEX - 1]); + mono_counters_register ("# scanned VECTOR", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_scanned_count_per_descriptor [DESC_TYPE_VECTOR - 1]); + mono_counters_register ("# scanned LARGE_BITMAP", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_scanned_count_per_descriptor [DESC_TYPE_LARGE_BITMAP - 1]); + mono_counters_register ("# scanned COMPLEX_ARR", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_scanned_count_per_descriptor [DESC_TYPE_COMPLEX_ARR - 1]); + mono_counters_register ("# scanned COMPLEX_PTRFREE", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_scanned_count_per_descriptor [DESC_TYPE_COMPLEX_PTRFREE - 1]); +#endif +} + #endif diff --git a/mono/metadata/sgen-descriptor.h b/mono/metadata/sgen-descriptor.h index 366c766777..c06354dd95 100644 --- a/mono/metadata/sgen-descriptor.h +++ b/mono/metadata/sgen-descriptor.h @@ -82,13 +82,14 @@ enum { * copy_object_no_checks(), without having to fetch the * object's class. */ - DESC_TYPE_RUN_LENGTH = 1, /* 16 bits aligned byte size | 1-3 (offset, numptr) bytes tuples */ - DESC_TYPE_SMALL_BITMAP, /* 16 bits aligned byte size | 16-48 bit bitmap */ - DESC_TYPE_COMPLEX, /* index for bitmap into complex_descriptors */ - DESC_TYPE_VECTOR, /* 10 bits element size | 1 bit kind | 2 bits desc | element desc */ - DESC_TYPE_LARGE_BITMAP, /* | 29-61 bitmap bits */ - DESC_TYPE_COMPLEX_ARR, /* index for bitmap into complex_descriptors */ - DESC_TYPE_COMPLEX_PTRFREE, /*Nothing, used to encode large ptr objects. */ + DESC_TYPE_RUN_LENGTH = 1, /* 16 bits aligned byte size | 1-3 (offset, numptr) bytes tuples */ + DESC_TYPE_SMALL_BITMAP = 2, /* 16 bits aligned byte size | 16-48 bit bitmap */ + DESC_TYPE_COMPLEX = 3, /* index for bitmap into complex_descriptors */ + DESC_TYPE_VECTOR = 4, /* 10 bits element size | 1 bit kind | 2 bits desc | element desc */ + DESC_TYPE_LARGE_BITMAP = 5, /* | 29-61 bitmap bits */ + DESC_TYPE_COMPLEX_ARR = 6, /* index for bitmap into complex_descriptors */ + DESC_TYPE_COMPLEX_PTRFREE = 7, /*Nothing, used to encode large ptr objects. */ + DESC_TYPE_MAX = 7, /* values for array kind */ DESC_TYPE_V_SZARRAY = 0, /*vector with no bounds data */ DESC_TYPE_V_ARRAY = 1, /* array with bounds data */ @@ -117,6 +118,11 @@ gsize* sgen_get_complex_descriptor (mword desc) MONO_INTERNAL; void* sgen_get_complex_descriptor_bitmap (mword desc) MONO_INTERNAL; MonoGCRootMarkFunc sgen_get_user_descriptor_func (mword desc) MONO_INTERNAL; +void sgen_init_descriptors (void) MONO_INTERNAL; + +#ifdef HEAVY_STATISTICS +void sgen_descriptor_count_scanned_object (mword desc) MONO_INTERNAL; +#endif static inline gboolean sgen_gc_descr_has_references (mword desc) @@ -168,8 +174,6 @@ sgen_gc_descr_has_references (mword desc) void **_objptr = (void**)(obj); \ _objptr += ((desc) >> 16) & 0xff; \ _objptr_end = _objptr + (((desc) >> 24) & 0xff); \ - HANDLE_PTR (_objptr, (obj)); \ - _objptr ++; \ while (_objptr < _objptr_end) { \ HANDLE_PTR (_objptr, (obj)); \ _objptr++; \ @@ -183,20 +187,13 @@ sgen_gc_descr_has_references (mword desc) void **_objptr = (void**)(obj); \ gsize _bmap = (desc) >> 16; \ _objptr += OBJECT_HEADER_WORDS; \ - { \ + do { \ int _index = GNUC_BUILTIN_CTZ (_bmap); \ _objptr += _index; \ _bmap >>= (_index + 1); \ HANDLE_PTR (_objptr, (obj)); \ _objptr ++; \ - } \ - while (_bmap) { \ - int _index = GNUC_BUILTIN_CTZ (_bmap); \ - _objptr += _index; \ - _bmap >>= (_index + 1); \ - HANDLE_PTR (_objptr, (obj)); \ - _objptr ++; \ - } \ + } while (_bmap); \ } while (0) #else #define OBJ_BITMAP_FOREACH_PTR(desc,obj) do { \ @@ -258,15 +255,16 @@ sgen_gc_descr_has_references (mword desc) } while (0) /* this one is untested */ -#define OBJ_COMPLEX_ARR_FOREACH_PTR(vt,obj) do { \ +#define OBJ_COMPLEX_ARR_FOREACH_PTR(desc,obj) do { \ /* there are pointers */ \ - gsize *mbitmap_data = sgen_get_complex_descriptor ((vt)->desc); \ + GCVTable *vt = (GCVTable*)SGEN_LOAD_VTABLE (obj); \ + gsize *mbitmap_data = sgen_get_complex_descriptor ((desc)); \ gsize mbwords = (*mbitmap_data++) - 1; \ gsize el_size = mono_array_element_size (vt->klass); \ char *e_start = (char*)(obj) + G_STRUCT_OFFSET (MonoArray, vector); \ char *e_end = e_start + el_size * mono_array_length_fast ((MonoArray*)(obj)); \ if (0) \ - g_print ("found %d at %p (0x%zx): %s.%s\n", mbwords, (obj), (vt)->desc, vt->klass->name_space, vt->klass->name); \ + g_print ("found %d at %p (0x%zx): %s.%s\n", mbwords, (obj), (desc), (vt)->klass->name_space, (vt)->klass->name); \ while (e_start < e_end) { \ void **_objptr = (void**)e_start; \ gsize *bitmap_data = mbitmap_data; \ diff --git a/mono/metadata/sgen-gc.c.REMOVED.git-id b/mono/metadata/sgen-gc.c.REMOVED.git-id index 6220dedd4a..530455e8aa 100644 --- a/mono/metadata/sgen-gc.c.REMOVED.git-id +++ b/mono/metadata/sgen-gc.c.REMOVED.git-id @@ -1 +1 @@ -477c6f1690a09b8f62573bec74dd8d45652a37c4 \ No newline at end of file +4b0b5a320121f3c064437be958d7da70e149d8fc \ No newline at end of file diff --git a/mono/metadata/sgen-gc.h b/mono/metadata/sgen-gc.h index 41a7151ba2..ece9af283d 100644 --- a/mono/metadata/sgen-gc.h +++ b/mono/metadata/sgen-gc.h @@ -190,14 +190,10 @@ extern LOCK_DECLARE (sgen_interruption_mutex); #endif #ifdef HEAVY_STATISTICS -#define HEAVY_STAT(x) x - extern long long stat_objects_alloced_degraded; extern long long stat_bytes_alloced_degraded; extern long long stat_copy_object_called_major; extern long long stat_objects_copied_major; -#else -#define HEAVY_STAT(x) #endif #define SGEN_ASSERT(level, a, ...) do { \ @@ -323,77 +319,42 @@ typedef struct { * The values are already shifted. * The forwarding address is stored in the sync block. */ -#define SGEN_FORWARDED_BIT 1 -#define SGEN_PINNED_BIT 2 + #define SGEN_VTABLE_BITS_MASK 0x3 +#include "sgen-tagged-pointer.h" + +#define SGEN_POINTER_IS_TAGGED_FORWARDED(p) SGEN_POINTER_IS_TAGGED_1((p)) +#define SGEN_POINTER_TAG_FORWARDED(p) SGEN_POINTER_TAG_1((p)) + +#define SGEN_POINTER_IS_TAGGED_PINNED(p) SGEN_POINTER_IS_TAGGED_2((p)) +#define SGEN_POINTER_TAG_PINNED(p) SGEN_POINTER_TAG_2((p)) + +#define SGEN_POINTER_UNTAG_VTABLE(p) SGEN_POINTER_UNTAG_12((p)) + /* returns NULL if not forwarded, or the forwarded address */ -#define SGEN_OBJECT_IS_FORWARDED(obj) (((mword*)(obj))[0] & SGEN_FORWARDED_BIT ? (void*)(((mword*)(obj))[0] & ~SGEN_VTABLE_BITS_MASK) : NULL) -#define SGEN_OBJECT_IS_PINNED(obj) (((mword*)(obj))[0] & SGEN_PINNED_BIT) +#define SGEN_VTABLE_IS_FORWARDED(vtable) (SGEN_POINTER_IS_TAGGED_FORWARDED ((vtable)) ? SGEN_POINTER_UNTAG_VTABLE ((vtable)) : NULL) +#define SGEN_OBJECT_IS_FORWARDED(obj) (SGEN_VTABLE_IS_FORWARDED (((mword*)(obj))[0])) + +#define SGEN_VTABLE_IS_PINNED(vtable) SGEN_POINTER_IS_TAGGED_PINNED ((vtable)) +#define SGEN_OBJECT_IS_PINNED(obj) (SGEN_VTABLE_IS_PINNED (((mword*)(obj))[0])) /* set the forwarded address fw_addr for object obj */ #define SGEN_FORWARD_OBJECT(obj,fw_addr) do { \ - ((mword*)(obj))[0] = (mword)(fw_addr) | SGEN_FORWARDED_BIT; \ + *(void**)(obj) = SGEN_POINTER_TAG_FORWARDED ((fw_addr)); \ } while (0) #define SGEN_PIN_OBJECT(obj) do { \ - ((mword*)(obj))[0] |= SGEN_PINNED_BIT; \ + *(void**)(obj) = SGEN_POINTER_TAG_PINNED (*(void**)(obj)); \ } while (0) #define SGEN_UNPIN_OBJECT(obj) do { \ - ((mword*)(obj))[0] &= ~SGEN_PINNED_BIT; \ + *(void**)(obj) = SGEN_POINTER_UNTAG_2 (*(void**)(obj)); \ } while (0) /* * Since we set bits in the vtable, use the macro to load it from the pointer to * an object that is potentially pinned. */ -#define SGEN_LOAD_VTABLE(addr) ((*(mword*)(addr)) & ~SGEN_VTABLE_BITS_MASK) - -static inline MONO_ALWAYS_INLINE void -GRAY_OBJECT_ENQUEUE (SgenGrayQueue *queue, char* obj) -{ -#if defined(SGEN_GRAY_OBJECT_ENQUEUE) || SGEN_MAX_DEBUG_LEVEL >= 9 - sgen_gray_object_enqueue (queue, obj); -#else - if (G_UNLIKELY (!queue->first || queue->cursor == GRAY_LAST_CURSOR_POSITION (queue->first))) { - sgen_gray_object_enqueue (queue, obj); - } else { - HEAVY_STAT (gc_stats.gray_queue_enqueue_fast_path ++); - - *++queue->cursor = obj; -#ifdef SGEN_HEAVY_BINARY_PROTOCOL - binary_protocol_gray_enqueue (queue, queue->cursor, obj); -#endif - } - - PREFETCH (obj); -#endif -} - -static inline MONO_ALWAYS_INLINE void -GRAY_OBJECT_DEQUEUE (SgenGrayQueue *queue, char** obj) -{ -#if defined(SGEN_GRAY_OBJECT_ENQUEUE) || SGEN_MAX_DEBUG_LEVEL >= 9 - *obj = sgen_gray_object_enqueue (queue); -#else - if (!queue->first) { - HEAVY_STAT (gc_stats.gray_queue_dequeue_fast_path ++); - - *obj = NULL; -#ifdef SGEN_HEAVY_BINARY_PROTOCOL - binary_protocol_gray_dequeue (queue, queue->cursor, *obj); -#endif - } else if (G_UNLIKELY (queue->cursor == GRAY_FIRST_CURSOR_POSITION (queue->first))) { - *obj = sgen_gray_object_dequeue (queue); - } else { - HEAVY_STAT (gc_stats.gray_queue_dequeue_fast_path ++); - - *obj = *queue->cursor--; -#ifdef SGEN_HEAVY_BINARY_PROTOCOL - binary_protocol_gray_dequeue (queue, queue->cursor + 1, *obj); -#endif - } -#endif -} +#define SGEN_LOAD_VTABLE(addr) SGEN_POINTER_UNTAG_12 (*(void**)(addr)) /* List of what each bit on of the vtable gc bits means. @@ -500,7 +461,7 @@ struct _ObjectList { }; typedef void (*CopyOrMarkObjectFunc) (void**, SgenGrayQueue*); -typedef void (*ScanObjectFunc) (char*, SgenGrayQueue*); +typedef void (*ScanObjectFunc) (char *obj, mword desc, SgenGrayQueue*); typedef void (*ScanVTypeFunc) (char*, mword desc, SgenGrayQueue* BINARY_PROTOCOL_ARG (size_t size)); typedef struct @@ -537,7 +498,6 @@ void sgen_sort_addresses (void **array, size_t size) MONO_INTERNAL; void sgen_add_to_global_remset (gpointer ptr, gpointer obj) MONO_INTERNAL; int sgen_get_current_collection_generation (void) MONO_INTERNAL; -gboolean sgen_collection_is_parallel (void) MONO_INTERNAL; gboolean sgen_collection_is_concurrent (void) MONO_INTERNAL; gboolean sgen_concurrent_collection_in_progress (void) MONO_INTERNAL; @@ -600,7 +560,7 @@ static inline gboolean sgen_nursery_is_to_space (char *object) { size_t idx = (object - sgen_nursery_start) >> SGEN_TO_SPACE_GRANULE_BITS; - size_t byte = idx / 8; + size_t byte = idx >> 3; size_t bit = idx & 0x7; SGEN_ASSERT (4, sgen_ptr_in_nursery (object), "object %p is not in nursery [%p - %p]", object, sgen_get_nursery_start (), sgen_get_nursery_end ()); @@ -634,10 +594,8 @@ typedef struct { gboolean is_split; char* (*alloc_for_promotion) (MonoVTable *vtable, char *obj, size_t objsize, gboolean has_references); - char* (*par_alloc_for_promotion) (MonoVTable *vtable, char *obj, size_t objsize, gboolean has_references); SgenObjectOperations serial_ops; - SgenObjectOperations parallel_ops; void (*prepare_to_space) (char *to_space_bitmap, size_t space_bitmap_size); void (*clear_fragments) (void); @@ -671,7 +629,6 @@ typedef enum { typedef struct _SgenMajorCollector SgenMajorCollector; struct _SgenMajorCollector { size_t section_size; - gboolean is_parallel; gboolean is_concurrent; gboolean supports_cardtable; gboolean sweeps_lazily; @@ -697,7 +654,6 @@ struct _SgenMajorCollector { SgenObjectOperations major_concurrent_ops; void* (*alloc_object) (MonoVTable *vtable, size_t size, gboolean has_references); - void* (*par_alloc_object) (MonoVTable *vtable, size_t size, gboolean has_references); void (*free_pinned_object) (char *obj, size_t size); void (*iterate_objects) (IterateObjectsFlags flags, IterateObjectCallbackFunc callback, void *data); void (*free_non_pinned_object) (char *obj, size_t size); @@ -791,6 +747,27 @@ slow_object_get_size (MonoVTable *vtable, MonoObject* o) } } +static inline mword +sgen_vtable_get_descriptor (MonoVTable *vtable) +{ + return (mword)vtable->gc_descr; +} + +static inline mword +sgen_obj_get_descriptor (char *obj) +{ + MonoVTable *vtable = ((MonoObject*)obj)->vtable; + SGEN_ASSERT (0, !SGEN_POINTER_IS_TAGGED_1_OR_2 (vtable), "Object can't be tagged"); + return sgen_vtable_get_descriptor (vtable); +} + +static inline mword +sgen_obj_get_descriptor_safe (char *obj) +{ + MonoVTable *vtable = (MonoVTable*)SGEN_LOAD_VTABLE (obj); + return sgen_vtable_get_descriptor (vtable); +} + /* * This function can be called on an object whose first word, the * vtable field, is not intact. This is necessary for the parallel @@ -834,6 +811,22 @@ sgen_safe_object_get_size (MonoObject *obj) return sgen_par_object_get_size ((MonoVTable*)SGEN_LOAD_VTABLE (obj), obj); } +/* + * This variant guarantees to return the exact size of the object + * before alignment. Needed for canary support. + */ +static inline guint +sgen_safe_object_get_size_unaligned (MonoObject *obj) +{ + char *forwarded; + + if ((forwarded = SGEN_OBJECT_IS_FORWARDED (obj))) { + obj = (MonoObject*)forwarded; + } + + return slow_object_get_size ((MonoVTable*)SGEN_LOAD_VTABLE (obj), obj); +} + const char* sgen_safe_name (void* obj) MONO_INTERNAL; gboolean sgen_object_is_live (void *obj) MONO_INTERNAL; @@ -1000,7 +993,6 @@ void sgen_nursery_alloc_prepare_for_minor (void) MONO_INTERNAL; void sgen_nursery_alloc_prepare_for_major (void) MONO_INTERNAL; char* sgen_alloc_for_promotion (char *obj, size_t objsize, gboolean has_references) MONO_INTERNAL; -char* sgen_par_alloc_for_promotion (char *obj, size_t objsize, gboolean has_references) MONO_INTERNAL; /* TLS Data */ @@ -1168,6 +1160,37 @@ void sgen_env_var_error (const char *env_var, const char *fallback, const char * void sgen_qsort (void *base, size_t nel, size_t width, int (*compar) (const void*, const void*)) MONO_INTERNAL; gint64 sgen_timestamp (void) MONO_INTERNAL; +/* + * Canary (guard word) support + * Notes: + * - CANARY_SIZE must be multiple of word size in bytes + * - Canary space is not included on checks against SGEN_MAX_SMALL_OBJ_SIZE + */ + +gboolean nursery_canaries_enabled (void) MONO_INTERNAL; + +#define CANARY_SIZE 8 +#define CANARY_STRING "koupepia" + +#define CANARIFY_SIZE(size) if (nursery_canaries_enabled ()) { \ + size = size + CANARY_SIZE; \ + } + +#define CANARIFY_ALLOC(addr,size) if (nursery_canaries_enabled ()) { \ + memcpy ((char*) (addr) + (size), CANARY_STRING, CANARY_SIZE); \ + } + +#define CANARY_VALID(addr) (strncmp ((char*) (addr), CANARY_STRING, CANARY_SIZE) == 0) + +#define CHECK_CANARY_FOR_OBJECT(addr) if (nursery_canaries_enabled ()) { \ + char* canary_ptr = (char*) (addr) + sgen_safe_object_get_size_unaligned ((MonoObject *) (addr)); \ + if (!CANARY_VALID(canary_ptr)) { \ + char canary_copy[CANARY_SIZE +1]; \ + strncpy (canary_copy, canary_ptr, 8); \ + canary_copy[CANARY_SIZE] = 0; \ + g_error ("CORRUPT CANARY:\naddr->%p\ntype->%s\nexcepted->'%s'\nfound->'%s'\n", (char*) addr, ((MonoObject*)addr)->vtable->klass->name, CANARY_STRING, canary_copy); \ + } } + #endif /* HAVE_SGEN_GC */ #endif /* __MONO_SGENGC_H__ */ diff --git a/mono/metadata/sgen-gray.c b/mono/metadata/sgen-gray.c index 2393cbabb1..9bff2c7d4a 100644 --- a/mono/metadata/sgen-gray.c +++ b/mono/metadata/sgen-gray.c @@ -25,6 +25,15 @@ #include "utils/mono-counters.h" #include "sgen-protocol.h" +#ifdef HEAVY_STATISTICS +unsigned long long stat_gray_queue_section_alloc; +unsigned long long stat_gray_queue_section_free; +unsigned long long stat_gray_queue_enqueue_fast_path; +unsigned long long stat_gray_queue_dequeue_fast_path; +unsigned long long stat_gray_queue_enqueue_slow_path; +unsigned long long stat_gray_queue_dequeue_slow_path; +#endif + #define GRAY_QUEUE_LENGTH_LIMIT 64 #ifdef SGEN_CHECK_GRAY_OBJECT_SECTIONS @@ -46,7 +55,7 @@ sgen_gray_object_alloc_queue_section (SgenGrayQueue *queue) { GrayQueueSection *section; - HEAVY_STAT (gc_stats.gray_queue_section_alloc ++); + HEAVY_STAT (stat_gray_queue_section_alloc ++); if (queue->alloc_prepare_func) queue->alloc_prepare_func (queue); @@ -69,13 +78,13 @@ sgen_gray_object_alloc_queue_section (SgenGrayQueue *queue) /* Link it with the others */ section->next = queue->first; queue->first = section; - queue->cursor = (char**)section->objects - 1; + queue->cursor = section->entries - 1; } void sgen_gray_object_free_queue_section (GrayQueueSection *section) { - HEAVY_STAT (gc_stats.gray_queue_section_free ++); + HEAVY_STAT (stat_gray_queue_section_free ++); STATE_TRANSITION (section, GRAY_QUEUE_SECTION_STATE_FLOATING, GRAY_QUEUE_SECTION_STATE_FREED); sgen_free_internal (section, INTERNAL_MEM_GRAY_QUEUE); @@ -88,9 +97,11 @@ sgen_gray_object_free_queue_section (GrayQueueSection *section) */ void -sgen_gray_object_enqueue (SgenGrayQueue *queue, char *obj) +sgen_gray_object_enqueue (SgenGrayQueue *queue, char *obj, mword desc) { - HEAVY_STAT (gc_stats.gray_queue_enqueue_slow_path ++); + GrayQueueEntry entry = { obj, desc }; + + HEAVY_STAT (stat_gray_queue_enqueue_slow_path ++); SGEN_ASSERT (9, obj, "enqueueing a null object"); //sgen_check_objref (obj); @@ -110,33 +121,35 @@ sgen_gray_object_enqueue (SgenGrayQueue *queue, char *obj) } STATE_ASSERT (queue->first, GRAY_QUEUE_SECTION_STATE_ENQUEUED); SGEN_ASSERT (9, queue->cursor <= GRAY_LAST_CURSOR_POSITION (queue->first), "gray queue %p overflow, first %p, cursor %p", queue, queue->first, queue->cursor); - *++queue->cursor = obj; + *++queue->cursor = entry; #ifdef SGEN_HEAVY_BINARY_PROTOCOL binary_protocol_gray_enqueue (queue, queue->cursor, obj); #endif } -char* +GrayQueueEntry sgen_gray_object_dequeue (SgenGrayQueue *queue) { - char *obj; + GrayQueueEntry entry; - HEAVY_STAT (gc_stats.gray_queue_dequeue_slow_path ++); + HEAVY_STAT (stat_gray_queue_dequeue_slow_path ++); - if (sgen_gray_object_queue_is_empty (queue)) - return NULL; + if (sgen_gray_object_queue_is_empty (queue)) { + entry.obj = NULL; + return entry; + } STATE_ASSERT (queue->first, GRAY_QUEUE_SECTION_STATE_ENQUEUED); - SGEN_ASSERT (9, queue->cursor >= (char**)queue->first->objects, "gray queue %p underflow, first %p, cursor %d", queue, queue->first, queue->cursor); + SGEN_ASSERT (9, queue->cursor >= GRAY_FIRST_CURSOR_POSITION (queue->first), "gray queue %p underflow, first %p, cursor %d", queue, queue->first, queue->cursor); - obj = *queue->cursor--; + entry = *queue->cursor--; #ifdef SGEN_HEAVY_BINARY_PROTOCOL - binary_protocol_gray_dequeue (queue, queue->cursor + 1, obj); + binary_protocol_gray_dequeue (queue, queue->cursor + 1, entry.obj); #endif - if (G_UNLIKELY (queue->cursor == (char**)queue->first->objects - 1)) { + if (G_UNLIKELY (queue->cursor < GRAY_FIRST_CURSOR_POSITION (queue->first))) { GrayQueueSection *section = queue->first; queue->first = section->next; section->next = queue->free_list; @@ -144,10 +157,10 @@ sgen_gray_object_dequeue (SgenGrayQueue *queue) STATE_TRANSITION (section, GRAY_QUEUE_SECTION_STATE_ENQUEUED, GRAY_QUEUE_SECTION_STATE_FREE_LIST); queue->free_list = section; - queue->cursor = queue->first ? (char**)queue->first->objects + queue->first->size - 1 : NULL; + queue->cursor = queue->first ? queue->first->entries + queue->first->size - 1 : NULL; } - return obj; + return entry; } GrayQueueSection* @@ -162,9 +175,9 @@ sgen_gray_object_dequeue_section (SgenGrayQueue *queue) queue->first = section->next; section->next = NULL; - section->size = queue->cursor - (char**)section->objects + 1; + section->size = queue->cursor - section->entries + 1; - queue->cursor = queue->first ? (char**)queue->first->objects + queue->first->size - 1 : NULL; + queue->cursor = queue->first ? queue->first->entries + queue->first->size - 1 : NULL; STATE_TRANSITION (section, GRAY_QUEUE_SECTION_STATE_ENQUEUED, GRAY_QUEUE_SECTION_STATE_FLOATING); @@ -177,36 +190,25 @@ sgen_gray_object_enqueue_section (SgenGrayQueue *queue, GrayQueueSection *sectio STATE_TRANSITION (section, GRAY_QUEUE_SECTION_STATE_FLOATING, GRAY_QUEUE_SECTION_STATE_ENQUEUED); if (queue->first) - queue->first->size = queue->cursor - (char**)queue->first->objects + 1; + queue->first->size = queue->cursor - queue->first->entries + 1; section->next = queue->first; queue->first = section; - queue->cursor = (char**)queue->first->objects + queue->first->size - 1; + queue->cursor = queue->first->entries + queue->first->size - 1; #ifdef SGEN_CHECK_GRAY_OBJECT_ENQUEUE if (queue->enqueue_check_func) { int i; for (i = 0; i < section->size; ++i) - queue->enqueue_check_func (section->objects [i]); + queue->enqueue_check_func (section->entries [i].obj); } #endif } void -sgen_gray_object_queue_init (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func) +sgen_gray_object_queue_trim_free_list (SgenGrayQueue *queue) { GrayQueueSection *section, *next; - int i; - - g_assert (sgen_gray_object_queue_is_empty (queue)); - - queue->alloc_prepare_func = NULL; - queue->alloc_prepare_data = NULL; -#ifdef SGEN_CHECK_GRAY_OBJECT_ENQUEUE - queue->enqueue_check_func = enqueue_check_func; -#endif - - /* Free the extra sections allocated during the last collection */ - i = 0; + int i = 0; for (section = queue->free_list; section && i < GRAY_QUEUE_LENGTH_LIMIT - 1; section = section->next) { STATE_ASSERT (section, GRAY_QUEUE_SECTION_STATE_FREE_LIST); i ++; @@ -221,6 +223,21 @@ sgen_gray_object_queue_init (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enq } } +void +sgen_gray_object_queue_init (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func) +{ + g_assert (sgen_gray_object_queue_is_empty (queue)); + + queue->alloc_prepare_func = NULL; + queue->alloc_prepare_data = NULL; +#ifdef SGEN_CHECK_GRAY_OBJECT_ENQUEUE + queue->enqueue_check_func = enqueue_check_func; +#endif + + /* Free the extra sections allocated during the last collection */ + sgen_gray_object_queue_trim_free_list (queue); +} + static void invalid_prepare_func (SgenGrayQueue *queue) { @@ -338,11 +355,23 @@ sgen_section_gray_queue_enqueue (SgenSectionGrayQueue *queue, GrayQueueSection * if (queue->enqueue_check_func) { int i; for (i = 0; i < section->size; ++i) - queue->enqueue_check_func (section->objects [i]); + queue->enqueue_check_func (section->entries [i].obj); } #endif unlock_section_queue (queue); } +void +sgen_init_gray_queues (void) +{ +#ifdef HEAVY_STATISTICS + mono_counters_register ("Gray Queue alloc section", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_gray_queue_section_alloc); + mono_counters_register ("Gray Queue free section", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_gray_queue_section_free); + mono_counters_register ("Gray Queue enqueue fast path", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_gray_queue_enqueue_fast_path); + mono_counters_register ("Gray Queue dequeue fast path", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_gray_queue_dequeue_fast_path); + mono_counters_register ("Gray Queue enqueue slow path", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_gray_queue_enqueue_slow_path); + mono_counters_register ("Gray Queue dequeue slow path", MONO_COUNTER_GC | MONO_COUNTER_ULONG, &stat_gray_queue_dequeue_slow_path); +#endif +} #endif diff --git a/mono/metadata/sgen-gray.h b/mono/metadata/sgen-gray.h index 2dfea35a14..a020323667 100644 --- a/mono/metadata/sgen-gray.h +++ b/mono/metadata/sgen-gray.h @@ -20,6 +20,8 @@ #ifndef __MONO_SGEN_GRAY_H__ #define __MONO_SGEN_GRAY_H__ +#include "sgen-protocol.h" + /* * This gray queue has to be as optimized as possible, because it is in the core of * the mark/copy phase of the garbage collector. The memory access has then to be as @@ -48,7 +50,14 @@ * array and another 1 for the actual value in the array. */ -#define SGEN_GRAY_QUEUE_SECTION_SIZE (128 - 3) +/* SGEN_GRAY_QUEUE_HEADER_SIZE is number of machine words */ +#ifdef SGEN_CHECK_GRAY_OBJECT_SECTIONS +#define SGEN_GRAY_QUEUE_HEADER_SIZE 4 +#else +#define SGEN_GRAY_QUEUE_HEADER_SIZE 2 +#endif + +#define SGEN_GRAY_QUEUE_SECTION_SIZE (128 - SGEN_GRAY_QUEUE_HEADER_SIZE) #ifdef SGEN_CHECK_GRAY_OBJECT_SECTIONS typedef enum { @@ -59,6 +68,12 @@ typedef enum { } GrayQueueSectionState; #endif +typedef struct _GrayQueueEntry GrayQueueEntry; +struct _GrayQueueEntry { + char *obj; + mword desc; +}; + /* * This is a stack now instead of a queue, so the most recently added items are removed * first, improving cache locality, and keeping the stack size manageable. @@ -75,7 +90,7 @@ struct _GrayQueueSection { #endif int size; GrayQueueSection *next; - char *objects [SGEN_GRAY_QUEUE_SECTION_SIZE]; + GrayQueueEntry entries [SGEN_GRAY_QUEUE_SECTION_SIZE]; }; typedef struct _SgenGrayQueue SgenGrayQueue; @@ -84,7 +99,7 @@ typedef void (*GrayQueueAllocPrepareFunc) (SgenGrayQueue*); typedef void (*GrayQueueEnqueueCheckFunc) (char*); struct _SgenGrayQueue { - char **cursor; + GrayQueueEntry *cursor; GrayQueueSection *first; GrayQueueSection *free_list; GrayQueueAllocPrepareFunc alloc_prepare_func; @@ -105,13 +120,25 @@ struct _SgenSectionGrayQueue { #endif }; -#define GRAY_LAST_CURSOR_POSITION(s) ((char**)(s)->objects + SGEN_GRAY_QUEUE_SECTION_SIZE - 1) -#define GRAY_FIRST_CURSOR_POSITION(s) ((char**)(s)->objects) +#define GRAY_LAST_CURSOR_POSITION(s) ((s)->entries + SGEN_GRAY_QUEUE_SECTION_SIZE - 1) +#define GRAY_FIRST_CURSOR_POSITION(s) ((s)->entries) -void sgen_gray_object_enqueue (SgenGrayQueue *queue, char *obj) MONO_INTERNAL; -char* sgen_gray_object_dequeue (SgenGrayQueue *queue) MONO_INTERNAL; +#ifdef HEAVY_STATISTICS +extern unsigned long long stat_gray_queue_section_alloc; +extern unsigned long long stat_gray_queue_section_free; +extern unsigned long long stat_gray_queue_enqueue_fast_path; +extern unsigned long long stat_gray_queue_dequeue_fast_path; +extern unsigned long long stat_gray_queue_enqueue_slow_path; +extern unsigned long long stat_gray_queue_dequeue_slow_path; +#endif + +void sgen_init_gray_queues (void) MONO_INTERNAL; + +void sgen_gray_object_enqueue (SgenGrayQueue *queue, char *obj, mword desc) MONO_INTERNAL; +GrayQueueEntry sgen_gray_object_dequeue (SgenGrayQueue *queue) MONO_INTERNAL; GrayQueueSection* sgen_gray_object_dequeue_section (SgenGrayQueue *queue) MONO_INTERNAL; void sgen_gray_object_enqueue_section (SgenGrayQueue *queue, GrayQueueSection *section) MONO_INTERNAL; +void sgen_gray_object_queue_trim_free_list (SgenGrayQueue *queue) MONO_INTERNAL; void sgen_gray_object_queue_init (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func) MONO_INTERNAL; void sgen_gray_object_queue_init_invalid (SgenGrayQueue *queue) MONO_INTERNAL; void sgen_gray_object_queue_init_with_alloc_prepare (SgenGrayQueue *queue, GrayQueueEnqueueCheckFunc enqueue_check_func, @@ -133,4 +160,58 @@ sgen_gray_object_queue_is_empty (SgenGrayQueue *queue) return queue->first == NULL; } +static inline MONO_ALWAYS_INLINE void +GRAY_OBJECT_ENQUEUE (SgenGrayQueue *queue, char* obj, mword desc) +{ +#if SGEN_MAX_DEBUG_LEVEL >= 9 + sgen_gray_object_enqueue (queue, obj, desc); +#else + if (G_UNLIKELY (!queue->first || queue->cursor == GRAY_LAST_CURSOR_POSITION (queue->first))) { + sgen_gray_object_enqueue (queue, obj, desc); + } else { + GrayQueueEntry entry = { obj, desc }; + + HEAVY_STAT (stat_gray_queue_enqueue_fast_path ++); + + *++queue->cursor = entry; +#ifdef SGEN_HEAVY_BINARY_PROTOCOL + binary_protocol_gray_enqueue (queue, queue->cursor, obj); +#endif + } +#endif +} + +static inline MONO_ALWAYS_INLINE void +GRAY_OBJECT_DEQUEUE (SgenGrayQueue *queue, char** obj, mword *desc) +{ + GrayQueueEntry entry; +#if SGEN_MAX_DEBUG_LEVEL >= 9 + entry = sgen_gray_object_enqueue (queue); + *obj = entry.obj; + *desc = entry.desc; +#else + if (!queue->first) { + HEAVY_STAT (stat_gray_queue_dequeue_fast_path ++); + + *obj = NULL; +#ifdef SGEN_HEAVY_BINARY_PROTOCOL + binary_protocol_gray_dequeue (queue, queue->cursor, *obj); +#endif + } else if (G_UNLIKELY (queue->cursor == GRAY_FIRST_CURSOR_POSITION (queue->first))) { + entry = sgen_gray_object_dequeue (queue); + *obj = entry.obj; + *desc = entry.desc; + } else { + HEAVY_STAT (stat_gray_queue_dequeue_fast_path ++); + + entry = *queue->cursor--; + *obj = entry.obj; + *desc = entry.desc; +#ifdef SGEN_HEAVY_BINARY_PROTOCOL + binary_protocol_gray_dequeue (queue, queue->cursor + 1, *obj); +#endif + } +#endif +} + #endif diff --git a/mono/metadata/sgen-internal.c b/mono/metadata/sgen-internal.c index 37ac5c6f32..333f8c3ee4 100644 --- a/mono/metadata/sgen-internal.c +++ b/mono/metadata/sgen-internal.c @@ -23,21 +23,53 @@ #include "utils/mono-counters.h" #include "metadata/sgen-gc.h" +#include "utils/mono-mmap.h" #include "utils/lock-free-alloc.h" #include "metadata/sgen-memory-governor.h" /* keep each size a multiple of ALLOC_ALIGN */ +#if SIZEOF_VOID_P == 4 static const int allocator_sizes [] = { 8, 16, 24, 32, 40, 48, 64, 80, - 96, 128, 160, 192, 224, 248, 320, 384, - 448, 528, 584, 680, 816, 1088, 1360, 2040, - 2336, 2728, 3272, 4088, 5456, 8184 }; + 96, 128, 160, 192, 224, 248, 296, 320, + 384, 448, 504, 528, 584, 680, 816, 1088, + 1360, 2044, 2336, 2728, 3272, 4092, 5456, 8188 }; +#else +static const int allocator_sizes [] = { + 8, 16, 24, 32, 40, 48, 64, 80, + 96, 128, 160, 192, 224, 248, 320, 328, + 384, 448, 528, 584, 680, 816, 1016, 1088, + 1360, 2040, 2336, 2728, 3272, 4088, 5456, 8184 }; +#endif #define NUM_ALLOCATORS (sizeof (allocator_sizes) / sizeof (int)) +static int allocator_block_sizes [NUM_ALLOCATORS]; + static MonoLockFreeAllocSizeClass size_classes [NUM_ALLOCATORS]; static MonoLockFreeAllocator allocators [NUM_ALLOCATORS]; +#ifdef HEAVY_STATISTICS +static int allocator_sizes_stats [NUM_ALLOCATORS]; +#endif + +static size_t +block_size (size_t slot_size) +{ + static int pagesize = -1; + + int size; + + if (pagesize == -1) + pagesize = mono_pagesize (); + + for (size = pagesize; size < LOCK_FREE_ALLOC_SB_MAX_SIZE; size <<= 1) { + if (slot_size * 2 <= LOCK_FREE_ALLOC_SB_USABLE_SIZE (size)) + return size; + } + return LOCK_FREE_ALLOC_SB_MAX_SIZE; +} + /* * Find the allocator index for memory chunks that can contain @size * objects. @@ -67,6 +99,7 @@ sgen_register_fixed_internal_mem_type (int type, size_t size) int slot; g_assert (type >= 0 && type < INTERNAL_MEM_MAX); + g_assert (size <= allocator_sizes [NUM_ALLOCATORS - 1]); slot = index_for_size (size); g_assert (slot >= 0); @@ -135,6 +168,10 @@ sgen_alloc_internal_dynamic (size_t size, int type, gboolean assert_on_failure) } else { index = index_for_size (size); +#ifdef HEAVY_STATISTICS + ++ allocator_sizes_stats [index]; +#endif + p = mono_lock_free_alloc (&allocators [index]); if (!p) sgen_assert_memory_alloc (NULL, size, description_for_type (type)); @@ -154,7 +191,7 @@ sgen_free_internal_dynamic (void *addr, size_t size, int type) if (size > allocator_sizes [NUM_ALLOCATORS - 1]) sgen_free_os_memory (addr, size, SGEN_ALLOC_INTERNAL); else - mono_lock_free_free (addr); + mono_lock_free_free (addr, block_size (size)); MONO_GC_INTERNAL_DEALLOC ((mword)addr, size, type); } @@ -162,10 +199,18 @@ sgen_free_internal_dynamic (void *addr, size_t size, int type) void* sgen_alloc_internal (int type) { - int index = fixed_type_allocator_indexes [type]; - int size = allocator_sizes [index]; + int index, size; void *p; + + index = fixed_type_allocator_indexes [type]; g_assert (index >= 0 && index < NUM_ALLOCATORS); + +#ifdef HEAVY_STATISTICS + ++ allocator_sizes_stats [index]; +#endif + + size = allocator_sizes [index]; + p = mono_lock_free_alloc (&allocators [index]); memset (p, 0, size); @@ -185,7 +230,7 @@ sgen_free_internal (void *addr, int type) index = fixed_type_allocator_indexes [type]; g_assert (index >= 0 && index < NUM_ALLOCATORS); - mono_lock_free_free (addr); + mono_lock_free_free (addr, allocator_block_sizes [index]); if (MONO_GC_INTERNAL_DEALLOC_ENABLED ()) { int size G_GNUC_UNUSED = allocator_sizes [index]; @@ -211,22 +256,37 @@ sgen_dump_internal_mem_usage (FILE *heap_dump_file) void sgen_report_internal_mem_usage (void) { - /* FIXME: implement */ - printf ("not implemented yet\n"); + int i G_GNUC_UNUSED; +#ifdef HEAVY_STATISTICS + printf ("size -> # allocations\n"); + for (i = 0; i < NUM_ALLOCATORS; ++i) + printf ("%d -> %d\n", allocator_sizes [i], allocator_sizes_stats [i]); +#endif } void sgen_init_internal_allocator (void) { - int i; + int i, size; for (i = 0; i < INTERNAL_MEM_MAX; ++i) fixed_type_allocator_indexes [i] = -1; for (i = 0; i < NUM_ALLOCATORS; ++i) { - mono_lock_free_allocator_init_size_class (&size_classes [i], allocator_sizes [i]); + allocator_block_sizes [i] = block_size (allocator_sizes [i]); + mono_lock_free_allocator_init_size_class (&size_classes [i], allocator_sizes [i], allocator_block_sizes [i]); mono_lock_free_allocator_init_allocator (&allocators [i], &size_classes [i]); } + + for (size = mono_pagesize (); size <= LOCK_FREE_ALLOC_SB_MAX_SIZE; size <<= 1) { + int max_size = LOCK_FREE_ALLOC_SB_USABLE_SIZE (size) / 2; + /* + * we assert that allocator_sizes contains the biggest possible object size + * per block (4K => 4080 / 2 = 2040, 8k => 8176 / 2 = 4088, 16k => 16368 / 2 = 8184 on 64bits), + * so that we do not get different block sizes for sizes that should go to the same one + */ + g_assert (allocator_sizes [index_for_size (max_size)] == max_size); + } } #endif diff --git a/mono/metadata/sgen-los.c b/mono/metadata/sgen-los.c index 1e38006cac..dc104a0a8c 100644 --- a/mono/metadata/sgen-los.c +++ b/mono/metadata/sgen-los.c @@ -38,6 +38,7 @@ #include "metadata/sgen-cardtable.h" #include "metadata/sgen-memory-governor.h" #include "utils/mono-mmap.h" +#include "utils/mono-compiler.h" #define LOS_SECTION_SIZE (1024 * 1024) @@ -336,13 +337,13 @@ sgen_los_alloc_large_inner (MonoVTable *vtable, size_t size) g_assert ((size & 1) == 0); /* - * size + sizeof (LOSObject) <= SIZE_MAX - (mono_pagesize () - 1) + * size + sizeof (LOSObject) <= SSIZE_MAX - (mono_pagesize () - 1) * * therefore: * - * size <= SIZE_MAX - (mono_pagesize () - 1) - sizeof (LOSObject) + * size <= SSIZE_MAX - (mono_pagesize () - 1) - sizeof (LOSObject) */ - if (size > SIZE_MAX - (mono_pagesize () - 1) - sizeof (LOSObject)) + if (size > SSIZE_MAX - (mono_pagesize () - 1) - sizeof (LOSObject)) return NULL; #ifdef LOS_DUMMY diff --git a/mono/metadata/sgen-major-scan-object.h b/mono/metadata/sgen-major-scan-object.h index a4674a2139..14b1131709 100644 --- a/mono/metadata/sgen-major-scan-object.h +++ b/mono/metadata/sgen-major-scan-object.h @@ -37,12 +37,23 @@ extern long long stat_scan_object_called_major; #define CONCURRENT_NAME(x) x #endif +/* + * FIXME: We use the same scanning function in the concurrent collector whether we scan + * during the starting/finishing collection pause (with the world stopped) or from the + * concurrent worker thread. + * + * As long as the world is stopped, we should just follow pointers into the nursery and + * evict if possible. In that case we also don't need the ALWAYS_ADD_TO_GLOBAL_REMSET case, + * which only seems to make sense for when the world is stopped, in which case we only need + * it because we don't follow into the nursery. + */ + #undef HANDLE_PTR #define HANDLE_PTR(ptr,obj) do { \ void *__old = *(ptr); \ - void *__copy; \ SGEN_OBJECT_LAYOUT_STATISTICS_MARK_BITMAP ((obj), (ptr)); \ if (__old && FOLLOW_OBJECT (__old)) { \ + void *__copy; \ PREFETCH_DYNAMIC_HEAP (__old); \ CONCURRENT_NAME (major_copy_or_mark_object) ((ptr), __old, queue); \ __copy = *(ptr); \ @@ -56,10 +67,14 @@ extern long long stat_scan_object_called_major; } while (0) static void -CONCURRENT_NAME (major_scan_object) (char *start, SgenGrayQueue *queue) +CONCURRENT_NAME (major_scan_object) (char *start, mword desc, SgenGrayQueue *queue) { SGEN_OBJECT_LAYOUT_STATISTICS_DECLARE_BITMAP; +#ifdef HEAVY_STATISTICS + sgen_descriptor_count_scanned_object (desc); +#endif + #define SCAN_OBJECT_PROTOCOL #include "sgen-scan-object.h" diff --git a/mono/metadata/sgen-marksweep-fixed-par.c b/mono/metadata/sgen-marksweep-fixed-par.c deleted file mode 100644 index 7c03e5b172..0000000000 --- a/mono/metadata/sgen-marksweep-fixed-par.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "config.h" - -#ifdef HAVE_SGEN_GC - -#ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_FIXED_PAR - -#define SGEN_PARALLEL_MARK -#define FIXED_HEAP - -#include "sgen-marksweep.c" - -#else - -#include "metadata/sgen-gc.h" - -void -sgen_marksweep_fixed_par_init (SgenMajorCollector *collector) -{ - fprintf (stderr, "Error: Mono was configured using --enable-minimal=sgen_marksweep_fixed_par.\n"); - exit (1); -} - -#endif - -#endif diff --git a/mono/metadata/sgen-marksweep-fixed.c b/mono/metadata/sgen-marksweep-fixed.c deleted file mode 100644 index 3d08895bce..0000000000 --- a/mono/metadata/sgen-marksweep-fixed.c +++ /dev/null @@ -1,24 +0,0 @@ -#include "config.h" - -#ifdef HAVE_SGEN_GC - -#ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_FIXED - -#define FIXED_HEAP - -#include "sgen-marksweep.c" - -#else - -#include "metadata/sgen-gc.h" - -void -sgen_marksweep_fixed_init (SgenMajorCollector *collector) -{ - fprintf (stderr, "Error: Mono was configured using --enable-minimal=sgen_marksweep_fixed.\n"); - exit (1); -} - -#endif - -#endif diff --git a/mono/metadata/sgen-marksweep-par.c b/mono/metadata/sgen-marksweep-par.c deleted file mode 100644 index 5bc7805c87..0000000000 --- a/mono/metadata/sgen-marksweep-par.c +++ /dev/null @@ -1,24 +0,0 @@ -#include "config.h" - -#ifdef HAVE_SGEN_GC - -#ifndef DISABLE_SGEN_MAJOR_MARKSWEEP_PAR - -#define SGEN_PARALLEL_MARK - -#include "sgen-marksweep.c" - -#else - -#include "metadata/sgen-gc.h" - -void -sgen_marksweep_par_init (SgenMajorCollector *collector) -{ - fprintf (stderr, "Error: Mono was configured using --enable-minimal=sgen_marksweep_par.\n"); - exit (1); -} - -#endif /* DISABLE_SGEN_MAJOR_MARKSWEEP_PAR */ - -#endif diff --git a/mono/metadata/sgen-marksweep.c b/mono/metadata/sgen-marksweep.c index d309338580..8980687134 100644 --- a/mono/metadata/sgen-marksweep.c +++ b/mono/metadata/sgen-marksweep.c @@ -40,20 +40,15 @@ #include "metadata/sgen-memory-governor.h" #include "metadata/sgen-layout-stats.h" #include "metadata/gc-internal.h" +#include "metadata/sgen-pointer-queue.h" -#if !defined(SGEN_PARALLEL_MARK) && !defined(FIXED_HEAP) #define SGEN_HAVE_CONCURRENT_MARK -#endif #define MS_BLOCK_SIZE (16*1024) #define MS_BLOCK_SIZE_SHIFT 14 #define MAJOR_SECTION_SIZE MS_BLOCK_SIZE #define CARDS_PER_BLOCK (MS_BLOCK_SIZE / CARD_SIZE_IN_BYTES) -#ifdef FIXED_HEAP -#define MS_DEFAULT_HEAP_NUM_BLOCKS (32 * 1024) /* 512 MB */ -#endif - /* * Don't allocate single blocks, but alloc a contingent of this many * blocks in one swoop. This must be a power of two. @@ -65,11 +60,7 @@ * of a block is the MSBlockHeader, then opional padding, then come * the objects, so this must be >= sizeof (MSBlockHeader). */ -#ifdef FIXED_HEAP -#define MS_BLOCK_SKIP 0 -#else #define MS_BLOCK_SKIP 16 -#endif #define MS_BLOCK_FREE (MS_BLOCK_SIZE - MS_BLOCK_SKIP) @@ -89,11 +80,6 @@ struct _MSBlockInfo { unsigned int has_pinned : 1; /* means cannot evacuate */ unsigned int is_to_space : 1; unsigned int swept : 1; -#ifdef FIXED_HEAP - unsigned int used : 1; - unsigned int zeroed : 1; -#endif - MSBlockInfo *next; char *block; void **free_list; MSBlockInfo *next_free; @@ -104,34 +90,20 @@ struct _MSBlockInfo { mword mark_words [MS_NUM_MARK_WORDS]; }; -#ifdef FIXED_HEAP -static mword ms_heap_num_blocks = MS_DEFAULT_HEAP_NUM_BLOCKS; +#define MS_BLOCK_FOR_BLOCK_INFO(b) ((b)->block) -static char *ms_heap_start; -static char *ms_heap_end; - -#define MS_PTR_IN_SMALL_MAJOR_HEAP(p) ((char*)(p) >= ms_heap_start && (char*)(p) < ms_heap_end) - -/* array of all all block infos in the system */ -static MSBlockInfo *block_infos; -#endif - -#define MS_BLOCK_OBJ(b,i) ((b)->block + MS_BLOCK_SKIP + (b)->obj_size * (i)) -#define MS_BLOCK_OBJ_FOR_SIZE(b,i,obj_size) ((b)->block + MS_BLOCK_SKIP + (obj_size) * (i)) +#define MS_BLOCK_OBJ(b,i) (MS_BLOCK_FOR_BLOCK_INFO(b) + MS_BLOCK_SKIP + (b)->obj_size * (i)) +#define MS_BLOCK_OBJ_FOR_SIZE(b,i,obj_size) (MS_BLOCK_FOR_BLOCK_INFO(b) + MS_BLOCK_SKIP + (obj_size) * (i)) #define MS_BLOCK_DATA_FOR_OBJ(o) ((char*)((mword)(o) & ~(mword)(MS_BLOCK_SIZE - 1))) -#ifdef FIXED_HEAP -#define MS_BLOCK_FOR_OBJ(o) (&block_infos [(mword)((char*)(o) - ms_heap_start) >> MS_BLOCK_SIZE_SHIFT]) -#else typedef struct { MSBlockInfo *info; } MSBlockHeader; #define MS_BLOCK_FOR_OBJ(o) (((MSBlockHeader*)MS_BLOCK_DATA_FOR_OBJ ((o)))->info) -#endif /* object index will always be small */ -#define MS_BLOCK_OBJ_INDEX(o,b) ((int)(((char*)(o) - ((b)->block + MS_BLOCK_SKIP)) / (b)->obj_size)) +#define MS_BLOCK_OBJ_INDEX(o,b) ((int)(((char*)(o) - (MS_BLOCK_FOR_BLOCK_INFO(b) + MS_BLOCK_SKIP)) / (b)->obj_size)) //casting to int is fine since blocks are 32k #define MS_CALC_MARK_BIT(w,b,o) do { \ @@ -163,7 +135,7 @@ typedef struct { } \ } while (1) -#define MS_OBJ_ALLOCED(o,b) (*(void**)(o) && (*(char**)(o) < (b)->block || *(char**)(o) >= (b)->block + MS_BLOCK_SIZE)) +#define MS_OBJ_ALLOCED(o,b) (*(void**)(o) && (*(char**)(o) < MS_BLOCK_FOR_BLOCK_INFO (b) || *(char**)(o) >= MS_BLOCK_FOR_BLOCK_INFO (b) + MS_BLOCK_SIZE)) #define MS_BLOCK_OBJ_SIZE_FACTOR (sqrt (2.0)) @@ -182,12 +154,6 @@ static int fast_block_obj_size_indexes [MS_NUM_FAST_BLOCK_OBJ_SIZE_INDEXES]; #define MS_BLOCK_TYPE_MAX 4 -#ifdef SGEN_PARALLEL_MARK -static LOCK_DECLARE (ms_block_list_mutex); -#define LOCK_MS_BLOCK_LIST mono_mutex_lock (&ms_block_list_mutex) -#define UNLOCK_MS_BLOCK_LIST mono_mutex_unlock (&ms_block_list_mutex) -#endif - static gboolean *evacuate_block_obj_sizes; static float evacuation_threshold = 0.666f; #ifdef SGEN_HAVE_CONCURRENT_MARK @@ -202,33 +168,28 @@ static gboolean have_swept; static gboolean concurrent_mark; #endif -/* all allocated blocks in the system */ -static MSBlockInfo *all_blocks; +#define BLOCK_IS_TAGGED_HAS_REFERENCES(bl) SGEN_POINTER_IS_TAGGED_1 ((bl)) +#define BLOCK_TAG_HAS_REFERENCES(bl) SGEN_POINTER_TAG_1 ((bl)) +#define BLOCK_UNTAG_HAS_REFERENCES(bl) SGEN_POINTER_UNTAG_1 ((bl)) + +#define BLOCK_TAG(bl) ((bl)->has_references ? BLOCK_TAG_HAS_REFERENCES ((bl)) : (bl)) + +/* all allocated blocks in the system */ +static SgenPointerQueue allocated_blocks; -#ifdef FIXED_HEAP -/* non-allocated block free-list */ -static MSBlockInfo *empty_blocks = NULL; -#else /* non-allocated block free-list */ static void *empty_blocks = NULL; static size_t num_empty_blocks = 0; -#endif -#define FOREACH_BLOCK(bl) for ((bl) = all_blocks; (bl); (bl) = (bl)->next) { -#define END_FOREACH_BLOCK } +#define FOREACH_BLOCK(bl) { size_t __index; for (__index = 0; __index < allocated_blocks.next_slot; ++__index) { (bl) = BLOCK_UNTAG_HAS_REFERENCES (allocated_blocks.data [__index]); +#define FOREACH_BLOCK_HAS_REFERENCES(bl,hr) { size_t __index; for (__index = 0; __index < allocated_blocks.next_slot; ++__index) { (bl) = allocated_blocks.data [__index]; (hr) = BLOCK_IS_TAGGED_HAS_REFERENCES ((bl)); (bl) = BLOCK_UNTAG_HAS_REFERENCES ((bl)); +#define END_FOREACH_BLOCK } } +#define DELETE_BLOCK_IN_FOREACH() (allocated_blocks.data [__index] = NULL) static size_t num_major_sections = 0; /* one free block list for each block object size */ static MSBlockInfo **free_block_lists [MS_BLOCK_TYPE_MAX]; -#ifdef SGEN_PARALLEL_MARK -#ifdef HAVE_KW_THREAD -static __thread MSBlockInfo ***workers_free_block_lists; -#else -static MonoNativeTlsKey workers_free_block_lists_key; -#endif -#endif - static long long stat_major_blocks_alloced = 0; static long long stat_major_blocks_freed = 0; static long long stat_major_blocks_lazy_swept = 0; @@ -264,55 +225,12 @@ ms_find_block_obj_size_index (size_t size) #define FREE_BLOCKS_FROM(lists,p,r) (lists [((p) ? MS_BLOCK_FLAG_PINNED : 0) | ((r) ? MS_BLOCK_FLAG_REFS : 0)]) #define FREE_BLOCKS(p,r) (FREE_BLOCKS_FROM (free_block_lists, (p), (r))) -#ifdef SGEN_PARALLEL_MARK -#ifdef HAVE_KW_THREAD -#define FREE_BLOCKS_LOCAL(p,r) (FREE_BLOCKS_FROM (workers_free_block_lists, (p), (r))) -#else -#define FREE_BLOCKS_LOCAL(p,r) (FREE_BLOCKS_FROM (((MSBlockInfo***)(mono_native_tls_get_value (workers_free_block_lists_key))), (p), (r))) -#endif -#else -//#define FREE_BLOCKS_LOCAL(p,r) (FREE_BLOCKS_FROM (free_block_lists, (p), (r))) -#endif #define MS_BLOCK_OBJ_SIZE_INDEX(s) \ (((s)+7)>>3 < MS_NUM_FAST_BLOCK_OBJ_SIZE_INDEXES ? \ fast_block_obj_size_indexes [((s)+7)>>3] : \ ms_find_block_obj_size_index ((s))) -#ifdef FIXED_HEAP -static void* -major_alloc_heap (mword nursery_size, mword nursery_align, int the_nursery_bits) -{ - char *nursery_start; - mword major_heap_size = ms_heap_num_blocks * MS_BLOCK_SIZE; - mword alloc_size = nursery_size + major_heap_size; - mword i; - - g_assert (ms_heap_num_blocks > 0); - g_assert (nursery_size % MS_BLOCK_SIZE == 0); - if (nursery_align) - g_assert (nursery_align % MS_BLOCK_SIZE == 0); - - nursery_start = sgen_alloc_os_memory_aligned (alloc_size, nursery_align ? nursery_align : MS_BLOCK_SIZE, SGEN_ALLOC_HEAP | SGEN_ALLOC_ACTIVATE, "heap"); - ms_heap_start = nursery_start + nursery_size; - ms_heap_end = ms_heap_start + major_heap_size; - - block_infos = sgen_alloc_internal_dynamic (sizeof (MSBlockInfo) * ms_heap_num_blocks, INTERNAL_MEM_MS_BLOCK_INFO, TRUE); - - for (i = 0; i < ms_heap_num_blocks; ++i) { - block_infos [i].block = ms_heap_start + i * MS_BLOCK_SIZE; - if (i < ms_heap_num_blocks - 1) - block_infos [i].next_free = &block_infos [i + 1]; - else - block_infos [i].next_free = NULL; - block_infos [i].zeroed = TRUE; - } - - empty_blocks = &block_infos [0]; - - return nursery_start; -} -#else static void* major_alloc_heap (mword nursery_size, mword nursery_align, int the_nursery_bits) { @@ -324,44 +242,13 @@ major_alloc_heap (mword nursery_size, mword nursery_align, int the_nursery_bits) return start; } -#endif static void update_heap_boundaries_for_block (MSBlockInfo *block) { - sgen_update_heap_boundaries ((mword)block->block, (mword)block->block + MS_BLOCK_SIZE); + sgen_update_heap_boundaries ((mword)MS_BLOCK_FOR_BLOCK_INFO (block), (mword)MS_BLOCK_FOR_BLOCK_INFO (block) + MS_BLOCK_SIZE); } -#ifdef FIXED_HEAP -static MSBlockInfo* -ms_get_empty_block (void) -{ - MSBlockInfo *block; - - g_assert (empty_blocks); - - do { - block = empty_blocks; - } while (SGEN_CAS_PTR ((gpointer*)&empty_blocks, block->next_free, block) != block); - - block->used = TRUE; - - if (!block->zeroed) - memset (block->block, 0, MS_BLOCK_SIZE); - - return block; -} - -static void -ms_free_block (MSBlockInfo *block) -{ - block->next_free = empty_blocks; - empty_blocks = block; - block->used = FALSE; - block->zeroed = FALSE; - sgen_memgov_release_space (MS_BLOCK_SIZE, SPACE_MAJOR); -} -#else static void* ms_get_empty_block (void) { @@ -440,7 +327,6 @@ ms_free_block (void *block) SGEN_ATOMIC_ADD_P (num_empty_blocks, 1); } -#endif //#define MARKSWEEP_CONSISTENCY_CHECK @@ -459,30 +345,19 @@ check_block_free_list (MSBlockInfo *block, int size, gboolean pinned) if (block->swept) g_assert (block->free_list); -#ifdef FIXED_HEAP - /* the block must not be in the empty_blocks list */ - for (b = empty_blocks; b; b = b->next_free) - g_assert (b != block); -#endif - /* the block must be in the all_blocks list */ - for (b = all_blocks; b; b = b->next) { - if (b == block) - break; - } - g_assert (b == block); + /* the block must be in the allocated_blocks array */ + g_assert (sgen_pointer_queue_find (&allocated_blocks, BLOCK_TAG (block)) != (size_t)-1); } } static void check_empty_blocks (void) { -#ifndef FIXED_HEAP void *p; size_t i = 0; for (p = empty_blocks; p; p = *(void**)p) ++i; g_assert (i == num_empty_blocks); -#endif } static void @@ -497,10 +372,8 @@ consistency_check (void) int num_free = 0; void **free; -#ifndef FIXED_HEAP /* check block header */ g_assert (((MSBlockHeader*)block->block)->info == block); -#endif /* count number of free slots */ for (i = 0; i < count; ++i) { @@ -540,12 +413,7 @@ ms_alloc_block (int size_index, gboolean pinned, gboolean has_references) int size = block_obj_sizes [size_index]; int count = MS_BLOCK_FREE / size; MSBlockInfo *info; -#ifdef SGEN_PARALLEL_MARK - MSBlockInfo *next; -#endif -#ifndef FIXED_HEAP MSBlockHeader *header; -#endif MSBlockInfo **free_blocks = FREE_BLOCKS (pinned, has_references); char *obj_start; int i; @@ -553,11 +421,7 @@ ms_alloc_block (int size_index, gboolean pinned, gboolean has_references) if (!sgen_memgov_try_alloc_space (MS_BLOCK_SIZE, SPACE_MAJOR)) return FALSE; -#ifdef FIXED_HEAP - info = ms_get_empty_block (); -#else info = sgen_alloc_internal (INTERNAL_MEM_MS_BLOCK_INFO); -#endif SGEN_ASSERT (9, count >= 2, "block with %d objects, it must hold at least 2", count); @@ -574,12 +438,10 @@ ms_alloc_block (int size_index, gboolean pinned, gboolean has_references) */ info->is_to_space = (sgen_get_current_collection_generation () == GENERATION_OLD); info->swept = 1; -#ifndef FIXED_HEAP info->block = ms_get_empty_block (); header = (MSBlockHeader*) info->block; header->info = info; -#endif #ifdef SGEN_HAVE_CONCURRENT_MARK info->cardtable_mod_union = NULL; #endif @@ -587,7 +449,7 @@ ms_alloc_block (int size_index, gboolean pinned, gboolean has_references) update_heap_boundaries_for_block (info); /* build free list */ - obj_start = info->block + MS_BLOCK_SKIP; + obj_start = MS_BLOCK_FOR_BLOCK_INFO (info) + MS_BLOCK_SKIP; info->free_list = (void**)obj_start; /* we're skipping the last one - it must be nulled */ for (i = 0; i < count - 1; ++i) { @@ -598,21 +460,10 @@ ms_alloc_block (int size_index, gboolean pinned, gboolean has_references) /* the last one */ *(void**)obj_start = NULL; -#ifdef SGEN_PARALLEL_MARK - do { - next = info->next_free = free_blocks [size_index]; - } while (SGEN_CAS_PTR ((void**)&free_blocks [size_index], info, next) != next); - - do { - next = info->next = all_blocks; - } while (SGEN_CAS_PTR ((void**)&all_blocks, info, next) != next); -#else info->next_free = free_blocks [size_index]; free_blocks [size_index] = info; - info->next = all_blocks; - all_blocks = info; -#endif + sgen_pointer_queue_add (&allocated_blocks, BLOCK_TAG (info)); ++num_major_sections; return TRUE; @@ -624,7 +475,7 @@ obj_is_from_pinned_alloc (char *ptr) MSBlockInfo *block; FOREACH_BLOCK (block) { - if (ptr >= block->block && ptr <= block->block + MS_BLOCK_SIZE) + if (ptr >= MS_BLOCK_FOR_BLOCK_INFO (block) && ptr <= MS_BLOCK_FOR_BLOCK_INFO (block) + MS_BLOCK_SIZE) return block->pinned; } END_FOREACH_BLOCK; return FALSE; @@ -656,86 +507,6 @@ unlink_slot_from_free_list_uncontested (MSBlockInfo **free_blocks, int size_inde return obj; } -#ifdef SGEN_PARALLEL_MARK -static gboolean -try_remove_block_from_free_list (MSBlockInfo *block, MSBlockInfo **free_blocks, int size_index) -{ - /* - * No more free slots in the block, so try to free the block. - * Don't try again if we don't succeed - another thread will - * already have done it. - */ - MSBlockInfo *next_block = block->next_free; - if (SGEN_CAS_PTR ((void**)&free_blocks [size_index], next_block, block) == block) { - /* - void *old = SGEN_CAS_PTR ((void**)&block->next_free, NULL, next_block); - g_assert (old == next_block); - */ - block->next_free = NULL; - return TRUE; - } - return FALSE; -} - -static void* -alloc_obj_par (MonoVTable *vtable, int size, gboolean pinned, gboolean has_references) -{ - int size_index = MS_BLOCK_OBJ_SIZE_INDEX (size); - MSBlockInfo **free_blocks_local = FREE_BLOCKS_LOCAL (pinned, has_references); - MSBlockInfo *block; - void *obj; - -#ifdef SGEN_HAVE_CONCURRENT_MARK - if (concurrent_mark) - g_assert_not_reached (); -#endif - - SGEN_ASSERT (9, current_collection_generation == GENERATION_OLD, "old gen parallel allocator called from a %d collection", current_collection_generation); - - if (free_blocks_local [size_index]) { - get_slot: - obj = unlink_slot_from_free_list_uncontested (free_blocks_local, size_index); - } else { - MSBlockInfo **free_blocks = FREE_BLOCKS (pinned, has_references); - - get_block: - block = free_blocks [size_index]; - if (block) { - if (!try_remove_block_from_free_list (block, free_blocks, size_index)) - goto get_block; - - g_assert (block->next_free == NULL); - g_assert (block->free_list); - block->next_free = free_blocks_local [size_index]; - free_blocks_local [size_index] = block; - - goto get_slot; - } else { - gboolean success; - - LOCK_MS_BLOCK_LIST; - success = ms_alloc_block (size_index, pinned, has_references); - UNLOCK_MS_BLOCK_LIST; - - if (G_UNLIKELY (!success)) - return NULL; - - goto get_block; - } - } - - *(MonoVTable**)obj = vtable; - - return obj; -} - -static void* -major_par_alloc_object (MonoVTable *vtable, size_t size, gboolean has_references) -{ - return alloc_obj_par (vtable, size, FALSE, has_references); -} -#endif - static void* alloc_obj (MonoVTable *vtable, size_t size, gboolean pinned, gboolean has_references) { @@ -743,11 +514,6 @@ alloc_obj (MonoVTable *vtable, size_t size, gboolean pinned, gboolean has_refere MSBlockInfo **free_blocks = FREE_BLOCKS (pinned, has_references); void *obj; -#ifdef SGEN_PARALLEL_MARK - SGEN_ASSERT (9, current_collection_generation == GENERATION_OLD, "old gen parallel allocator called from a %d collection", current_collection_generation); - -#endif - if (!free_blocks [size_index]) { if (G_UNLIKELY (!ms_alloc_block (size_index, pinned, has_references))) return NULL; @@ -859,24 +625,16 @@ major_is_object_live (char *obj) { MSBlockInfo *block; int word, bit; -#ifndef FIXED_HEAP mword objsize; -#endif if (sgen_ptr_in_nursery (obj)) return FALSE; -#ifdef FIXED_HEAP - /* LOS */ - if (!MS_PTR_IN_SMALL_MAJOR_HEAP (obj)) - return FALSE; -#else objsize = SGEN_ALIGN_UP (sgen_safe_object_get_size ((MonoObject*)obj)); /* LOS */ if (objsize > SGEN_MAX_SMALL_OBJ_SIZE) return FALSE; -#endif /* now we know it's in a major block */ block = MS_BLOCK_FOR_OBJ (obj); @@ -891,7 +649,7 @@ major_ptr_is_in_non_pinned_space (char *ptr, char **start) MSBlockInfo *block; FOREACH_BLOCK (block) { - if (ptr >= block->block && ptr <= block->block + MS_BLOCK_SIZE) { + if (ptr >= MS_BLOCK_FOR_BLOCK_INFO (block) && ptr <= MS_BLOCK_FOR_BLOCK_INFO (block) + MS_BLOCK_SIZE) { int count = MS_BLOCK_FREE / block->obj_size; int i; @@ -952,7 +710,7 @@ major_is_valid_object (char *object) int idx; char *obj; - if ((block->block > object) || ((block->block + MS_BLOCK_SIZE) <= object)) + if ((MS_BLOCK_FOR_BLOCK_INFO (block) > object) || ((MS_BLOCK_FOR_BLOCK_INFO (block) + MS_BLOCK_SIZE) <= object)) continue; idx = MS_BLOCK_OBJ_INDEX (object, block); @@ -979,11 +737,11 @@ major_describe_pointer (char *ptr) int w, b; gboolean marked; - if ((block->block > ptr) || ((block->block + MS_BLOCK_SIZE) <= ptr)) + if ((MS_BLOCK_FOR_BLOCK_INFO (block) > ptr) || ((MS_BLOCK_FOR_BLOCK_INFO (block) + MS_BLOCK_SIZE) <= ptr)) continue; SGEN_LOG (0, "major-ptr (block %p sz %d pin %d ref %d)\n", - block->block, block->obj_size, block->pinned, block->has_references); + MS_BLOCK_FOR_BLOCK_INFO (block), block->obj_size, block->pinned, block->has_references); idx = MS_BLOCK_OBJ_INDEX (ptr, block); obj = (char*)MS_BLOCK_OBJ (block, idx); @@ -1061,7 +819,7 @@ major_dump_heap (FILE *heap_dump_file) start = i; } else { if (start >= 0) { - sgen_dump_occupied (MS_BLOCK_OBJ (block, start), MS_BLOCK_OBJ (block, i), block->block); + sgen_dump_occupied (MS_BLOCK_OBJ (block, start), MS_BLOCK_OBJ (block, i), MS_BLOCK_FOR_BLOCK_INFO (block)); start = -1; } } @@ -1073,30 +831,30 @@ major_dump_heap (FILE *heap_dump_file) #define LOAD_VTABLE SGEN_LOAD_VTABLE -#define MS_MARK_OBJECT_AND_ENQUEUE_CHECKED(obj,block,queue) do { \ +#define MS_MARK_OBJECT_AND_ENQUEUE_CHECKED(obj,desc,block,queue) do { \ int __word, __bit; \ MS_CALC_MARK_BIT (__word, __bit, (obj)); \ if (!MS_MARK_BIT ((block), __word, __bit) && MS_OBJ_ALLOCED ((obj), (block))) { \ MS_SET_MARK_BIT ((block), __word, __bit); \ if ((block)->has_references) \ - GRAY_OBJECT_ENQUEUE ((queue), (obj)); \ + GRAY_OBJECT_ENQUEUE ((queue), (obj), (desc)); \ binary_protocol_mark ((obj), (gpointer)LOAD_VTABLE ((obj)), sgen_safe_object_get_size ((MonoObject*)(obj))); \ INC_NUM_MAJOR_OBJECTS_MARKED (); \ } \ } while (0) -#define MS_MARK_OBJECT_AND_ENQUEUE(obj,block,queue) do { \ +#define MS_MARK_OBJECT_AND_ENQUEUE(obj,desc,block,queue) do { \ int __word, __bit; \ MS_CALC_MARK_BIT (__word, __bit, (obj)); \ SGEN_ASSERT (9, MS_OBJ_ALLOCED ((obj), (block)), "object %p not allocated", obj); \ if (!MS_MARK_BIT ((block), __word, __bit)) { \ MS_SET_MARK_BIT ((block), __word, __bit); \ if ((block)->has_references) \ - GRAY_OBJECT_ENQUEUE ((queue), (obj)); \ + GRAY_OBJECT_ENQUEUE ((queue), (obj), (desc)); \ binary_protocol_mark ((obj), (gpointer)LOAD_VTABLE ((obj)), sgen_safe_object_get_size ((MonoObject*)(obj))); \ INC_NUM_MAJOR_OBJECTS_MARKED (); \ } \ } while (0) -#define MS_PAR_MARK_OBJECT_AND_ENQUEUE(obj,block,queue) do { \ +#define MS_PAR_MARK_OBJECT_AND_ENQUEUE(obj,desc,block,queue) do { \ int __word, __bit; \ gboolean __was_marked; \ SGEN_ASSERT (9, MS_OBJ_ALLOCED ((obj), (block)), "object %p not allocated", obj); \ @@ -1104,7 +862,7 @@ major_dump_heap (FILE *heap_dump_file) MS_PAR_SET_MARK_BIT (__was_marked, (block), __word, __bit); \ if (!__was_marked) { \ if ((block)->has_references) \ - GRAY_OBJECT_ENQUEUE ((queue), (obj)); \ + GRAY_OBJECT_ENQUEUE ((queue), (obj), (desc)); \ binary_protocol_mark ((obj), (gpointer)LOAD_VTABLE ((obj)), sgen_safe_object_get_size ((MonoObject*)(obj))); \ INC_NUM_MAJOR_OBJECTS_MARKED (); \ } \ @@ -1122,170 +880,11 @@ pin_major_object (char *obj, SgenGrayQueue *queue) block = MS_BLOCK_FOR_OBJ (obj); block->has_pinned = TRUE; - MS_MARK_OBJECT_AND_ENQUEUE (obj, block, queue); + MS_MARK_OBJECT_AND_ENQUEUE (obj, sgen_obj_get_descriptor (obj), block, queue); } #include "sgen-major-copy-object.h" -#ifdef SGEN_PARALLEL_MARK -static void -major_copy_or_mark_object (void **ptr, void *obj, SgenGrayQueue *queue) -{ - mword objsize; - MSBlockInfo *block; - MonoVTable *vt; - - HEAVY_STAT (++stat_copy_object_called_major); - - SGEN_ASSERT (9, obj, "null object from pointer %p", ptr); - SGEN_ASSERT (9, current_collection_generation == GENERATION_OLD, "old gen parallel allocator called from a %d collection", current_collection_generation); - - if (sgen_ptr_in_nursery (obj)) { - int word, bit; - gboolean has_references; - void *destination; - mword vtable_word = *(mword*)obj; - vt = (MonoVTable*)(vtable_word & ~SGEN_VTABLE_BITS_MASK); - - if (vtable_word & SGEN_FORWARDED_BIT) { - *ptr = (void*)vt; - return; - } - - if (vtable_word & SGEN_PINNED_BIT) - return; - - /* An object in the nursery To Space has already been copied and grayed. Nothing to do. */ - if (sgen_nursery_is_to_space (obj)) - return; - - HEAVY_STAT (++stat_objects_copied_major); - - do_copy_object: - objsize = SGEN_ALIGN_UP (sgen_par_object_get_size (vt, (MonoObject*)obj)); - has_references = SGEN_VTABLE_HAS_REFERENCES (vt); - - destination = sgen_minor_collector.par_alloc_for_promotion (vt, obj, objsize, has_references); - if (G_UNLIKELY (!destination)) { - if (!sgen_ptr_in_nursery (obj)) { - int size_index; - block = MS_BLOCK_FOR_OBJ (obj); - size_index = block->obj_size_index; - evacuate_block_obj_sizes [size_index] = FALSE; - } - - sgen_parallel_pin_or_update (ptr, obj, vt, queue); - sgen_set_pinned_from_failed_allocation (objsize); - return; - } - - if (SGEN_CAS_PTR (obj, (void*)((mword)destination | SGEN_FORWARDED_BIT), vt) == vt) { - gboolean was_marked; - - par_copy_object_no_checks (destination, vt, obj, objsize, has_references ? queue : NULL); - obj = destination; - *ptr = obj; - - /* - * FIXME: If we make major_alloc_object() give - * us the block info, too, we won't have to - * re-fetch it here. - * - * FIXME (2): We should rework this to avoid all those nursery checks. - */ - /* - * For the split nursery allocator the object - * might still be in the nursery despite - * having being promoted, in which case we - * can't mark it. - */ - if (!sgen_ptr_in_nursery (obj)) { - block = MS_BLOCK_FOR_OBJ (obj); - MS_CALC_MARK_BIT (word, bit, obj); - SGEN_ASSERT (9, !MS_MARK_BIT (block, word, bit), "object %p already marked", obj); - MS_PAR_SET_MARK_BIT (was_marked, block, word, bit); - binary_protocol_mark (obj, vt, sgen_safe_object_get_size ((MonoObject*)obj)); - } - } else { - /* - * FIXME: We have allocated destination, but - * we cannot use it. Give it back to the - * allocator. - */ - *(void**)destination = NULL; - - vtable_word = *(mword*)obj; - g_assert (vtable_word & SGEN_FORWARDED_BIT); - - obj = (void*)(vtable_word & ~SGEN_VTABLE_BITS_MASK); - - *ptr = obj; - - HEAVY_STAT (++stat_slots_allocated_in_vain); - } - } else { -#ifdef FIXED_HEAP - if (MS_PTR_IN_SMALL_MAJOR_HEAP (obj)) -#else - mword vtable_word = *(mword*)obj; - vt = (MonoVTable*)(vtable_word & ~SGEN_VTABLE_BITS_MASK); - - /* see comment in the non-parallel version below */ - if (vtable_word & SGEN_FORWARDED_BIT) { - *ptr = (void*)vt; - return; - } - objsize = SGEN_ALIGN_UP (sgen_par_object_get_size (vt, (MonoObject*)obj)); - - if (objsize <= SGEN_MAX_SMALL_OBJ_SIZE) -#endif - { - int size_index; - - block = MS_BLOCK_FOR_OBJ (obj); - size_index = block->obj_size_index; - - if (!block->has_pinned && evacuate_block_obj_sizes [size_index]) { - if (block->is_to_space) - return; - -#ifdef FIXED_HEAP - { - mword vtable_word = *(mword*)obj; - vt = (MonoVTable*)(vtable_word & ~SGEN_VTABLE_BITS_MASK); - - if (vtable_word & SGEN_FORWARDED_BIT) { - *ptr = (void*)vt; - return; - } - } -#endif - - HEAVY_STAT (++stat_major_objects_evacuated); - goto do_copy_object; - } - - MS_PAR_MARK_OBJECT_AND_ENQUEUE (obj, block, queue); - } else { - LOSObject *bigobj = sgen_los_header_for_object (obj); - mword size_word = bigobj->size; -#ifdef FIXED_HEAP - mword vtable_word = *(mword*)obj; - vt = (MonoVTable*)(vtable_word & ~SGEN_VTABLE_BITS_MASK); -#endif - if (size_word & 1) - return; - binary_protocol_pin (obj, vt, sgen_safe_object_get_size ((MonoObject*)obj)); - if (SGEN_CAS_PTR ((void*)&bigobj->size, (void*)(size_word | 1), (void*)size_word) == (void*)size_word) { - if (SGEN_VTABLE_HAS_REFERENCES (vt)) - GRAY_OBJECT_ENQUEUE (queue, obj); - } else { - g_assert (sgen_los_object_is_pinned (obj)); - } - } - } -} -#else #ifdef SGEN_HAVE_CONCURRENT_MARK static void major_copy_or_mark_object_concurrent (void **ptr, void *obj, SgenGrayQueue *queue) @@ -1293,18 +892,13 @@ major_copy_or_mark_object_concurrent (void **ptr, void *obj, SgenGrayQueue *queu g_assert (!SGEN_OBJECT_IS_FORWARDED (obj)); if (!sgen_ptr_in_nursery (obj)) { -#ifdef FIXED_HEAP - if (MS_PTR_IN_SMALL_MAJOR_HEAP (obj)) -#else mword objsize; objsize = SGEN_ALIGN_UP (sgen_safe_object_get_size ((MonoObject*)obj)); - if (objsize <= SGEN_MAX_SMALL_OBJ_SIZE) -#endif - { + if (objsize <= SGEN_MAX_SMALL_OBJ_SIZE) { MSBlockInfo *block = MS_BLOCK_FOR_OBJ (obj); - MS_MARK_OBJECT_AND_ENQUEUE (obj, block, queue); + MS_MARK_OBJECT_AND_ENQUEUE (obj, sgen_obj_get_descriptor (obj), block, queue); } else { if (sgen_los_object_is_pinned (obj)) return; @@ -1318,7 +912,7 @@ major_copy_or_mark_object_concurrent (void **ptr, void *obj, SgenGrayQueue *queu sgen_los_pin_object (obj); if (SGEN_OBJECT_HAS_REFERENCES (obj)) - GRAY_OBJECT_ENQUEUE (queue, obj); + GRAY_OBJECT_ENQUEUE (queue, obj, sgen_obj_get_descriptor (obj)); INC_NUM_MAJOR_OBJECTS_MARKED (); } } @@ -1362,7 +956,7 @@ major_copy_or_mark_object (void **ptr, void *obj, SgenGrayQueue *queue) block = MS_BLOCK_FOR_OBJ (obj); size_index = block->obj_size_index; evacuate_block_obj_sizes [size_index] = FALSE; - MS_MARK_OBJECT_AND_ENQUEUE (obj, block, queue); + MS_MARK_OBJECT_AND_ENQUEUE (obj, sgen_obj_get_descriptor (obj), block, queue); } return; } @@ -1390,9 +984,6 @@ major_copy_or_mark_object (void **ptr, void *obj, SgenGrayQueue *queue) } } else { char *forwarded; -#ifdef FIXED_HEAP - if (MS_PTR_IN_SMALL_MAJOR_HEAP (obj)) -#else mword objsize; /* @@ -1410,9 +1001,7 @@ major_copy_or_mark_object (void **ptr, void *obj, SgenGrayQueue *queue) objsize = SGEN_ALIGN_UP (sgen_safe_object_get_size ((MonoObject*)obj)); - if (objsize <= SGEN_MAX_SMALL_OBJ_SIZE) -#endif - { + if (objsize <= SGEN_MAX_SMALL_OBJ_SIZE) { int size_index; gboolean evacuate; @@ -1420,20 +1009,6 @@ major_copy_or_mark_object (void **ptr, void *obj, SgenGrayQueue *queue) size_index = block->obj_size_index; evacuate = evacuate_block_obj_sizes [size_index]; -#ifdef FIXED_HEAP - /* - * We could also check for !block->has_pinned - * here, but it would only make an uncommon case - * faster, namely objects that are in blocks - * whose slot sizes are evacuated but which have - * pinned objects. - */ - if (evacuate && (forwarded = SGEN_OBJECT_IS_FORWARDED (obj))) { - *ptr = forwarded; - return; - } -#endif - if (evacuate && !block->has_pinned) { g_assert (!SGEN_OBJECT_IS_PINNED (obj)); if (block->is_to_space) @@ -1441,7 +1016,7 @@ major_copy_or_mark_object (void **ptr, void *obj, SgenGrayQueue *queue) HEAVY_STAT (++stat_major_objects_evacuated); goto do_copy_object; } else { - MS_MARK_OBJECT_AND_ENQUEUE (obj, block, queue); + MS_MARK_OBJECT_AND_ENQUEUE (obj, sgen_obj_get_descriptor (obj), block, queue); } } else { if (sgen_los_object_is_pinned (obj)) @@ -1457,11 +1032,10 @@ major_copy_or_mark_object (void **ptr, void *obj, SgenGrayQueue *queue) sgen_los_pin_object (obj); if (SGEN_OBJECT_HAS_REFERENCES (obj)) - GRAY_OBJECT_ENQUEUE (queue, obj); + GRAY_OBJECT_ENQUEUE (queue, obj, sgen_obj_get_descriptor (obj)); } } } -#endif static void major_copy_or_mark_object_canonical (void **ptr, SgenGrayQueue *queue) @@ -1475,6 +1049,7 @@ major_copy_or_mark_object_concurrent_canonical (void **ptr, SgenGrayQueue *queue { major_copy_or_mark_object_concurrent (ptr, *ptr, queue); } +#endif static long long major_get_and_reset_num_major_objects_marked (void) @@ -1487,7 +1062,6 @@ major_get_and_reset_num_major_objects_marked (void) return 0; #endif } -#endif #include "sgen-major-scan-object.h" @@ -1510,10 +1084,12 @@ mark_pinned_objects_in_block (MSBlockInfo *block, SgenGrayQueue *queue) for (i = 0; i < block->pin_queue_num_entries; ++i) { int index = MS_BLOCK_OBJ_INDEX (block->pin_queue_start [i], block); + char *obj; SGEN_ASSERT (9, index >= 0 && index < MS_BLOCK_FREE / block->obj_size, "invalid object %p index %d max-index %d", block->pin_queue_start [i], index, MS_BLOCK_FREE / block->obj_size); if (index == last_index) continue; - MS_MARK_OBJECT_AND_ENQUEUE_CHECKED (MS_BLOCK_OBJ (block, index), block, queue); + obj = MS_BLOCK_OBJ (block, index); + MS_MARK_OBJECT_AND_ENQUEUE_CHECKED (obj, sgen_obj_get_descriptor (obj), block, queue); last_index = index; } } @@ -1620,7 +1196,7 @@ static void ms_sweep (void) { int i; - MSBlockInfo **iter; + MSBlockInfo *block; /* statistics for evacuation */ int *slots_available = alloca (sizeof (int) * num_block_obj_sizes); @@ -1644,9 +1220,7 @@ ms_sweep (void) } /* traverse all blocks, free and zero unmarked objects */ - iter = &all_blocks; - while (*iter) { - MSBlockInfo *block = *iter; + FOREACH_BLOCK (block) { int count; gboolean have_live = FALSE; gboolean has_pinned; @@ -1691,8 +1265,6 @@ ms_sweep (void) slots_available [obj_size_index] += count; } - iter = &block->next; - /* * If there are free slots in the block, add * the block to the corresponding free list. @@ -1710,20 +1282,16 @@ ms_sweep (void) * Blocks without live objects are removed from the * block list and freed. */ - *iter = block->next; + DELETE_BLOCK_IN_FOREACH (); binary_protocol_empty (MS_BLOCK_OBJ (block, 0), (char*)MS_BLOCK_OBJ (block, count) - (char*)MS_BLOCK_OBJ (block, 0)); -#ifdef FIXED_HEAP - ms_free_block (block); -#else ms_free_block (block->block); - sgen_free_internal (block, INTERNAL_MEM_MS_BLOCK_INFO); -#endif --num_major_sections; } - } + } END_FOREACH_BLOCK; + sgen_pointer_queue_remove_nulls (&allocated_blocks); for (i = 0; i < num_block_obj_sizes; ++i) { float usage = (float)slots_used [i] / (float)slots_available [i]; @@ -1869,18 +1437,13 @@ major_start_major_collection (void) // Sweep all unswept blocks if (lazy_sweep) { - MSBlockInfo **iter; + MSBlockInfo *block; MONO_GC_SWEEP_BEGIN (GENERATION_OLD, TRUE); - iter = &all_blocks; - while (*iter) { - MSBlockInfo *block = *iter; - + FOREACH_BLOCK (block) { sweep_block (block, TRUE); - - iter = &block->next; - } + } END_FOREACH_BLOCK; MONO_GC_SWEEP_END (GENERATION_OLD, TRUE); } @@ -1891,7 +1454,7 @@ major_finish_major_collection (void) { } -#if !defined(FIXED_HEAP) && SIZEOF_VOID_P != 8 +#if SIZEOF_VOID_P != 8 static int compare_pointers (const void *va, const void *vb) { char *a = *(char**)va, *b = *(char**)vb; @@ -1906,7 +1469,6 @@ compare_pointers (const void *va, const void *vb) { static void major_have_computer_minor_collection_allowance (void) { -#ifndef FIXED_HEAP size_t section_reserve = sgen_get_minor_collection_allowance () / MS_BLOCK_SIZE; g_assert (have_swept); @@ -2056,7 +1618,6 @@ major_have_computer_minor_collection_allowance (void) ++stat_major_blocks_freed_individual; #endif } -#endif } static void @@ -2065,7 +1626,7 @@ major_find_pin_queue_start_ends (SgenGrayQueue *queue) MSBlockInfo *block; FOREACH_BLOCK (block) { - block->pin_queue_start = sgen_find_optimized_pin_queue_area (block->block + MS_BLOCK_SKIP, block->block + MS_BLOCK_SIZE, + block->pin_queue_start = sgen_find_optimized_pin_queue_area (MS_BLOCK_FOR_BLOCK_INFO (block) + MS_BLOCK_SKIP, MS_BLOCK_FOR_BLOCK_INFO (block) + MS_BLOCK_SIZE, &block->pin_queue_num_entries); } END_FOREACH_BLOCK; } @@ -2117,17 +1678,6 @@ get_num_major_sections (void) static gboolean major_handle_gc_param (const char *opt) { -#ifdef FIXED_HEAP - if (g_str_has_prefix (opt, "major-heap-size=")) { - const char *arg = strchr (opt, '=') + 1; - size_t size; - if (!mono_gc_parse_environment_string_extract_number (arg, &size)) - return FALSE; - ms_heap_num_blocks = (size + MS_BLOCK_SIZE - 1) / MS_BLOCK_SIZE; - g_assert (ms_heap_num_blocks > 0); - return TRUE; - } else -#endif if (g_str_has_prefix (opt, "evacuation-threshold=")) { const char *arg = strchr (opt, '=') + 1; int percentage = atoi (arg); @@ -2153,9 +1703,6 @@ major_print_gc_param_usage (void) { fprintf (stderr, "" -#ifdef FIXED_HEAP - " major-heap-size=N (where N is an integer, possibly with a k, m or a g suffix)\n" -#endif " evacuation-threshold=P (where P is a percentage, an integer in 0-100)\n" " (no-)lazy-sweep\n" ); @@ -2165,10 +1712,11 @@ static void major_iterate_live_block_ranges (sgen_cardtable_block_callback callback) { MSBlockInfo *block; + gboolean has_references; - FOREACH_BLOCK (block) { - if (block->has_references) - callback ((mword)block->block, MS_BLOCK_SIZE); + FOREACH_BLOCK_HAS_REFERENCES (block, has_references) { + if (has_references) + callback ((mword)MS_BLOCK_FOR_BLOCK_INFO (block), MS_BLOCK_SIZE); } END_FOREACH_BLOCK; } @@ -2232,6 +1780,7 @@ static void major_scan_card_table (gboolean mod_union, SgenGrayQueue *queue) { MSBlockInfo *block; + gboolean has_references; ScanObjectFunc scan_func = sgen_get_current_object_ops ()->scan_object; #ifdef SGEN_HAVE_CONCURRENT_MARK @@ -2241,15 +1790,15 @@ major_scan_card_table (gboolean mod_union, SgenGrayQueue *queue) g_assert (!mod_union); #endif - FOREACH_BLOCK (block) { + FOREACH_BLOCK_HAS_REFERENCES (block, has_references) { int block_obj_size; char *block_start; - if (!block->has_references) + if (!has_references) continue; block_obj_size = block->obj_size; - block_start = block->block; + block_start = MS_BLOCK_FOR_BLOCK_INFO (block); if (block_obj_size >= CARD_SIZE_IN_BYTES) { guint8 *cards; @@ -2377,7 +1926,7 @@ major_scan_card_table (gboolean mod_union, SgenGrayQueue *queue) } HEAVY_STAT (++scanned_objects); - scan_func (obj, queue); + scan_func (obj, sgen_obj_get_descriptor (obj), queue); next_small: obj += block_obj_size; } @@ -2392,14 +1941,15 @@ static void major_count_cards (long long *num_total_cards, long long *num_marked_cards) { MSBlockInfo *block; + gboolean has_references; long long total_cards = 0; long long marked_cards = 0; - FOREACH_BLOCK (block) { - guint8 *cards = sgen_card_table_get_card_scan_address ((mword) block->block); + FOREACH_BLOCK_HAS_REFERENCES (block, has_references) { + guint8 *cards = sgen_card_table_get_card_scan_address ((mword) MS_BLOCK_FOR_BLOCK_INFO (block)); int i; - if (!block->has_references) + if (!has_references) continue; total_cards += CARDS_PER_BLOCK; @@ -2423,7 +1973,7 @@ update_cardtable_mod_union (void) size_t num_cards; block->cardtable_mod_union = sgen_card_table_update_mod_union (block->cardtable_mod_union, - block->block, MS_BLOCK_SIZE, &num_cards); + MS_BLOCK_FOR_BLOCK_INFO (block), MS_BLOCK_SIZE, &num_cards); SGEN_ASSERT (0, num_cards == CARDS_PER_BLOCK, "Number of cards calculation is wrong"); } END_FOREACH_BLOCK; @@ -2433,7 +1983,7 @@ static guint8* major_get_cardtable_mod_union_for_object (char *obj) { MSBlockInfo *block = MS_BLOCK_FOR_OBJ (obj); - return &block->cardtable_mod_union [(obj - (char*)sgen_card_table_align_pointer (block->block)) >> CARD_BITS]; + return &block->cardtable_mod_union [(obj - (char*)sgen_card_table_align_pointer (MS_BLOCK_FOR_BLOCK_INFO (block))) >> CARD_BITS]; } #endif @@ -2445,49 +1995,6 @@ alloc_free_block_lists (MSBlockInfo ***lists) lists [i] = sgen_alloc_internal_dynamic (sizeof (MSBlockInfo*) * num_block_obj_sizes, INTERNAL_MEM_MS_TABLES, TRUE); } -#ifdef SGEN_PARALLEL_MARK -static void* -major_alloc_worker_data (void) -{ - /* FIXME: free this when the workers come down */ - MSBlockInfo ***lists = malloc (sizeof (MSBlockInfo**) * MS_BLOCK_TYPE_MAX); - alloc_free_block_lists (lists); - return lists; -} - -static void -major_init_worker_thread (void *data) -{ - MSBlockInfo ***lists = data; - int i; - - g_assert (lists && lists != free_block_lists); - for (i = 0; i < MS_BLOCK_TYPE_MAX; ++i) { - int j; - for (j = 0; j < num_block_obj_sizes; ++j) - g_assert (!lists [i][j]); - } - -#ifdef HAVE_KW_THREAD - workers_free_block_lists = data; -#else - mono_native_tls_set_value (workers_free_block_lists_key, data); -#endif -} - -static void -major_reset_worker_data (void *data) -{ - MSBlockInfo ***lists = data; - int i; - for (i = 0; i < MS_BLOCK_TYPE_MAX; ++i) { - int j; - for (j = 0; j < num_block_obj_sizes; ++j) - lists [i][j] = NULL; - } -} -#endif - #undef pthread_create static void @@ -2500,29 +2007,12 @@ post_param_init (SgenMajorCollector *collector) static void sgen_marksweep_init_internal (SgenMajorCollector *collector, gboolean is_concurrent) #else // SGEN_HAVE_CONCURRENT_MARK -#ifdef SGEN_PARALLEL_MARK -#ifdef FIXED_HEAP -void -sgen_marksweep_fixed_par_init (SgenMajorCollector *collector) -#else // FIXED_HEAP -void -sgen_marksweep_par_init (SgenMajorCollector *collector) -#endif // FIXED_HEAP -#else // SGEN_PARALLEL_MARK -#ifdef FIXED_HEAP -void -sgen_marksweep_fixed_init (SgenMajorCollector *collector) -#else // FIXED_HEAP #error unknown configuration -#endif // FIXED_HEAP -#endif // SGEN_PARALLEL_MARK #endif // SGEN_HAVE_CONCURRENT_MARK { int i; -#ifndef FIXED_HEAP sgen_register_fixed_internal_mem_type (INTERNAL_MEM_MS_BLOCK_INFO, sizeof (MSBlockInfo)); -#endif num_block_obj_sizes = ms_calculate_block_obj_sizes (MS_BLOCK_OBJ_SIZE_FACTOR, NULL); block_obj_sizes = sgen_alloc_internal_dynamic (sizeof (int) * num_block_obj_sizes, INTERNAL_MEM_MS_TABLES, TRUE); @@ -2548,10 +2038,6 @@ sgen_marksweep_fixed_init (SgenMajorCollector *collector) for (i = 0; i < MS_NUM_FAST_BLOCK_OBJ_SIZE_INDEXES * 8; ++i) g_assert (MS_BLOCK_OBJ_SIZE_INDEX (i) == ms_find_block_obj_size_index (i)); -#ifdef SGEN_PARALLEL_MARK - LOCK_INIT (ms_block_list_mutex); -#endif - mono_counters_register ("# major blocks allocated", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_major_blocks_alloced); mono_counters_register ("# major blocks freed", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_major_blocks_freed); mono_counters_register ("# major blocks lazy swept", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_major_blocks_lazy_swept); @@ -2563,33 +2049,20 @@ sgen_marksweep_fixed_init (SgenMajorCollector *collector) mono_counters_register ("# major blocks allocated less ideally", MONO_COUNTER_GC | MONO_COUNTER_LONG, &stat_major_blocks_alloced_less_ideal); #endif -#ifdef SGEN_PARALLEL_MARK -#ifndef HAVE_KW_THREAD - mono_native_tls_alloc (&workers_free_block_lists_key, NULL); -#endif -#endif - collector->section_size = MAJOR_SECTION_SIZE; -#ifdef SGEN_PARALLEL_MARK - collector->is_parallel = TRUE; - collector->alloc_worker_data = major_alloc_worker_data; - collector->init_worker_thread = major_init_worker_thread; - collector->reset_worker_data = major_reset_worker_data; -#else - collector->is_parallel = FALSE; -#endif + #ifdef SGEN_HAVE_CONCURRENT_MARK concurrent_mark = is_concurrent; if (is_concurrent) { collector->is_concurrent = TRUE; collector->want_synchronous_collection = &want_evacuation; - collector->get_and_reset_num_major_objects_marked = major_get_and_reset_num_major_objects_marked; } else #endif { collector->is_concurrent = FALSE; collector->want_synchronous_collection = NULL; } + collector->get_and_reset_num_major_objects_marked = major_get_and_reset_num_major_objects_marked; collector->supports_cardtable = TRUE; collector->have_swept = &have_swept; @@ -2600,9 +2073,6 @@ sgen_marksweep_fixed_init (SgenMajorCollector *collector) collector->alloc_degraded = major_alloc_degraded; collector->alloc_object = major_alloc_object; -#ifdef SGEN_PARALLEL_MARK - collector->par_alloc_object = major_par_alloc_object; -#endif collector->free_pinned_object = free_pinned_object; collector->iterate_objects = major_iterate_objects; collector->free_non_pinned_object = major_free_non_pinned_object; diff --git a/mono/metadata/sgen-memory-governor.c b/mono/metadata/sgen-memory-governor.c index 448ebef3f0..5d17a0d721 100644 --- a/mono/metadata/sgen-memory-governor.c +++ b/mono/metadata/sgen-memory-governor.c @@ -48,6 +48,7 @@ static double save_target_ratio = SGEN_DEFAULT_SAVE_TARGET_RATIO; /**/ static mword allocated_heap; static mword total_alloc = 0; +static mword total_alloc_max = 0; /* GC triggers. */ @@ -72,21 +73,13 @@ static mword last_collection_los_memory_alloced; static mword sgen_memgov_available_free_space (void); -static mword -double_to_mword_with_saturation (double value) -{ - if (value >= (double)MWORD_MAX_VALUE) - return MWORD_MAX_VALUE; - return (mword)value; -} - /* GC trigger heuristics. */ static void sgen_memgov_try_calculate_minor_collection_allowance (gboolean overwrite) { - size_t num_major_sections, num_major_sections_saved; - mword los_memory_saved, new_major, new_heap_size, save_target, allowance_target; + size_t num_major_sections; + mword new_major, new_heap_size, allowance_target; if (overwrite) g_assert (need_calculate_minor_collection_allowance); @@ -102,32 +95,16 @@ sgen_memgov_try_calculate_minor_collection_allowance (gboolean overwrite) num_major_sections = major_collector.get_num_major_sections (); - num_major_sections_saved = MAX (last_collection_old_num_major_sections - num_major_sections, 0); - los_memory_saved = MAX (last_collection_old_los_memory_usage - last_collection_los_memory_usage, 1); - new_major = num_major_sections * major_collector.section_size; new_heap_size = new_major + last_collection_los_memory_usage; - save_target = (mword)((new_major + last_collection_los_memory_usage) * SGEN_DEFAULT_SAVE_TARGET_RATIO); - /* - * We aim to allow the allocation of as many sections as is - * necessary to reclaim save_target sections in the next - * collection. We assume the collection pattern won't change. - * In the last cycle, we had num_major_sections_saved for - * minor_collection_sections_alloced. Assuming things won't - * change, this must be the same ratio as save_target for - * allowance_target, i.e. - * - * num_major_sections_saved save_target - * --------------------------------- == ---------------- - * minor_collection_sections_alloced allowance_target - * - * hence: + * We allow the heap to grow by one third its current size before we start the next + * major collection. */ - allowance_target = double_to_mword_with_saturation ((double)save_target * (double)(minor_collection_sections_alloced * major_collector.section_size + last_collection_los_memory_alloced) / (double)(num_major_sections_saved * major_collector.section_size + los_memory_saved)); + allowance_target = new_heap_size / 3; - minor_collection_allowance = MAX (MIN (allowance_target, num_major_sections * major_collector.section_size + los_memory_usage), MIN_MINOR_COLLECTION_ALLOWANCE); + minor_collection_allowance = MAX (allowance_target, MIN_MINOR_COLLECTION_ALLOWANCE); if (new_heap_size + minor_collection_allowance > soft_heap_limit) { if (new_heap_size > soft_heap_limit) @@ -311,6 +288,7 @@ sgen_alloc_os_memory (size_t size, SgenAllocFlags flags, const char *assert_desc SGEN_ATOMIC_ADD_P (total_alloc, size); if (flags & SGEN_ALLOC_HEAP) MONO_GC_HEAP_ALLOC ((mword)ptr, size); + total_alloc_max = MAX (total_alloc_max, total_alloc); } return ptr; } @@ -329,6 +307,7 @@ sgen_alloc_os_memory_aligned (size_t size, mword alignment, SgenAllocFlags flags SGEN_ATOMIC_ADD_P (total_alloc, size); if (flags & SGEN_ALLOC_HEAP) MONO_GC_HEAP_ALLOC ((mword)ptr, size); + total_alloc_max = MAX (total_alloc_max, total_alloc); } return ptr; } @@ -345,6 +324,7 @@ sgen_free_os_memory (void *addr, size_t size, SgenAllocFlags flags) SGEN_ATOMIC_ADD_P (total_alloc, -(gssize)size); if (flags & SGEN_ALLOC_HEAP) MONO_GC_HEAP_FREE ((mword)addr, size); + total_alloc_max = MAX (total_alloc_max, total_alloc); } int64_t @@ -392,6 +372,9 @@ sgen_memgov_init (size_t max_heap, size_t soft_limit, gboolean debug_allowance, debug_print_allowance = debug_allowance; minor_collection_allowance = MIN_MINOR_COLLECTION_ALLOWANCE; + mono_counters_register ("Memgov alloc", MONO_COUNTER_GC | MONO_COUNTER_WORD | MONO_COUNTER_BYTES | MONO_COUNTER_VARIABLE, &total_alloc); + mono_counters_register ("Memgov max alloc", MONO_COUNTER_GC | MONO_COUNTER_WORD | MONO_COUNTER_BYTES | MONO_COUNTER_MONOTONIC, &total_alloc_max); + if (max_heap == 0) return; diff --git a/mono/metadata/sgen-minor-copy-object.h b/mono/metadata/sgen-minor-copy-object.h index 782bbdf8de..c18e49f16d 100644 --- a/mono/metadata/sgen-minor-copy-object.h +++ b/mono/metadata/sgen-minor-copy-object.h @@ -21,10 +21,11 @@ #define collector_pin_object(obj, queue) sgen_pin_object (obj, queue); #define COLLECTOR_SERIAL_ALLOC_FOR_PROMOTION alloc_for_promotion -#define COLLECTOR_PARALLEL_ALLOC_FOR_PROMOTION par_alloc_for_promotion extern long long stat_nursery_copy_object_failed_to_space; /* from sgen-gc.c */ +#include "mono/utils/mono-compiler.h" + #include "sgen-copy-object.h" /* @@ -47,11 +48,7 @@ extern long long stat_nursery_copy_object_failed_to_space; /* from sgen-gc.c */ * copy_object could be made into a macro once debugged (use inline for now). */ -#ifdef _MSC_VER -static __forceinline void -#else -static inline void __attribute__((always_inline)) -#endif +static MONO_ALWAYS_INLINE void SERIAL_COPY_OBJECT (void **obj_slot, SgenGrayQueue *queue) { char *forwarded; @@ -107,11 +104,7 @@ SERIAL_COPY_OBJECT (void **obj_slot, SgenGrayQueue *queue) * * Similar to SERIAL_COPY_OBJECT, but assumes that OBJ_SLOT is part of an object, so it handles global remsets as well. */ -#ifdef _MSC_VER -static __forceinline void -#else -static inline void __attribute__((always_inline)) -#endif +static MONO_ALWAYS_INLINE void SERIAL_COPY_OBJECT_FROM_OBJ (void **obj_slot, SgenGrayQueue *queue) { char *forwarded; @@ -217,88 +210,6 @@ SERIAL_COPY_OBJECT_FROM_OBJ (void **obj_slot, SgenGrayQueue *queue) #endif } -static void -PARALLEL_COPY_OBJECT (void **obj_slot, SgenGrayQueue *queue) -{ - char *obj = *obj_slot; - mword vtable_word, objsize; - MonoVTable *vt; - void *destination; - gboolean has_references; - - SGEN_ASSERT (9, current_collection_generation == GENERATION_NURSERY, "calling minor-par-copy from a %d generation collection", current_collection_generation); - - HEAVY_STAT (++stat_copy_object_called_nursery); - - if (!sgen_ptr_in_nursery (obj)) { - HEAVY_STAT (++stat_nursery_copy_object_failed_from_space); - return; - } - - vtable_word = *(mword*)obj; - vt = (MonoVTable*)(vtable_word & ~SGEN_VTABLE_BITS_MASK); - - /* - * Before we can copy the object we must make sure that we are - * allowed to, i.e. that the object not pinned, not already - * forwarded and not in the nursery To Space. - */ - - if (vtable_word & SGEN_FORWARDED_BIT) { - HEAVY_STAT (++stat_nursery_copy_object_failed_forwarded); - *obj_slot = vt; - return; - } - if (vtable_word & SGEN_PINNED_BIT) { - HEAVY_STAT (++stat_nursery_copy_object_failed_pinned); - return; - } - - if (sgen_nursery_is_to_space (obj)) { - HEAVY_STAT (++stat_nursery_copy_object_failed_to_space); - return; - } - - HEAVY_STAT (++stat_objects_copied_nursery); - - objsize = SGEN_ALIGN_UP (sgen_par_object_get_size (vt, (MonoObject*)obj)); - has_references = SGEN_VTABLE_HAS_REFERENCES (vt); - - destination = COLLECTOR_PARALLEL_ALLOC_FOR_PROMOTION (vt, obj, objsize, has_references); - - if (G_UNLIKELY (!destination)) { - sgen_parallel_pin_or_update (obj_slot, obj, vt, queue); - return; - } - - *(MonoVTable**)destination = vt; - - if (SGEN_CAS_PTR ((void*)obj, (void*)((mword)destination | SGEN_FORWARDED_BIT), vt) == vt) { - par_copy_object_no_checks (destination, vt, obj, objsize, has_references ? queue : NULL); - obj = destination; - *obj_slot = obj; - } else { - /* FIXME: unify with code in major_copy_or_mark_object() */ - - /* FIXME: Give destination back to the allocator. */ - /*The major collector only needs the first word zeroed and nursery requires all bits to be. */ - if (!sgen_ptr_in_nursery (destination)) - *(void**)destination = NULL; - else - memset (destination, 0, objsize); - - vtable_word = *(mword*)obj; - g_assert (vtable_word & SGEN_FORWARDED_BIT); - - obj = (void*)(vtable_word & ~SGEN_VTABLE_BITS_MASK); - - *obj_slot = obj; - - HEAVY_STAT (++stat_slots_allocated_in_vain); - } -} - #define FILL_MINOR_COLLECTOR_COPY_OBJECT(collector) do { \ (collector)->serial_ops.copy_or_mark_object = SERIAL_COPY_OBJECT; \ - (collector)->parallel_ops.copy_or_mark_object = PARALLEL_COPY_OBJECT; \ } while (0) diff --git a/mono/metadata/sgen-minor-scan-object.h b/mono/metadata/sgen-minor-scan-object.h index 7a34dfd4ac..3cff269a7d 100644 --- a/mono/metadata/sgen-minor-scan-object.h +++ b/mono/metadata/sgen-minor-scan-object.h @@ -24,70 +24,15 @@ extern long long stat_scan_object_called_nursery; #if defined(SGEN_SIMPLE_NURSERY) #define SERIAL_SCAN_OBJECT simple_nursery_serial_scan_object #define SERIAL_SCAN_VTYPE simple_nursery_serial_scan_vtype -#define PARALLEL_SCAN_OBJECT simple_nursery_parallel_scan_object -#define PARALLEL_SCAN_VTYPE simple_nursery_parallel_scan_vtype #elif defined (SGEN_SPLIT_NURSERY) #define SERIAL_SCAN_OBJECT split_nursery_serial_scan_object #define SERIAL_SCAN_VTYPE split_nursery_serial_scan_vtype -#define PARALLEL_SCAN_OBJECT split_nursery_parallel_scan_object -#define PARALLEL_SCAN_VTYPE split_nursery_parallel_scan_vtype #else #error "Please define GC_CONF_NAME" #endif -#undef HANDLE_PTR -#define HANDLE_PTR(ptr,obj) do { \ - void *__old = *(ptr); \ - void *__copy; \ - SGEN_OBJECT_LAYOUT_STATISTICS_MARK_BITMAP ((obj), (ptr)); \ - if (__old) { \ - PARALLEL_COPY_OBJECT ((ptr), queue); \ - __copy = *(ptr); \ - SGEN_COND_LOG (9, __old != __copy, "Overwrote field at %p with %p (was: %p)", (ptr), *(ptr), __old); \ - if (G_UNLIKELY (sgen_ptr_in_nursery (__copy) && !sgen_ptr_in_nursery ((ptr)))) \ - sgen_add_to_global_remset ((ptr), __copy); \ - } \ - } while (0) - -/* - * Scan the object pointed to by @start for references to - * other objects between @from_start and @from_end and copy - * them to the gray_objects area. - */ -static void -PARALLEL_SCAN_OBJECT (char *start, SgenGrayQueue *queue) -{ - SGEN_OBJECT_LAYOUT_STATISTICS_DECLARE_BITMAP; - -#define SCAN_OBJECT_PROTOCOL -#include "sgen-scan-object.h" - - SGEN_OBJECT_LAYOUT_STATISTICS_COMMIT_BITMAP; - HEAVY_STAT (++stat_scan_object_called_nursery); -} - -/* - * scan_vtype: - * - * Scan the valuetype pointed to by START, described by DESC for references to - * other objects between @from_start and @from_end and copy them to the gray_objects area. - * Returns a pointer to the end of the object. - */ -static void -PARALLEL_SCAN_VTYPE (char *start, mword desc, SgenGrayQueue *queue BINARY_PROTOCOL_ARG (size_t size)) -{ - SGEN_OBJECT_LAYOUT_STATISTICS_DECLARE_BITMAP; - - /* The descriptors include info about the MonoObject header as well */ - start -= sizeof (MonoObject); - -#define SCAN_OBJECT_NOVTABLE -#define SCAN_OBJECT_PROTOCOL -#include "sgen-scan-object.h" -} - #undef HANDLE_PTR /* Global remsets are handled in SERIAL_COPY_OBJECT_FROM_OBJ */ #define HANDLE_PTR(ptr,obj) do { \ @@ -100,10 +45,14 @@ PARALLEL_SCAN_VTYPE (char *start, mword desc, SgenGrayQueue *queue BINARY_PROTOC } while (0) static void -SERIAL_SCAN_OBJECT (char *start, SgenGrayQueue *queue) +SERIAL_SCAN_OBJECT (char *start, mword desc, SgenGrayQueue *queue) { SGEN_OBJECT_LAYOUT_STATISTICS_DECLARE_BITMAP; +#ifdef HEAVY_STATISTICS + sgen_descriptor_count_scanned_object (desc); +#endif + #define SCAN_OBJECT_PROTOCOL #include "sgen-scan-object.h" @@ -125,8 +74,6 @@ SERIAL_SCAN_VTYPE (char *start, mword desc, SgenGrayQueue *queue BINARY_PROTOCOL } #define FILL_MINOR_COLLECTOR_SCAN_OBJECT(collector) do { \ - (collector)->parallel_ops.scan_object = PARALLEL_SCAN_OBJECT; \ - (collector)->parallel_ops.scan_vtype = PARALLEL_SCAN_VTYPE; \ (collector)->serial_ops.scan_object = SERIAL_SCAN_OBJECT; \ (collector)->serial_ops.scan_vtype = SERIAL_SCAN_VTYPE; \ } while (0) diff --git a/mono/metadata/sgen-new-bridge.c b/mono/metadata/sgen-new-bridge.c index d07203db4d..51b00e9669 100644 --- a/mono/metadata/sgen-new-bridge.c +++ b/mono/metadata/sgen-new-bridge.c @@ -652,6 +652,7 @@ dfs1 (HashEntry *obj_entry) if (obj_entry) { /* obj_entry needs to be expanded */ src = dyn_array_ptr_pop (&dfs_stack); + if (src) g_assert (!src->v.dfs1.forwarded_to); @@ -664,6 +665,7 @@ dfs1 (HashEntry *obj_entry) if (!obj_entry->v.dfs1.is_visited) { int num_links = 0; + mword desc = sgen_obj_get_descriptor (start); obj_entry->v.dfs1.is_visited = 1; diff --git a/mono/metadata/sgen-nursery-allocator.c b/mono/metadata/sgen-nursery-allocator.c index 3d422e6b7b..01d1bd1a79 100644 --- a/mono/metadata/sgen-nursery-allocator.c +++ b/mono/metadata/sgen-nursery-allocator.c @@ -782,12 +782,13 @@ sgen_build_nursery_fragments (GCMemSection *nursery_section, void **start, size_ if (addr0 < addr1) { if (unpin_queue) - GRAY_OBJECT_ENQUEUE (unpin_queue, addr0); + GRAY_OBJECT_ENQUEUE (unpin_queue, addr0, sgen_obj_get_descriptor_safe (addr0)); else SGEN_UNPIN_OBJECT (addr0); + size = SGEN_ALIGN_UP (sgen_safe_object_get_size ((MonoObject*)addr0)); + CANARIFY_SIZE (size); sgen_set_nursery_scan_start (addr0); frag_end = addr0; - size = SGEN_ALIGN_UP (sgen_safe_object_get_size ((MonoObject*)addr0)); ++i; } else { frag_end = addr1; @@ -871,7 +872,7 @@ sgen_can_alloc_size (size_t size) void* sgen_nursery_alloc (size_t size) { - SGEN_ASSERT (1, size >= sizeof (MonoObject) && size <= SGEN_MAX_SMALL_OBJ_SIZE, "Invalid nursery object size"); + SGEN_ASSERT (1, size >= sizeof (MonoObject) && size <= (SGEN_MAX_SMALL_OBJ_SIZE + CANARY_SIZE), "Invalid nursery object size"); SGEN_LOG (4, "Searching nursery for size: %zd", size); size = SGEN_ALIGN_UP (size); diff --git a/mono/metadata/sgen-old-bridge.c b/mono/metadata/sgen-old-bridge.c index 42a588164d..4e2ba7b84d 100644 --- a/mono/metadata/sgen-old-bridge.c +++ b/mono/metadata/sgen-old-bridge.c @@ -521,10 +521,12 @@ dfs1 (HashEntry *obj_entry) obj_entry = dyn_array_ptr_pop (&dfs_stack); if (obj_entry) { + mword desc; src = dyn_array_ptr_pop (&dfs_stack); obj = obj_entry->obj; start = (char*)obj; + desc = sgen_obj_get_descriptor (start); if (src) { //g_print ("link %s -> %s\n", sgen_safe_name (src->obj), sgen_safe_name (obj)); diff --git a/mono/metadata/sgen-os-posix.c b/mono/metadata/sgen-os-posix.c index 909b8382c8..55acf5137c 100644 --- a/mono/metadata/sgen-os-posix.c +++ b/mono/metadata/sgen-os-posix.c @@ -56,17 +56,30 @@ suspend_thread (SgenThreadInfo *info, void *context) #ifndef USE_MONO_CTX gpointer regs [ARCH_NUM_REGS]; #endif + MonoContext ctx; gpointer stack_start; info->stopped_domain = mono_domain_get (); - info->stopped_ip = context ? (gpointer) ARCH_SIGCTX_IP (context) : NULL; info->signal = 0; stop_count = sgen_global_stop_count; /* duplicate signal */ if (0 && info->stop_count == stop_count) return; +#ifdef USE_MONO_CTX + if (context) { + mono_sigctx_to_monoctx (context, &ctx); + info->stopped_ip = MONO_CONTEXT_GET_IP (&ctx); + stack_start = MONO_CONTEXT_GET_SP (&ctx) - REDZONE_SIZE; + } else { + info->stopped_ip = NULL; + stack_start = NULL; + } +#else + info->stopped_ip = context ? (gpointer) ARCH_SIGCTX_IP (context) : NULL; stack_start = context ? (char*) ARCH_SIGCTX_SP (context) - REDZONE_SIZE : NULL; +#endif + /* If stack_start is not within the limits, then don't set it in info and we will be restarted. */ if (stack_start >= info->stack_start_limit && info->stack_start <= info->stack_end) { @@ -74,7 +87,7 @@ suspend_thread (SgenThreadInfo *info, void *context) #ifdef USE_MONO_CTX if (context) { - mono_sigctx_to_monoctx (context, &info->ctx); + memcpy (&info->ctx, &ctx, sizeof (MonoContext)); } else { memset (&info->ctx, 0, sizeof (MonoContext)); } @@ -122,7 +135,7 @@ suspend_thread (SgenThreadInfo *info, void *context) } /* LOCKING: assumes the GC lock is held (by the stopping thread) */ -MONO_SIGNAL_HANDLER_FUNC (static, suspend_handler, (int sig, siginfo_t *siginfo, void *context)) +MONO_SIG_HANDLER_FUNC (static, suspend_handler) { /* * The suspend signal handler potentially uses syscalls that @@ -131,19 +144,19 @@ MONO_SIGNAL_HANDLER_FUNC (static, suspend_handler, (int sig, siginfo_t *siginfo, * must restore those to the values they had when we * interrupted. */ - SgenThreadInfo *info; int old_errno = errno; int hp_save_index = mono_hazard_pointer_save_for_signal_handler (); + MONO_SIG_HANDLER_GET_CONTEXT; info = mono_thread_info_current (); - suspend_thread (info, context); + suspend_thread (info, ctx); mono_hazard_pointer_restore_for_signal_handler (hp_save_index); errno = old_errno; } -MONO_SIGNAL_HANDLER_FUNC (static, restart_handler, (int sig)) +MONO_SIG_HANDLER_FUNC (static, restart_handler) { SgenThreadInfo *info; int old_errno = errno; diff --git a/mono/metadata/sgen-pinning.c b/mono/metadata/sgen-pinning.c index 523c7737b1..71a8dbefeb 100644 --- a/mono/metadata/sgen-pinning.c +++ b/mono/metadata/sgen-pinning.c @@ -25,10 +25,9 @@ #include "metadata/sgen-gc.h" #include "metadata/sgen-pinning.h" #include "metadata/sgen-protocol.h" +#include "metadata/sgen-pointer-queue.h" -static void** pin_queue; -static size_t pin_queue_size = 0; -static size_t next_pin_slot = 0; +static SgenPointerQueue pin_queue; static size_t last_num_pinned = 0; #define PIN_HASH_SIZE 1024 @@ -43,20 +42,8 @@ sgen_init_pinning (void) void sgen_finish_pinning (void) { - last_num_pinned = next_pin_slot; - next_pin_slot = 0; -} - -static void -realloc_pin_queue (void) -{ - size_t new_size = pin_queue_size? pin_queue_size + pin_queue_size/2: 1024; - void **new_pin = sgen_alloc_internal_dynamic (sizeof (void*) * new_size, INTERNAL_MEM_PIN_QUEUE, TRUE); - memcpy (new_pin, pin_queue, sizeof (void*) * next_pin_slot); - sgen_free_internal_dynamic (pin_queue, sizeof (void*) * pin_queue_size, INTERNAL_MEM_PIN_QUEUE); - pin_queue = new_pin; - pin_queue_size = new_size; - SGEN_LOG (4, "Reallocated pin queue to size: %zd", new_size); + last_num_pinned = pin_queue.next_slot; + sgen_pointer_queue_clear (&pin_queue); } void @@ -69,37 +56,19 @@ sgen_pin_stage_ptr (void *ptr) pin_hash_filter [hash_idx] = ptr; - if (next_pin_slot >= pin_queue_size) - realloc_pin_queue (); - - pin_queue [next_pin_slot++] = ptr; -} - -static size_t -optimized_pin_queue_search (void *addr) -{ - size_t first = 0, last = next_pin_slot; - while (first < last) { - size_t middle = first + ((last - first) >> 1); - if (addr <= pin_queue [middle]) - last = middle; - else - first = middle + 1; - } - g_assert (first == last); - return first; + sgen_pointer_queue_add (&pin_queue, ptr); } void** sgen_find_optimized_pin_queue_area (void *start, void *end, size_t *num) { size_t first, last; - first = optimized_pin_queue_search (start); - last = optimized_pin_queue_search (end); + first = sgen_pointer_queue_search (&pin_queue, start); + last = sgen_pointer_queue_search (&pin_queue, end); *num = last - first; if (first == last) return NULL; - return pin_queue + first; + return pin_queue.data + first; } void @@ -114,21 +83,21 @@ sgen_find_section_pin_queue_start_end (GCMemSection *section) void sgen_pinning_setup_section (GCMemSection *section) { - section->pin_queue_start = pin_queue; - section->pin_queue_num_entries = next_pin_slot; + section->pin_queue_start = pin_queue.data; + section->pin_queue_num_entries = pin_queue.next_slot; } void sgen_pinning_trim_queue_to_section (GCMemSection *section) { - next_pin_slot = section->pin_queue_num_entries; + pin_queue.next_slot = section->pin_queue_num_entries; } void sgen_pin_queue_clear_discarded_entries (GCMemSection *section, size_t max_pin_slot) { void **start = section->pin_queue_start + section->pin_queue_num_entries; - void **end = pin_queue + max_pin_slot; + void **end = pin_queue.data + max_pin_slot; void *addr; if (!start) @@ -144,30 +113,15 @@ sgen_pin_queue_clear_discarded_entries (GCMemSection *section, size_t max_pin_sl /* reduce the info in the pin queue, removing duplicate pointers and sorting them */ void -sgen_optimize_pin_queue (size_t start_slot) +sgen_optimize_pin_queue (void) { - void **start, **cur, **end; - /* sort and uniq pin_queue: we just sort and we let the rest discard multiple values */ - /* it may be better to keep ranges of pinned memory instead of individually pinning objects */ - SGEN_LOG (5, "Sorting pin queue, size: %zd", next_pin_slot); - if ((next_pin_slot - start_slot) > 1) - sgen_sort_addresses (pin_queue + start_slot, next_pin_slot - start_slot); - start = cur = pin_queue + start_slot; - end = pin_queue + next_pin_slot; - while (cur < end) { - *start = *cur++; - while (*start == *cur && cur < end) - cur++; - start++; - }; - next_pin_slot = start - pin_queue; - SGEN_LOG (5, "Pin queue reduced to size: %zd", next_pin_slot); + sgen_pointer_queue_sort_uniq (&pin_queue); } size_t sgen_get_pinned_count (void) { - return next_pin_slot; + return pin_queue.next_slot; } void @@ -176,8 +130,9 @@ sgen_dump_pin_queue (void) int i; for (i = 0; i < last_num_pinned; ++i) { - SGEN_LOG (3, "Bastard pinning obj %p (%s), size: %zd", pin_queue [i], sgen_safe_name (pin_queue [i]), sgen_safe_object_get_size (pin_queue [i])); - } + void *ptr = pin_queue.data [i]; + SGEN_LOG (3, "Bastard pinning obj %p (%s), size: %zd", ptr, sgen_safe_name (ptr), sgen_safe_object_get_size (ptr)); + } } typedef struct _CementHashEntry CementHashEntry; @@ -311,7 +266,7 @@ sgen_cement_lookup_or_register (char *obj) } void -sgen_cement_iterate (IterateObjectCallbackFunc callback, void *callback_data) +sgen_pin_cemented_objects (void) { int i; for (i = 0; i < SGEN_CEMENT_HASH_SIZE; ++i) { @@ -320,7 +275,8 @@ sgen_cement_iterate (IterateObjectCallbackFunc callback, void *callback_data) SGEN_ASSERT (5, cement_hash [i].count >= SGEN_CEMENT_THRESHOLD, "Cementing hash inconsistent"); - callback (cement_hash [i].obj, 0, callback_data); + sgen_pin_stage_ptr (cement_hash [i].obj); + /* FIXME: do pin stats if enabled */ } } diff --git a/mono/metadata/sgen-pinning.h b/mono/metadata/sgen-pinning.h index ef41df24d2..19840beb64 100644 --- a/mono/metadata/sgen-pinning.h +++ b/mono/metadata/sgen-pinning.h @@ -28,7 +28,7 @@ enum { }; void sgen_pin_stage_ptr (void *ptr) MONO_INTERNAL; -void sgen_optimize_pin_queue (size_t start_slot) MONO_INTERNAL; +void sgen_optimize_pin_queue (void) MONO_INTERNAL; void sgen_init_pinning (void) MONO_INTERNAL; void sgen_finish_pinning (void) MONO_INTERNAL; void sgen_pin_queue_clear_discarded_entries (GCMemSection *section, size_t max_pin_slot) MONO_INTERNAL; @@ -53,7 +53,7 @@ void sgen_cement_concurrent_start (void) MONO_INTERNAL; void sgen_cement_concurrent_finish (void) MONO_INTERNAL; gboolean sgen_cement_lookup (char *obj) MONO_INTERNAL; gboolean sgen_cement_lookup_or_register (char *obj) MONO_INTERNAL; -void sgen_cement_iterate (IterateObjectCallbackFunc callback, void *callback_data) MONO_INTERNAL; +void sgen_pin_cemented_objects (void) MONO_INTERNAL; void sgen_cement_clear_below_threshold (void) MONO_INTERNAL; #endif diff --git a/mono/metadata/sgen-pointer-queue.c b/mono/metadata/sgen-pointer-queue.c new file mode 100644 index 0000000000..793c294532 --- /dev/null +++ b/mono/metadata/sgen-pointer-queue.c @@ -0,0 +1,124 @@ +/* + * sgen-pointer-queue.c: A pointer queue that can be sorted. + * + * 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. + */ + +#include "utils/mono-compiler.h" +#include "metadata/sgen-gc.h" +#include "metadata/sgen-pointer-queue.h" + +#ifdef HAVE_SGEN_GC + +void +sgen_pointer_queue_clear (SgenPointerQueue *queue) +{ + queue->next_slot = 0; +} + +static void +realloc_queue (SgenPointerQueue *queue) +{ + size_t new_size = queue->size ? queue->size + queue->size/2 : 1024; + void **new_data = sgen_alloc_internal_dynamic (sizeof (void*) * new_size, INTERNAL_MEM_PIN_QUEUE, TRUE); + memcpy (new_data, queue->data, sizeof (void*) * queue->next_slot); + sgen_free_internal_dynamic (queue->data, sizeof (void*) * queue->size, INTERNAL_MEM_PIN_QUEUE); + queue->data = new_data; + queue->size = new_size; + SGEN_LOG (4, "Reallocated pointer queue to size: %lu", new_size); +} + +void +sgen_pointer_queue_add (SgenPointerQueue *queue, void *ptr) +{ + if (queue->next_slot >= queue->size) + realloc_queue (queue); + + queue->data [queue->next_slot++] = ptr; +} + +size_t +sgen_pointer_queue_search (SgenPointerQueue *queue, void *addr) +{ + size_t first = 0, last = queue->next_slot; + while (first < last) { + size_t middle = first + ((last - first) >> 1); + if (addr <= queue->data [middle]) + last = middle; + else + first = middle + 1; + } + g_assert (first == last); + return first; +} + +/* + * Removes all NULL pointers from the queue. + */ +void +sgen_pointer_queue_remove_nulls (SgenPointerQueue *queue) +{ + void **start, **cur, **end; + start = cur = queue->data; + end = queue->data + queue->next_slot; + while (cur < end) { + if (*cur) + *start++ = *cur++; + else + ++cur; + } + queue->next_slot = start - queue->data; +} + +/* + * Sorts the pointers in the queue, then removes duplicates. + */ +void +sgen_pointer_queue_sort_uniq (SgenPointerQueue *queue) +{ + void **start, **cur, **end; + /* sort and uniq pin_queue: we just sort and we let the rest discard multiple values */ + /* it may be better to keep ranges of pinned memory instead of individually pinning objects */ + SGEN_LOG (5, "Sorting pointer queue, size: %lu", queue->next_slot); + if (queue->next_slot > 1) + sgen_sort_addresses (queue->data, queue->next_slot); + start = cur = queue->data; + end = queue->data + queue->next_slot; + while (cur < end) { + *start = *cur++; + while (cur < end && *start == *cur) + cur++; + start++; + }; + queue->next_slot = start - queue->data; + SGEN_LOG (5, "Pointer queue reduced to size: %lu", queue->next_slot); +} + +/* + * Does a linear search through the pointer queue to find `ptr`. Returns the index if + * found, otherwise (size_t)-1. + */ +size_t +sgen_pointer_queue_find (SgenPointerQueue *queue, void *ptr) +{ + size_t i; + for (i = 0; i < queue->next_slot; ++i) + if (queue->data [i] == ptr) + return i; + return (size_t)-1; +} + +#endif diff --git a/mono/metadata/sgen-pointer-queue.h b/mono/metadata/sgen-pointer-queue.h new file mode 100644 index 0000000000..d972f3cc92 --- /dev/null +++ b/mono/metadata/sgen-pointer-queue.h @@ -0,0 +1,36 @@ +/* + * sgen-pointer-queue.h: A pointer queue that can be sorted. + * + * 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. + */ + +#ifndef __MONO_SGEN_POINTER_QUEUE_H__ +#define __MONO_SGEN_POINTER_QUEUE_H__ + +typedef struct { + void **data; + size_t size; + size_t next_slot; +} SgenPointerQueue; + +void sgen_pointer_queue_add (SgenPointerQueue *queue, void *ptr) MONO_INTERNAL; +void sgen_pointer_queue_clear (SgenPointerQueue *queue) MONO_INTERNAL; +void sgen_pointer_queue_remove_nulls (SgenPointerQueue *queue) MONO_INTERNAL; +void sgen_pointer_queue_sort_uniq (SgenPointerQueue *queue) MONO_INTERNAL; +size_t sgen_pointer_queue_search (SgenPointerQueue *queue, void *addr) MONO_INTERNAL; +size_t sgen_pointer_queue_find (SgenPointerQueue *queue, void *ptr) MONO_INTERNAL; + +#endif diff --git a/mono/metadata/sgen-scan-object.h b/mono/metadata/sgen-scan-object.h index 7cbe57a6c8..ad569dda35 100644 --- a/mono/metadata/sgen-scan-object.h +++ b/mono/metadata/sgen-scan-object.h @@ -23,7 +23,12 @@ * object must be given in the variable "char* start". Afterwards, * "start" will point to the start of the next object, if the scanned * object contained references. If not, the value of "start" should - * be considered undefined after executing this code. + * be considered undefined after executing this code. The object's + * GC descriptor must be in the variable "mword desc". + * + * The macro `HANDLE_PTR` will be invoked for every reference encountered while scanning the + * object. It is called with two parameters: The pointer to the reference (not the + * reference itself!) as well as the pointer to the scanned object. * * Modifiers (automatically undefined): * @@ -40,17 +45,8 @@ { #ifndef SCAN_OBJECT_NOVTABLE - GCVTable *vt; - mword desc; - - vt = (GCVTable*)SGEN_LOAD_VTABLE (start); - //type = vt->desc & 0x7; - - /* gcc should be smart enough to remove the bounds check, but it isn't:( */ - desc = vt->desc; - #if defined(SGEN_HEAVY_BINARY_PROTOCOL) && defined(SCAN_OBJECT_PROTOCOL) - binary_protocol_scan_begin (start, vt, sgen_safe_object_get_size ((MonoObject*)start)); + binary_protocol_scan_begin (start, SGEN_LOAD_VTABLE (start), sgen_safe_object_get_size ((MonoObject*)start)); #endif #else #if defined(SGEN_HEAVY_BINARY_PROTOCOL) && defined(SCAN_OBJECT_PROTOCOL) @@ -97,7 +93,7 @@ #ifndef SCAN_OBJECT_NOVTABLE case DESC_TYPE_COMPLEX_ARR: /* this is an array of complex structs */ -#define SCAN OBJ_COMPLEX_ARR_FOREACH_PTR (vt, start) +#define SCAN OBJ_COMPLEX_ARR_FOREACH_PTR (desc, start) #ifndef SCAN_OBJECT_NOSCAN SCAN; #endif diff --git a/mono/metadata/sgen-simple-nursery.c b/mono/metadata/sgen-simple-nursery.c index f2f7066c30..2cfb9d3211 100644 --- a/mono/metadata/sgen-simple-nursery.c +++ b/mono/metadata/sgen-simple-nursery.c @@ -35,12 +35,6 @@ alloc_for_promotion (MonoVTable *vtable, char *obj, size_t objsize, gboolean has return major_collector.alloc_object (vtable, objsize, has_references); } -static inline char* -par_alloc_for_promotion (MonoVTable *vtable, char *obj, size_t objsize, gboolean has_references) -{ - return major_collector.par_alloc_object (vtable, objsize, has_references); -} - static SgenFragment* build_fragments_get_exclude_head (void) { @@ -79,7 +73,6 @@ init_nursery (SgenFragmentAllocator *allocator, char *start, char *end) #define SGEN_SIMPLE_NURSERY #define SERIAL_COPY_OBJECT simple_nursery_serial_copy_object -#define PARALLEL_COPY_OBJECT simple_nursery_parallel_copy_object #define SERIAL_COPY_OBJECT_FROM_OBJ simple_nursery_serial_copy_object_from_obj #include "sgen-minor-copy-object.h" @@ -91,7 +84,6 @@ sgen_simple_nursery_init (SgenMinorCollector *collector) collector->is_split = FALSE; collector->alloc_for_promotion = alloc_for_promotion; - collector->par_alloc_for_promotion = par_alloc_for_promotion; collector->prepare_to_space = prepare_to_space; collector->clear_fragments = clear_fragments; diff --git a/mono/metadata/sgen-split-nursery.c b/mono/metadata/sgen-split-nursery.c index 1f62d14b70..87cc412c67 100644 --- a/mono/metadata/sgen-split-nursery.c +++ b/mono/metadata/sgen-split-nursery.c @@ -145,8 +145,6 @@ static AgeAllocationBuffer age_alloc_buffers [MAX_AGE]; /* The collector allocs from here. */ static SgenFragmentAllocator collector_allocator; -static LOCK_DECLARE (par_alloc_buffer_refill_mutex); - static inline int get_object_age (char *object) { @@ -292,82 +290,6 @@ alloc_for_promotion (MonoVTable *vtable, char *obj, size_t objsize, gboolean has return p; } -static char* -par_alloc_for_promotion_slow_path (int age, size_t objsize) -{ - char *p; - size_t allocated_size; - size_t aligned_objsize = (size_t)align_up (objsize, SGEN_TO_SPACE_GRANULE_BITS); - - mono_mutex_lock (&par_alloc_buffer_refill_mutex); - -restart: - p = age_alloc_buffers [age].next; - if (G_LIKELY (p + objsize <= age_alloc_buffers [age].end)) { - if (SGEN_CAS_PTR ((void*)&age_alloc_buffers [age].next, p + objsize, p) != p) - goto restart; - } else { - /* Reclaim remaining space - if we OOMd the nursery nothing to see here. */ - char *end = age_alloc_buffers [age].end; - if (end) { - do { - p = age_alloc_buffers [age].next; - } while (SGEN_CAS_PTR ((void*)&age_alloc_buffers [age].next, end, p) != p); - sgen_clear_range (p, end); - } - - /* By setting end to NULL we make sure no other thread can advance while we're updating.*/ - age_alloc_buffers [age].end = NULL; - STORE_STORE_FENCE; - - p = sgen_fragment_allocator_par_range_alloc ( - &collector_allocator, - MAX (aligned_objsize, AGE_ALLOC_BUFFER_DESIRED_SIZE), - MAX (aligned_objsize, AGE_ALLOC_BUFFER_MIN_SIZE), - &allocated_size); - if (p) { - set_age_in_range (p, p + allocated_size, age); - age_alloc_buffers [age].next = p + objsize; - STORE_STORE_FENCE; /* Next must arrive before the new value for next. */ - age_alloc_buffers [age].end = p + allocated_size; - } - } - - mono_mutex_unlock (&par_alloc_buffer_refill_mutex); - return p; -} - -static inline char* -par_alloc_for_promotion (MonoVTable *vtable, char *obj, size_t objsize, gboolean has_references) -{ - char *p; - int age; - - age = get_object_age (obj); - if (age >= promote_age) - return major_collector.par_alloc_object (vtable, objsize, has_references); - -restart: - p = age_alloc_buffers [age].next; - - LOAD_LOAD_FENCE; /* The read of ->next must happen before ->end */ - - if (G_LIKELY (p + objsize <= age_alloc_buffers [age].end)) { - if (SGEN_CAS_PTR ((void*)&age_alloc_buffers [age].next, p + objsize, p) != p) - goto restart; - } else { - p = par_alloc_for_promotion_slow_path (age, objsize); - - /* Have we failed to promote to the nursery, lets just evacuate it to old gen. */ - if (!p) - return major_collector.par_alloc_object (vtable, objsize, has_references); - } - - *(MonoVTable**)p = vtable; - - return p; -} - static char* minor_alloc_for_promotion (MonoVTable *vtable, char *obj, size_t objsize, gboolean has_references) { @@ -380,18 +302,6 @@ minor_alloc_for_promotion (MonoVTable *vtable, char *obj, size_t objsize, gboole return alloc_for_promotion (vtable, obj, objsize, has_references); } -static char* -minor_par_alloc_for_promotion (MonoVTable *vtable, char *obj, size_t objsize, gboolean has_references) -{ - /* - We only need to check for a non-nursery object if we're doing a major collection. - */ - if (!sgen_ptr_in_nursery (obj)) - return major_collector.par_alloc_object (vtable, objsize, has_references); - - return par_alloc_for_promotion (vtable, obj, objsize, has_references); -} - static SgenFragment* build_fragments_get_exclude_head (void) { @@ -522,7 +432,6 @@ print_gc_param_usage (void) #define SGEN_SPLIT_NURSERY #define SERIAL_COPY_OBJECT split_nursery_serial_copy_object -#define PARALLEL_COPY_OBJECT split_nursery_parallel_copy_object #define SERIAL_COPY_OBJECT_FROM_OBJ split_nursery_serial_copy_object_from_obj #include "sgen-minor-copy-object.h" @@ -534,7 +443,6 @@ sgen_split_nursery_init (SgenMinorCollector *collector) collector->is_split = TRUE; collector->alloc_for_promotion = minor_alloc_for_promotion; - collector->par_alloc_for_promotion = minor_par_alloc_for_promotion; collector->prepare_to_space = prepare_to_space; collector->clear_fragments = clear_fragments; @@ -547,7 +455,6 @@ sgen_split_nursery_init (SgenMinorCollector *collector) FILL_MINOR_COLLECTOR_COPY_OBJECT (collector); FILL_MINOR_COLLECTOR_SCAN_OBJECT (collector); - LOCK_INIT (par_alloc_buffer_refill_mutex); } diff --git a/mono/metadata/sgen-stw.c b/mono/metadata/sgen-stw.c index 5a2ab0e968..2a9bf34788 100644 --- a/mono/metadata/sgen-stw.c +++ b/mono/metadata/sgen-stw.c @@ -52,7 +52,7 @@ align_pointer (void *ptr) #ifdef USE_MONO_CTX static MonoContext cur_thread_ctx; #else -static mword cur_thread_regs [ARCH_NUM_REGS] = {0}; +static mword cur_thread_regs [ARCH_NUM_REGS]; #endif static void diff --git a/mono/metadata/sgen-tagged-pointer.h b/mono/metadata/sgen-tagged-pointer.h new file mode 100644 index 0000000000..fc065f7f96 --- /dev/null +++ b/mono/metadata/sgen-tagged-pointer.h @@ -0,0 +1,34 @@ +/* + * sgen-tagged-pointer.h: Macros for tagging and untagging pointers. + * + * 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. + */ + +#ifndef __MONO_SGEN_TAGGED_POINTER_H__ +#define __MONO_SGEN_TAGGED_POINTER_H__ + +#define SGEN_POINTER_IS_TAGGED_1(p) ((mword)(p) & 1) +#define SGEN_POINTER_TAG_1(p) ((void*)((mword)(p) | 1)) +#define SGEN_POINTER_UNTAG_1(p) ((void*)((mword)(p) & ~1)) + +#define SGEN_POINTER_IS_TAGGED_2(p) ((mword)(p) & 2) +#define SGEN_POINTER_TAG_2(p) ((void*)((mword)(p) | 2)) +#define SGEN_POINTER_UNTAG_2(p) ((void*)((mword)(p) & ~2)) + +#define SGEN_POINTER_IS_TAGGED_1_OR_2(p) ((mword)(p) & 3) +#define SGEN_POINTER_UNTAG_12(p) ((void*)((mword)(p) & ~3)) + +#endif diff --git a/mono/metadata/sgen-tarjan-bridge.c b/mono/metadata/sgen-tarjan-bridge.c index 59013f7012..5c6525e9ec 100644 --- a/mono/metadata/sgen-tarjan-bridge.c +++ b/mono/metadata/sgen-tarjan-bridge.c @@ -661,6 +661,7 @@ push_all (ScanData *data) { MonoObject *obj = data->obj; char *start = (char*)obj; + mword desc = sgen_obj_get_descriptor (start); #if DUMP_GRAPH printf ("**scanning %p %s\n", obj, safe_name_bridge (obj)); @@ -712,6 +713,7 @@ compute_low (ScanData *data) { MonoObject *obj = data->obj; char *start = (char*)obj; + mword desc = sgen_obj_get_descriptor (start); #include "sgen-scan-object.h" } diff --git a/mono/metadata/sgen-workers.c b/mono/metadata/sgen-workers.c index b3eebb02d9..2d48745762 100644 --- a/mono/metadata/sgen-workers.c +++ b/mono/metadata/sgen-workers.c @@ -140,7 +140,7 @@ workers_wait (void) static gboolean collection_needs_workers (void) { - return sgen_collection_is_parallel () || sgen_collection_is_concurrent (); + return sgen_collection_is_concurrent (); } void @@ -243,9 +243,9 @@ workers_steal (WorkerData *data, WorkerData *victim_data, gboolean lock) n -= m; sgen_gray_object_alloc_queue_section (queue); - memcpy (queue->first->objects, + memcpy (queue->first->entries, victim_data->stealable_stack + victim_data->stealable_stack_fill - num + n, - sizeof (char*) * m); + sizeof (GrayQueueEntry) * m); queue->first->size = m; /* @@ -253,10 +253,10 @@ workers_steal (WorkerData *data, WorkerData *victim_data, gboolean lock) * Doing so trigger "assert not reached" in sgen-scan-object.h : we use the queue->cursor * to compute the size of the first section during section allocation (via alloc_prepare_func * -> workers_gray_queue_share_redirect -> sgen_gray_object_dequeue_section) which will be then - * set to 0, because queue->cursor is still pointing to queue->first->objects [-1], thus + * set to 0, because queue->cursor is still pointing to queue->first->entries [-1], thus * losing objects in the gray queue. */ - queue->cursor = (char**)queue->first->objects + queue->first->size - 1; + queue->cursor = queue->first->entries + queue->first->size - 1; } victim_data->stealable_stack_fill -= num; @@ -301,7 +301,7 @@ workers_get_work (WorkerData *data) * distribute gray queue. */ major = sgen_get_major_collector (); - if (major->is_concurrent || major->is_parallel) { + if (major->is_concurrent) { GrayQueueSection *section = sgen_section_gray_queue_dequeue (&workers_distribute_gray_queue); if (section) { sgen_gray_object_enqueue_section (&data->private_gray_queue, section); @@ -338,8 +338,8 @@ workers_gray_queue_share_redirect (SgenGrayQueue *queue) int num = MIN (section->size, STEALABLE_STACK_SIZE - data->stealable_stack_fill); memcpy (data->stealable_stack + data->stealable_stack_fill, - section->objects + section->size - num, - sizeof (char*) * num); + section->entries + section->size - num, + sizeof (GrayQueueEntry) * num); section->size -= num; data->stealable_stack_fill += num; @@ -441,7 +441,7 @@ sgen_workers_init_distribute_gray_queue (void) if (!collection_needs_workers ()) return; - init_distribute_gray_queue (sgen_get_major_collector ()->is_concurrent || sgen_get_major_collector ()->is_parallel); + init_distribute_gray_queue (sgen_get_major_collector ()->is_concurrent); } void @@ -449,7 +449,7 @@ sgen_workers_init (int num_workers) { int i; - if (!sgen_get_major_collector ()->is_parallel && !sgen_get_major_collector ()->is_concurrent) + if (!sgen_get_major_collector ()->is_concurrent) return; //g_print ("initing %d workers\n", num_workers); @@ -462,7 +462,7 @@ sgen_workers_init (int num_workers) MONO_SEM_INIT (&workers_waiting_sem, 0); MONO_SEM_INIT (&workers_done_sem, 0); - init_distribute_gray_queue (sgen_get_major_collector ()->is_concurrent || sgen_get_major_collector ()->is_parallel); + init_distribute_gray_queue (sgen_get_major_collector ()->is_concurrent); if (sgen_get_major_collector ()->alloc_worker_data) workers_gc_thread_major_collector_data = sgen_get_major_collector ()->alloc_worker_data (); diff --git a/mono/metadata/sgen-workers.h b/mono/metadata/sgen-workers.h index 9070623673..d13c460967 100644 --- a/mono/metadata/sgen-workers.h +++ b/mono/metadata/sgen-workers.h @@ -34,7 +34,7 @@ struct _WorkerData { mono_mutex_t stealable_stack_mutex; volatile int stealable_stack_fill; - char *stealable_stack [STEALABLE_STACK_SIZE]; + GrayQueueEntry stealable_stack [STEALABLE_STACK_SIZE]; }; typedef void (*JobFunc) (WorkerData *worker_data, void *job_data); diff --git a/mono/metadata/socket-io.c b/mono/metadata/socket-io.c index cbce0f7726..949164e554 100644 --- a/mono/metadata/socket-io.c +++ b/mono/metadata/socket-io.c @@ -20,12 +20,6 @@ #include #include #include -#ifdef HAVE_UNISTD_H -#include -#endif -#include - -#include #ifdef HOST_WIN32 #include #else @@ -36,6 +30,12 @@ #include #include #endif +#ifdef HAVE_UNISTD_H +#include +#endif +#include + +#include #include #include diff --git a/mono/metadata/string-icalls.c b/mono/metadata/string-icalls.c index 0927141e79..9c95f04c5e 100644 --- a/mono/metadata/string-icalls.c +++ b/mono/metadata/string-icalls.c @@ -67,3 +67,10 @@ ves_icall_System_String_GetLOSLimit (void) return (limit - 2 - sizeof (MonoString)) / 2; } + +void +ves_icall_System_String_InternalSetLength (MonoString *str, gint32 new_length) +{ + mono_gc_set_string_length (str, new_length); +} + diff --git a/mono/metadata/string-icalls.h b/mono/metadata/string-icalls.h index a0b831a1e2..33bcf80378 100644 --- a/mono/metadata/string-icalls.h +++ b/mono/metadata/string-icalls.h @@ -30,4 +30,7 @@ ves_icall_System_String_InternalIsInterned (MonoString *str) MONO_INTERNAL; int ves_icall_System_String_GetLOSLimit (void) MONO_INTERNAL; +void +ves_icall_System_String_InternalSetLength (MonoString *str, gint32 new_length) MONO_INTERNAL; + #endif /* _MONO_CLI_STRING_ICALLS_H_ */ diff --git a/mono/metadata/threadpool.c b/mono/metadata/threadpool.c index 39ade54daa..36514cc6ea 100644 --- a/mono/metadata/threadpool.c +++ b/mono/metadata/threadpool.c @@ -41,6 +41,7 @@ #include #endif #include +#include #ifdef HAVE_SYS_SOCKET_H #include #endif @@ -62,13 +63,6 @@ #define THREAD_WANTS_A_BREAK(t) ((t->state & (ThreadState_StopRequested | \ ThreadState_SuspendRequested)) != 0) -#define SPIN_TRYLOCK(i) (InterlockedCompareExchange (&(i), 1, 0) == 0) -#define SPIN_LOCK(i) do { \ - if (SPIN_TRYLOCK (i)) \ - break; \ - } while (1) - -#define SPIN_UNLOCK(i) i = 0 #define SMALL_STACK (128 * (sizeof (gpointer) / 4) * 1024) /* DEBUG: prints tp data every 2s */ @@ -83,6 +77,12 @@ enum { KQUEUE_BACKEND }; +enum { + MONITOR_STATE_AWAKE, + MONITOR_STATE_FALLING_ASLEEP, + MONITOR_STATE_SLEEPING +}; + typedef struct { mono_mutex_t io_lock; /* access to sock_to_state */ int inited; // 0 -> not initialized , 1->initializing, 2->initialized, 3->cleaned up @@ -127,12 +127,10 @@ typedef struct { void *pc_nthreads; /* Performance counter for total number of active threads */ /**/ volatile gint destroy_thread; - volatile gint ignore_times; /* Used when there's a thread being created or destroyed */ - volatile gint sp_lock; /* spin lock used to protect ignore_times */ - volatile gint64 last_check; - volatile gint64 time_sum; - volatile gint n_sum; - gint64 averages [2]; +#if DEBUG + volatile gint32 njobs; +#endif + volatile gint32 nexecuted; gboolean is_io; } ThreadPool; @@ -148,6 +146,7 @@ static void threadpool_init (ThreadPool *tp, int min_threads, int max_threads, v static void threadpool_start_idle_threads (ThreadPool *tp); static void threadpool_kill_idle_threads (ThreadPool *tp); static gboolean threadpool_start_thread (ThreadPool *tp); +static void threadpool_kill_thread (ThreadPool *tp); static void monitor_thread (gpointer data); static void socket_io_cleanup (SocketIOData *data); static MonoObject *get_io_event (MonoMList **list, gint event); @@ -159,10 +158,17 @@ static MonoClass *async_call_klass; static MonoClass *socket_async_call_klass; static MonoClass *process_async_call_klass; +static GPtrArray *threads; +mono_mutex_t threads_lock; static GPtrArray *wsqs; mono_mutex_t wsqs_lock; static gboolean suspended; +static volatile gint32 monitor_njobs = 0; +static volatile gint32 monitor_state; +static MonoSemType monitor_sem; +static MonoInternalThread *monitor_internal_thread; + /* Hooks */ static MonoThreadPoolFunc tp_start_func; static MonoThreadPoolFunc tp_finish_func; @@ -656,6 +662,16 @@ mono_async_invoke (ThreadPool *tp, MonoAsyncResult *ares) mono_thread_set_execution_context (ares->original_context); ares->original_context = NULL; } + +#if DEBUG + InterlockedDecrement (&tp->njobs); +#endif + if (!tp->is_io) + InterlockedIncrement (&tp->nexecuted); + + if (InterlockedDecrement (&monitor_njobs) == 0) + monitor_state = MONITOR_STATE_FALLING_ASLEEP; + return exc; } @@ -757,21 +773,135 @@ signal_handler (int signo) } #endif +#define SAMPLES_PERIOD 500 +#define HISTORY_SIZE 10 +/* number of iteration without any jobs + in the queue before going to sleep */ +#define NUM_WAITING_ITERATIONS 10 + +typedef struct { + gint32 nexecuted; + gint32 nthreads; + gint8 nthreads_diff; +} SamplesHistory; + +/* + * returns : + * - 1 if the number of threads should increase + * - 0 if it should not change + * - -1 if it should decrease + * - -2 in case of error + */ +static gint8 +monitor_heuristic (gint16 *current, gint16 *history_size, SamplesHistory *history, ThreadPool *tp) +{ + int i; + gint8 decision; + gint16 cur, max = 0; + gboolean all_waitsleepjoin; + MonoInternalThread *thread; + + /* + * The following heuristic tries to approach the optimal number of threads to maximize jobs throughput. To + * achieve this, it simply stores the number of jobs executed (nexecuted), the number of Threads (nthreads) + * and the decision (nthreads_diff) for the past HISTORY_SIZE periods of time, each period being of + * duration SAMPLES_PERIOD ms. This history gives us an insight into what happened, and to see if we should + * increase or reduce the number of threads by comparing the last period (current) to the best one. + * + * The algorithm can be describe as following : + * - if we have a better throughput than the best period : we should either increase the number of threads + * in case we already have more threads, either reduce the number of threads if we have less threads; this + * is equivalent to move away from the number of threads of the best period, because we are currently better + * - if we have a worse throughput than the best period : we should either decrease the number of threads if + * we have more threads, either increase the number of threads if we have less threads; this is equivalent + * to get closer to the number of threads of the best period, because we are currently worse + */ + + *history_size = MIN (*history_size + 1, HISTORY_SIZE); + cur = *current = (*current + 1) % *history_size; + + history [cur].nthreads = tp->nthreads; + history [cur].nexecuted = InterlockedExchange (&tp->nexecuted, 0); + + if (tp->waiting) { + /* if we have waiting thread in the pool, then do not create a new one */ + history [cur].nthreads_diff = tp->waiting > 1 ? -1 : 0; + decision = 0; + } else if (tp->nthreads < tp->min_threads) { + history [cur].nthreads_diff = 1; + decision = 1; + } else if (*history_size <= 1) { + /* first iteration, let's add a thread by default */ + history [cur].nthreads_diff = 1; + decision = 2; + } else { + mono_mutex_lock (&threads_lock); + if (threads == NULL) { + mono_mutex_unlock (&threads_lock); + return -2; + } + all_waitsleepjoin = TRUE; + for (i = 0; i < threads->len; ++i) { + thread = g_ptr_array_index (threads, i); + if (!(thread->state & ThreadState_WaitSleepJoin)) { + all_waitsleepjoin = FALSE; + break; + } + } + mono_mutex_unlock (&threads_lock); + + if (all_waitsleepjoin) { + /* we might be in a condition of starvation/deadlock with tasks waiting for each others */ + history [cur].nthreads_diff = 1; + decision = 5; + } else { + max = cur == 0 ? 1 : 0; + for (i = 0; i < *history_size; i++) { + if (i == cur) + continue; + if (history [i].nexecuted > history [max].nexecuted) + max = i; + } + + if (history [cur].nexecuted >= history [max].nexecuted) { + /* we improved the situation, let's continue ! */ + history [cur].nthreads_diff = history [cur].nthreads >= history [max].nthreads ? 1 : -1; + decision = 3; + } else { + /* we made it worse, let's return to previous situation */ + history [cur].nthreads_diff = history [cur].nthreads >= history [max].nthreads ? -1 : 1; + decision = 4; + } + } + } + +#if DEBUG + printf ("monitor_thread: decision: %1d, history [current]: {nexecuted: %5d, nthreads: %3d, waiting: %2d, nthreads_diff: %2d}, history [max]: {nexecuted: %5d, nthreads: %3d}\n", + decision, history [cur].nexecuted, history [cur].nthreads, tp->waiting, history [cur].nthreads_diff, history [max].nexecuted, history [max].nthreads); +#endif + + return history [cur].nthreads_diff; +} + static void monitor_thread (gpointer unused) { ThreadPool *pools [2]; MonoInternalThread *thread; - guint32 ms; - gboolean need_one; int i; + guint32 ms; + gint8 num_waiting_iterations = 0; + + gint16 history_size = 0, current = -1; + SamplesHistory *history = malloc (sizeof (SamplesHistory) * HISTORY_SIZE); + pools [0] = &async_tp; pools [1] = &async_io_tp; thread = mono_thread_internal_current (); ves_icall_System_Threading_Thread_SetName_internal (thread, mono_string_new (mono_domain_get (), "Threadpool monitor")); while (1) { - ms = 500; + ms = SAMPLES_PERIOD; i = 10; //number of spurious awakes we tolerate before doing a round of rebalancing. do { guint32 ts; @@ -791,26 +921,44 @@ monitor_thread (gpointer unused) if (suspended) continue; + /* threadpool is cleaning up */ + if (async_tp.pool_status == 2 || async_io_tp.pool_status == 2) + break; + + switch (monitor_state) { + case MONITOR_STATE_AWAKE: + num_waiting_iterations = 0; + break; + case MONITOR_STATE_FALLING_ASLEEP: + if (++num_waiting_iterations == NUM_WAITING_ITERATIONS) { + if (monitor_state == MONITOR_STATE_FALLING_ASLEEP && InterlockedCompareExchange (&monitor_state, MONITOR_STATE_SLEEPING, MONITOR_STATE_FALLING_ASLEEP) == MONITOR_STATE_FALLING_ASLEEP) { + MONO_SEM_WAIT (&monitor_sem); + + num_waiting_iterations = 0; + current = -1; + history_size = 0; + } + } + break; + case MONITOR_STATE_SLEEPING: + g_assert_not_reached (); + } + for (i = 0; i < 2; i++) { ThreadPool *tp; tp = pools [i]; - if (tp->waiting > 0) - continue; - need_one = (mono_cq_count (tp->queue) > 0); - if (!need_one && !tp->is_io) { - mono_mutex_lock (&wsqs_lock); - for (i = 0; wsqs != NULL && i < wsqs->len; i++) { - MonoWSQ *wsq; - wsq = g_ptr_array_index (wsqs, i); - if (mono_wsq_count (wsq) != 0) { - need_one = TRUE; - break; - } - } - mono_mutex_unlock (&wsqs_lock); + + if (tp->is_io) { + if (!tp->waiting && mono_cq_count (tp->queue) > 0) + threadpool_start_thread (tp); + } else { + gint8 nthreads_diff = monitor_heuristic (¤t, &history_size, history, tp); + + if (nthreads_diff == 1) + threadpool_start_thread (tp); + else if (nthreads_diff == -1) + threadpool_kill_thread (tp); } - if (need_one) - threadpool_start_thread (tp); } } } @@ -857,6 +1005,10 @@ mono_thread_pool_init (void) async_call_klass = mono_class_from_name (mono_defaults.corlib, "System", "MonoAsyncCall"); g_assert (async_call_klass); + mono_mutex_init (&threads_lock); + threads = g_ptr_array_sized_new (thread_count); + g_assert (threads); + mono_mutex_init_recursive (&wsqs_lock); wsqs = g_ptr_array_sized_new (MAX (100 * cpu_count, thread_count)); @@ -878,6 +1030,10 @@ mono_thread_pool_init (void) signal (SIGALRM, signal_handler); alarm (2); #endif + + MONO_SEM_INIT (&monitor_sem, 0); + monitor_state = MONITOR_STATE_AWAKE; + monitor_njobs = 0; } static MonoAsyncResult * @@ -1004,6 +1160,14 @@ mono_thread_pool_cleanup (void) threadpool_kill_idle_threads (&async_tp); threadpool_free_queue (&async_tp); } + + if (threads) { + mono_mutex_lock (&threads_lock); + if (threads) + g_ptr_array_free (threads, FALSE); + threads = NULL; + mono_mutex_unlock (&threads_lock); + } if (wsqs) { mono_mutex_lock (&wsqs_lock); @@ -1014,6 +1178,8 @@ mono_thread_pool_cleanup (void) mono_mutex_unlock (&wsqs_lock); MONO_SEM_DESTROY (&async_tp.new_job); } + + MONO_SEM_DESTROY (&monitor_sem); } static gboolean @@ -1021,6 +1187,7 @@ threadpool_start_thread (ThreadPool *tp) { gint n; guint32 stack_size; + MonoInternalThread *thread; stack_size = (!tp->is_io) ? 0 : SMALL_STACK; while (!mono_runtime_is_shutting_down () && (n = tp->nthreads) < tp->max_threads) { @@ -1028,7 +1195,13 @@ threadpool_start_thread (ThreadPool *tp) #ifndef DISABLE_PERFCOUNTERS mono_perfcounter_update_value (tp->pc_nthreads, TRUE, 1); #endif - mono_thread_create_internal (mono_get_root_domain (), tp->async_invoke, tp, TRUE, stack_size); + thread = mono_thread_create_internal (mono_get_root_domain (), tp->async_invoke, tp, TRUE, stack_size); + if (!tp->is_io) { + mono_mutex_lock (&threads_lock); + g_assert (threads != NULL); + g_ptr_array_add (threads, thread); + mono_mutex_unlock (&threads_lock); + } return TRUE; } } @@ -1043,6 +1216,13 @@ pulse_on_new_job (ThreadPool *tp) MONO_SEM_POST (&tp->new_job); } +static void +threadpool_kill_thread (ThreadPool *tp) +{ + if (tp->destroy_thread == 0 && InterlockedCompareExchange (&tp->destroy_thread, 1, 0) == 0) + pulse_on_new_job (tp); +} + void icall_append_job (MonoObject *ar) { @@ -1058,7 +1238,6 @@ threadpool_append_job (ThreadPool *tp, MonoObject *ar) static void threadpool_append_jobs (ThreadPool *tp, MonoObject **jobs, gint njobs) { - static int job_counter; MonoObject *ar; gint i; @@ -1067,7 +1246,8 @@ threadpool_append_jobs (ThreadPool *tp, MonoObject **jobs, gint njobs) if (tp->pool_status == 0 && InterlockedCompareExchange (&tp->pool_status, 1, 0) == 0) { if (!tp->is_io) { - mono_thread_create_internal (mono_get_root_domain (), monitor_thread, NULL, TRUE, SMALL_STACK); + monitor_internal_thread = mono_thread_create_internal (mono_get_root_domain (), monitor_thread, NULL, TRUE, SMALL_STACK); + monitor_internal_thread->flags |= MONO_THREAD_FLAG_DONT_MANAGE; threadpool_start_thread (tp); } /* Create on demand up to min_threads to avoid startup penalty for apps that don't use @@ -1078,14 +1258,18 @@ threadpool_append_jobs (ThreadPool *tp, MonoObject **jobs, gint njobs) } } + InterlockedAdd (&monitor_njobs, njobs); + + if (monitor_state == MONITOR_STATE_SLEEPING && InterlockedCompareExchange (&monitor_state, MONITOR_STATE_AWAKE, MONITOR_STATE_SLEEPING) == MONITOR_STATE_SLEEPING) + MONO_SEM_POST (&monitor_sem); + + if (monitor_state == MONITOR_STATE_FALLING_ASLEEP) + InterlockedCompareExchange (&monitor_state, MONITOR_STATE_AWAKE, MONITOR_STATE_FALLING_ASLEEP); + for (i = 0; i < njobs; i++) { ar = jobs [i]; if (ar == NULL || mono_domain_is_unloading (ar->vtable->domain)) continue; /* Might happen when cleaning domain jobs */ - if (!tp->is_io && (InterlockedIncrement (&job_counter) % 10) == 0) { - MonoAsyncResult *o = (MonoAsyncResult *) ar; - o->add_time = mono_100ns_ticks (); - } threadpool_jobs_inc (ar); #ifndef DISABLE_PERFCOUNTERS mono_perfcounter_update_value (tp->pc_nitems, TRUE, 1); @@ -1096,6 +1280,10 @@ threadpool_append_jobs (ThreadPool *tp, MonoObject **jobs, gint njobs) mono_cq_enqueue (tp->queue, ar); } +#if DEBUG + InterlockedAdd (&tp->njobs, njobs); +#endif + for (i = 0; tp->waiting > 0 && i < MIN(njobs, tp->max_threads); i++) pulse_on_new_job (tp); } @@ -1309,84 +1497,6 @@ dequeue_or_steal (ThreadPool *tp, gpointer *data, MonoWSQ *local_wsq) return (*data != NULL); } -static void -process_idle_times (ThreadPool *tp, gint64 t) -{ - gint64 ticks; - gint64 avg; - gboolean compute_avg; - gint new_threads; - gint64 per1; - - if (tp->ignore_times || t <= 0) - return; - - compute_avg = FALSE; - ticks = mono_100ns_ticks (); - t = ticks - t; - SPIN_LOCK (tp->sp_lock); - if (tp->ignore_times) { - SPIN_UNLOCK (tp->sp_lock); - return; - } - tp->time_sum += t; - tp->n_sum++; - if (tp->last_check == 0) - tp->last_check = ticks; - else if (tp->last_check > 0 && (ticks - tp->last_check) > 5000000) { - tp->ignore_times = 1; - compute_avg = TRUE; - } - SPIN_UNLOCK (tp->sp_lock); - - if (!compute_avg) - return; - - //printf ("Items: %d Time elapsed: %.3fs\n", tp->n_sum, (ticks - tp->last_check) / 10000.0); - tp->last_check = ticks; - new_threads = 0; - avg = tp->time_sum / tp->n_sum; - if (tp->averages [1] == 0) { - tp->averages [1] = avg; - } else { - per1 = ((100 * (ABS (avg - tp->averages [1]))) / tp->averages [1]); - if (per1 > 5) { - if (avg > tp->averages [1]) { - if (tp->averages [1] < tp->averages [0]) { - new_threads = -1; - } else { - new_threads = 1; - } - } else if (avg < tp->averages [1] && tp->averages [1] < tp->averages [0]) { - new_threads = 1; - } - } else { - int min, n; - min = tp->min_threads; - n = tp->nthreads; - if ((n - min) < min && tp->busy_threads == n) - new_threads = 1; - } - /* - if (new_threads != 0) { - printf ("n: %d per1: %lld avg=%lld avg1=%lld avg0=%lld\n", new_threads, per1, avg, tp->averages [1], tp->averages [0]); - } - */ - } - - tp->time_sum = 0; - tp->n_sum = 0; - - tp->averages [0] = tp->averages [1]; - tp->averages [1] = avg; - tp->ignore_times = 0; - - if (new_threads == -1) { - if (tp->destroy_thread == 0 && InterlockedCompareExchange (&tp->destroy_thread, 1, 0) == 0) - pulse_on_new_job (tp); - } -} - static gboolean should_i_die (ThreadPool *tp) { @@ -1513,8 +1623,6 @@ async_invoke_thread (gpointer data) if (tp_item_begin_func) tp_item_begin_func (tp_item_user_data); - if (!is_io_task && ar->add_time > 0) - process_idle_times (tp, ar->add_time); exc = mono_async_invoke (tp, ar); if (tp_item_end_func) tp_item_end_func (tp_item_user_data); @@ -1541,8 +1649,12 @@ async_invoke_thread (gpointer data) ar = NULL; data = NULL; must_die = should_i_die (tp); - if (!must_die && (tp->is_io || !mono_wsq_local_pop (&data))) - dequeue_or_steal (tp, &data, wsq); + if (must_die) { + mono_wsq_suspend (wsq); + } else { + if (tp->is_io || !mono_wsq_local_pop (&data)) + dequeue_or_steal (tp, &data, wsq); + } n_naps = 0; while (!must_die && !data && n_naps < 4) { @@ -1608,6 +1720,16 @@ async_invoke_thread (gpointer data) if (tp_finish_func) tp_finish_func (tp_hooks_user_data); + + if (!tp->is_io) { + if (threads) { + mono_mutex_lock (&threads_lock); + if (threads) + g_ptr_array_remove_fast (threads, mono_thread_current ()->internal_thread); + mono_mutex_unlock (&threads_lock); + } + } + return; } } diff --git a/mono/metadata/threads-types.h b/mono/metadata/threads-types.h index 6aeca4acf5..860bb5b67e 100644 --- a/mono/metadata/threads-types.h +++ b/mono/metadata/threads-types.h @@ -40,8 +40,6 @@ typedef enum { ThreadApartmentState_Unknown = 0x00000002 } MonoThreadApartmentState; -typedef void (*MonoThreadNotifyPendingExcFunc) (void); - #define SPECIAL_STATIC_NONE 0 #define SPECIAL_STATIC_THREAD 1 #define SPECIAL_STATIC_CONTEXT 2 @@ -54,6 +52,8 @@ typedef LPTHREAD_START_ROUTINE WapiThreadStart; typedef struct _MonoInternalThread MonoInternalThread; typedef void (*MonoThreadCleanupFunc) (MonoInternalThread* thread); +/* INFO has type MonoThreadInfo* */ +typedef void (*MonoThreadNotifyPendingExcFunc) (gpointer info); MonoInternalThread* mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, gboolean threadpool_thread, guint32 stack_size) MONO_INTERNAL; diff --git a/mono/metadata/threads.c.REMOVED.git-id b/mono/metadata/threads.c.REMOVED.git-id index 74d6730492..ebbbbb9d30 100644 --- a/mono/metadata/threads.c.REMOVED.git-id +++ b/mono/metadata/threads.c.REMOVED.git-id @@ -1 +1 @@ -67df295370b4690937b2805267309468881fe376 \ No newline at end of file +36a847d10b5f6f6d72cc5bfb9023b0b82f7840d3 \ No newline at end of file diff --git a/mono/metadata/verify.c.REMOVED.git-id b/mono/metadata/verify.c.REMOVED.git-id index 9398c849f2..03a86eb694 100644 --- a/mono/metadata/verify.c.REMOVED.git-id +++ b/mono/metadata/verify.c.REMOVED.git-id @@ -1 +1 @@ -50781a4bbf4016b6955b6eb6f6a40211525dc3a3 \ No newline at end of file +95bde8efbc5433a93c092b52b3d363ee63b859b5 \ No newline at end of file diff --git a/mono/mini/Makefile.am b/mono/mini/Makefile.am index f928eec806..d43605ce62 100644 --- a/mono/mini/Makefile.am +++ b/mono/mini/Makefile.am @@ -83,8 +83,6 @@ libmonoldflags=$(monoldflags) -version-info 1:0:0 endif endif -if JIT_SUPPORTED - if SUPPORT_SGEN sgen_binaries = mono-sgen sgen_libraries = libmonosgen-2.0.la @@ -166,8 +164,6 @@ libmono_llvm_la_LIBADD += $(top_builddir)/mono/mini/libmonoboehm-$(API_VER).la $ endif endif -endif - mono_boehm_SOURCES = \ main.c @@ -195,6 +191,8 @@ buildver-boehm.h: libmini-static.la $(monodir)/mono/metadata/libmonoruntime-stat endif @echo "const char *build_date = \"`date`\";" > buildver-boehm.h mono_boehm-main.$(OBJEXT): buildver-boehm.h +main.c: buildver-boehm.h + endif if DISABLE_EXECUTABLES @@ -204,6 +202,8 @@ buildver-sgen.h: libmini-static.la $(monodir)/mono/metadata/libmonoruntimesgen-s endif @echo "const char *build_date = \"`date`\";" > buildver-sgen.h mono_sgen-main-sgen.$(OBJEXT): buildver-sgen.h +main-sgen.c: buildver-sgen.h + if DTRACE_G_REQUIRED LIBMONO_DTRACE_OBJECT = .libs/mono-dtrace.$(OBJEXT) @@ -344,6 +344,7 @@ sparc_sources = \ s390x_sources = \ mini-s390x.c \ mini-s390x.h \ + support-s390x.h \ exceptions-s390x.c \ tramp-s390x.c @@ -726,11 +727,7 @@ clean-local: pkgconfigdir = $(libdir)/pkgconfig -if JIT_SUPPORTED BUILT_SOURCES = version.h $(arch_built) -else -BUILT_SOURCES = version.h -endif CLEANFILES= $(BUILT_SOURCES) *.exe *.dll EXTRA_DIST = TestDriver.cs ldscript ldscript.mono \ diff --git a/mono/mini/Makefile.am.in b/mono/mini/Makefile.am.in index f928eec806..d43605ce62 100755 --- a/mono/mini/Makefile.am.in +++ b/mono/mini/Makefile.am.in @@ -83,8 +83,6 @@ libmonoldflags=$(monoldflags) -version-info 1:0:0 endif endif -if JIT_SUPPORTED - if SUPPORT_SGEN sgen_binaries = mono-sgen sgen_libraries = libmonosgen-2.0.la @@ -166,8 +164,6 @@ libmono_llvm_la_LIBADD += $(top_builddir)/mono/mini/libmonoboehm-$(API_VER).la $ endif endif -endif - mono_boehm_SOURCES = \ main.c @@ -195,6 +191,8 @@ buildver-boehm.h: libmini-static.la $(monodir)/mono/metadata/libmonoruntime-stat endif @echo "const char *build_date = \"`date`\";" > buildver-boehm.h mono_boehm-main.$(OBJEXT): buildver-boehm.h +main.c: buildver-boehm.h + endif if DISABLE_EXECUTABLES @@ -204,6 +202,8 @@ buildver-sgen.h: libmini-static.la $(monodir)/mono/metadata/libmonoruntimesgen-s endif @echo "const char *build_date = \"`date`\";" > buildver-sgen.h mono_sgen-main-sgen.$(OBJEXT): buildver-sgen.h +main-sgen.c: buildver-sgen.h + if DTRACE_G_REQUIRED LIBMONO_DTRACE_OBJECT = .libs/mono-dtrace.$(OBJEXT) @@ -344,6 +344,7 @@ sparc_sources = \ s390x_sources = \ mini-s390x.c \ mini-s390x.h \ + support-s390x.h \ exceptions-s390x.c \ tramp-s390x.c @@ -726,11 +727,7 @@ clean-local: pkgconfigdir = $(libdir)/pkgconfig -if JIT_SUPPORTED BUILT_SOURCES = version.h $(arch_built) -else -BUILT_SOURCES = version.h -endif CLEANFILES= $(BUILT_SOURCES) *.exe *.dll EXTRA_DIST = TestDriver.cs ldscript ldscript.mono \ diff --git a/mono/mini/Makefile.in.REMOVED.git-id b/mono/mini/Makefile.in.REMOVED.git-id index bd848b8f31..d685e341b2 100644 --- a/mono/mini/Makefile.in.REMOVED.git-id +++ b/mono/mini/Makefile.in.REMOVED.git-id @@ -1 +1 @@ -2f30bdbf60795aee40ea0f4f24cae680080b15fa \ No newline at end of file +4a25b5dd42ff9776e3727b7cacb27601db947e95 \ No newline at end of file diff --git a/mono/mini/aot-compiler.c.REMOVED.git-id b/mono/mini/aot-compiler.c.REMOVED.git-id index 90e420b2e7..df49569399 100644 --- a/mono/mini/aot-compiler.c.REMOVED.git-id +++ b/mono/mini/aot-compiler.c.REMOVED.git-id @@ -1 +1 @@ -c92ecebebaa1eee09c940cc7d1c4c93e5d1d4144 \ No newline at end of file +bb3b34a253893bd4fa2466a3f04dd95872fc7ec3 \ No newline at end of file diff --git a/mono/mini/aot-runtime.c.REMOVED.git-id b/mono/mini/aot-runtime.c.REMOVED.git-id index 3cc3532ef4..94009859bc 100644 --- a/mono/mini/aot-runtime.c.REMOVED.git-id +++ b/mono/mini/aot-runtime.c.REMOVED.git-id @@ -1 +1 @@ -aaff578a306f09ba5b7a8446ffd93c37c72d27f3 \ No newline at end of file +63b62dadf81942b3d97f9b4e5cc609c2809911c8 \ No newline at end of file diff --git a/mono/mini/branch-opts.c b/mono/mini/branch-opts.c index 44a78aa476..2be95e7364 100644 --- a/mono/mini/branch-opts.c +++ b/mono/mini/branch-opts.c @@ -1299,7 +1299,7 @@ mono_optimize_branches (MonoCompile *cfg) /* branches to the following block can be removed */ if (bb->last_ins && bb->last_ins->opcode == OP_BR && !bbn->out_of_line) { - bb->last_ins->opcode = OP_NOP; + NULLIFY_INS (bb->last_ins); changed = TRUE; if (cfg->verbose_level > 2) g_print ("br removal triggered %d -> %d\n", bb->block_num, bbn->block_num); diff --git a/mono/mini/cpu-amd64.md b/mono/mini/cpu-amd64.md old mode 100644 new mode 100755 index bb6f32f9e6..be535210a6 --- a/mono/mini/cpu-amd64.md +++ b/mono/mini/cpu-amd64.md @@ -114,7 +114,7 @@ cgt: dest:c len:8 cgt.un: dest:c len:8 clt: dest:c len:8 clt.un: dest:c len:8 -localloc: dest:i src1:i len:84 +localloc: dest:i src1:i len:96 compare: src1:i src2:i len:3 lcompare: src1:i src2:i len:3 icompare: src1:i src2:i len:3 @@ -511,7 +511,7 @@ vcall2_membase: src1:b len:64 clob:c dyn_call: src1:i src2:i len:64 clob:c nacl:128 -localloc_imm: dest:i len:84 +localloc_imm: dest:i len:96 load_mem: dest:i len:16 loadi8_mem: dest:i len:16 diff --git a/mono/mini/cpu-arm.md b/mono/mini/cpu-arm.md index 431936113c..b31b368ec7 100644 --- a/mono/mini/cpu-arm.md +++ b/mono/mini/cpu-arm.md @@ -211,7 +211,7 @@ sbb_imm: dest:i src1:i len:12 br_reg: src1:i len:8 bigmul: len:8 dest:l src1:i src2:i bigmul_un: len:8 dest:l src1:i src2:i -tls_get: len:8 dest:i clob:c +tls_get: len:24 dest:i clob:c # 32 bit opcodes int_add: dest:i src1:i src2:i len:4 diff --git a/mono/mini/cpu-s390x.md b/mono/mini/cpu-s390x.md index b3dce352ec..2eee2e4e57 100644 --- a/mono/mini/cpu-s390x.md +++ b/mono/mini/cpu-s390x.md @@ -283,6 +283,7 @@ long_xor: dest:i src1:i src2:i len:8 long_neg: dest:i src1:i len:6 long_not: dest:i src1:i len:12 long_rem: dest:i src1:i src2:i len:12 +long_rem_imm: dest:i src1:i src2:i len:12 long_rem_un: dest:i src1:i src2:i len:16 long_shl: dest:i src1:i src2:i len:14 long_shl_imm: dest:i src1:i len:14 diff --git a/mono/mini/debugger-agent.c.REMOVED.git-id b/mono/mini/debugger-agent.c.REMOVED.git-id index 8c7eee8c92..e97f2cccd9 100644 --- a/mono/mini/debugger-agent.c.REMOVED.git-id +++ b/mono/mini/debugger-agent.c.REMOVED.git-id @@ -1 +1 @@ -5919430186944c79d1bc0037ae77e8d81457d584 \ No newline at end of file +c01cb0f1d7cc08de553c82563b55dc957e759ac0 \ No newline at end of file diff --git a/mono/mini/decompose.c b/mono/mini/decompose.c index 07242d8613..f29e913acf 100644 --- a/mono/mini/decompose.c +++ b/mono/mini/decompose.c @@ -470,7 +470,7 @@ mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins) } #endif MONO_EMIT_NEW_BIALU (cfg, ins->opcode, ins->dreg, ins->sreg1, ins->sreg2); - ins->opcode = OP_NOP; + NULLIFY_INS (ins); } else { emulate = TRUE; } @@ -486,6 +486,9 @@ mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins) ins->opcode = OP_ICONST; MONO_INST_NULLIFY_SREGS (ins); ins->inst_c0 = 0; +#if __s390__ + } +#else } else if ((ins->inst_imm > 0) && (ins->inst_imm < (1LL << 32)) && (power != -1)) { gboolean is_long = ins->opcode == OP_LREM_IMM; int compensator_reg = alloc_ireg (cfg); @@ -497,12 +500,12 @@ mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins) if (power > 1) { intermediate_reg = compensator_reg; - MONO_EMIT_NEW_BIALU_IMM (cfg, is_long ? OP_LSHR_IMM : OP_SHR_IMM, intermediate_reg, ins->sreg1, is_long ? 63 : 31); + MONO_EMIT_NEW_BIALU_IMM (cfg, is_long ? OP_LSHR_IMM : OP_ISHR_IMM, intermediate_reg, ins->sreg1, is_long ? 63 : 31); } else { intermediate_reg = ins->sreg1; } - MONO_EMIT_NEW_BIALU_IMM (cfg, is_long ? OP_LSHR_UN_IMM : OP_SHR_UN_IMM, compensator_reg, intermediate_reg, (is_long ? 64 : 32) - power); + MONO_EMIT_NEW_BIALU_IMM (cfg, is_long ? OP_LSHR_UN_IMM : OP_ISHR_UN_IMM, compensator_reg, intermediate_reg, (is_long ? 64 : 32) - power); MONO_EMIT_NEW_BIALU (cfg, is_long ? OP_LADD : OP_IADD, ins->dreg, ins->sreg1, compensator_reg); /* Compute remainder */ MONO_EMIT_NEW_BIALU_IMM (cfg, is_long ? OP_LAND_IMM : OP_AND_IMM, ins->dreg, ins->dreg, (1 << power) - 1); @@ -511,6 +514,7 @@ mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins) NULLIFY_INS (ins); } +#endif break; } @@ -980,7 +984,7 @@ mono_decompose_long_opts (MonoCompile *cfg) MONO_EMIT_NEW_BIALU (cfg, OP_IOR, d1, d1, d2); MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ICOMPARE_IMM, -1, d1, 0); MONO_EMIT_NEW_BRANCH_BLOCK2 (cfg, next->opcode == OP_LBEQ ? OP_IBEQ : OP_IBNE_UN, next->inst_true_bb, next->inst_false_bb); - next->opcode = OP_NOP; + NULLIFY_INS (next); break; } case OP_LBGE: @@ -998,7 +1002,7 @@ mono_decompose_long_opts (MonoCompile *cfg) MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBNE_UN, next->inst_false_bb); MONO_EMIT_NEW_BIALU (cfg, OP_COMPARE, -1, tree->sreg1 + 1, tree->sreg2 + 1); MONO_EMIT_NEW_BRANCH_BLOCK2 (cfg, lbr_decomp [next->opcode - OP_LBEQ][1], next->inst_true_bb, next->inst_false_bb); - next->opcode = OP_NOP; + NULLIFY_INS (next); break; case OP_LCEQ: { int d1, d2; @@ -1012,7 +1016,7 @@ mono_decompose_long_opts (MonoCompile *cfg) MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ICOMPARE_IMM, -1, d1, 0); MONO_EMIT_NEW_UNALU (cfg, OP_ICEQ, next->dreg, -1); - next->opcode = OP_NOP; + NULLIFY_INS (next); break; } case OP_LCLT: @@ -1034,7 +1038,7 @@ mono_decompose_long_opts (MonoCompile *cfg) MONO_START_BB (cfg, set_to_1); MONO_EMIT_NEW_ICONST (cfg, next->dreg, 1); MONO_START_BB (cfg, set_to_0); - next->opcode = OP_NOP; + NULLIFY_INS (next); break; } default: @@ -1066,7 +1070,7 @@ mono_decompose_long_opts (MonoCompile *cfg) MONO_EMIT_NEW_BIALU (cfg, OP_IOR, d1, d1, d2); MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ICOMPARE_IMM, -1, d1, 0); MONO_EMIT_NEW_BRANCH_BLOCK2 (cfg, next->opcode == OP_LBEQ ? OP_IBEQ : OP_IBNE_UN, next->inst_true_bb, next->inst_false_bb); - next->opcode = OP_NOP; + NULLIFY_INS (next); break; } @@ -1085,7 +1089,7 @@ mono_decompose_long_opts (MonoCompile *cfg) MONO_EMIT_NEW_BRANCH_BLOCK (cfg, OP_IBNE_UN, next->inst_false_bb); MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, low_reg, low_imm); MONO_EMIT_NEW_BRANCH_BLOCK2 (cfg, lbr_decomp [next->opcode - OP_LBEQ][1], next->inst_true_bb, next->inst_false_bb); - next->opcode = OP_NOP; + NULLIFY_INS (next); break; case OP_LCEQ: { int d1, d2; @@ -1099,7 +1103,7 @@ mono_decompose_long_opts (MonoCompile *cfg) MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ICOMPARE_IMM, -1, d1, 0); MONO_EMIT_NEW_UNALU (cfg, OP_ICEQ, next->dreg, -1); - next->opcode = OP_NOP; + NULLIFY_INS (next); break; } case OP_LCLT: @@ -1121,7 +1125,7 @@ mono_decompose_long_opts (MonoCompile *cfg) MONO_START_BB (cfg, set_to_1); MONO_EMIT_NEW_ICONST (cfg, next->dreg, 1); MONO_START_BB (cfg, set_to_0); - next->opcode = OP_NOP; + NULLIFY_INS (next); break; } default: @@ -1330,18 +1334,18 @@ mono_decompose_vtype_opts (MonoCompile *cfg) if (call->vret_in_reg) { MonoCallInst *call2; - /* Replace the vcall with an integer call */ + /* Replace the vcall with a scalar call */ MONO_INST_NEW_CALL (cfg, call2, OP_NOP); memcpy (call2, call, sizeof (MonoCallInst)); switch (ins->opcode) { case OP_VCALL: - call2->inst.opcode = OP_CALL; + call2->inst.opcode = call->vret_in_reg_fp ? OP_FCALL : OP_CALL; break; case OP_VCALL_REG: - call2->inst.opcode = OP_CALL_REG; + call2->inst.opcode = call->vret_in_reg_fp ? OP_FCALL_REG : OP_CALL_REG; break; case OP_VCALL_MEMBASE: - call2->inst.opcode = OP_CALL_MEMBASE; + call2->inst.opcode = call->vret_in_reg_fp ? OP_FCALL_MEMBASE : OP_CALL_MEMBASE; break; } call2->inst.dreg = alloc_preg (cfg); @@ -1367,12 +1371,19 @@ mono_decompose_vtype_opts (MonoCompile *cfg) break; case 3: case 4: - MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, dest->dreg, 0, call2->inst.dreg); + if (call->vret_in_reg_fp) + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER4_MEMBASE_REG, dest->dreg, 0, call2->inst.dreg); + else + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STOREI4_MEMBASE_REG, dest->dreg, 0, call2->inst.dreg); break; case 5: case 6: case 7: case 8: + if (call->vret_in_reg_fp) { + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER8_MEMBASE_REG, dest->dreg, 0, call2->inst.dreg); + break; + } #if SIZEOF_REGISTER == 4 /* FIXME Other ABIs might return in different regs than the ones used for LCALL. diff --git a/mono/mini/driver.c b/mono/mini/driver.c index 7b34b18df0..c6c8e20628 100644 --- a/mono/mini/driver.c +++ b/mono/mini/driver.c @@ -408,8 +408,7 @@ mini_regression_step (MonoImage *image, int verbose, int *total_run, int *total, } else { cfailed++; - if (verbose) - g_print ("Test '%s' failed compilation.\n", method->name); + g_print ("Test '%s' failed compilation.\n", method->name); } if (mini_stats_fd) fprintf (mini_stats_fd, "%f, ", @@ -1903,6 +1902,9 @@ mono_main (int argc, char* argv[]) mono_load_coree (argv [i]); #endif + /* Set rootdir before loading config */ + mono_set_rootdir (); + /* Parse gac loading options before loading assemblies. */ if (mono_compile_aot || action == DO_EXEC || action == DO_DEBUGGER) { mono_config_parse (config_file); diff --git a/mono/mini/dwarfwriter.c b/mono/mini/dwarfwriter.c index 9f68a62683..67585763b6 100644 --- a/mono/mini/dwarfwriter.c +++ b/mono/mini/dwarfwriter.c @@ -1376,6 +1376,7 @@ static const guint8 *token_handler_ip; static char* token_handler (MonoDisHelper *dh, MonoMethod *method, guint32 token) { + MonoError error; char *res, *desc; MonoMethod *cmethod; MonoClass *klass; @@ -1389,10 +1390,12 @@ token_handler (MonoDisHelper *dh, MonoMethod *method, guint32 token) case CEE_ISINST: case CEE_CASTCLASS: case CEE_LDELEMA: - if (method->wrapper_type) + if (method->wrapper_type) { klass = data; - else - klass = mono_class_get_full (method->klass->image, token, NULL); + } else { + klass = mono_class_get_checked (method->klass->image, token, &error); + g_assert (mono_error_ok (&error)); /* FIXME error handling */ + } res = g_strdup_printf ("<%s>", klass->name); break; case CEE_NEWOBJ: diff --git a/mono/mini/exceptions-amd64.c b/mono/mini/exceptions-amd64.c index 12b4ef31dd..a0865b7e2b 100644 --- a/mono/mini/exceptions-amd64.c +++ b/mono/mini/exceptions-amd64.c @@ -45,7 +45,7 @@ LPTOP_LEVEL_EXCEPTION_FILTER mono_old_win_toplevel_exception_filter; void *mono_win_vectored_exception_handle; #define W32_SEH_HANDLE_EX(_ex) \ - if (_ex##_handler) _ex##_handler(0, ep, sctx) + if (_ex##_handler) _ex##_handler(0, ep, ctx) static LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep) { @@ -68,7 +68,6 @@ static LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) { EXCEPTION_RECORD* er; CONTEXT* ctx; - MonoContext* sctx; LONG res; MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); @@ -81,22 +80,6 @@ static LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) er = ep->ExceptionRecord; ctx = ep->ContextRecord; - sctx = g_malloc(sizeof(MonoContext)); - - /* Copy Win32 context to UNIX style context */ - sctx->rax = ctx->Rax; - sctx->rbx = ctx->Rbx; - sctx->rcx = ctx->Rcx; - sctx->rdx = ctx->Rdx; - sctx->rbp = ctx->Rbp; - sctx->rsp = ctx->Rsp; - sctx->rsi = ctx->Rsi; - sctx->rdi = ctx->Rdi; - sctx->rip = ctx->Rip; - sctx->r12 = ctx->R12; - sctx->r13 = ctx->R13; - sctx->r14 = ctx->R14; - sctx->r15 = ctx->R15; switch (er->ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: @@ -126,30 +109,8 @@ static LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) * can correctly chain the exception. */ res = EXCEPTION_CONTINUE_SEARCH; - } else { - /* Copy context back */ - /* Nonvolatile */ - ctx->Rsp = sctx->rsp; - ctx->Rdi = sctx->rdi; - ctx->Rsi = sctx->rsi; - ctx->Rbx = sctx->rbx; - ctx->Rbp = sctx->rbp; - ctx->R12 = sctx->r12; - ctx->R13 = sctx->r13; - ctx->R14 = sctx->r14; - ctx->R15 = sctx->r15; - ctx->Rip = sctx->rip; - - /* Volatile But should not matter?*/ - ctx->Rax = sctx->rax; - ctx->Rcx = sctx->rcx; - ctx->Rdx = sctx->rdx; } - /* TODO: Find right place to free this in stack overflow case */ - if (er->ExceptionCode != EXCEPTION_STACK_OVERFLOW) - g_free (sctx); - return res; } @@ -591,7 +552,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, guint8 *cfa; guint32 unwind_info_len; guint8 *unwind_info; - guint8 *epilog; + guint8 *epilog = NULL; frame->type = FRAME_TYPE_MANAGED; @@ -604,7 +565,9 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, printf ("%s %p %p\n", ji->d.method->name, ji->code_start, ip); mono_print_unwind_info (unwind_info, unwind_info_len); */ - epilog = (guint8*)ji->code_start + ji->code_size - mono_jinfo_get_epilog_size (ji); + /* LLVM compiled code doesn't have this info */ + if (ji->has_arch_eh_info) + epilog = (guint8*)ji->code_start + ji->code_size - mono_jinfo_get_epilog_size (ji); regs [AMD64_RAX] = new_ctx->rax; regs [AMD64_RBX] = new_ctx->rbx; @@ -622,7 +585,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, mono_unwind_frame (unwind_info, unwind_info_len, ji->code_start, (guint8*)ji->code_start + ji->code_size, - ip, &epilog, regs, MONO_MAX_IREGS + 1, + ip, epilog ? &epilog : NULL, regs, MONO_MAX_IREGS + 1, save_locations, MONO_MAX_IREGS, &cfa); new_ctx->rax = regs [AMD64_RAX]; @@ -645,12 +608,6 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, /* Adjust IP */ new_ctx->rip --; -#ifndef MONO_AMD64_NO_PUSHES - /* Pop arguments off the stack */ - if (ji->has_arch_eh_info) - new_ctx->rsp += mono_jit_info_get_arch_eh_info (ji)->stack_size; -#endif - return TRUE; } else if (*lmf) { guint64 rip; @@ -841,6 +798,8 @@ mono_arch_ip_from_context (void *sigctx) ucontext_t *ctx = (ucontext_t*)sigctx; return (gpointer)UCONTEXT_REG_RIP (ctx); +#elif defined(HOST_WIN32) + return ((CONTEXT*)sigctx)->Rip; #else MonoContext *ctx = sigctx; return (gpointer)ctx->rip; @@ -1062,10 +1021,17 @@ static gpointer throw_pending_exception; * exception. */ void -mono_arch_notify_pending_exc (void) +mono_arch_notify_pending_exc (MonoThreadInfo *info) { MonoLMF *lmf = mono_get_lmf (); + if (!info) { + lmf = mono_get_lmf (); + } else { + g_assert (info->suspend_state.valid); + lmf = info->suspend_state.unwind_data [MONO_UNWIND_DATA_LMF]; + } + if (!lmf) /* Not yet started */ return; diff --git a/mono/mini/exceptions-arm.c b/mono/mini/exceptions-arm.c index d7fd3318f3..e39248ceda 100644 --- a/mono/mini/exceptions-arm.c +++ b/mono/mini/exceptions-arm.c @@ -36,6 +36,7 @@ #include "mini.h" #include "mini-arm.h" #include "mono/utils/mono-sigcontext.h" +#include "mono/utils/mono-compiler.h" /* * arch_get_restore_context: @@ -536,10 +537,7 @@ handle_signal_exception (gpointer obj) * This works around a gcc 4.5 bug: * https://bugs.launchpad.net/ubuntu/+source/gcc-4.5/+bug/721531 */ -#if defined(__GNUC__) -__attribute__((noinline)) -#endif -static gpointer +static MONO_NEVER_INLINE gpointer get_handle_signal_exception_addr (void) { return handle_signal_exception; diff --git a/mono/mini/exceptions-x86.c b/mono/mini/exceptions-x86.c old mode 100644 new mode 100755 index d335d7ea5c..cb21804db1 --- a/mono/mini/exceptions-x86.c +++ b/mono/mini/exceptions-x86.c @@ -49,7 +49,7 @@ extern int (*gUnhandledExceptionHandler)(EXCEPTION_POINTERS*); #endif #define W32_SEH_HANDLE_EX(_ex) \ - if (_ex##_handler) _ex##_handler(0, ep, sctx) + if (_ex##_handler) _ex##_handler(0, ep, ctx) LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep) { @@ -189,7 +189,6 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) { EXCEPTION_RECORD* er; CONTEXT* ctx; - struct sigcontext* sctx; LONG res; MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); @@ -202,22 +201,10 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) er = ep->ExceptionRecord; ctx = ep->ContextRecord; - sctx = g_malloc(sizeof(struct sigcontext)); - - /* Copy Win32 context to UNIX style context */ - sctx->eax = ctx->Eax; - sctx->ebx = ctx->Ebx; - sctx->ecx = ctx->Ecx; - sctx->edx = ctx->Edx; - sctx->ebp = ctx->Ebp; - sctx->esp = ctx->Esp; - sctx->esi = ctx->Esi; - sctx->edi = ctx->Edi; - sctx->eip = ctx->Eip; switch (er->ExceptionCode) { case EXCEPTION_STACK_OVERFLOW: - win32_handle_stack_overflow (ep, sctx); + win32_handle_stack_overflow (ep, ctx); break; case EXCEPTION_ACCESS_VIOLATION: W32_SEH_HANDLE_EX(segv); @@ -246,23 +233,8 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) * can correctly chain the exception. */ res = EXCEPTION_CONTINUE_SEARCH; - } else { - /* Copy context back */ - ctx->Eax = sctx->eax; - ctx->Ebx = sctx->ebx; - ctx->Ecx = sctx->ecx; - ctx->Edx = sctx->edx; - ctx->Ebp = sctx->ebp; - ctx->Esp = sctx->esp; - ctx->Esi = sctx->esi; - ctx->Edi = sctx->edi; - ctx->Eip = sctx->eip; } - /* TODO: Find right place to free this in stack overflow case */ - if (er->ExceptionCode != EXCEPTION_STACK_OVERFLOW) - g_free (sctx); - return res; } @@ -278,8 +250,9 @@ void win32_seh_init() void win32_seh_cleanup() { - if (mono_old_win_toplevel_exception_filter) SetUnhandledExceptionFilter(mono_old_win_toplevel_exception_filter); - RemoveVectoredExceptionHandler (seh_unhandled_exception_filter); + if (mono_old_win_toplevel_exception_filter) + SetUnhandledExceptionFilter(mono_old_win_toplevel_exception_filter); + RemoveVectoredExceptionHandler (mono_win_vectored_exception_handle); } void win32_seh_set_handler(int type, MonoW32ExceptionHandler handler) @@ -835,29 +808,6 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, /* Adjust IP */ new_ctx->eip --; - -#ifndef MONO_X86_NO_PUSHES - /* Pop arguments off the stack */ - if (ji->has_arch_eh_info) { - int stack_size; - - stack_size = mono_jit_info_get_arch_eh_info (ji)->stack_size; - - if (stack_size) { -#ifdef ENABLE_LLVM - MonoJitInfo *caller_ji; - - caller_ji = mini_jit_info_table_find (domain, (char*)new_ctx->eip, NULL); - /* LLVM doesn't push the arguments */ - if (caller_ji && !caller_ji->from_llvm) - new_ctx->esp += stack_size; -#else - new_ctx->esp += stack_size; -#endif - } - } -#endif - return TRUE; } else if (*lmf) { @@ -878,14 +828,12 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, return TRUE; } - + if ((ji = mini_jit_info_table_find (domain, (gpointer)(*lmf)->eip, NULL))) { + frame->ji = ji; } else { - if (!((guint32)((*lmf)->previous_lmf) & 1)) - /* Top LMF entry */ + if (!(*lmf)->method) return FALSE; - g_assert_not_reached (); - /* Trampoline lmf frame */ frame->method = (*lmf)->method; } @@ -898,7 +846,6 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, /* Adjust IP */ new_ctx->eip --; - frame->ji = ji; frame->type = FRAME_TYPE_MANAGED_TO_NATIVE; /* Check if we are in a trampoline LMF frame */ @@ -952,15 +899,15 @@ mono_arch_ip_from_context (void *sigctx) #if defined(__native_client__) printf("WARNING: mono_arch_ip_from_context() called!\n"); return (NULL); -#else -#ifdef MONO_ARCH_USE_SIGACTION +#elif defined(MONO_ARCH_USE_SIGACTION) ucontext_t *ctx = (ucontext_t*)sigctx; return (gpointer)UCONTEXT_REG_EIP (ctx); +#elif defined(HOST_WIN32) + return ((CONTEXT*)sigctx)->Eip; #else struct sigcontext *ctx = sigctx; return (gpointer)ctx->SC_EIP; #endif -#endif /* __native_client__ */ } /* diff --git a/mono/mini/generics.cs b/mono/mini/generics.cs index cdf7b36ef6..f350710c76 100644 --- a/mono/mini/generics.cs +++ b/mono/mini/generics.cs @@ -913,6 +913,7 @@ class Tests } } + [Category ("GSHAREDVT")] static int test_0_synchronized_gshared () { var c = new SyncClass (); if (c.getInstance () != typeof (string)) @@ -1088,6 +1089,36 @@ class Tests var s = f2 (f); return s == "A" ? 0 : 1; } + + public interface ICovariant + { + } + + // Deleting the `out` modifier from this line stop the problem + public interface IExtCovariant : ICovariant + { + } + + public class Sample : ICovariant + { + } + + public interface IMyInterface + { + } + + public static int test_0_variant_cast_cache () { + object covariant = new Sample(); + + var foo = (ICovariant)(covariant); + + try { + var extCovariant = (IExtCovariant)covariant; + return 1; + } catch { + return 0; + } + } } #if !MOBILE diff --git a/mono/mini/jit-icalls.c b/mono/mini/jit-icalls.c index 8c7c00c832..fcfcf4f3cd 100644 --- a/mono/mini/jit-icalls.c +++ b/mono/mini/jit-icalls.c @@ -17,7 +17,7 @@ #endif #include "jit-icalls.h" - +#include void* mono_ldftn (MonoMethod *method) { @@ -1022,9 +1022,9 @@ mono_helper_ldstr_mscorlib (guint32 idx) MonoObject* mono_helper_newobj_mscorlib (guint32 idx) { - MonoClass *klass = mono_class_get (mono_defaults.corlib, MONO_TOKEN_TYPE_DEF | idx); - - g_assert (klass); + MonoError error; + MonoClass *klass = mono_class_get_checked (mono_defaults.corlib, MONO_TOKEN_TYPE_DEF | idx, &error); + mono_error_raise_exception (&error); return mono_object_new (mono_domain_get (), klass); } diff --git a/mono/mini/liveness.c b/mono/mini/liveness.c index a5cbabb53a..5f304b390f 100644 --- a/mono/mini/liveness.c +++ b/mono/mini/liveness.c @@ -812,9 +812,7 @@ update_liveness2 (MonoCompile *cfg, MonoInst *ins, gboolean set_volatile, int in /* Try dead code elimination */ if ((var != cfg->ret) && !(var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) && ((ins->opcode == OP_ICONST) || (ins->opcode == OP_I8CONST) || (ins->opcode == OP_R8CONST)) && !(var->flags & MONO_INST_VOLATILE)) { LIVENESS_DEBUG (printf ("\tdead def of R%d, eliminated\n", ins->dreg)); - ins->opcode = OP_NOP; - ins->dreg = -1; - MONO_INST_NULLIFY_SREGS (ins); + NULLIFY_INS (ins); return; } diff --git a/mono/mini/method-to-ir.c.REMOVED.git-id b/mono/mini/method-to-ir.c.REMOVED.git-id index 8dcf1402bc..84b52db425 100644 --- a/mono/mini/method-to-ir.c.REMOVED.git-id +++ b/mono/mini/method-to-ir.c.REMOVED.git-id @@ -1 +1 @@ -ce9026a4fc62ef49c761e5a82c5ad86b4c9fea6c \ No newline at end of file +783208d12240464610ce0690d42ee4beb31d48e0 \ No newline at end of file diff --git a/mono/mini/mini-amd64.c.REMOVED.git-id b/mono/mini/mini-amd64.c.REMOVED.git-id index 6e512572e4..b95e619ffa 100644 --- a/mono/mini/mini-amd64.c.REMOVED.git-id +++ b/mono/mini/mini-amd64.c.REMOVED.git-id @@ -1 +1 @@ -3cefc22c87dae6fb6f254bd3ecf05eaaf0359cf2 \ No newline at end of file +652129e00d6b3c1a3de439b3fdccf626e6c4bae8 \ No newline at end of file diff --git a/mono/mini/mini-amd64.h b/mono/mini/mini-amd64.h old mode 100644 new mode 100755 index b7c974e3ac..dc43eb731a --- a/mono/mini/mini-amd64.h +++ b/mono/mini/mini-amd64.h @@ -33,7 +33,7 @@ void amd64_nacl_membase_handler (guint8** code, gint8 basereg, gint32 offset, gi #include #endif - +#if !defined(_MSC_VER) /* sigcontext surrogate */ struct sigcontext { guint64 eax; @@ -46,6 +46,7 @@ struct sigcontext { guint64 edi; guint64 eip; }; +#endif typedef void (* MonoW32ExceptionHandler) (int _dummy, EXCEPTION_POINTERS *info, void *context); void win32_seh_init(void); @@ -121,14 +122,23 @@ struct sigcontext { #define MONO_ARCH_FP_RETURN_REG AMD64_XMM0 -/* xmm15 is reserved for use by some opcodes */ +#ifdef TARGET_WIN32 +/* xmm5 is used as a scratch register */ +#define MONO_ARCH_CALLEE_FREGS 0x1f +/* xmm6:xmm15 */ +#define MONO_ARCH_CALLEE_SAVED_FREGS (0xffff - 0x3f) +#define MONO_ARCH_FP_SCRATCH_REG AMD64_XMM5 +#else +/* xmm15 is used as a scratch register */ #define MONO_ARCH_CALLEE_FREGS 0x7fff #define MONO_ARCH_CALLEE_SAVED_FREGS 0 +#define MONO_ARCH_FP_SCRATCH_REG AMD64_XMM15 +#endif #define MONO_MAX_XREGS MONO_MAX_FREGS -#define MONO_ARCH_CALLEE_XREGS 0x7fff -#define MONO_ARCH_CALLEE_SAVED_XREGS 0 +#define MONO_ARCH_CALLEE_XREGS MONO_ARCH_CALLEE_FREGS +#define MONO_ARCH_CALLEE_SAVED_XREGS MONO_ARCH_CALLEE_SAVED_FREGS #define MONO_ARCH_CALLEE_REGS AMD64_CALLEE_REGS @@ -191,7 +201,7 @@ typedef struct MonoCompileArch { gint32 stack_alloc_size; gint32 sp_fp_offset; guint32 saved_iregs; - gboolean omit_fp, omit_fp_computed, no_pushes; + gboolean omit_fp, omit_fp_computed; gpointer cinfo; gint32 async_point_count; gpointer vret_addr_loc; @@ -275,74 +285,18 @@ typedef struct { #endif /* !HOST_WIN32 && !__native_client__ */ -#if defined (__APPLE__) - -#define MONO_ARCH_NOMAP32BIT - -#elif defined (__NetBSD__) - -#define REG_RAX 14 -#define REG_RCX 3 -#define REG_RDX 2 -#define REG_RBX 13 -#define REG_RSP 24 -#define REG_RBP 12 -#define REG_RSI 1 -#define REG_RDI 0 -#define REG_R8 4 -#define REG_R9 5 -#define REG_R10 6 -#define REG_R11 7 -#define REG_R12 8 -#define REG_R13 9 -#define REG_R14 10 -#define REG_R15 11 -#define REG_RIP 21 - -#define MONO_ARCH_NOMAP32BIT - -#elif defined (__OpenBSD__) - -#define MONO_ARCH_NOMAP32BIT - -#elif defined (__DragonFly__) - -#define MONO_ARCH_NOMAP32BIT - -#elif defined (__FreeBSD__) || defined(__FreeBSD_kernel__) - -#define REG_RAX 7 -#define REG_RCX 4 -#define REG_RDX 3 -#define REG_RBX 8 -#define REG_RSP 23 -#define REG_RBP 9 -#define REG_RSI 2 -#define REG_RDI 1 -#define REG_R8 5 -#define REG_R9 6 -#define REG_R10 10 -#define REG_R11 11 -#define REG_R12 12 -#define REG_R13 13 -#define REG_R14 14 -#define REG_R15 15 -#define REG_RIP 20 - -/* - * FreeBSD does not have MAP_32BIT, so code allocated by the code manager might not have a - * 32 bit address. - */ -#define MONO_ARCH_NOMAP32BIT - -#endif /* __FreeBSD__ */ +#if !defined(__linux__) +#define MONO_ARCH_NOMAP32BIT 1 +#endif #ifdef HOST_WIN32 #define MONO_AMD64_ARG_REG1 AMD64_RCX #define MONO_AMD64_ARG_REG2 AMD64_RDX +#define MONO_AMD64_ARG_REG3 AMD64_R8 #else #define MONO_AMD64_ARG_REG1 AMD64_RDI #define MONO_AMD64_ARG_REG2 AMD64_RSI +#define MONO_AMD64_ARG_REG3 AMD64_RDX #endif #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS @@ -352,7 +306,6 @@ typedef struct { #define MONO_ARCH_EMULATE_FREM 1 #define MONO_ARCH_HAVE_IS_INT_OVERFLOW 1 -#define MONO_ARCH_ENABLE_REGALLOC_IN_EH_BLOCKS 1 #define MONO_ARCH_ENABLE_MONO_LMF_VAR 1 #define MONO_ARCH_HAVE_INVALIDATE_METHOD 1 #define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE 1 @@ -373,35 +326,25 @@ typedef struct { #define MONO_ARCH_ENABLE_GLOBAL_RA 1 #define MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK 1 #define MONO_ARCH_HAVE_LIVERANGE_OPS 1 -#define MONO_ARCH_HAVE_XP_UNWIND 1 #define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX 1 -#if !defined(HOST_WIN32) #define MONO_ARCH_MONITOR_OBJECT_REG MONO_AMD64_ARG_REG1 -#endif #define MONO_ARCH_HAVE_GET_TRAMPOLINES 1 #define MONO_ARCH_AOT_SUPPORTED 1 -#if !defined( HOST_WIN32 ) && !defined( __native_client__ ) +#if !defined( __native_client__ ) #define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1 #endif -#if !defined(HOST_WIN32) || defined(__sun) #define MONO_ARCH_ENABLE_MONITOR_IL_FASTPATH 1 -#endif #define MONO_ARCH_SUPPORT_TASKLETS 1 -#ifndef HOST_WIN32 -#define MONO_AMD64_NO_PUSHES 1 -#endif - #define MONO_ARCH_GSHARED_SUPPORTED 1 #define MONO_ARCH_DYN_CALL_SUPPORTED 1 #define MONO_ARCH_DYN_CALL_PARAM_AREA 0 #define MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE 1 #define MONO_ARCH_LLVM_SUPPORTED 1 -#define MONO_ARCH_THIS_AS_FIRST_ARG 1 #define MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD 1 #define MONO_ARCH_HAVE_CARD_TABLE_WBARRIER 1 #define MONO_ARCH_HAVE_SETUP_RESUME_FROM_SIGNAL_HANDLER_CTX 1 diff --git a/mono/mini/mini-arm.c.REMOVED.git-id b/mono/mini/mini-arm.c.REMOVED.git-id index eceb1f0b72..12b5d57fcc 100644 --- a/mono/mini/mini-arm.c.REMOVED.git-id +++ b/mono/mini/mini-arm.c.REMOVED.git-id @@ -1 +1 @@ -b644d7dca7a0ab20b6d2d6150c1de81cae6c66f4 \ No newline at end of file +7e7c5937b974dc6615418c63d4a1bedc2714ab3c \ No newline at end of file diff --git a/mono/mini/mini-arm.h b/mono/mini/mini-arm.h index 7c3fd9ad04..f22514b61e 100644 --- a/mono/mini/mini-arm.h +++ b/mono/mini/mini-arm.h @@ -256,7 +256,6 @@ typedef struct MonoCompileArch { #define MONO_ARCH_NEED_DIV_CHECK 1 #define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE -#define MONO_ARCH_HAVE_XP_UNWIND 1 #define MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK 1 #define ARM_NUM_REG_ARGS (ARM_LAST_ARG_REG-ARM_FIRST_ARG_REG+1) @@ -267,7 +266,6 @@ typedef struct MonoCompileArch { #define MONO_ARCH_AOT_SUPPORTED 1 #define MONO_ARCH_LLVM_SUPPORTED 1 -#define MONO_ARCH_THIS_AS_FIRST_ARG 1 #define MONO_ARCH_GSHARED_SUPPORTED 1 #define MONO_ARCH_DYN_CALL_SUPPORTED 1 @@ -284,6 +282,7 @@ typedef struct MonoCompileArch { #define MONO_ARCH_GC_MAPS_SUPPORTED 1 #define MONO_ARCH_HAVE_SETUP_ASYNC_CALLBACK 1 #define MONO_ARCH_HAVE_CONTEXT_SET_INT_REG 1 +#define MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD 1 #define MONO_ARCH_HAVE_SETUP_RESUME_FROM_SIGNAL_HANDLER_CTX 1 #define MONO_ARCH_GSHAREDVT_SUPPORTED 1 #define MONO_ARCH_HAVE_GENERAL_RGCTX_LAZY_FETCH_TRAMPOLINE 1 diff --git a/mono/mini/mini-codegen.c b/mono/mini/mini-codegen.c index 66eb8fcdcf..f4bdecb727 100644 --- a/mono/mini/mini-codegen.c +++ b/mono/mini/mini-codegen.c @@ -1173,6 +1173,8 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb) * bblock. */ for (ins = bb->code; ins; ins = ins->next) { + gboolean modify = FALSE; + spec = ins_get_spec (ins->opcode); if ((ins->dreg != -1) && (ins->dreg < max)) { @@ -1198,12 +1200,14 @@ mono_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb) #if SIZEOF_REGISTER == 4 if (MONO_ARCH_INST_IS_REGPAIR (spec [MONO_INST_SRC1 + j])) { sregs [j]++; + modify = TRUE; memset (®info [sregs [j] + 1], 0, sizeof (RegTrack)); } #endif } } - mono_inst_set_src_registers (ins, sregs); + if (modify) + mono_inst_set_src_registers (ins, sregs); } /*if (cfg->opt & MONO_OPT_COPYPROP) diff --git a/mono/mini/mini-exceptions.c b/mono/mini/mini-exceptions.c index 5993ddddb6..db4a1ce4b0 100644 --- a/mono/mini/mini-exceptions.c +++ b/mono/mini/mini-exceptions.c @@ -2227,8 +2227,8 @@ print_stack_frame_to_string (StackFrameInfo *frame, MonoContext *ctx, gpointer d if (frame->ji) method = jinfo_get_method (frame->ji); - if (method) { - gchar *location = mono_debug_print_stack_frame (method, frame->native_offset, mono_domain_get ()); + if (method && frame->domain) { + gchar *location = mono_debug_print_stack_frame (method, frame->native_offset, frame->domain); g_string_append_printf (p, " %s\n", location); g_free (location); } else diff --git a/mono/mini/mini-ia64.h b/mono/mini/mini-ia64.h index d419bc26c7..15bb596d41 100644 --- a/mono/mini/mini-ia64.h +++ b/mono/mini/mini-ia64.h @@ -115,6 +115,5 @@ unw_dyn_region_info_t* mono_ia64_create_unwind_region (Ia64CodegenState *code); #define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE 1 #define MONO_ARCH_HAVE_SAVE_UNWIND_INFO 1 #define MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK 1 -#define MONO_ARCH_THIS_AS_FIRST_ARG 1 #endif /* __MONO_MINI_IA64_H__ */ diff --git a/mono/mini/mini-llvm.c.REMOVED.git-id b/mono/mini/mini-llvm.c.REMOVED.git-id index 60cd245857..60f5283f1e 100644 --- a/mono/mini/mini-llvm.c.REMOVED.git-id +++ b/mono/mini/mini-llvm.c.REMOVED.git-id @@ -1 +1 @@ -6551f78e021a1ed172043611b8f6a4dd9c11861b \ No newline at end of file +28e76665e16b5a197410e2f8833ed6419092e315 \ No newline at end of file diff --git a/mono/mini/mini-mips.h b/mono/mini/mini-mips.h index c94f7c898f..d8d769130c 100644 --- a/mono/mini/mini-mips.h +++ b/mono/mini/mini-mips.h @@ -268,7 +268,6 @@ typedef struct MonoCompileArch { #define MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK 1 #define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1 #define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX 1 -#define MONO_ARCH_HAVE_XP_UNWIND 1 #define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE 1 #define MONO_ARCH_HAVE_SETUP_RESUME_FROM_SIGNAL_HANDLER_CTX 1 #define MONO_ARCH_GSHARED_SUPPORTED 1 @@ -280,8 +279,6 @@ typedef struct MonoCompileArch { #define MONO_ARCH_NEED_DIV_CHECK 1 #define MONO_ARCH_NO_IOV_CHECK 1 -#define MONO_ARCH_THIS_AS_FIRST_ARG 1 - #define MIPS_NUM_REG_ARGS (MIPS_LAST_ARG_REG-MIPS_FIRST_ARG_REG+1) #define MIPS_NUM_REG_FPARGS (MIPS_LAST_FPARG_REG-MIPS_FIRST_FPARG_REG+1) diff --git a/mono/mini/mini-posix.c b/mono/mini/mini-posix.c index d26b4af4e9..abec7e33d3 100644 --- a/mono/mini/mini-posix.c +++ b/mono/mini/mini-posix.c @@ -25,6 +25,8 @@ #ifdef HAVE_SYS_SYSCALL_H #include #endif +#include + #include #include @@ -55,6 +57,7 @@ #include #include #include +#include #include "mini.h" #include @@ -81,7 +84,7 @@ mono_runtime_shutdown_stat_profiler (void) gboolean -SIG_HANDLER_SIGNATURE (mono_chain_signal) +MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal) { return FALSE; } @@ -173,19 +176,17 @@ free_saved_signal_handlers (void) * was called, false otherwise. */ gboolean -SIG_HANDLER_SIGNATURE (mono_chain_signal) +MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal) { - int signal = _dummy; + int signal = MONO_SIG_HANDLER_GET_SIGNO (); struct sigaction *saved_handler = get_saved_signal_handler (signal); - GET_CONTEXT; - if (saved_handler && saved_handler->sa_handler) { if (!(saved_handler->sa_flags & SA_SIGINFO)) { saved_handler->sa_handler (signal); } else { #ifdef MONO_ARCH_USE_SIGACTION - saved_handler->sa_sigaction (signal, info, ctx); + saved_handler->sa_sigaction (MONO_SIG_HANDLER_PARAMS); #endif /* MONO_ARCH_USE_SIGACTION */ } return TRUE; @@ -193,29 +194,28 @@ SIG_HANDLER_SIGNATURE (mono_chain_signal) return FALSE; } -SIG_HANDLER_FUNC (static, sigabrt_signal_handler) +MONO_SIG_HANDLER_FUNC (static, sigabrt_signal_handler) { MonoJitInfo *ji = NULL; - GET_CONTEXT; + MONO_SIG_HANDLER_GET_CONTEXT; if (mono_thread_internal_current ()) - ji = mono_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context(ctx)); + ji = mono_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context (ctx)); if (!ji) { - if (mono_chain_signal (SIG_HANDLER_PARAMS)) + if (mono_chain_signal (MONO_SIG_HANDLER_PARAMS)) return; mono_handle_native_sigsegv (SIGABRT, ctx); } } -SIG_HANDLER_FUNC (static, sigusr1_signal_handler) +MONO_SIG_HANDLER_FUNC (static, sigusr1_signal_handler) { gboolean running_managed; MonoException *exc; MonoInternalThread *thread = mono_thread_internal_current (); MonoDomain *domain = mono_domain_get (); void *ji; - - GET_CONTEXT; + MONO_SIG_HANDLER_GET_CONTEXT; if (!thread || !domain) { /* The thread might not have started up yet */ @@ -299,9 +299,9 @@ SIG_HANDLER_FUNC (static, sigusr1_signal_handler) #ifdef SIGPROF #if defined(__ia64__) || defined(__sparc__) || defined(sparc) || defined(__s390__) || defined(s390) -SIG_HANDLER_FUNC (static, sigprof_signal_handler) +MONO_SIG_HANDLER_FUNC (static, sigprof_signal_handler) { - if (mono_chain_signal (SIG_HANDLER_PARAMS)) + if (mono_chain_signal (MONO_SIG_HANDLER_PARAMS)) return; NOT_IMPLEMENTED; @@ -309,12 +309,14 @@ SIG_HANDLER_FUNC (static, sigprof_signal_handler) #else -SIG_HANDLER_FUNC (static, sigprof_signal_handler) +static int profiling_signal_in_use; + +static void +per_thread_profiler_hit (void *ctx) { int call_chain_depth = mono_profiler_stat_get_call_chain_depth (); MonoProfilerCallChainStrategy call_chain_strategy = mono_profiler_stat_get_call_chain_strategy (); - GET_CONTEXT; - + if (call_chain_depth == 0) { mono_profiler_stat_hit (mono_arch_ip_from_context (ctx), ctx); } else { @@ -381,18 +383,51 @@ SIG_HANDLER_FUNC (static, sigprof_signal_handler) mono_profiler_stat_call_chain (current_frame_index, & ips [0], ctx); } +} - mono_chain_signal (SIG_HANDLER_PARAMS); +MONO_SIG_HANDLER_FUNC (static, sigprof_signal_handler) +{ + MonoThreadInfo *info; + int old_errno = errno; + int hp_save_index; + MONO_SIG_HANDLER_GET_CONTEXT; + + if (mono_thread_info_get_small_id () == -1) + return; //an non-attached thread got the signal + + if (!mono_domain_get () || !mono_native_tls_get_value (mono_jit_tls_id)) + return; //thread in the process of dettaching + + hp_save_index = mono_hazard_pointer_save_for_signal_handler (); + + /* If we can't consume a profiling request it means we're the initiator. */ + if (!(mono_threads_consume_async_jobs () & MONO_SERVICE_REQUEST_SAMPLE)) { + FOREACH_THREAD_SAFE (info) { + if (mono_thread_info_get_tid (info) == mono_native_thread_id_get ()) + continue; + + mono_threads_add_async_job (info, MONO_SERVICE_REQUEST_SAMPLE); + mono_threads_pthread_kill (info, profiling_signal_in_use); + } END_FOREACH_THREAD_SAFE; + } + + mono_thread_info_set_is_async_context (TRUE); + per_thread_profiler_hit (ctx); + mono_thread_info_set_is_async_context (FALSE); + + mono_hazard_pointer_restore_for_signal_handler (hp_save_index); + errno = old_errno; + + mono_chain_signal (MONO_SIG_HANDLER_PARAMS); } #endif #endif -SIG_HANDLER_FUNC (static, sigquit_signal_handler) +MONO_SIG_HANDLER_FUNC (static, sigquit_signal_handler) { gboolean res; - - GET_CONTEXT; + MONO_SIG_HANDLER_GET_CONTEXT; /* We use this signal to start the attach agent too */ res = mono_attach_start (); @@ -415,16 +450,16 @@ SIG_HANDLER_FUNC (static, sigquit_signal_handler) mono_print_thread_dump (ctx); } - mono_chain_signal (SIG_HANDLER_PARAMS); + mono_chain_signal (MONO_SIG_HANDLER_PARAMS); } -SIG_HANDLER_FUNC (static, sigusr2_signal_handler) +MONO_SIG_HANDLER_FUNC (static, sigusr2_signal_handler) { gboolean enabled = mono_trace_is_enabled (); mono_trace_enable (!enabled); - mono_chain_signal (SIG_HANDLER_PARAMS); + mono_chain_signal (MONO_SIG_HANDLER_PARAMS); } static void @@ -604,6 +639,30 @@ mono_runtime_shutdown_stat_profiler (void) #endif } +#ifdef ITIMER_PROF +static int +get_itimer_mode (void) +{ + switch (mono_profiler_get_sampling_mode ()) { + case MONO_PROFILER_STAT_MODE_PROCESS: return ITIMER_PROF; + case MONO_PROFILER_STAT_MODE_REAL: return ITIMER_REAL; + } + g_assert_not_reached (); + return 0; +} + +static int +get_itimer_signal (void) +{ + switch (mono_profiler_get_sampling_mode ()) { + case MONO_PROFILER_STAT_MODE_PROCESS: return SIGPROF; + case MONO_PROFILER_STAT_MODE_REAL: return SIGALRM; + } + g_assert_not_reached (); + return 0; +} +#endif + void mono_runtime_setup_stat_profiler (void) { @@ -624,7 +683,8 @@ mono_runtime_setup_stat_profiler (void) perror ("open /dev/rtc"); return; } - add_signal_handler (SIGPROF, sigprof_signal_handler); + profiling_signal_in_use = SIGPROF; + add_signal_handler (profiling_signal_in_use, sigprof_signal_handler); if (ioctl (rtc_fd, RTC_IRQP_SET, freq) == -1) { perror ("set rtc freq"); return; @@ -648,14 +708,15 @@ mono_runtime_setup_stat_profiler (void) return; #endif - itval.it_interval.tv_usec = 999; + itval.it_interval.tv_usec = (1000000 / mono_profiler_get_sampling_rate ()) - 1; itval.it_interval.tv_sec = 0; itval.it_value = itval.it_interval; - setitimer (ITIMER_PROF, &itval, NULL); if (inited) return; inited = 1; - add_signal_handler (SIGPROF, sigprof_signal_handler); + profiling_signal_in_use = get_itimer_signal (); + add_signal_handler (profiling_signal_in_use, sigprof_signal_handler); + setitimer (get_itimer_mode (), &itval, NULL); #endif } @@ -663,7 +724,11 @@ mono_runtime_setup_stat_profiler (void) pid_t mono_runtime_syscall_fork () { -#if defined(SYS_fork) +#if defined(PLATFORM_ANDROID) + /* SYS_fork is defined to be __NR_fork which is not defined in some ndk versions */ + g_assert_not_reached (); + return 0; +#elif defined(SYS_fork) return (pid_t) syscall (SYS_fork); #else g_assert_not_reached (); diff --git a/mono/mini/mini-ppc.h b/mono/mini/mini-ppc.h index c3025a712e..4b39b7ac22 100644 --- a/mono/mini/mini-ppc.h +++ b/mono/mini/mini-ppc.h @@ -182,7 +182,6 @@ typedef struct MonoCompileArch { #define MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK 1 #define MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES 1 -#define MONO_ARCH_HAVE_XP_UNWIND 1 #define MONO_ARCH_GSHARED_SUPPORTED 1 @@ -192,7 +191,6 @@ typedef struct MonoCompileArch { #if !defined(MONO_CROSS_COMPILE) && !defined(TARGET_PS3) #define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1 #endif -#define MONO_ARCH_THIS_AS_FIRST_ARG 1 #define MONO_ARCH_HAVE_OP_TAIL_CALL 1 #define PPC_NUM_REG_ARGS (PPC_LAST_ARG_REG-PPC_FIRST_ARG_REG+1) diff --git a/mono/mini/mini-s390x.c.REMOVED.git-id b/mono/mini/mini-s390x.c.REMOVED.git-id index cfcbab562f..b3d1e04efa 100644 --- a/mono/mini/mini-s390x.c.REMOVED.git-id +++ b/mono/mini/mini-s390x.c.REMOVED.git-id @@ -1 +1 @@ -435ef2904a495ce910dd6a9aa36e55ea1d9db6f7 \ No newline at end of file +d84c87860d1f95b652405201c0823ed719a62097 \ No newline at end of file diff --git a/mono/mini/mini-s390x.h b/mono/mini/mini-s390x.h index 50b74c51fd..b40425c647 100644 --- a/mono/mini/mini-s390x.h +++ b/mono/mini/mini-s390x.h @@ -53,8 +53,6 @@ typedef struct #define MONO_ARCH_IMT_REG s390_r9 #define MONO_ARCH_VTABLE_REG MONO_ARCH_IMT_REG #define MONO_ARCH_RGCTX_REG MONO_ARCH_IMT_REG -#define MONO_ARCH_THIS_AS_FIRST_ARG 1 -#define MONO_ARCH_HAVE_XP_UNWIND 1 #define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX 1 #define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1 #define MONO_ARCH_HAVE_CONTEXT_SET_INT_REG 1 diff --git a/mono/mini/mini-sparc.c.REMOVED.git-id b/mono/mini/mini-sparc.c.REMOVED.git-id index e18c0405f8..61f4fb35a2 100644 --- a/mono/mini/mini-sparc.c.REMOVED.git-id +++ b/mono/mini/mini-sparc.c.REMOVED.git-id @@ -1 +1 @@ -3b95fd970336c9f187ef0e05f7f563b96acc9190 \ No newline at end of file +21c2b0cda1b62453e6573e46440774a7c07a47dd \ No newline at end of file diff --git a/mono/mini/mini-sparc.h b/mono/mini/mini-sparc.h index 4b94778455..ab8e452b70 100644 --- a/mono/mini/mini-sparc.h +++ b/mono/mini/mini-sparc.h @@ -112,8 +112,6 @@ void mono_arch_tls_init (void); #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS #endif -#define MONO_ARCH_THIS_AS_FIRST_ARG 1 - #ifndef __GNUC__ /* assume Sun compiler if not GCC */ static void * __builtin_return_address(int depth) diff --git a/mono/mini/mini-trampolines.c b/mono/mini/mini-trampolines.c index f65dab8c1e..d8f1e4298e 100644 --- a/mono/mini/mini-trampolines.c +++ b/mono/mini/mini-trampolines.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "mini.h" @@ -140,18 +141,15 @@ mono_create_static_rgctx_trampoline (MonoMethod *m, gpointer addr) /* * Either IMPL_METHOD or AOT_ADDR will be set on return. - */ -static gpointer* -#ifdef __GNUC__ -/* + * + * MONO_NEVER_INLINE : * This works against problems when compiling with gcc 4.6 on arm. The 'then' part of * this line gets executed, even when the condition is false: * if (impl && mono_method_needs_static_rgctx_invoke (impl, FALSE)) * *need_rgctx_tramp = TRUE; */ -__attribute__ ((noinline)) -#endif - mono_convert_imt_slot_to_vtable_slot (gpointer* slot, mgreg_t *regs, guint8 *code, MonoMethod *method, gboolean lookup_aot, MonoMethod **impl_method, gboolean *need_rgctx_tramp, gboolean *variance_used, gpointer *aot_addr) +static MONO_NEVER_INLINE gpointer* +mono_convert_imt_slot_to_vtable_slot (gpointer* slot, mgreg_t *regs, guint8 *code, MonoMethod *method, gboolean lookup_aot, MonoMethod **impl_method, gboolean *need_rgctx_tramp, gboolean *variance_used, gpointer *aot_addr) { MonoObject *this_argument = mono_arch_get_this_arg_from_call (regs, code); MonoVTable *vt = this_argument->vtable; @@ -730,10 +728,6 @@ mono_vcall_trampoline (mgreg_t *regs, guint8 *code, int slot, guint8 *tramp) * We use one vtable trampoline per vtable slot index, so we need only the vtable, * the other two can be computed from the vtable + the slot index. */ -#ifndef MONO_ARCH_THIS_AS_FIRST_ARG - /* All architectures should support this */ - g_assert_not_reached (); -#endif /* * Obtain the vtable from the 'this' arg. diff --git a/mono/mini/mini-windows.c b/mono/mini/mini-windows.c index c43b1d0102..9488ac895d 100644 --- a/mono/mini/mini-windows.c +++ b/mono/mini/mini-windows.c @@ -79,7 +79,7 @@ mono_runtime_cleanup_handlers (void) * was called, false otherwise. */ gboolean -SIG_HANDLER_SIGNATURE (mono_chain_signal) +MONO_SIG_HANDLER_SIGNATURE (mono_chain_signal) { MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); jit_tls->mono_win_chained_exception_needs_run = TRUE; @@ -123,7 +123,7 @@ mono_runtime_setup_stat_profiler (void) if (timeBeginPeriod (1) != TIMERR_NOERROR) return; - if ((win32_timer = timeSetEvent (1, 0, win32_time_proc, 0, TIME_PERIODIC)) == 0) { + if ((win32_timer = timeSetEvent (1, 0, (LPTIMECALLBACK)win32_time_proc, (DWORD_PTR)NULL, TIME_PERIODIC)) == 0) { timeEndPeriod (1); return; } @@ -137,7 +137,65 @@ mono_runtime_shutdown_stat_profiler (void) gboolean mono_thread_state_init_from_handle (MonoThreadUnwindState *tctx, MonoThreadInfo *info) { - g_error ("Windows systems haven't been ported to support mono_thread_state_init_from_handle"); - return FALSE; + DWORD id = mono_thread_info_get_tid (info); + HANDLE handle; + CONTEXT context; + DWORD result; + MonoContext *ctx; + MonoJitTlsData *jit_tls; + void *domain; + MonoLMF *lmf = NULL; + gpointer *addr; + + tctx->valid = FALSE; + tctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = NULL; + tctx->unwind_data [MONO_UNWIND_DATA_LMF] = NULL; + tctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = NULL; + + g_assert (id != GetCurrentThreadId ()); + + handle = OpenThread (THREAD_ALL_ACCESS, FALSE, id); + g_assert (handle); + + context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL; + + if (!GetThreadContext (handle, &context)) { + CloseHandle (handle); + return FALSE; + } + + g_assert (context.ContextFlags & CONTEXT_INTEGER); + g_assert (context.ContextFlags & CONTEXT_CONTROL); + + ctx = &tctx->ctx; + + memset (ctx, 0, sizeof (MonoContext)); + mono_sigctx_to_monoctx (&context, ctx); + + /* mono_set_jit_tls () sets this */ + jit_tls = mono_thread_info_tls_get (info, TLS_KEY_JIT_TLS); + /* SET_APPDOMAIN () sets this */ + domain = mono_thread_info_tls_get (info, TLS_KEY_DOMAIN); + + /*Thread already started to cleanup, can no longer capture unwind state*/ + if (!jit_tls || !domain) + return FALSE; + + /* + * The current LMF address is kept in a separate TLS variable, and its hard to read its value without + * arch-specific code. But the address of the TLS variable is stored in another TLS variable which + * can be accessed through MonoThreadInfo. + */ + /* mono_set_lmf_addr () sets this */ + addr = mono_thread_info_tls_get (info, TLS_KEY_LMF_ADDR); + if (addr) + lmf = *addr; + + tctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = domain; + tctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = jit_tls; + tctx->unwind_data [MONO_UNWIND_DATA_LMF] = lmf; + tctx->valid = TRUE; + + return TRUE; } diff --git a/mono/mini/mini-x86.c.REMOVED.git-id b/mono/mini/mini-x86.c.REMOVED.git-id index f652ca23da..1e8c9a30e4 100644 --- a/mono/mini/mini-x86.c.REMOVED.git-id +++ b/mono/mini/mini-x86.c.REMOVED.git-id @@ -1 +1 @@ -c7931e328ff6b032e4e3e5beb1862cdc2ac4f68d \ No newline at end of file +05b72c05f6b237f9350d8b9cb3496ff7a9d1ec49 \ No newline at end of file diff --git a/mono/mini/mini-x86.h b/mono/mini/mini-x86.h index 05b977c547..f6ddc93042 100644 --- a/mono/mini/mini-x86.h +++ b/mono/mini/mini-x86.h @@ -74,8 +74,6 @@ struct sigcontext { #endif /* HAVE_WORKING_SIGALTSTACK */ #endif /* !HOST_WIN32 */ -/* #define MONO_X86_NO_PUSHES 1 */ - #define MONO_ARCH_SUPPORT_TASKLETS 1 #ifndef DISABLE_SIMD @@ -169,7 +167,6 @@ struct MonoLMF { typedef struct { gboolean need_stack_frame_inited; gboolean need_stack_frame; - gboolean no_pushes; int sp_fp_offset, param_area_size; } MonoCompileArch; @@ -220,7 +217,6 @@ typedef struct { #define MONO_ARCH_RGCTX_REG MONO_ARCH_IMT_REG #define MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK 1 #define MONO_ARCH_HAVE_LIVERANGE_OPS 1 -#define MONO_ARCH_HAVE_XP_UNWIND 1 #define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX 1 #if defined(__linux__) || defined (__APPLE__) #define MONO_ARCH_MONITOR_OBJECT_REG X86_EAX @@ -249,7 +245,6 @@ typedef struct { #define MONO_ARCH_GSHARED_SUPPORTED 1 #define MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE 1 #define MONO_ARCH_LLVM_SUPPORTED 1 -#define MONO_ARCH_THIS_AS_FIRST_ARG 1 #if defined(MONO_ARCH_USE_SIGACTION) || defined(TARGET_WIN32) #define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1 diff --git a/mono/mini/mini.c.REMOVED.git-id b/mono/mini/mini.c.REMOVED.git-id index 0d285aa540..dd8042b235 100644 --- a/mono/mini/mini.c.REMOVED.git-id +++ b/mono/mini/mini.c.REMOVED.git-id @@ -1 +1 @@ -a31e9003a13596f56a2bff26c347a6bd75ae4be1 \ No newline at end of file +97f9bfa375eeac9d3590c30ff2fa078194efa4c7 \ No newline at end of file diff --git a/mono/mini/mini.h.REMOVED.git-id b/mono/mini/mini.h.REMOVED.git-id index bd2fa229ac..f7eb5e6884 100644 --- a/mono/mini/mini.h.REMOVED.git-id +++ b/mono/mini/mini.h.REMOVED.git-id @@ -1 +1 @@ -4bb5ad1d7d4641a6e6a275e2d41567e5550cb4d7 \ No newline at end of file +71906332b88657c5f07031bc04eaf02549214747 \ No newline at end of file diff --git a/mono/mini/ssa.c b/mono/mini/ssa.c index 801826b96e..160db5fec5 100644 --- a/mono/mini/ssa.c +++ b/mono/mini/ssa.c @@ -26,10 +26,8 @@ //#define DEBUG_SSA 1 #define NEW_PHI(cfg,dest,val) do { \ - (dest) = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst)); \ - (dest)->opcode = OP_PHI; \ - (dest)->inst_c0 = (val); \ - (dest)->dreg = (dest)->sreg1 = (dest)->sreg2 = -1; \ + MONO_INST_NEW ((cfg), (dest), OP_PHI); \ + (dest)->inst_c0 = (val); \ } while (0) typedef struct { @@ -530,8 +528,7 @@ mono_ssa_remove (MonoCompile *cfg) } } - ins->opcode = OP_NOP; - ins->dreg = -1; + NULLIFY_INS (ins); } } } @@ -1287,12 +1284,10 @@ mono_ssa_deadce (MonoCompile *cfg) MonoInst *src_var = get_vreg_to_inst (cfg, def->sreg1); if (src_var && !(src_var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT))) add_to_dce_worklist (cfg, info, MONO_VARINFO (cfg, src_var->inst_c0), &work_list); - def->opcode = OP_NOP; - def->dreg = def->sreg1 = def->sreg2 = -1; + NULLIFY_INS (def); info->reg = -1; } else if ((def->opcode == OP_ICONST) || (def->opcode == OP_I8CONST) || MONO_IS_ZERO (def)) { - def->opcode = OP_NOP; - def->dreg = def->sreg1 = def->sreg2 = -1; + NULLIFY_INS (def); info->reg = -1; } else if (MONO_IS_PHI (def)) { int j; @@ -1300,8 +1295,7 @@ mono_ssa_deadce (MonoCompile *cfg) MonoMethodVar *u = MONO_VARINFO (cfg, get_vreg_to_inst (cfg, def->inst_phi_args [j])->inst_c0); add_to_dce_worklist (cfg, info, u, &work_list); } - def->opcode = OP_NOP; - def->dreg = def->sreg1 = def->sreg2 = -1; + NULLIFY_INS (def); info->reg = -1; } else if (def->opcode == OP_NOP) { diff --git a/mono/mini/support-s390x.h b/mono/mini/support-s390x.h new file mode 100644 index 0000000000..f93dc88c0c --- /dev/null +++ b/mono/mini/support-s390x.h @@ -0,0 +1,97 @@ +#ifndef __MONO_SUPPORT_S390X_H__ +#define __MONO_SUPPORT_S390X_H__ + +#define S390_SET(loc, dr, v) \ + do { \ + guint64 val = (guint64) v; \ + if (s390_is_imm16(val)) { \ + s390_lghi(loc, dr, val); \ + } else if (s390_is_uimm16(val)) { \ + s390_llill(loc, dr, val); \ + } else if (s390_is_imm32(val)) { \ + s390_lgfi(loc, dr, val); \ + } else if (s390_is_uimm32(val)) { \ + s390_llilf(loc, dr, val); \ + } else { \ + guint32 hi = (val) >> 32; \ + guint32 lo = (val) & 0xffffffff; \ + s390_iihf(loc, dr, hi); \ + s390_iilf(loc, dr, lo); \ + } \ + } while (0) + +#define S390_LONG(loc, opy, op, r, ix, br, off) \ + if (s390_is_imm20(off)) { \ + s390_##opy (loc, r, ix, br, off); \ + } else { \ + if (ix == 0) { \ + S390_SET(loc, s390_r13, off); \ + s390_la (loc, s390_r13, s390_r13, br, 0); \ + } else { \ + s390_la (loc, s390_r13, ix, br, 0); \ + S390_SET (loc, s390_r0, off); \ + s390_agr (loc, s390_r13, s390_r0); \ + } \ + s390_##op (loc, r, 0, s390_r13, 0); \ + } + +#define S390_SET_MASK(loc, dr, v) \ + do { \ + if (s390_is_imm16 (v)) { \ + s390_lghi (loc, dr, v); \ + } else if (s390_is_imm32 (v)) { \ + s390_lgfi (loc, dr, v); \ + } else { \ + gint64 val = (gint64) v; \ + guint32 hi = (val) >> 32; \ + guint32 lo = (val) & 0xffffffff; \ + s390_iilf(loc, dr, lo); \ + s390_iihf(loc, dr, hi); \ + } \ + } while (0) + +#define S390_CALL_TEMPLATE(loc, r) \ + do { \ + s390_iihf (loc, r, 0); \ + s390_iilf (loc, r, 0); \ + s390_basr (loc, s390_r14, r); \ + } while (0) + +#define S390_BR_TEMPLATE(loc, r) \ + do { \ + s390_iihf (loc, r, 0); \ + s390_iilf (loc, r, 0); \ + s390_br (loc, r); \ + } while (0) + +#define S390_LOAD_TEMPLATE(loc, r) \ + do { \ + s390_iihf (loc, r, 0); \ + s390_iilf (loc, r, 0); \ + } while (0) + +#define S390_EMIT_CALL(loc, t) \ + do { \ + gint64 val = (gint64) t; \ + guint32 hi = (val) >> 32; \ + guint32 lo = (val) & 0xffffffff; \ + uintptr_t p = (uintptr_t) loc; \ + p += 2; \ + *(guint32 *) p = hi; \ + p += 6; \ + *(guint32 *) p = lo; \ + } while (0) + +#define S390_EMIT_LOAD(loc, v) \ + do { \ + gint64 val = (gint64) v; \ + guint32 hi = (val) >> 32; \ + guint32 lo = (val) & 0xffffffff; \ + uintptr_t p = (uintptr_t) loc; \ + p += 2; \ + *(guint32 *) p = hi; \ + p += 6; \ + *(guint32 *) p = lo; \ + } while (0) + +#endif /* __MONO_SUPPORT_S390X_H__ */ diff --git a/mono/mini/tramp-amd64.c b/mono/mini/tramp-amd64.c old mode 100644 new mode 100755 index 50d57970fe..cfc14ee2a4 --- a/mono/mini/tramp-amd64.c +++ b/mono/mini/tramp-amd64.c @@ -522,7 +522,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf amd64_mov_reg_imm (code, AMD64_R11, 0); amd64_mov_reg_membase (code, AMD64_R11, AMD64_R11, 0, 8); } else { - amd64_mov_reg_imm (code, AMD64_RDI, tramp_type); + amd64_mov_reg_imm (code, MONO_AMD64_ARG_REG1, tramp_type); amd64_mov_reg_imm (code, AMD64_R11, stack_unaligned); amd64_call_reg (code, AMD64_R11); } @@ -946,8 +946,6 @@ mono_arch_create_generic_class_init_trampoline (MonoTrampInfo **info, gboolean a return buf; } -#ifdef MONO_ARCH_MONITOR_OBJECT_REG - gpointer mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean aot) { @@ -958,8 +956,11 @@ mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean aot) int owner_offset, nest_offset, dummy; MonoJumpInfo *ji = NULL; GSList *unwind_ops = NULL; + int obj_reg = MONO_AMD64_ARG_REG1; + int sync_reg = MONO_AMD64_ARG_REG2; + int tid_reg = MONO_AMD64_ARG_REG3; - g_assert (MONO_ARCH_MONITOR_OBJECT_REG == AMD64_RDI); + g_assert (MONO_ARCH_MONITOR_OBJECT_REG == obj_reg); mono_monitor_threads_sync_members_offset (&owner_offset, &nest_offset, &dummy); g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (owner_offset) == sizeof (gpointer)); @@ -973,51 +974,52 @@ mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean aot) unwind_ops = mono_arch_get_cie_program (); - if (mono_thread_get_tls_offset () != -1) { - /* MonoObject* obj is in RDI */ + if (!aot && mono_thread_get_tls_offset () != -1) { + /* MonoObject* obj is in obj_reg */ /* is obj null? */ - amd64_test_reg_reg (code, AMD64_RDI, AMD64_RDI); + amd64_test_reg_reg (code, obj_reg, obj_reg); /* if yes, jump to actual trampoline */ jump_obj_null = code; amd64_branch8 (code, X86_CC_Z, -1, 1); - /* load obj->synchronization to RCX */ - amd64_mov_reg_membase (code, AMD64_RCX, AMD64_RDI, MONO_STRUCT_OFFSET (MonoObject, synchronisation), 8); + /* load obj->synchronization to sync_reg */ + amd64_mov_reg_membase (code, sync_reg, obj_reg, MONO_STRUCT_OFFSET (MonoObject, synchronisation), 8); if (mono_gc_is_moving ()) { /*if bit zero is set it's a thin hash*/ /*FIXME use testb encoding*/ - amd64_test_reg_imm (code, AMD64_RCX, 0x01); + amd64_test_reg_imm (code, sync_reg, 0x01); jump_sync_thin_hash = code; amd64_branch8 (code, X86_CC_NE, -1, 1); /*clear bits used by the gc*/ - amd64_alu_reg_imm (code, X86_AND, AMD64_RCX, ~0x3); + amd64_alu_reg_imm (code, X86_AND, sync_reg, ~0x3); } /* is synchronization null? */ - amd64_test_reg_reg (code, AMD64_RCX, AMD64_RCX); + amd64_test_reg_reg (code, sync_reg, sync_reg); /* if yes, jump to actual trampoline */ jump_sync_null = code; amd64_branch8 (code, X86_CC_Z, -1, 1); - /* load MonoInternalThread* into RDX */ - code = mono_amd64_emit_tls_get (code, AMD64_RDX, mono_thread_get_tls_offset ()); - /* load TID into RDX */ - amd64_mov_reg_membase (code, AMD64_RDX, AMD64_RDX, MONO_STRUCT_OFFSET (MonoInternalThread, tid), 8); + /* load MonoInternalThread* into tid_reg */ + code = mono_amd64_emit_tls_get (code, tid_reg, mono_thread_get_tls_offset ()); + /* load TID into tid_reg */ + amd64_mov_reg_membase (code, tid_reg, tid_reg, MONO_STRUCT_OFFSET (MonoInternalThread, tid), 8); /* is synchronization->owner null? */ - amd64_alu_membase_imm_size (code, X86_CMP, AMD64_RCX, owner_offset, 0, 8); + amd64_alu_membase_imm_size (code, X86_CMP, sync_reg, owner_offset, 0, 8); /* if not, jump to next case */ jump_tid = code; amd64_branch8 (code, X86_CC_NZ, -1, 1); /* if yes, try a compare-exchange with the TID */ + g_assert (tid_reg != X86_EAX); /* zero RAX */ amd64_alu_reg_reg (code, X86_XOR, AMD64_RAX, AMD64_RAX); /* compare and exchange */ amd64_prefix (code, X86_LOCK_PREFIX); - amd64_cmpxchg_membase_reg_size (code, AMD64_RCX, owner_offset, AMD64_RDX, 8); + amd64_cmpxchg_membase_reg_size (code, sync_reg, owner_offset, tid_reg, 8); /* if not successful, jump to actual trampoline */ jump_cmpxchg_failed = code; amd64_branch8 (code, X86_CC_NZ, -1, 1); @@ -1027,12 +1029,12 @@ mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean aot) /* next case: synchronization->owner is not null */ x86_patch (jump_tid, code); /* is synchronization->owner == TID? */ - amd64_alu_membase_reg_size (code, X86_CMP, AMD64_RCX, owner_offset, AMD64_RDX, 8); + amd64_alu_membase_reg_size (code, X86_CMP, sync_reg, owner_offset, tid_reg, 8); /* if not, jump to actual trampoline */ jump_other_owner = code; amd64_branch8 (code, X86_CC_NZ, -1, 1); /* if yes, increment nest */ - amd64_inc_membase_size (code, AMD64_RCX, nest_offset, 4); + amd64_inc_membase_size (code, sync_reg, nest_offset, 4); /* return */ amd64_ret (code); @@ -1045,9 +1047,8 @@ mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean aot) } /* jump to the actual trampoline */ -#if MONO_AMD64_ARG_REG1 != AMD64_RDI - amd64_mov_reg_reg (code, MONO_AMD64_ARG_REG1, AMD64_RDI); -#endif + if (MONO_AMD64_ARG_REG1 != obj_reg) + amd64_mov_reg_reg (code, MONO_AMD64_ARG_REG1, obj_reg, sizeof (mgreg_t)); if (aot) { code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "specific_trampoline_monitor_enter"); @@ -1081,8 +1082,10 @@ mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot) int owner_offset, nest_offset, entry_count_offset; MonoJumpInfo *ji = NULL; GSList *unwind_ops = NULL; + int obj_reg = MONO_AMD64_ARG_REG1; + int sync_reg = MONO_AMD64_ARG_REG2; - g_assert (MONO_ARCH_MONITOR_OBJECT_REG == AMD64_RDI); + g_assert (obj_reg == MONO_ARCH_MONITOR_OBJECT_REG); mono_monitor_threads_sync_members_offset (&owner_offset, &nest_offset, &entry_count_offset); g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (owner_offset) == sizeof (gpointer)); @@ -1098,64 +1101,64 @@ mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot) unwind_ops = mono_arch_get_cie_program (); - if (mono_thread_get_tls_offset () != -1) { - /* MonoObject* obj is in RDI */ + if (!aot && mono_thread_get_tls_offset () != -1) { + /* MonoObject* obj is in obj_reg */ /* is obj null? */ - amd64_test_reg_reg (code, AMD64_RDI, AMD64_RDI); + amd64_test_reg_reg (code, obj_reg, obj_reg); /* if yes, jump to actual trampoline */ jump_obj_null = code; amd64_branch8 (code, X86_CC_Z, -1, 1); /* load obj->synchronization to RCX */ - amd64_mov_reg_membase (code, AMD64_RCX, AMD64_RDI, MONO_STRUCT_OFFSET (MonoObject, synchronisation), 8); + amd64_mov_reg_membase (code, sync_reg, obj_reg, MONO_STRUCT_OFFSET (MonoObject, synchronisation), 8); if (mono_gc_is_moving ()) { /*if bit zero is set it's a thin hash*/ /*FIXME use testb encoding*/ - amd64_test_reg_imm (code, AMD64_RCX, 0x01); + amd64_test_reg_imm (code, sync_reg, 0x01); jump_sync_thin_hash = code; amd64_branch8 (code, X86_CC_NE, -1, 1); /*clear bits used by the gc*/ - amd64_alu_reg_imm (code, X86_AND, AMD64_RCX, ~0x3); + amd64_alu_reg_imm (code, X86_AND, sync_reg, ~0x3); } /* is synchronization null? */ - amd64_test_reg_reg (code, AMD64_RCX, AMD64_RCX); + amd64_test_reg_reg (code, sync_reg, sync_reg); /* if yes, jump to actual trampoline */ jump_sync_null = code; amd64_branch8 (code, X86_CC_Z, -1, 1); /* next case: synchronization is not null */ - /* load MonoInternalThread* into RDX */ - code = mono_amd64_emit_tls_get (code, AMD64_RDX, mono_thread_get_tls_offset ()); - /* load TID into RDX */ - amd64_mov_reg_membase (code, AMD64_RDX, AMD64_RDX, MONO_STRUCT_OFFSET (MonoInternalThread, tid), 8); + /* load MonoInternalThread* into RAX */ + code = mono_amd64_emit_tls_get (code, AMD64_RAX, mono_thread_get_tls_offset ()); + /* load TID into RAX */ + amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RAX, MONO_STRUCT_OFFSET (MonoInternalThread, tid), 8); /* is synchronization->owner == TID */ - amd64_alu_membase_reg_size (code, X86_CMP, AMD64_RCX, owner_offset, AMD64_RDX, 8); + amd64_alu_membase_reg_size (code, X86_CMP, sync_reg, owner_offset, AMD64_RAX, 8); /* if no, jump to actual trampoline */ jump_not_owned = code; amd64_branch8 (code, X86_CC_NZ, -1, 1); /* next case: synchronization->owner == TID */ /* is synchronization->nest == 1 */ - amd64_alu_membase_imm_size (code, X86_CMP, AMD64_RCX, nest_offset, 1, 4); + amd64_alu_membase_imm_size (code, X86_CMP, sync_reg, nest_offset, 1, 4); /* if not, jump to next case */ jump_next = code; amd64_branch8 (code, X86_CC_NZ, -1, 1); /* if yes, is synchronization->entry_count zero? */ - amd64_alu_membase_imm_size (code, X86_CMP, AMD64_RCX, entry_count_offset, 0, 4); + amd64_alu_membase_imm_size (code, X86_CMP, sync_reg, entry_count_offset, 0, 4); /* if not, jump to actual trampoline */ jump_have_waiters = code; amd64_branch8 (code, X86_CC_NZ, -1 , 1); /* if yes, set synchronization->owner to null and return */ - amd64_mov_membase_imm (code, AMD64_RCX, owner_offset, 0, 8); + amd64_mov_membase_imm (code, sync_reg, owner_offset, 0, 8); amd64_ret (code); /* next case: synchronization->nest is not 1 */ x86_patch (jump_next, code); /* decrease synchronization->nest and return */ - amd64_dec_membase_size (code, AMD64_RCX, nest_offset, 4); + amd64_dec_membase_size (code, sync_reg, nest_offset, 4); amd64_ret (code); x86_patch (jump_obj_null, code); @@ -1165,9 +1168,8 @@ mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot) } /* jump to the actual trampoline */ -#if MONO_AMD64_ARG_REG1 != AMD64_RDI - amd64_mov_reg_reg (code, MONO_AMD64_ARG_REG1, AMD64_RDI); -#endif + if (MONO_AMD64_ARG_REG1 != obj_reg) + amd64_mov_reg_reg (code, MONO_AMD64_ARG_REG1, obj_reg, sizeof (mgreg_t)); if (aot) { code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "specific_trampoline_monitor_exit"); @@ -1187,7 +1189,6 @@ mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot) return buf; } -#endif void mono_arch_invalidate_method (MonoJitInfo *ji, void *func, gpointer func_arg) @@ -1226,18 +1227,18 @@ mono_arch_create_handler_block_trampoline (MonoTrampInfo **info, gboolean aot) /* This trampoline restore the call chain of the handler block then jumps into the code that deals with it. */ - if (mono_get_jit_tls_offset () != -1) { - code = mono_amd64_emit_tls_get (code, AMD64_RDI, mono_get_jit_tls_offset ()); - amd64_mov_reg_membase (code, AMD64_RDI, AMD64_RDI, MONO_STRUCT_OFFSET (MonoJitTlsData, handler_block_return_address), 8); + code = mono_amd64_emit_tls_get (code, MONO_AMD64_ARG_REG1, mono_get_jit_tls_offset ()); + amd64_mov_reg_membase (code, MONO_AMD64_ARG_REG1, MONO_AMD64_ARG_REG1, MONO_STRUCT_OFFSET (MonoJitTlsData, handler_block_return_address), 8); /* Simulate a call */ amd64_push_reg (code, AMD64_RAX); amd64_jump_code (code, tramp); } else { /*Slow path uses a c helper*/ - amd64_mov_reg_reg (code, AMD64_RDI, AMD64_RSP, 8); + amd64_mov_reg_reg (code, MONO_AMD64_ARG_REG1, AMD64_RSP, 8); amd64_mov_reg_imm (code, AMD64_RAX, tramp); amd64_push_reg (code, AMD64_RAX); + amd64_push_reg (code, AMD64_RAX); amd64_jump_code (code, handler_block_trampoline_helper); } diff --git a/mono/mini/tramp-arm.c b/mono/mini/tramp-arm.c index bb500a7c0f..f9e651093b 100644 --- a/mono/mini/tramp-arm.c +++ b/mono/mini/tramp-arm.c @@ -505,17 +505,21 @@ mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_ty tramp = mono_get_trampoline_code (tramp_type); - mono_domain_lock (domain); + if (domain) { + mono_domain_lock (domain); #ifdef USE_JUMP_TABLES - code = buf = mono_domain_code_reserve_align (domain, size, 4); + code = buf = mono_domain_code_reserve_align (domain, size, 4); #else - code = buf = mono_domain_code_reserve_align (domain, size, 4); - if ((short_branch = branch_for_target_reachable (code + 4, tramp))) { - size = 12; - mono_domain_code_commit (domain, code, SPEC_TRAMP_SIZE, size); + code = buf = mono_domain_code_reserve_align (domain, size, 4); + if ((short_branch = branch_for_target_reachable (code + 4, tramp))) { + size = 12; + mono_domain_code_commit (domain, code, SPEC_TRAMP_SIZE, size); } #endif - mono_domain_unlock (domain); + mono_domain_unlock (domain); + } else { + code = buf = mono_global_codeman_reserve (size); + } #ifdef USE_JUMP_TABLES /* For jumptables case we always generate the same code for trampolines, @@ -894,6 +898,59 @@ mono_arch_create_generic_class_init_trampoline (MonoTrampInfo **info, gboolean a return buf; } +static gpointer +handler_block_trampoline_helper (gpointer *ptr) +{ + MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); + return jit_tls->handler_block_return_address; +} + +gpointer +mono_arch_create_handler_block_trampoline (MonoTrampInfo **info, gboolean aot) +{ + guint8 *tramp; + guint8 *code, *buf; + int tramp_size = 64; + MonoJumpInfo *ji = NULL; + GSList *unwind_ops = NULL; + + g_assert (!aot); + + code = buf = mono_global_codeman_reserve (tramp_size); + + tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD, NULL, NULL); + + /* + This trampoline restore the call chain of the handler block then jumps into the code that deals with it. + */ + + /* + * We are in a method frame after the call emitted by OP_CALL_HANDLER. + */ + /* Obtain jit_tls->handler_block_return_address */ + ARM_LDR_IMM (code, ARMREG_R0, ARMREG_PC, 0); + ARM_B (code, 0); + *(gpointer*)code = handler_block_trampoline_helper; + code += 4; + + /* Set it as the return address so the trampoline will return to it */ + ARM_MOV_REG_REG (code, ARMREG_LR, ARMREG_R0); + + /* Call the trampoline */ + ARM_LDR_IMM (code, ARMREG_R0, ARMREG_PC, 0); + code = emit_bx (code, ARMREG_R0); + *(gpointer*)code = tramp; + code += 4; + + mono_arch_flush_icache (buf, code - buf); + g_assert (code - buf <= tramp_size); + + if (info) + *info = mono_tramp_info_create ("handler_block_trampoline", buf, code - buf, ji, unwind_ops); + + return buf; +} + #else guchar* @@ -944,6 +1001,13 @@ mono_arch_get_nullified_class_init_trampoline (MonoTrampInfo **info) g_assert_not_reached (); return NULL; } + +gpointer +mono_arch_create_handler_block_trampoline (MonoTrampInfo **info, gboolean aot) +{ + g_assert_not_reached (); + return NULL; +} #endif /* DISABLE_JIT */ diff --git a/mono/mini/unwind.c b/mono/mini/unwind.c index 31024bfee0..d671093978 100644 --- a/mono/mini/unwind.c +++ b/mono/mini/unwind.c @@ -349,9 +349,10 @@ mono_unwind_ops_encode (GSList *unwind_ops, guint32 *out_len) GSList *l; MonoUnwindOp *op; int loc; - guint8 *buf, *p, *res; + guint8 buf [4096]; + guint8 *p, *res; - p = buf = g_malloc0 (4096); + p = buf; loc = 0; l = unwind_ops; @@ -443,7 +444,6 @@ mono_unwind_ops_encode (GSList *unwind_ops, guint32 *out_len) *out_len = p - buf; res = g_malloc (p - buf); memcpy (res, buf, p - buf); - g_free (buf); return res; } @@ -498,6 +498,8 @@ mono_unwind_frame (guint8 *unwind_info, guint32 unwind_info_len, int state_stack_pos; memset (reg_saved, 0, sizeof (reg_saved)); + state_stack [0].cfa_reg = -1; + state_stack [0].cfa_offset = 0; p = unwind_info; pos = 0; diff --git a/mono/mini/version.h b/mono/mini/version.h index 3cc1180e38..a2e5cabcb2 100644 --- a/mono/mini/version.h +++ b/mono/mini/version.h @@ -1 +1 @@ -#define FULL_VERSION "(detached/633e444" +#define FULL_VERSION "(detached/a813491" diff --git a/mono/mini/wapihandles.c b/mono/mini/wapihandles.c index c2a31ce1ea..7bda38843e 100644 --- a/mono/mini/wapihandles.c +++ b/mono/mini/wapihandles.c @@ -3,7 +3,7 @@ #include "mini.h" -#if defined(HOST_WIN32) || !defined(HAVE_SYS_IPC_H) || !defined(HAVE_SYS_SEM_H) || (defined(__native_client__) && defined(__GLIBC__)) +#if defined(HOST_WIN32) || !defined(HAVE_SYS_IPC_H) || !defined(HAVE_SYS_SEM_H) || (defined(__native_client__) && defined(__GLIBC__)) || defined(DISABLE_SHARED_HANDLES) int mini_wapi_hps (int argc, char **argv) { @@ -42,7 +42,6 @@ static const gchar *thread_details (struct _WapiHandleShared *handle); static const gchar *namedmutex_details (struct _WapiHandleShared *handle); static const gchar *namedsem_details (struct _WapiHandleShared *handle); static const gchar *namedevent_details (struct _WapiHandleShared *handle); -static const gchar *process_details (struct _WapiHandleShared *handle); /* This depends on the ordering of the enum WapiHandleType in * io-layer/wapi-private.h @@ -58,7 +57,7 @@ static const gchar * (*details[])(struct _WapiHandleShared *)= unshared_details, /* event */ unshared_details, /* socket */ unshared_details, /* find */ - process_details, + unshared_details, /* process */ unshared_details, /* pipe */ namedmutex_details, namedsem_details, @@ -191,20 +190,6 @@ static const gchar *namedevent_details (struct _WapiHandleShared *handle) return(buf); } -static const gchar *process_details (struct _WapiHandleShared *handle) -{ - static gchar buf[80]; - gchar *name; - struct _WapiHandle_process *proc=&handle->u.process; - - name = proc->proc_name; - - g_snprintf (buf, sizeof(buf), "[%25.25s] pid: %5u exit: %u", - name==NULL?(gchar *)"":name, proc->id, proc->exitstatus); - - return(buf); -} - /* The old handles/semdel.c */ int mini_wapi_semdel (int argc, char **argv) { diff --git a/mono/mini/xdebug.c b/mono/mini/xdebug.c index 9e415ca339..167b2b9e2b 100644 --- a/mono/mini/xdebug.c +++ b/mono/mini/xdebug.c @@ -51,6 +51,8 @@ #include "image-writer.h" #include "dwarfwriter.h" +#include "mono/utils/mono-compiler.h" + #define USE_GDB_JIT_INTERFACE /* The recommended gdb macro is: */ @@ -95,15 +97,8 @@ struct jit_descriptor struct jit_code_entry *first_entry; }; - -#ifdef _MSC_VER -#define MONO_NOINLINE __declspec (noinline) -#else -#define MONO_NOINLINE __attribute__((noinline)) -#endif - /* GDB puts a breakpoint in this function. */ -void MONO_NOINLINE __jit_debug_register_code(void); +void MONO_NEVER_INLINE __jit_debug_register_code(void); #if !defined(MONO_LLVM_LOADED) && defined(ENABLE_LLVM) && !defined(MONO_CROSS_COMPILE) @@ -114,7 +109,7 @@ extern struct jit_descriptor __jit_debug_descriptor; #else /* gcc seems to inline/eliminate calls to noinline functions, thus the asm () */ -void MONO_NOINLINE __jit_debug_register_code(void) { +void MONO_NEVER_INLINE __jit_debug_register_code(void) { #if defined(__GNUC__) asm (""); #endif diff --git a/mono/monograph/Makefile.am b/mono/monograph/Makefile.am index 585b564182..25555809f1 100644 --- a/mono/monograph/Makefile.am +++ b/mono/monograph/Makefile.am @@ -3,7 +3,6 @@ if HOST_WIN32 export HOST_CC endif -if JIT_SUPPORTED if DISABLE_EXECUTABLES runtime_lib=../mini/$(LIBMONO_LA) $(static_libs) else @@ -20,9 +19,6 @@ else runtime_lib=../mini/$(LIBMONO_LA) endif endif -else -runtime_lib=../interpreter/libmint.la -endif if DISABLE_EXECUTABLES bin_PROGRAMS = diff --git a/mono/monograph/Makefile.in b/mono/monograph/Makefile.in index 42070f8617..df01934be4 100644 --- a/mono/monograph/Makefile.in +++ b/mono/monograph/Makefile.in @@ -103,18 +103,17 @@ PROGRAMS = $(bin_PROGRAMS) monograph_SOURCES = monograph.c monograph_OBJECTS = monograph.$(OBJEXT) am__DEPENDENCIES_1 = -@DISABLE_EXECUTABLES_FALSE@@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@am__DEPENDENCIES_2 = $(top_builddir)/mono/metadata/libmonoruntime-static.la \ -@DISABLE_EXECUTABLES_FALSE@@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(top_builddir)/mono/io-layer/libwapi.la \ -@DISABLE_EXECUTABLES_FALSE@@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(top_builddir)/mono/utils/libmonoutils.la \ -@DISABLE_EXECUTABLES_FALSE@@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(am__DEPENDENCIES_1) \ -@DISABLE_EXECUTABLES_FALSE@@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(am__DEPENDENCIES_1) \ -@DISABLE_EXECUTABLES_FALSE@@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(am__DEPENDENCIES_1) -@DISABLE_EXECUTABLES_FALSE@@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@am__DEPENDENCIES_3 = ../mini/$(LIBMONO_LA) \ -@DISABLE_EXECUTABLES_FALSE@@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(am__DEPENDENCIES_2) -@DISABLE_EXECUTABLES_FALSE@@JIT_SUPPORTED_TRUE@@SHARED_MONO_TRUE@am__DEPENDENCIES_3 = ../mini/$(LIBMONO_LA) -@DISABLE_EXECUTABLES_TRUE@@JIT_SUPPORTED_TRUE@am__DEPENDENCIES_3 = ../mini/$(LIBMONO_LA) \ -@DISABLE_EXECUTABLES_TRUE@@JIT_SUPPORTED_TRUE@ $(am__DEPENDENCIES_2) -@JIT_SUPPORTED_FALSE@am__DEPENDENCIES_3 = ../interpreter/libmint.la +@DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_FALSE@am__DEPENDENCIES_2 = $(top_builddir)/mono/metadata/libmonoruntime-static.la \ +@DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_FALSE@ $(top_builddir)/mono/io-layer/libwapi.la \ +@DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_FALSE@ $(top_builddir)/mono/utils/libmonoutils.la \ +@DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_FALSE@ $(am__DEPENDENCIES_1) \ +@DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_FALSE@ $(am__DEPENDENCIES_1) \ +@DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_FALSE@ $(am__DEPENDENCIES_1) +@DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_FALSE@am__DEPENDENCIES_3 = ../mini/$(LIBMONO_LA) \ +@DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_FALSE@ $(am__DEPENDENCIES_2) +@DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_TRUE@am__DEPENDENCIES_3 = ../mini/$(LIBMONO_LA) +@DISABLE_EXECUTABLES_TRUE@am__DEPENDENCIES_3 = ../mini/$(LIBMONO_LA) \ +@DISABLE_EXECUTABLES_TRUE@ $(am__DEPENDENCIES_2) monograph_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) @@ -385,16 +384,15 @@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -@DISABLE_EXECUTABLES_FALSE@@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@runtime_lib = ../mini/$(LIBMONO_LA) $(static_libs) -@DISABLE_EXECUTABLES_FALSE@@JIT_SUPPORTED_TRUE@@SHARED_MONO_TRUE@runtime_lib = ../mini/$(LIBMONO_LA) -@DISABLE_EXECUTABLES_TRUE@@JIT_SUPPORTED_TRUE@runtime_lib = ../mini/$(LIBMONO_LA) $(static_libs) -@JIT_SUPPORTED_FALSE@runtime_lib = ../interpreter/libmint.la -@DISABLE_EXECUTABLES_FALSE@@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@static_libs = \ -@DISABLE_EXECUTABLES_FALSE@@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(top_builddir)/mono/metadata/libmonoruntime-static.la \ -@DISABLE_EXECUTABLES_FALSE@@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(top_builddir)/mono/io-layer/libwapi.la \ -@DISABLE_EXECUTABLES_FALSE@@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(top_builddir)/mono/utils/libmonoutils.la \ -@DISABLE_EXECUTABLES_FALSE@@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(GLIB_LIBS) $(LIBICONV) \ -@DISABLE_EXECUTABLES_FALSE@@JIT_SUPPORTED_TRUE@@SHARED_MONO_FALSE@ $(LIBGC_STATIC_LIBS) +@DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_FALSE@runtime_lib = ../mini/$(LIBMONO_LA) $(static_libs) +@DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_TRUE@runtime_lib = ../mini/$(LIBMONO_LA) +@DISABLE_EXECUTABLES_TRUE@runtime_lib = ../mini/$(LIBMONO_LA) $(static_libs) +@DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_FALSE@static_libs = \ +@DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_FALSE@ $(top_builddir)/mono/metadata/libmonoruntime-static.la \ +@DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_FALSE@ $(top_builddir)/mono/io-layer/libwapi.la \ +@DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_FALSE@ $(top_builddir)/mono/utils/libmonoutils.la \ +@DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_FALSE@ $(GLIB_LIBS) $(LIBICONV) \ +@DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_FALSE@ $(LIBGC_STATIC_LIBS) AM_CPPFLAGS = \ -I$(top_srcdir) \ diff --git a/mono/profiler/Makefile.am b/mono/profiler/Makefile.am index 25bb9b51f7..b0d1e2f77d 100644 --- a/mono/profiler/Makefile.am +++ b/mono/profiler/Makefile.am @@ -11,7 +11,6 @@ AM_CPPFLAGS = \ if !DISABLE_LIBRARIES if !DISABLE_PROFILER -if JIT_SUPPORTED bin_PROGRAMS = mprof-report lib_LTLIBRARIES = libmono-profiler-cov.la libmono-profiler-aot.la libmono-profiler-iomap.la libmono-profiler-log.la if PLATFORM_DARWIN @@ -22,7 +21,6 @@ libmono_profiler_log_la_LDFLAGS = -avoid-version endif endif endif -endif if HAVE_OPROFILE # Do something that uses OPROFILE_CFLAGS and OPROFILE_LIBS diff --git a/mono/profiler/Makefile.in b/mono/profiler/Makefile.in index f22c9b576d..52fd9eea5c 100644 --- a/mono/profiler/Makefile.in +++ b/mono/profiler/Makefile.in @@ -80,7 +80,7 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ -@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@@JIT_SUPPORTED_TRUE@bin_PROGRAMS = mprof-report$(EXEEXT) +@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@bin_PROGRAMS = mprof-report$(EXEEXT) @PLATFORM_ANDROID_TRUE@am__append_1 = $(GLIB_LIBS) subdir = mono/profiler DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ @@ -150,22 +150,25 @@ AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@@JIT_SUPPORTED_TRUE@am_libmono_profiler_aot_la_rpath = -rpath \ -@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@@JIT_SUPPORTED_TRUE@ $(libdir) +@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@am_libmono_profiler_aot_la_rpath = \ +@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@ -rpath \ +@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@ $(libdir) libmono_profiler_cov_la_DEPENDENCIES = $(am__DEPENDENCIES_3) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libmono_profiler_cov_la_OBJECTS = mono-cov.lo libmono_profiler_cov_la_OBJECTS = \ $(am_libmono_profiler_cov_la_OBJECTS) -@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@@JIT_SUPPORTED_TRUE@am_libmono_profiler_cov_la_rpath = -rpath \ -@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@@JIT_SUPPORTED_TRUE@ $(libdir) +@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@am_libmono_profiler_cov_la_rpath = \ +@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@ -rpath \ +@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@ $(libdir) libmono_profiler_iomap_la_DEPENDENCIES = $(am__DEPENDENCIES_3) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libmono_profiler_iomap_la_OBJECTS = mono-profiler-iomap.lo libmono_profiler_iomap_la_OBJECTS = \ $(am_libmono_profiler_iomap_la_OBJECTS) -@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@@JIT_SUPPORTED_TRUE@am_libmono_profiler_iomap_la_rpath = -rpath \ -@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@@JIT_SUPPORTED_TRUE@ $(libdir) +@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@am_libmono_profiler_iomap_la_rpath = \ +@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@ -rpath \ +@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@ $(libdir) @PLATFORM_ANDROID_TRUE@am__DEPENDENCIES_4 = $(am__DEPENDENCIES_1) libmono_profiler_log_la_DEPENDENCIES = $(am__DEPENDENCIES_3) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_4) @@ -176,8 +179,9 @@ libmono_profiler_log_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ $(AM_CFLAGS) $(CFLAGS) $(libmono_profiler_log_la_LDFLAGS) \ $(LDFLAGS) -o $@ -@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@@JIT_SUPPORTED_TRUE@am_libmono_profiler_log_la_rpath = -rpath \ -@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@@JIT_SUPPORTED_TRUE@ $(libdir) +@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@am_libmono_profiler_log_la_rpath = \ +@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@ -rpath \ +@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@ $(libdir) PROGRAMS = $(bin_PROGRAMS) am_mprof_report_OBJECTS = decode.$(OBJEXT) mprof_report_OBJECTS = $(am_mprof_report_OBJECTS) @@ -456,9 +460,9 @@ AM_CPPFLAGS = \ -I$(top_srcdir) \ $(GLIB_CFLAGS) -@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@@JIT_SUPPORTED_TRUE@lib_LTLIBRARIES = libmono-profiler-cov.la libmono-profiler-aot.la libmono-profiler-iomap.la libmono-profiler-log.la -@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@@JIT_SUPPORTED_TRUE@@PLATFORM_ANDROID_TRUE@libmono_profiler_log_la_LDFLAGS = -avoid-version -@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@@JIT_SUPPORTED_TRUE@@PLATFORM_DARWIN_TRUE@libmono_profiler_log_la_LDFLAGS = -Wl,-undefined -Wl,suppress -Wl,-flat_namespace +@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@lib_LTLIBRARIES = libmono-profiler-cov.la libmono-profiler-aot.la libmono-profiler-iomap.la libmono-profiler-log.la +@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@@PLATFORM_ANDROID_TRUE@libmono_profiler_log_la_LDFLAGS = -avoid-version +@DISABLE_LIBRARIES_FALSE@@DISABLE_PROFILER_FALSE@@PLATFORM_DARWIN_TRUE@libmono_profiler_log_la_LDFLAGS = -Wl,-undefined -Wl,suppress -Wl,-flat_namespace @DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_FALSE@@SUPPORT_BOEHM_TRUE@LIBMONO = $(top_builddir)/mono/mini/$(LIBMONO_LA) $(static_libs) @DISABLE_EXECUTABLES_FALSE@@SHARED_MONO_TRUE@@SUPPORT_BOEHM_TRUE@LIBMONO = $(top_builddir)/mono/mini/$(LIBMONO_LA) diff --git a/mono/profiler/perf_event.h b/mono/profiler/perf_event.h index 057bf22a83..3137aea798 100644 --- a/mono/profiler/perf_event.h +++ b/mono/profiler/perf_event.h @@ -18,6 +18,8 @@ #include #include +#include "mono/utils/mono-compiler.h" + /* * User-space ABI bits: */ @@ -1004,7 +1006,7 @@ static inline void perf_fetch_caller_regs(struct pt_regs *regs) perf_arch_fetch_caller_regs(regs, CALLER_ADDR0); } -static __always_inline void +static MONO_ALWAYS_INLINE void perf_sw_event(u32 event_id, u64 nr, int nmi, struct pt_regs *regs, u64 addr) { struct pt_regs hot_regs; diff --git a/mono/profiler/proflog.c b/mono/profiler/proflog.c index 520b3b228d..b12058d21f 100644 --- a/mono/profiler/proflog.c +++ b/mono/profiler/proflog.c @@ -90,6 +90,7 @@ static int do_mono_sample = 0; static int in_shutdown = 0; static int do_debug = 0; static int do_counters = 0; +static MonoProfileSamplingMode sampling_mode = MONO_PROFILER_STAT_MODE_PROCESS; /* For linux compile with: * gcc -fPIC -shared -o libmono-profiler-log.so proflog.c utils.c -Wall -g -lz `pkg-config --cflags --libs mono-2` @@ -831,13 +832,10 @@ walk_stack (MonoMethod *method, int32_t native_offset, int32_t il_offset, mono_b * event, hence the collect_bt/emit_bt split. */ static void -collect_bt (FrameData *data, gboolean async_safe) +collect_bt (FrameData *data) { data->count = 0; - if (async_safe) - mono_stack_walk_async_safe (walk_stack, data); - else - mono_stack_walk_no_il (walk_stack, data); + mono_stack_walk_no_il (walk_stack, data); } static void @@ -870,7 +868,7 @@ gc_alloc (MonoProfiler *prof, MonoObject *obj, MonoClass *klass) len += 7; len &= ~7; if (do_bt) - collect_bt (&data, FALSE); + collect_bt (&data); logbuffer = ensure_logbuf (32 + MAX_FRAMES * 8); now = current_time (); ENTER_LOG (logbuffer, "gcalloc"); @@ -1135,7 +1133,7 @@ throw_exc (MonoProfiler *prof, MonoObject *object) FrameData data; LogBuffer *logbuffer; if (do_bt) - collect_bt (&data, FALSE); + collect_bt (&data); logbuffer = ensure_logbuf (16 + MAX_FRAMES * 8); now = current_time (); ENTER_LOG (logbuffer, "throw"); @@ -1171,7 +1169,7 @@ monitor_event (MonoProfiler *profiler, MonoObject *object, MonoProfilerMonitorEv FrameData data; LogBuffer *logbuffer; if (do_bt) - collect_bt (&data, FALSE); + collect_bt (&data); logbuffer = ensure_logbuf (16 + MAX_FRAMES * 8); now = current_time (); ENTER_LOG (logbuffer, "monitor"); @@ -1220,11 +1218,44 @@ thread_name (MonoProfiler *prof, uintptr_t tid, const char *name) EXIT_LOG (logbuffer); } +typedef struct { + MonoMethod *method; + MonoDomain *domain; + void *base_address; + int offset; +} AsyncFrameInfo; + +typedef struct { + int count; + AsyncFrameInfo *data; +} AsyncFrameData; + +static mono_bool +async_walk_stack (MonoMethod *method, MonoDomain *domain, void *base_address, int offset, void *data) +{ + AsyncFrameData *frame = data; + if (frame->count < num_frames) { + frame->data [frame->count].method = method; + frame->data [frame->count].domain = domain; + frame->data [frame->count].base_address = base_address; + frame->data [frame->count].offset = offset; + // printf ("In %d at %p (dom %p) (native: %p)\n", frame->count, method, domain, base_address); + frame->count++; + } + return frame->count == num_frames; +} + +/* +(type | frame count), tid, time, ip, [method, domain, base address, offset] * frames +*/ +#define SAMPLE_EVENT_SIZE_IN_SLOTS(FRAMES) (4 + (FRAMES) * 4) + static void mono_sample_hit (MonoProfiler *profiler, unsigned char *ip, void *context) { StatBuffer *sbuf; - FrameData bt_data; + AsyncFrameInfo frames [num_frames]; + AsyncFrameData bt_data = { 0, &frames [0]}; uint64_t now; uintptr_t *data, *new_data, *old_data; uintptr_t elapsed; @@ -1233,7 +1264,9 @@ mono_sample_hit (MonoProfiler *profiler, unsigned char *ip, void *context) if (in_shutdown) return; now = current_time (); - collect_bt (&bt_data, TRUE); + + mono_stack_walk_async_safe (&async_walk_stack, context, &bt_data); + elapsed = (now - profiler->startup_time) / 10000; if (do_debug) { int len; @@ -1272,7 +1305,7 @@ mono_sample_hit (MonoProfiler *profiler, unsigned char *ip, void *context) } do { old_data = sbuf->data; - new_data = old_data + 4 + bt_data.count * 3; + new_data = old_data + SAMPLE_EVENT_SIZE_IN_SLOTS (bt_data.count); data = InterlockedCompareExchangePointer ((void * volatile*)&sbuf->data, new_data, old_data); } while (data != old_data); if (old_data >= sbuf->data_end) @@ -1282,9 +1315,10 @@ mono_sample_hit (MonoProfiler *profiler, unsigned char *ip, void *context) old_data [2] = elapsed; old_data [3] = (uintptr_t)ip; for (i = 0; i < bt_data.count; ++i) { - old_data [4+3*i] = (uintptr_t)bt_data.methods [i]; - old_data [4+3*i+1] = (uintptr_t)bt_data.il_offsets [i]; - old_data [4+3*i+2] = (uintptr_t)bt_data.native_offsets [i]; + old_data [4 + 4 * i + 0] = (uintptr_t)frames [i].method; + old_data [4 + 4 * i + 1] = (uintptr_t)frames [i].domain; + old_data [4 + 4 * i + 2] = (uintptr_t)frames [i].base_address; + old_data [4 + 4 * i + 3] = (uintptr_t)frames [i].offset; } } @@ -1624,8 +1658,22 @@ dump_sample_hits (MonoProfiler *prof, StatBuffer *sbuf, int recurse) int count = sample [0] & 0xff; int mbt_count = (sample [0] & 0xff00) >> 8; int type = sample [0] >> 16; - if (sample + count + 3 + mbt_count * 3 > sbuf->data) + uintptr_t *managed_sample_base = sample + count + 3; + + if (sample + SAMPLE_EVENT_SIZE_IN_SLOTS (mbt_count) > sbuf->data) break; + + for (i = 0; i < mbt_count; ++i) { + MonoMethod *method = (MonoMethod*)managed_sample_base [i * 4 + 0]; + MonoDomain *domain = (MonoDomain*)managed_sample_base [i * 4 + 1]; + void *address = (void*)managed_sample_base [i * 4 + 2]; + + if (!method) { + MonoJitInfo *ji = mono_jit_info_table_find (domain, address); + if (ji) + managed_sample_base [i * 4 + 0] = (uintptr_t)mono_jit_info_get_method (ji); + } + } logbuffer = ensure_logbuf (20 + count * 8); emit_byte (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_HIT); emit_value (logbuffer, type); @@ -1635,15 +1683,16 @@ dump_sample_hits (MonoProfiler *prof, StatBuffer *sbuf, int recurse) emit_ptr (logbuffer, (void*)sample [i + 3]); add_code_pointer (sample [i + 3]); } + sample += count + 3; /* new in data version 6 */ emit_uvalue (logbuffer, mbt_count); for (i = 0; i < mbt_count; ++i) { - emit_method (logbuffer, (void*)sample [i * 3]); /* method */ - emit_svalue (logbuffer, sample [i * 3 + 1]); /* il offset */ - emit_svalue (logbuffer, sample [i * 3 + 2]); /* native offset */ + emit_method (logbuffer, (void*)sample [i * 4]); /* method */ + emit_svalue (logbuffer, 0); /* il offset will always be 0 from now on */ + emit_svalue (logbuffer, sample [i * 4 + 3]); /* native offset */ } - sample += 3 * mbt_count; + sample += 4 * mbt_count; } dump_unmanaged_coderefs (prof); } @@ -2188,6 +2237,10 @@ new_filename (const char* filename) } #ifndef DISABLE_HELPER_THREAD + +//this is exposed by the JIT, but it's not meant to be a supported API for now. +extern void mono_threads_attach_tools_thread (void); + static void* helper_thread (void* arg) { @@ -2198,6 +2251,7 @@ helper_thread (void* arg) MonoThread *thread = NULL; uint64_t start, now; + mono_threads_attach_tools_thread (); //fprintf (stderr, "Server listening\n"); start = current_time (); command_socket = -1; @@ -2255,9 +2309,11 @@ helper_thread (void* arg) sbufbase->next->next = NULL; if (do_debug) fprintf (stderr, "stat buffer dump\n"); - dump_sample_hits (prof, sbuf, 1); - free_buffer (sbuf, sbuf->size); - safe_dump (prof, ensure_logbuf (0)); + if (sbuf) { + dump_sample_hits (prof, sbuf, 1); + free_buffer (sbuf, sbuf->size); + safe_dump (prof, ensure_logbuf (0)); + } continue; } /* time to shut down */ @@ -2692,6 +2748,14 @@ mono_profiler_startup (const char *desc) do_debug = 1; continue; } + if ((opt = match_option (p, "sampling-real", NULL)) != p) { + sampling_mode = MONO_PROFILER_STAT_MODE_REAL; + continue; + } + if ((opt = match_option (p, "sampling-process", NULL)) != p) { + sampling_mode = MONO_PROFILER_STAT_MODE_PROCESS; + continue; + } if ((opt = match_option (p, "heapshot", &val)) != p) { events &= ~MONO_PROFILE_ALLOCATIONS; events &= ~MONO_PROFILE_ENTER_LEAVE; @@ -2781,6 +2845,7 @@ mono_profiler_startup (const char *desc) if (do_mono_sample && sample_type == SAMPLE_CYCLES) { events |= MONO_PROFILE_STATISTICAL; + mono_profiler_set_statistical_mode (sampling_mode, 1000000 / sample_freq); mono_profiler_install_statistical (mono_sample_hit); } diff --git a/mono/tests/Makefile.am b/mono/tests/Makefile.am index 7d448d374a..86f33d6f76 100644 --- a/mono/tests/Makefile.am +++ b/mono/tests/Makefile.am @@ -43,6 +43,7 @@ STRESS_TESTS_SRC= \ monitor-stress.cs \ thread-stress.cs \ gc-stress.cs \ + gc-copy-stress.cs \ gc-graystack-stress.cs \ exit-stress.cs \ process-stress.cs \ @@ -213,6 +214,7 @@ BASE_TEST_CS_SRC= \ array3.cs \ classinit.cs \ classinit2.cs \ + classinit3.cs \ synchronized.cs \ async_read.cs \ threadpool.cs \ @@ -435,7 +437,8 @@ endif if X86 if HOST_WIN32 -PLATFORM_DISABLED_TESTS=async-exc-compilation.exe finally_guard.exe finally_block_ending_in_dead_bb.exe +PLATFORM_DISABLED_TESTS=async-exc-compilation.exe finally_guard.exe finally_block_ending_in_dead_bb.exe \ + bug-18026.exe monitor.exe threadpool-exceptions5.exe endif endif @@ -934,13 +937,11 @@ SGEN_TESTS = \ SGEN_CONFIGURATIONS = \ "|plain" \ - "major=marksweep-par|ms-par" \ "major=marksweep-conc|ms-conc" \ "major=marksweep-conc,minor=split|ms-conc-split" \ "minor=split|ms-split" \ "minor=split,alloc-ratio=95|ms-split-95" \ "|plain-clear-at-gc|clear-at-gc" \ - "major=marksweep-par|ms-par-clear-at-gc|clear-at-gc" \ "major=marksweep-conc|ms-conc-clear-at-gc|clear-at-gc" \ "minor=split|ms-split-clear-at-gc|clear-at-gc" @@ -1299,12 +1300,8 @@ patch-libtool: if NACL_CODEGEN test-process-exit: else -EXTRA_DIST += bug-438454.cs bug-438454.exe.stdout.expected threadpool-in-processexit.cs threadpool-in-processexit.exe.stdout.expected +EXTRA_DIST += threadpool-in-processexit.cs threadpool-in-processexit.exe.stdout.expected test-process-exit: - @$(MCS) $(srcdir)/bug-438454.cs -out:bug-438454.exe - @echo "Testing bug-438454.exe..." - @$(RUNTIME) bug-438454.exe > bug-438454.exe.stdout - @diff -w bug-438454.exe.stdout $(srcdir)/bug-438454.exe.stdout.expected @$(MCS) $(srcdir)/threadpool-in-processexit.cs -out:threadpool-in-processexit.exe @echo "Testing threadpool-in-processexit.exe..." @$(RUNTIME) threadpool-in-processexit.exe > threadpool-in-processexit.exe.stdout @@ -1319,7 +1316,6 @@ OOM_TESTS = \ test-oom: $(OOM_TESTS) @for fn in $+ ; do \ echo "Testing $$fn ..."; \ - MONO_GC_PARAMS=max-heap-size=16m,major=marksweep-par MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.stdout || exit 1; \ MONO_GC_PARAMS=max-heap-size=16m MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.stdout || exit 1; \ MONO_GC_PARAMS=max-heap-size=16m $(RUNTIME) $$fn > $$fn.stdout || exit 1; \ done diff --git a/mono/tests/Makefile.in b/mono/tests/Makefile.in index 9a79d00a3a..d332d6fb23 100644 --- a/mono/tests/Makefile.in +++ b/mono/tests/Makefile.in @@ -94,7 +94,7 @@ target_triplet = @target@ @NACL_CODEGEN_TRUE@@X86_TRUE@ main-returns-background-resetabort.exe \ @NACL_CODEGEN_TRUE@@X86_TRUE@ main-returns-background.exe \ @NACL_CODEGEN_TRUE@@X86_TRUE@ main-returns-background-change.exe -@NACL_CODEGEN_FALSE@am__append_3 = bug-438454.cs bug-438454.exe.stdout.expected threadpool-in-processexit.cs threadpool-in-processexit.exe.stdout.expected +@NACL_CODEGEN_FALSE@am__append_3 = threadpool-in-processexit.cs threadpool-in-processexit.exe.stdout.expected subdir = mono/tests DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/mkinstalldirs $(srcdir)/tests-config.in \ @@ -457,6 +457,7 @@ STRESS_TESTS_SRC = \ monitor-stress.cs \ thread-stress.cs \ gc-stress.cs \ + gc-copy-stress.cs \ gc-graystack-stress.cs \ exit-stress.cs \ process-stress.cs \ @@ -628,6 +629,7 @@ BASE_TEST_CS_SRC = \ array3.cs \ classinit.cs \ classinit2.cs \ + classinit3.cs \ synchronized.cs \ async_read.cs \ threadpool.cs \ @@ -847,6 +849,8 @@ TEST_CS_SRC_GEN = \ @HOST_WIN32_TRUE@@X86_TRUE@ async-exc-compilation.exe \ @HOST_WIN32_TRUE@@X86_TRUE@ finally_guard.exe \ @HOST_WIN32_TRUE@@X86_TRUE@ finally_block_ending_in_dead_bb.exe \ +@HOST_WIN32_TRUE@@X86_TRUE@ bug-18026.exe monitor.exe \ +@HOST_WIN32_TRUE@@X86_TRUE@ threadpool-exceptions5.exe \ @HOST_WIN32_TRUE@@X86_TRUE@ $(am__append_2) # bug #319249 @IA64_TRUE@PLATFORM_DISABLED_TESTS = exception17.exe winx64structs.exe \ @@ -1076,13 +1080,11 @@ SGEN_TESTS = \ SGEN_CONFIGURATIONS = \ "|plain" \ - "major=marksweep-par|ms-par" \ "major=marksweep-conc|ms-conc" \ "major=marksweep-conc,minor=split|ms-conc-split" \ "minor=split|ms-split" \ "minor=split,alloc-ratio=95|ms-split-95" \ "|plain-clear-at-gc|clear-at-gc" \ - "major=marksweep-par|ms-par-clear-at-gc|clear-at-gc" \ "major=marksweep-conc|ms-conc-clear-at-gc|clear-at-gc" \ "minor=split|ms-split-clear-at-gc|clear-at-gc" @@ -1999,10 +2001,6 @@ patch-libtool: @NACL_CODEGEN_TRUE@test-process-exit: @NACL_CODEGEN_FALSE@test-process-exit: -@NACL_CODEGEN_FALSE@ @$(MCS) $(srcdir)/bug-438454.cs -out:bug-438454.exe -@NACL_CODEGEN_FALSE@ @echo "Testing bug-438454.exe..." -@NACL_CODEGEN_FALSE@ @$(RUNTIME) bug-438454.exe > bug-438454.exe.stdout -@NACL_CODEGEN_FALSE@ @diff -w bug-438454.exe.stdout $(srcdir)/bug-438454.exe.stdout.expected @NACL_CODEGEN_FALSE@ @$(MCS) $(srcdir)/threadpool-in-processexit.cs -out:threadpool-in-processexit.exe @NACL_CODEGEN_FALSE@ @echo "Testing threadpool-in-processexit.exe..." @NACL_CODEGEN_FALSE@ @$(RUNTIME) threadpool-in-processexit.exe > threadpool-in-processexit.exe.stdout @@ -2011,7 +2009,6 @@ patch-libtool: test-oom: $(OOM_TESTS) @for fn in $+ ; do \ echo "Testing $$fn ..."; \ - MONO_GC_PARAMS=max-heap-size=16m,major=marksweep-par MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.stdout || exit 1; \ MONO_GC_PARAMS=max-heap-size=16m MONO_ENV_OPTIONS="--gc=sgen" $(RUNTIME) $$fn > $$fn.stdout || exit 1; \ MONO_GC_PARAMS=max-heap-size=16m $(RUNTIME) $$fn > $$fn.stdout || exit 1; \ done diff --git a/mono/tests/bug-438454.cs b/mono/tests/bug-438454.cs deleted file mode 100755 index f95b17a79b..0000000000 --- a/mono/tests/bug-438454.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using System.Threading; - -class Program -{ - static void Main () - { - var d = AppDomain.CreateDomain("Foo"); - d.ProcessExit += AppDomain_ProcessExit; - - AppDomain.CurrentDomain.ProcessExit += new EventHandler (AppDomain_ProcessExit); - ThreadPool.QueueUserWorkItem (new WaitCallback (Proc)); - Thread.Sleep (100); - } - - static void Proc (object unused) - { - Thread.CurrentThread.IsBackground = false; - Thread.Sleep (500); - Console.WriteLine ("done"); - } - - static void AppDomain_ProcessExit (object sender, EventArgs e) - { - Console.WriteLine ("exit"); - - // No messages should be printed, as when this event is fired the - // ThreadPool has been shutdown, thus `a.BeginInvoke()` has no effect. - Action a = () => { - int i = 0; - while (i < 1024) - Console.WriteLine ("Ha! {0}", i++); - }; - a.BeginInvoke (null, null); - } -} diff --git a/mono/tests/bug-438454.exe.stdout.expected b/mono/tests/bug-438454.exe.stdout.expected deleted file mode 100644 index 56500e762e..0000000000 --- a/mono/tests/bug-438454.exe.stdout.expected +++ /dev/null @@ -1,3 +0,0 @@ -done -exit -exit diff --git a/mono/tests/classinit3.cs b/mono/tests/classinit3.cs new file mode 100644 index 0000000000..865b621c29 --- /dev/null +++ b/mono/tests/classinit3.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Threading; +namespace integer_test +{ + class MainClass + { + // #23242 + public static void Main (string[] args) + { + var _trigger = new ManualResetEvent (false); + + var testThreads = new Thread[100]; + for (Int16 i = 0; i < testThreads.Length; ++i) + { + testThreads [i] = new Thread ( () => + { + _trigger.WaitOne(); + for (Int16 index = 0; index < 1000; ++index) + { + var val = index.ToString(); + GC.KeepAlive(val); + } + }); + testThreads [i].Start (); + } + Console.WriteLine ("setting event"); + _trigger.Set (); + foreach (var thread in testThreads) + { + thread.Join (); + } + } + } +} diff --git a/mono/tests/gc-copy-stress.cs b/mono/tests/gc-copy-stress.cs new file mode 100644 index 0000000000..130f33f828 --- /dev/null +++ b/mono/tests/gc-copy-stress.cs @@ -0,0 +1,35 @@ +using System; + +class T { + + static int count = 1000000; + static int loops = 20; + static int persist_factor = 10; + + static object obj; + + static object[] persist; + static int persist_idx; + + static void work () { + persist = new object[count / persist_factor + 1]; + persist_idx = 0; + for (int i = 0; i < count; ++i) { + obj = new object (); + if (i % persist_factor == 0) + persist[persist_idx++] = obj; + } + } + + static void Main (string[] args) { + if (args.Length > 0) + loops = int.Parse (args [0]); + if (args.Length > 1) + count = int.Parse (args [1]); + if (args.Length > 2) + persist_factor = int.Parse (args [2]); + for (int i = 0; i < loops; ++i) { + work (); + } + } +} diff --git a/mono/tests/libtest.c.REMOVED.git-id b/mono/tests/libtest.c.REMOVED.git-id index 10f0375ffc..8dddd396b1 100644 --- a/mono/tests/libtest.c.REMOVED.git-id +++ b/mono/tests/libtest.c.REMOVED.git-id @@ -1 +1 @@ -e057944bbd7ef44810b06a3c925dbc9e51e5c0ac \ No newline at end of file +ceecaf02ae426835d9d311b09c9c2e1a96b3fce8 \ No newline at end of file diff --git a/mono/tests/pinvoke2.cs b/mono/tests/pinvoke2.cs index 71c51a7d81..edf9a6dad4 100644 --- a/mono/tests/pinvoke2.cs +++ b/mono/tests/pinvoke2.cs @@ -71,6 +71,11 @@ public class Tests { public SimpleDelegate del3; } + [StructLayout (LayoutKind.Sequential)] + public struct SingleDoubleStruct { + public double d; + } + /* sparcv9 has complex conventions when passing structs with doubles in them by value, some simple tests for them */ [StructLayout (LayoutKind.Sequential)] @@ -1800,5 +1805,16 @@ public class Tests { return 0; } + + [DllImport ("libtest", EntryPoint = "mono_test_marshal_return_single_double_struct")] + public static extern SingleDoubleStruct mono_test_marshal_return_single_double_struct (); + + public static int test_0_x86_single_double_struct_ret () { + double d = mono_test_marshal_return_single_double_struct ().d; + if (d != 3.0) + return 1; + else + return 0; + } } diff --git a/mono/tests/stress-runner.pl b/mono/tests/stress-runner.pl index 24d5b9db8d..165b1d877a 100755 --- a/mono/tests/stress-runner.pl +++ b/mono/tests/stress-runner.pl @@ -72,6 +72,13 @@ my %tests = ( 'arg-knob' => 2, # loops 'ratio' => 10, }, + 'gc-copy-stress' => { + 'program' => 'gc-copy-stress.exe', + # loops, count, persist_factor + 'args' => [250, 500000, 10], + 'arg-knob' => 1, # count + 'ratio' => 4, + }, 'thread-stress' => { 'program' => 'thread-stress.exe', # loops diff --git a/mono/utils/Makefile.am b/mono/utils/Makefile.am index c5464d16b1..c2c8a0d790 100644 --- a/mono/utils/Makefile.am +++ b/mono/utils/Makefile.am @@ -32,6 +32,7 @@ monoutils_sources = \ mono-math.c \ mono-mmap.c \ mono-mmap.h \ + mono-mmap-internal.h \ mono-mutex.c \ mono-mutex.h \ mono-networkinterfaces.c \ diff --git a/mono/utils/Makefile.in b/mono/utils/Makefile.in index 11cc0ed094..73b7516069 100644 --- a/mono/utils/Makefile.in +++ b/mono/utils/Makefile.in @@ -123,15 +123,16 @@ am__libmonoutils_la_SOURCES_DIST = mono-md5.c mono-sha1.c \ mono-internal-hash.c mono-internal-hash.h \ mono-io-portability.c mono-io-portability.h monobitset.c \ mono-filemap.c mono-math.c mono-mmap.c mono-mmap.h \ - mono-mutex.c mono-mutex.h mono-networkinterfaces.c \ - mono-networkinterfaces.h mono-proclib.c mono-proclib.h \ - mono-publib.c mono-string.h mono-time.c mono-time.h strtod.h \ - strtod.c strenc.h strenc.c mono-uri.c mono-poll.c mono-path.c \ - mono-semaphore.c mono-semaphore.h mono-sigcontext.h \ - mono-stdlib.c mono-property-hash.h mono-property-hash.c \ - mono-value-hash.h mono-value-hash.c freebsd-elf_common.h \ - freebsd-elf32.h freebsd-elf64.h freebsd-dwarf.h dtrace.h \ - gc_wrapper.h mono-error.c mono-error-internals.h monobitset.h \ + mono-mmap-internal.h mono-mutex.c mono-mutex.h \ + mono-networkinterfaces.c mono-networkinterfaces.h \ + mono-proclib.c mono-proclib.h mono-publib.c mono-string.h \ + mono-time.c mono-time.h strtod.h strtod.c strenc.h strenc.c \ + mono-uri.c mono-poll.c mono-path.c mono-semaphore.c \ + mono-semaphore.h mono-sigcontext.h mono-stdlib.c \ + mono-property-hash.h mono-property-hash.c mono-value-hash.h \ + mono-value-hash.c freebsd-elf_common.h freebsd-elf32.h \ + freebsd-elf64.h freebsd-dwarf.h dtrace.h gc_wrapper.h \ + mono-error.c mono-error-internals.h monobitset.h \ mono-codeman.h mono-counters.h mono-digest.h mono-error.h \ mono-machine.h mono-math.h mono-membar.h mono-path.h \ mono-poll.h mono-uri.h mono-stdlib.h valgrind.h mach-support.c \ @@ -515,6 +516,7 @@ monoutils_sources = \ mono-math.c \ mono-mmap.c \ mono-mmap.h \ + mono-mmap-internal.h \ mono-mutex.c \ mono-mutex.h \ mono-networkinterfaces.c \ diff --git a/mono/utils/lock-free-alloc.c b/mono/utils/lock-free-alloc.c index 4befb3b86a..33fed096ea 100644 --- a/mono/utils/lock-free-alloc.c +++ b/mono/utils/lock-free-alloc.c @@ -113,6 +113,7 @@ struct _MonoLockFreeAllocDescriptor { MonoLockFreeAllocator *heap; volatile Anchor anchor; unsigned int slot_size; + unsigned int block_size; unsigned int max_count; gpointer sb; #ifndef DESC_AVAIL_DUMMY @@ -123,12 +124,11 @@ struct _MonoLockFreeAllocDescriptor { #define NUM_DESC_BATCH 64 -#define SB_SIZE 16384 -#define SB_HEADER_SIZE 16 -#define SB_USABLE_SIZE (SB_SIZE - SB_HEADER_SIZE) - -#define SB_HEADER_FOR_ADDR(a) ((gpointer)((size_t)(a) & ~(size_t)(SB_SIZE-1))) -#define DESCRIPTOR_FOR_ADDR(a) (*(Descriptor**)SB_HEADER_FOR_ADDR (a)) +static MONO_ALWAYS_INLINE gpointer +sb_header_for_addr (gpointer addr, size_t block_size) +{ + return (gpointer)(((size_t)addr) & (~(block_size - 1))); +} /* Taken from SGen */ @@ -139,41 +139,34 @@ prot_flags_for_activate (int activate) return prot_flags | MONO_MMAP_PRIVATE | MONO_MMAP_ANON; } -static void* -mono_sgen_alloc_os_memory (size_t size, int activate) -{ - return mono_valloc (0, size, prot_flags_for_activate (activate)); -} - -static void -mono_sgen_free_os_memory (void *addr, size_t size) -{ - mono_vfree (addr, size); -} - -/* size must be a power of 2 */ -static void* -mono_sgen_alloc_os_memory_aligned (size_t size, size_t alignment, gboolean activate) -{ - return mono_valloc_aligned (size, alignment, prot_flags_for_activate (activate)); -} - static gpointer alloc_sb (Descriptor *desc) { - gpointer sb_header = mono_sgen_alloc_os_memory_aligned (SB_SIZE, SB_SIZE, TRUE); - g_assert (sb_header == SB_HEADER_FOR_ADDR (sb_header)); - DESCRIPTOR_FOR_ADDR (sb_header) = desc; + static int pagesize = -1; + + gpointer sb_header; + + if (pagesize == -1) + pagesize = mono_pagesize (); + + sb_header = desc->block_size == pagesize ? + mono_valloc (0, desc->block_size, prot_flags_for_activate (TRUE)) : + mono_valloc_aligned (desc->block_size, desc->block_size, prot_flags_for_activate (TRUE)); + + g_assert (sb_header == sb_header_for_addr (sb_header, desc->block_size)); + + *(Descriptor**)sb_header = desc; //g_print ("sb %p for %p\n", sb_header, desc); - return (char*)sb_header + SB_HEADER_SIZE; + + return (char*)sb_header + LOCK_FREE_ALLOC_SB_HEADER_SIZE; } static void -free_sb (gpointer sb) +free_sb (gpointer sb, size_t block_size) { - gpointer sb_header = SB_HEADER_FOR_ADDR (sb); - g_assert ((char*)sb_header + SB_HEADER_SIZE == sb); - mono_sgen_free_os_memory (sb_header, SB_SIZE); + gpointer sb_header = sb_header_for_addr (sb, block_size); + g_assert ((char*)sb_header + LOCK_FREE_ALLOC_SB_HEADER_SIZE == sb); + mono_vfree (sb_header, block_size); //g_print ("free sb %p\n", sb_header); } @@ -198,7 +191,7 @@ desc_alloc (void) Descriptor *d; int i; - desc = mono_sgen_alloc_os_memory (desc_size * NUM_DESC_BATCH, TRUE); + desc = mono_valloc (0, desc_size * NUM_DESC_BATCH, prot_flags_for_activate (TRUE)); /* Organize into linked list. */ d = desc; @@ -214,7 +207,7 @@ desc_alloc (void) success = (InterlockedCompareExchangePointer ((gpointer * volatile)&desc_avail, desc->next, NULL) == NULL); if (!success) - mono_sgen_free_os_memory (desc, desc_size * NUM_DESC_BATCH); + mono_vfree (desc, desc_size * NUM_DESC_BATCH); } mono_hazard_pointer_clear (hp, 1); @@ -251,7 +244,7 @@ desc_retire (Descriptor *desc) g_assert (desc->anchor.data.state == STATE_EMPTY); g_assert (desc->in_use); desc->in_use = FALSE; - free_sb (desc->sb); + free_sb (desc->sb, desc->block_size); mono_thread_hazardous_free_or_queue (desc, desc_enqueue_avail, FALSE, TRUE); } #else @@ -271,7 +264,7 @@ desc_alloc (void) static void desc_retire (Descriptor *desc) { - free_sb (desc->sb); + free_sb (desc->sb, desc->block_size); mono_lock_free_queue_enqueue (&available_descs, &desc->node); } #endif @@ -388,7 +381,7 @@ alloc_from_active_or_partial (MonoLockFreeAllocator *heap) mono_memory_read_barrier (); next = *(unsigned int*)addr; - g_assert (next < SB_USABLE_SIZE / desc->slot_size); + g_assert (next < LOCK_FREE_ALLOC_SB_USABLE_SIZE (desc->block_size) / desc->slot_size); new_anchor.data.avail = next; --new_anchor.data.count; @@ -409,17 +402,12 @@ alloc_from_active_or_partial (MonoLockFreeAllocator *heap) static gpointer alloc_from_new_sb (MonoLockFreeAllocator *heap) { - unsigned int slot_size, count, i; + unsigned int slot_size, block_size, count, i; Descriptor *desc = desc_alloc (); - desc->sb = alloc_sb (desc); - slot_size = desc->slot_size = heap->sc->slot_size; - count = SB_USABLE_SIZE / slot_size; - - /* Organize blocks into linked list. */ - for (i = 1; i < count - 1; ++i) - *(unsigned int*)((char*)desc->sb + i * slot_size) = i + 1; + block_size = desc->block_size = heap->sc->block_size; + count = LOCK_FREE_ALLOC_SB_USABLE_SIZE (block_size) / slot_size; desc->heap = heap; /* @@ -433,6 +421,12 @@ alloc_from_new_sb (MonoLockFreeAllocator *heap) desc->anchor.data.count = desc->max_count - 1; desc->anchor.data.state = STATE_PARTIAL; + desc->sb = alloc_sb (desc); + + /* Organize blocks into linked list. */ + for (i = 1; i < count - 1; ++i) + *(unsigned int*)((char*)desc->sb + i * slot_size) = i + 1; + mono_memory_write_barrier (); /* Make it active or free it again. */ @@ -465,22 +459,23 @@ mono_lock_free_alloc (MonoLockFreeAllocator *heap) } void -mono_lock_free_free (gpointer ptr) +mono_lock_free_free (gpointer ptr, size_t block_size) { Anchor old_anchor, new_anchor; Descriptor *desc; gpointer sb; MonoLockFreeAllocator *heap = NULL; - desc = DESCRIPTOR_FOR_ADDR (ptr); + desc = *(Descriptor**) sb_header_for_addr (ptr, block_size); + g_assert (block_size == desc->block_size); + sb = desc->sb; - g_assert (SB_HEADER_FOR_ADDR (ptr) == SB_HEADER_FOR_ADDR (sb)); do { new_anchor = old_anchor = *(volatile Anchor*)&desc->anchor.value; *(unsigned int*)ptr = old_anchor.data.avail; new_anchor.data.avail = ((char*)ptr - (char*)sb) / desc->slot_size; - g_assert (new_anchor.data.avail < SB_USABLE_SIZE / desc->slot_size); + g_assert (new_anchor.data.avail < LOCK_FREE_ALLOC_SB_USABLE_SIZE (block_size) / desc->slot_size); if (old_anchor.data.state == STATE_FULL) new_anchor.data.state = STATE_PARTIAL; @@ -530,7 +525,7 @@ static void descriptor_check_consistency (Descriptor *desc, gboolean print) { int count = desc->anchor.data.count; - int max_count = SB_USABLE_SIZE / desc->slot_size; + int max_count = LOCK_FREE_ALLOC_SB_USABLE_SIZE (desc->block_size) / desc->slot_size; #if _MSC_VER gboolean* linked = alloca(max_count*sizeof(gboolean)); #else @@ -607,12 +602,15 @@ mono_lock_free_allocator_check_consistency (MonoLockFreeAllocator *heap) } void -mono_lock_free_allocator_init_size_class (MonoLockFreeAllocSizeClass *sc, unsigned int slot_size) +mono_lock_free_allocator_init_size_class (MonoLockFreeAllocSizeClass *sc, unsigned int slot_size, unsigned int block_size) { - g_assert (slot_size <= SB_USABLE_SIZE / 2); + g_assert (block_size > 0); + g_assert ((block_size & (block_size - 1)) == 0); /* check if power of 2 */ + g_assert (slot_size * 2 <= LOCK_FREE_ALLOC_SB_USABLE_SIZE (block_size)); mono_lock_free_queue_init (&sc->partial); sc->slot_size = slot_size; + sc->block_size = block_size; } void diff --git a/mono/utils/lock-free-alloc.h b/mono/utils/lock-free-alloc.h index ed07a2971a..84935646d3 100644 --- a/mono/utils/lock-free-alloc.h +++ b/mono/utils/lock-free-alloc.h @@ -33,6 +33,7 @@ typedef struct { MonoLockFreeQueue partial; unsigned int slot_size; + unsigned int block_size; } MonoLockFreeAllocSizeClass; struct _MonoLockFreeAllocDescriptor; @@ -42,11 +43,15 @@ typedef struct { MonoLockFreeAllocSizeClass *sc; } MonoLockFreeAllocator; -void mono_lock_free_allocator_init_size_class (MonoLockFreeAllocSizeClass *sc, unsigned int slot_size) MONO_INTERNAL; +#define LOCK_FREE_ALLOC_SB_MAX_SIZE 16384 +#define LOCK_FREE_ALLOC_SB_HEADER_SIZE (sizeof (MonoLockFreeAllocator)) +#define LOCK_FREE_ALLOC_SB_USABLE_SIZE(block_size) ((block_size) - LOCK_FREE_ALLOC_SB_HEADER_SIZE) + +void mono_lock_free_allocator_init_size_class (MonoLockFreeAllocSizeClass *sc, unsigned int slot_size, unsigned int block_size) MONO_INTERNAL; void mono_lock_free_allocator_init_allocator (MonoLockFreeAllocator *heap, MonoLockFreeAllocSizeClass *sc) MONO_INTERNAL; gpointer mono_lock_free_alloc (MonoLockFreeAllocator *heap) MONO_INTERNAL; -void mono_lock_free_free (gpointer ptr) MONO_INTERNAL; +void mono_lock_free_free (gpointer ptr, size_t block_size) MONO_INTERNAL; gboolean mono_lock_free_allocator_check_consistency (MonoLockFreeAllocator *heap) MONO_INTERNAL; diff --git a/mono/utils/mono-compiler.h b/mono/utils/mono-compiler.h index c1d0e27a49..bad994cc29 100644 --- a/mono/utils/mono-compiler.h +++ b/mono/utils/mono-compiler.h @@ -161,7 +161,7 @@ #define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1 #endif -#elif defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__)) +#elif defined(TARGET_MACH) && (defined(__i386__) || defined(__x86_64__)) #define MONO_HAVE_FAST_TLS #define MONO_FAST_TLS_SET(x,y) pthread_setspecific(x, y) @@ -198,10 +198,12 @@ #endif #include -#define isnan(x) _isnan(x) #define trunc(x) (((x) < 0) ? ceil((x)) : floor((x))) +#if _MSC_VER < 1800 /* VS 2013 */ +#define isnan(x) _isnan(x) #define isinf(x) (_isnan(x) ? 0 : (_fpclass(x) == _FPCLASS_NINF) ? -1 : (_fpclass(x) == _FPCLASS_PINF) ? 1 : 0) #define isnormal(x) _finite(x) +#endif #define popen _popen #define pclose _pclose @@ -217,6 +219,20 @@ #include typedef SSIZE_T ssize_t; +/* + * SSIZE_MAX is not defined in MSVC, so define it here. + * + * These values come from MinGW64, and are public domain. + * + */ +#ifndef SSIZE_MAX +#ifdef _WIN64 +#define SSIZE_MAX _I64_MAX +#else +#define SSIZE_MAX INT_MAX +#endif +#endif + #endif /* _MSC_VER */ #if !defined(_MSC_VER) && !defined(PLATFORM_SOLARIS) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MONOTOUCH) && HAVE_VISIBILITY_HIDDEN @@ -245,5 +261,13 @@ typedef SSIZE_T ssize_t; #define MONO_ALWAYS_INLINE #endif +#ifdef __GNUC__ +#define MONO_NEVER_INLINE __attribute__((noinline)) +#elif defined(_MSC_VER) +#define MONO_NEVER_INLINE __declspec(noinline) +#else +#define MONO_NEVER_INLINE +#endif + #endif /* __UTILS_MONO_COMPILER_H__*/ diff --git a/mono/utils/mono-context.c b/mono/utils/mono-context.c index bc0286485f..c52d0442f4 100644 --- a/mono/utils/mono-context.c +++ b/mono/utils/mono-context.c @@ -15,6 +15,10 @@ #include +#ifdef HOST_WIN32 +#include +#endif + #ifdef __sun #define REG_EAX EAX #define REG_EBX EBX @@ -53,6 +57,18 @@ mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) mctx->esi = UCONTEXT_REG_ESI (ctx); mctx->edi = UCONTEXT_REG_EDI (ctx); mctx->eip = UCONTEXT_REG_EIP (ctx); +#elif defined(HOST_WIN32) + CONTEXT *context = (CONTEXT*)sigctx; + + mctx->eip = context->Eip; + mctx->edi = context->Edi; + mctx->esi = context->Esi; + mctx->ebx = context->Ebx; + mctx->edx = context->Edx; + mctx->ecx = context->Ecx; + mctx->eax = context->Eax; + mctx->ebp = context->Ebp; + mctx->esp = context->Esp; #else struct sigcontext *ctx = (struct sigcontext *)sigctx; @@ -85,6 +101,18 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx) UCONTEXT_REG_ESI (ctx) = mctx->esi; UCONTEXT_REG_EDI (ctx) = mctx->edi; UCONTEXT_REG_EIP (ctx) = mctx->eip; +#elif defined(HOST_WIN32) + CONTEXT *context = (CONTEXT*)sigctx; + + context->Eip = mctx->eip; + context->Edi = mctx->edi; + context->Esi = mctx->esi; + context->Ebx = mctx->ebx; + context->Edx = mctx->edx; + context->Ecx = mctx->ecx; + context->Eax = mctx->eax; + context->Ebp = mctx->ebp; + context->Esp = mctx->esp; #else struct sigcontext *ctx = (struct sigcontext *)sigctx; @@ -104,6 +132,10 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx) #include +#ifdef HOST_WIN32 +#include +#endif + void mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) { @@ -131,6 +163,26 @@ mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) mctx->r14 = UCONTEXT_REG_R14 (ctx); mctx->r15 = UCONTEXT_REG_R15 (ctx); mctx->rip = UCONTEXT_REG_RIP (ctx); +#elif defined(HOST_WIN32) + CONTEXT *context = (CONTEXT*)sigctx; + + mctx->rip = context->Rip; + mctx->rax = context->Rax; + mctx->rcx = context->Rcx; + mctx->rdx = context->Rdx; + mctx->rbx = context->Rbx; + mctx->rsp = context->Rsp; + mctx->rbp = context->Rbp; + mctx->rsi = context->Rsi; + mctx->rdi = context->Rdi; + mctx->r8 = context->R8; + mctx->r9 = context->R9; + mctx->r10 = context->R10; + mctx->r11 = context->R11; + mctx->r12 = context->R12; + mctx->r13 = context->R13; + mctx->r14 = context->R14; + mctx->r15 = context->R15; #else MonoContext *ctx = (MonoContext *)sigctx; @@ -181,6 +233,26 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx) UCONTEXT_REG_R14 (ctx) = mctx->r14; UCONTEXT_REG_R15 (ctx) = mctx->r15; UCONTEXT_REG_RIP (ctx) = mctx->rip; +#elif defined(HOST_WIN32) + CONTEXT *context = (CONTEXT*)sigctx; + + context->Rip = mctx->rip; + context->Rax = mctx->rax; + context->Rcx = mctx->rcx; + context->Rdx = mctx->rdx; + context->Rbx = mctx->rbx; + context->Rsp = mctx->rsp; + context->Rbp = mctx->rbp; + context->Rsi = mctx->rsi; + context->Rdi = mctx->rdi; + context->R8 = mctx->r8; + context->R9 = mctx->r9; + context->R10 = mctx->r10; + context->R11 = mctx->r11; + context->R12 = mctx->r12; + context->R13 = mctx->r13; + context->R14 = mctx->r14; + context->R15 = mctx->r15; #else MonoContext *ctx = (MonoContext *)sigctx; diff --git a/mono/utils/mono-context.h b/mono/utils/mono-context.h index 11254802fc..3b01b49f06 100755 --- a/mono/utils/mono-context.h +++ b/mono/utils/mono-context.h @@ -236,12 +236,12 @@ extern void mono_context_get_current (void *); : "rdx", "memory") #endif -#if !defined(HOST_WIN32) #define MONO_ARCH_HAS_MONO_CONTEXT 1 -#endif #elif (defined(__arm__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM)) /* defined(__x86_64__) */ +#include + typedef struct { mgreg_t pc; mgreg_t regs [16]; @@ -281,6 +281,8 @@ typedef struct { ctx.pc = ctx.regs [15]; \ } while (0) +#define MONO_ARCH_HAS_MONO_CONTEXT 1 + #elif (defined(__aarch64__) && !defined(MONO_CROSS_COMPILE)) || (defined(TARGET_ARM64)) #include @@ -546,7 +548,18 @@ typedef struct ucontext MonoContext; #endif +/* + * The naming is misleading, the SIGCTX argument should be the platform's context + * structure (ucontext_c on posix, CONTEXT on windows). + */ void mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx) MONO_INTERNAL; + +/* + * This will not completely initialize SIGCTX since MonoContext contains less + * information that the system context. The caller should obtain a SIGCTX from + * the system, and use this function to override the parts of it which are + * also in MonoContext. + */ void mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx) MONO_INTERNAL; #endif /* __MONO_MONO_CONTEXT_H__ */ diff --git a/mono/utils/mono-dl.c b/mono/utils/mono-dl.c index b59ab2d5aa..04e9165b7c 100644 --- a/mono/utils/mono-dl.c +++ b/mono/utils/mono-dl.c @@ -124,7 +124,7 @@ w32_dlerror (void) wchar_t* buf = NULL; DWORD code = GetLastError (); - if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, + if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buf, 0, NULL)) { ret = g_utf16_to_utf8 (buf, wcslen(buf), NULL, NULL, NULL); diff --git a/mono/utils/mono-error-internals.h b/mono/utils/mono-error-internals.h index 8067240308..ac2394fa41 100644 --- a/mono/utils/mono-error-internals.h +++ b/mono/utils/mono-error-internals.h @@ -32,6 +32,9 @@ mono_error_set_error (MonoError *error, int error_code, const char *msg_format, void mono_error_set_assembly_load (MonoError *error, const char *assembly_name, const char *msg_format, ...) MONO_INTERNAL; +void +mono_error_set_assembly_load_simple (MonoError *error, const char *assembly_name, gboolean refection_only) MONO_INTERNAL; + void mono_error_set_type_load_class (MonoError *error, MonoClass *klass, const char *msg_format, ...) MONO_INTERNAL; @@ -68,6 +71,9 @@ mono_error_set_from_loader_error (MonoError *error) MONO_INTERNAL; MonoException* mono_error_prepare_exception (MonoError *error, MonoError *error_out) MONO_INTERNAL; +MonoException* +mono_error_convert_to_exception (MonoError *error) MONO_INTERNAL; + void mono_error_raise_exception (MonoError *error) MONO_INTERNAL; diff --git a/mono/utils/mono-error.c b/mono/utils/mono-error.c index a59de349f3..63d6fcc00f 100644 --- a/mono/utils/mono-error.c +++ b/mono/utils/mono-error.c @@ -188,6 +188,16 @@ mono_error_set_assembly_load (MonoError *oerror, const char *assembly_name, cons set_error_message (); } + +void +mono_error_set_assembly_load_simple (MonoError *oerror, const char *assembly_name, gboolean refection_only) +{ + if (refection_only) + mono_error_set_assembly_load (oerror, assembly_name, "Cannot resolve dependency to assembly because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event."); + else + mono_error_set_assembly_load (oerror, assembly_name, "Could not load file or assembly or one of its dependencies."); +} + void mono_error_set_type_load_class (MonoError *oerror, MonoClass *klass, const char *msg_format, ...) { @@ -321,10 +331,7 @@ mono_error_set_from_loader_error (MonoError *oerror) break; case MONO_EXCEPTION_FILE_NOT_FOUND: - if (loader_error->ref_only) - mono_error_set_assembly_load (oerror, loader_error->assembly_name, "Cannot resolve dependency to assembly because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event."); - else - mono_error_set_assembly_load (oerror, loader_error->assembly_name, "Could not load file or assembly or one of its dependencies."); + mono_error_set_assembly_load_simple (oerror, loader_error->assembly_name, loader_error->ref_only); break; case MONO_EXCEPTION_METHOD_ACCESS: @@ -629,20 +636,18 @@ mono_error_prepare_exception (MonoError *oerror, MonoError *error_out) } /* -Raises the exception of @error. -Does nothing if @error has a success error code. -Aborts in case of a double fault. This happens when it can't recover from an error caused by trying -to construct the first exception object. -The error object @error is cleaned up. +Convert this MonoError to an exception if it's faulty or return NULL. +The error object is cleant after. */ -void -mono_error_raise_exception (MonoError *target_error) + +MonoException* +mono_error_convert_to_exception (MonoError *target_error) { MonoError error; MonoException *ex; if (mono_error_ok (target_error)) - return; + return NULL; ex = mono_error_prepare_exception (target_error, &error); if (!mono_error_ok (&error)) { @@ -654,6 +659,21 @@ mono_error_raise_exception (MonoError *target_error) mono_error_cleanup (&error); } mono_error_cleanup (target_error); - - mono_raise_exception (ex); + return ex; +} + + +/* +Raises the exception of @error. +Does nothing if @error has a success error code. +Aborts in case of a double fault. This happens when it can't recover from an error caused by trying +to construct the first exception object. +The error object @error is cleaned up. +*/ +void +mono_error_raise_exception (MonoError *target_error) +{ + MonoException *ex = mono_error_convert_to_exception (target_error); + if (ex) + mono_raise_exception (ex); } diff --git a/mono/utils/mono-linked-list-set.h b/mono/utils/mono-linked-list-set.h index efb14f0352..89c7f1181c 100644 --- a/mono/utils/mono-linked-list-set.h +++ b/mono/utils/mono-linked-list-set.h @@ -66,7 +66,15 @@ Requires the world to be stoped MonoLinkedListSetNode *__cur; \ for (__cur = (list)->head; __cur; __cur = mono_lls_pointer_unmask (__cur->next)) \ if (!mono_lls_pointer_get_mark (__cur->next)) { \ - (element) = (type)__cur; \ + (element) = (type)__cur; + + +#define MONO_LLS_FOREACH_FILTERED(list, element, filter_func, type) {\ + MonoLinkedListSetNode *__cur; \ + for (__cur = (list)->head; __cur; __cur = mono_lls_pointer_unmask (__cur->next)) \ + if (!mono_lls_pointer_get_mark (__cur->next)) { \ + (element) = (type)__cur; \ + if (!filter_func (element)) continue; #define MONO_LLS_END_FOREACH }} @@ -91,6 +99,18 @@ Provides snapshot iteration if (!mono_lls_pointer_get_mark (__next)) { \ (element) = (type)__cur; +#define MONO_LLS_FOREACH_FILTERED_SAFE(list, element, filter_func, type) {\ + MonoThreadHazardPointers *__hp = mono_hazard_pointer_get (); \ + MonoLinkedListSetNode *__cur, *__next; \ + for (__cur = mono_lls_pointer_unmask (get_hazardous_pointer ((gpointer volatile*)&(list)->head, __hp, 1)); \ + __cur; \ + __cur = mono_lls_info_step (__next, __hp)) { \ + __next = get_hazardous_pointer_with_mask ((gpointer volatile*)&__cur->next, __hp, 0); \ + if (!mono_lls_pointer_get_mark (__next)) { \ + (element) = (type)__cur; \ + if (!filter_func (element)) continue; + + #define MONO_LLS_END_FOREACH_SAFE \ } \ } \ diff --git a/mono/utils/mono-logger.c b/mono/utils/mono-logger.c index cd3a838049..a6be2717e5 100644 --- a/mono/utils/mono-logger.c +++ b/mono/utils/mono-logger.c @@ -16,6 +16,7 @@ static MonoTraceMask current_mask = MONO_TRACE_ALL; static const char *mono_log_domain = "Mono"; static GQueue *level_stack = NULL; +static MonoPrintCallback print_callback, printerr_callback; /** * mono_trace_init: @@ -295,6 +296,17 @@ mono_trace_set_log_handler (MonoLogCallback callback, void *user_data) g_log_set_default_handler (log_adapter, user_data); } +static void +print_handler (const char *string) +{ + print_callback (string, TRUE); +} + +static void +printerr_handler (const char *string) +{ + printerr_callback (string, FALSE); +} /** * mono_trace_set_print_handler: @@ -308,7 +320,8 @@ void mono_trace_set_print_handler (MonoPrintCallback callback) { g_assert (callback); - g_set_print_handler (callback); + print_callback = callback; + g_set_print_handler (print_handler); } /** @@ -323,5 +336,6 @@ void mono_trace_set_printerr_handler (MonoPrintCallback callback) { g_assert (callback); - g_set_printerr_handler (callback); + printerr_callback = callback; + g_set_print_handler (printerr_handler); } diff --git a/mono/utils/mono-mmap-internal.h b/mono/utils/mono-mmap-internal.h new file mode 100644 index 0000000000..1818e5c303 --- /dev/null +++ b/mono/utils/mono-mmap-internal.h @@ -0,0 +1,28 @@ +/* + * mono-mmap-internal.h: Internal virtual memory stuff. + * + * 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. + */ + +#ifndef __MONO_UTILS_MMAP_INTERNAL_H__ +#define __MONO_UTILS_MMAP_INTERNAL_H__ + +#include "mono-compiler.h" + +int mono_pages_not_faulted (void *addr, size_t length) MONO_INTERNAL; + +#endif /* __MONO_UTILS_MMAP_INTERNAL_H__ */ + diff --git a/mono/utils/mono-mmap.c b/mono/utils/mono-mmap.c index 60ef156b15..ed11c9f1b2 100644 --- a/mono/utils/mono-mmap.c +++ b/mono/utils/mono-mmap.c @@ -29,6 +29,7 @@ #endif #include "mono-mmap.h" +#include "mono-mmap-internal.h" #include "mono-proclib.h" #ifndef MAP_ANONYMOUS @@ -243,6 +244,12 @@ mono_shared_area_instances (void **array, int count) return 0; } +int +mono_pages_not_faulted (void *addr, size_t length) +{ + return -1; +} + #else #if defined(HAVE_MMAP) @@ -443,6 +450,30 @@ mono_mprotect (void *addr, size_t length, int flags) } #endif // __native_client__ +int +mono_pages_not_faulted (void *addr, size_t size) +{ + int i; + gint64 count; + int pagesize = mono_pagesize (); + int npages = (size + pagesize - 1) / pagesize; + char *faulted = g_malloc0 (sizeof (char*) * npages); + + if (mincore (addr, size, faulted) != 0) { + count = -1; + } else { + count = 0; + for (i = 0; i < npages; ++i) { + if (faulted [i] != 0) + ++count; + } + } + + g_free (faulted); + + return count; +} + #else /* dummy malloc-based implementation */ @@ -481,6 +512,13 @@ mono_mprotect (void *addr, size_t length, int flags) } return 0; } + +int +mono_pages_not_faulted (void *addr, size_t length) +{ + return -1; +} + #endif // HAVE_MMAP #if defined(HAVE_SHM_OPEN) && !defined (DISABLE_SHARED_PERFCOUNTERS) @@ -607,7 +645,7 @@ mono_shared_area (void) header->stats_start = sizeof (SAreaHeader); header->stats_end = sizeof (SAreaHeader); - atexit (mono_shared_area_remove); + mono_atexit (mono_shared_area_remove); return res; } diff --git a/mono/utils/mono-poll.c b/mono/utils/mono-poll.c old mode 100644 new mode 100755 index 7326254c35..5e5adfe2f0 --- a/mono/utils/mono-poll.c +++ b/mono/utils/mono-poll.c @@ -20,6 +20,11 @@ mono_poll (mono_pollfd *ufds, unsigned int nfds, int timeout) } #else +#ifdef HOST_WIN32 +/* For select */ +#include +#endif + int mono_poll (mono_pollfd *ufds, unsigned int nfds, int timeout) { diff --git a/mono/utils/mono-proclib.c b/mono/utils/mono-proclib.c index 3f032f9d22..09de17850e 100644 --- a/mono/utils/mono-proclib.c +++ b/mono/utils/mono-proclib.c @@ -105,6 +105,10 @@ mono_process_list (int *size) if (size) *size = res; return buf; +#elif defined(__HAIKU__) + /* FIXME: Add back the code from 9185fcc305e43428d0f40f3ee37c8a405d41c9ae */ + g_assert_not_reached (); + return NULL; #else const char *name; void **buf = NULL; @@ -660,3 +664,13 @@ mono_cpu_get_data (int cpu_id, MonoCpuData data, MonoProcessError *error) return value; } +int +mono_atexit (void (*func)(void)) +{ +#ifdef PLATFORM_ANDROID + /* Some versions of android libc doesn't define atexit () */ + return 0; +#else + return atexit (func); +#endif +} diff --git a/mono/utils/mono-proclib.h b/mono/utils/mono-proclib.h index e0d84ec023..95783edc1d 100644 --- a/mono/utils/mono-proclib.h +++ b/mono/utils/mono-proclib.h @@ -52,5 +52,7 @@ int mono_process_current_pid (void) MONO_INTERNAL; int mono_cpu_count (void) MONO_INTERNAL; gint64 mono_cpu_get_data (int cpu_id, MonoCpuData data, MonoProcessError *error) MONO_INTERNAL; +int mono_atexit (void (*func)(void)) MONO_INTERNAL; + #endif /* __MONO_PROC_LIB_H__ */ diff --git a/mono/utils/mono-sigcontext.h b/mono/utils/mono-sigcontext.h index 05817a842f..f61f3dd3ee 100644 --- a/mono/utils/mono-sigcontext.h +++ b/mono/utils/mono-sigcontext.h @@ -4,6 +4,9 @@ #include #if defined(PLATFORM_ANDROID) #include +#ifdef HAVE_UCONTEXT_H +#include +#endif #endif #ifdef HAVE_UNISTD_H @@ -16,9 +19,6 @@ #if defined(TARGET_X86) -#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__APPLE__) || defined(__DragonFly__) -#include -#endif #if defined(__APPLE__) #include #endif @@ -87,7 +87,7 @@ #define UCONTEXT_REG_EIP(ctx) (((ucontext_t*)(ctx))->uc_mcontext.gregs [EIP]) #else -#if defined(TARGET_ANDROID) +#if defined(PLATFORM_ANDROID) && !defined(HAVE_UCONTEXT_H) /* No ucontext.h as of NDK v6b */ typedef int greg_t; #define NGREG 19 diff --git a/mono/utils/mono-signal-handler.h b/mono/utils/mono-signal-handler.h index 3a01146d5e..fbe798eeb0 100644 --- a/mono/utils/mono-signal-handler.h +++ b/mono/utils/mono-signal-handler.h @@ -12,18 +12,48 @@ #ifdef ENABLE_EXTENSION_MODULE #include "../../../mono-extensions/mono/utils/mono-signal-handler.h" #endif -/* -Not all platforms support signal handlers in the same way. Some have the same concept but -for some weird reason pass different kind of arguments. -All signal handler helpers should go here so they can be properly shared across the JIT, -utils and sgen. - -TODO: Cleanup & move mini's macros to here so they can leveraged by other parts. - -*/ +/* Don't use this */ #ifndef MONO_SIGNAL_HANDLER_FUNC #define MONO_SIGNAL_HANDLER_FUNC(access, name, arglist) access void name arglist #endif +/* + * Macros to work around signal handler differences on various platforms. + * + * To declare a signal handler function: + * void MONO_SIG_HANDLER_SIGNATURE (handler_func) + * To define a signal handler function: + * MONO_SIG_HANDLER_FUNC(access, name) + * To call another signal handler function: + * handler_func (MONO_SIG_HANDLER_PARAMS); + * To obtain the signal number: + * int signo = MONO_SIG_HANDLER_GET_SIGNO (); + * To obtain the signal context: + * MONO_SIG_HANDLER_GET_CONTEXT (). + * This will define a variable name 'ctx'. + */ + +#ifdef HOST_WIN32 +#define MONO_SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, EXCEPTION_POINTERS *_info, void *context) +#define MONO_SIG_HANDLER_FUNC(access, ftn) MONO_SIGNAL_HANDLER_FUNC (access, ftn, (int _dummy, EXCEPTION_POINTERS *_info, void *context)) +#define MONO_SIG_HANDLER_PARAMS _dummy, _info, context +#define MONO_SIG_HANDLER_GET_SIGNO() (_dummy) +#define MONO_SIG_HANDLER_GET_INFO() (_info) +#define MONO_SIG_HANDLER_INFO_TYPE EXCEPTION_POINTERS +/* seh_vectored_exception_handler () passes in a CONTEXT* */ +#define MONO_SIG_HANDLER_GET_CONTEXT \ + void *ctx = context; +#else +/* sigaction */ +#define MONO_SIG_HANDLER_SIGNATURE(ftn) ftn (int _dummy, siginfo_t *_info, void *context) +#define MONO_SIG_HANDLER_FUNC(access, ftn) MONO_SIGNAL_HANDLER_FUNC (access, ftn, (int _dummy, siginfo_t *_info, void *context)) +#define MONO_SIG_HANDLER_PARAMS _dummy, _info, context +#define MONO_SIG_HANDLER_GET_SIGNO() (_dummy) +#define MONO_SIG_HANDLER_GET_INFO() (_info) +#define MONO_SIG_HANDLER_INFO_TYPE siginfo_t +#define MONO_SIG_HANDLER_GET_CONTEXT \ + void *ctx = context; +#endif + #endif diff --git a/mono/utils/mono-threads-freebsd.c b/mono/utils/mono-threads-freebsd.c index 7cbbca14b5..cdee0ab406 100644 --- a/mono/utils/mono-threads-freebsd.c +++ b/mono/utils/mono-threads-freebsd.c @@ -2,6 +2,7 @@ #if defined(__FreeBSD__) +#include #include #include diff --git a/mono/utils/mono-threads-posix.c b/mono/utils/mono-threads-posix.c index ce087bbc36..4846a4431d 100644 --- a/mono/utils/mono-threads-posix.c +++ b/mono/utils/mono-threads-posix.c @@ -19,7 +19,11 @@ #include -#if defined(PLATFORM_ANDROID) +#if defined(PLATFORM_ANDROID) && !defined(TARGET_ARM64) +#define USE_TKILL_ON_ANDROID 1 +#endif + +#ifdef USE_TKILL_ON_ANDROID extern int tkill (pid_t tid, int signal); #endif @@ -236,6 +240,50 @@ mono_threads_core_open_thread_handle (HANDLE handle, MonoNativeThreadId tid) return handle; } +gpointer +mono_threads_core_prepare_interrupt (HANDLE thread_handle) +{ + return wapi_prepare_interrupt_thread (thread_handle); +} + +void +mono_threads_core_finish_interrupt (gpointer wait_handle) +{ + wapi_finish_interrupt_thread (wait_handle); +} + +void +mono_threads_core_self_interrupt (void) +{ + wapi_self_interrupt (); +} + +void +mono_threads_core_clear_interruption (void) +{ + wapi_clear_interruption (); +} + +int +mono_threads_pthread_kill (MonoThreadInfo *info, int signum) +{ +#ifdef USE_TKILL_ON_ANDROID + int result, old_errno = errno; + result = tkill (info->native_handle, signum); + if (result < 0) { + result = errno; + errno = old_errno; + } + return result; +#elif defined(__native_client__) + /* Workaround pthread_kill abort() in NaCl glibc. */ + return 0; +#else + return pthread_kill (mono_thread_info_get_tid (info), signum); +#endif + +} + #if !defined (__MACH__) #if !defined(__native_client__) @@ -317,26 +365,6 @@ mono_threads_core_interrupt (MonoThreadInfo *info) { } -int -mono_threads_pthread_kill (MonoThreadInfo *info, int signum) -{ -#if defined (PLATFORM_ANDROID) - int result, old_errno = errno; - result = tkill (info->native_handle, signum); - if (result < 0) { - result = errno; - errno = old_errno; - } - return result; -#elif defined(__native_client__) - /* Workaround pthread_kill abort() in NaCl glibc. */ - return 0; -#else - return pthread_kill (mono_thread_info_get_tid (info), signum); -#endif - -} - void mono_threads_core_abort_syscall (MonoThreadInfo *info) { diff --git a/mono/utils/mono-threads-windows.c b/mono/utils/mono-threads-windows.c old mode 100644 new mode 100755 index 2ab2e6596e..04430fb021 --- a/mono/utils/mono-threads-windows.c +++ b/mono/utils/mono-threads-windows.c @@ -12,6 +12,7 @@ #if defined(HOST_WIN32) #include +#include #include @@ -20,10 +21,23 @@ mono_threads_init_platform (void) { } +static void CALLBACK +interrupt_apc (ULONG_PTR param) +{ +} + void mono_threads_core_interrupt (MonoThreadInfo *info) { - g_assert (0); + DWORD id = mono_thread_info_get_tid (info); + HANDLE handle; + + handle = OpenThread (THREAD_ALL_ACCESS, FALSE, id); + g_assert (handle); + + QueueUserAPC ((PAPCFUNC)interrupt_apc, handle, (ULONG_PTR)NULL); + + CloseHandle (handle); } void @@ -46,13 +60,73 @@ mono_threads_core_self_suspend (MonoThreadInfo *info) gboolean mono_threads_core_suspend (MonoThreadInfo *info) { - g_assert_not_reached (); + DWORD id = mono_thread_info_get_tid (info); + HANDLE handle; + DWORD result; + gboolean res; + + g_assert (id != GetCurrentThreadId ()); + + handle = OpenThread (THREAD_ALL_ACCESS, FALSE, id); + g_assert (handle); + + result = SuspendThread (handle); + if (result == (DWORD)-1) { + fprintf (stderr, "could not suspend thread %x (handle %p): %d\n", id, handle, GetLastError ()); fflush (stderr); + CloseHandle (handle); + return FALSE; + } + + CloseHandle (handle); + + res = mono_threads_get_runtime_callbacks ()->thread_state_init_from_handle (&info->suspend_state, info); + g_assert (res); + + return TRUE; } gboolean mono_threads_core_resume (MonoThreadInfo *info) { - g_assert_not_reached (); + DWORD id = mono_thread_info_get_tid (info); + HANDLE handle; + DWORD result; + + handle = OpenThread (THREAD_ALL_ACCESS, FALSE, id); + g_assert (handle); + + if (info->async_target) { + MonoContext ctx; + CONTEXT context; + gboolean res; + + ctx = info->suspend_state.ctx; + mono_threads_get_runtime_callbacks ()->setup_async_callback (&ctx, info->async_target, info->user_data); + info->async_target = info->user_data = NULL; + + context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL; + + if (!GetThreadContext (handle, &context)) { + CloseHandle (handle); + return FALSE; + } + + g_assert (context.ContextFlags & CONTEXT_INTEGER); + g_assert (context.ContextFlags & CONTEXT_CONTROL); + + mono_monoctx_to_sigctx (&ctx, &context); + + context.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL; + res = SetThreadContext (handle, &context); + g_assert (res); + } + + result = ResumeThread (handle); + g_assert (result != (DWORD)-1); + + CloseHandle (handle); + + return result != (DWORD)-1; } void @@ -175,8 +249,7 @@ mono_threads_core_resume_created (MonoThreadInfo *info, MonoNativeThreadId tid) } #if HAVE_DECL___READFSDWORD==0 -static __inline__ __attribute__((always_inline)) -unsigned long long +static MONO_ALWAYS_INLINE unsigned long long __readfsdword (unsigned long offset) { unsigned long value; @@ -263,9 +336,58 @@ mono_threads_core_open_thread_handle (HANDLE handle, MonoNativeThreadId tid) return OpenThread (THREAD_ALL_ACCESS, TRUE, tid); } +#if !defined(__GNUC__) +const DWORD MS_VC_EXCEPTION=0x406D1388; +#pragma pack(push,8) +typedef struct tagTHREADNAME_INFO +{ + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. +} THREADNAME_INFO; +#pragma pack(pop) +#endif + void mono_threads_core_set_name (MonoNativeThreadId tid, const char *name) { +#if !defined(__GNUC__) + /* http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx */ + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = name; + info.dwThreadID = tid; + info.dwFlags = 0; + + __try { + RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info ); + } + __except(EXCEPTION_EXECUTE_HANDLER) { + } +#endif +} + + +gpointer +mono_threads_core_prepare_interrupt (HANDLE thread_handle) +{ + return NULL; +} + +void +mono_threads_core_finish_interrupt (gpointer wait_handle) +{ +} + +void +mono_threads_core_self_interrupt (void) +{ +} + +void +mono_threads_core_clear_interruption (void) +{ } #endif diff --git a/mono/utils/mono-threads.c b/mono/utils/mono-threads.c index cbb768aea8..83bc94a7f0 100644 --- a/mono/utils/mono-threads.c +++ b/mono/utils/mono-threads.c @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -144,7 +145,7 @@ register_thread (MonoThreadInfo *info, gpointer baseptr) if (threads_callbacks.thread_register) { if (threads_callbacks.thread_register (info, baseptr) == NULL) { - g_warning ("thread registation failed\n"); + // g_warning ("thread registation failed\n"); g_free (info); return NULL; } @@ -286,6 +287,31 @@ mono_thread_info_list_head (void) return &thread_list; } +/** + * mono_threads_attach_tools_thread + * + * Attach the current thread as a tool thread. DON'T USE THIS FUNCTION WITHOUT READING ALL DISCLAIMERS. + * + * A tools thread is a very special kind of thread that needs access to core runtime facilities but should + * not be counted as a regular thread for high order facilities such as executing managed code or accessing + * the managed heap. + * + * This is intended only to tools such as a profiler than needs to be able to use our lock-free support when + * doing things like resolving backtraces in their background processing thread. + */ +void +mono_threads_attach_tools_thread (void) +{ + int dummy = 0; + MonoThreadInfo *info; + + /* Must only be called once */ + g_assert (!mono_native_tls_get_value (thread_info_key)); + + info = mono_thread_info_attach (&dummy); + info->tools_thread = TRUE; +} + MonoThreadInfo* mono_thread_info_attach (void *baseptr) { @@ -605,7 +631,7 @@ mono_thread_info_safe_suspend_sync (MonoNativeThreadId id, gboolean interrupt_ke for (;;) { const char *suspend_error = "Unknown error"; if (!(info = mono_thread_info_suspend_sync (id, interrupt_kernel, &suspend_error))) { - g_warning ("failed to suspend thread %p due to %s, hopefully it is dead", (gpointer)id, suspend_error); + // g_warning ("failed to suspend thread %p due to %s, hopefully it is dead", (gpointer)id, suspend_error); mono_thread_info_suspend_unlock (); return NULL; } @@ -614,7 +640,7 @@ mono_thread_info_safe_suspend_sync (MonoNativeThreadId id, gboolean interrupt_ke break; if (!mono_thread_info_core_resume (info)) { - g_warning ("failed to resume thread %p, hopefully it is dead", (gpointer)id); + // g_warning ("failed to resume thread %p, hopefully it is dead", (gpointer)id); mono_hazard_pointer_clear (mono_hazard_pointer_get (), 1); mono_thread_info_suspend_unlock (); return NULL; @@ -731,11 +757,13 @@ mono_thread_info_new_interrupt_enabled (void) #if defined (HAVE_BOEHM_GC) && !defined (USE_INCLUDED_LIBGC) return FALSE; #endif - /*port not done*/ #if defined(HOST_WIN32) - return FALSE; + return !disable_new_interrupt; #endif -#if defined (__i386__) +#if defined (__i386__) || defined(__x86_64__) + return !disable_new_interrupt; +#endif +#if defined(__arm__) return !disable_new_interrupt; #endif return FALSE; @@ -852,7 +880,7 @@ mono_thread_info_open_handle (void) } /* - * mono_thread_info_open_handle: + * mono_threads_open_thread_handle: * * Return a io-layer/win32 handle for the thread identified by HANDLE/TID. * The handle need to be closed by calling CloseHandle () when it is no @@ -869,3 +897,65 @@ mono_thread_info_set_name (MonoNativeThreadId tid, const char *name) { mono_threads_core_set_name (tid, name); } + +/* + * mono_thread_info_prepare_interrupt: + * + * See wapi_prepare_interrupt (). + */ +gpointer +mono_thread_info_prepare_interrupt (HANDLE thread_handle) +{ + return mono_threads_core_prepare_interrupt (thread_handle); +} + +void +mono_thread_info_finish_interrupt (gpointer wait_handle) +{ + mono_threads_core_finish_interrupt (wait_handle); +} + +void +mono_thread_info_interrupt (HANDLE thread_handle) +{ + gpointer wait_handle; + + wait_handle = mono_thread_info_prepare_interrupt (thread_handle); + mono_thread_info_finish_interrupt (wait_handle); +} + +void +mono_thread_info_self_interrupt (void) +{ + mono_threads_core_self_interrupt (); +} + +void +mono_thread_info_clear_interruption (void) +{ + mono_threads_core_clear_interruption (); +} + +/* info must be self or be held in a hazard pointer. */ +gboolean +mono_threads_add_async_job (MonoThreadInfo *info, MonoAsyncJob job) +{ + MonoAsyncJob old_job; + do { + old_job = info->service_requests; + if (old_job & job) + return FALSE; + } while (InterlockedCompareExchange (&info->service_requests, old_job | job, old_job) != old_job); + return TRUE; +} + +MonoAsyncJob +mono_threads_consume_async_jobs (void) +{ + MonoThreadInfo *info = (MonoThreadInfo*)mono_native_tls_get_value (thread_info_key); + + if (!info) + return 0; + + return InterlockedExchange (&info->service_requests, 0); +} diff --git a/mono/utils/mono-threads.h b/mono/utils/mono-threads.h index d97543313c..ac4c34470a 100644 --- a/mono/utils/mono-threads.h +++ b/mono/utils/mono-threads.h @@ -94,6 +94,13 @@ enum { SUSPEND_STATE_MASK = 0xF0, }; +/* + * This enum tells which async thread service corresponds to which bit. + */ +typedef enum { + MONO_SERVICE_REQUEST_SAMPLE = 1, +} MonoAsyncJob; + #define mono_thread_info_run_state(info) (((MonoThreadInfo*)info)->thread_state & RUN_STATE_MASK) #define mono_thread_info_suspend_state(info) (((MonoThreadInfo*)info)->thread_state & SUSPEND_STATE_MASK) @@ -106,6 +113,9 @@ typedef struct { /*Tells if this thread was created by the runtime or not.*/ gboolean runtime_thread; + /* Tells if this thread should be ignored or not by runtime services such as GC and profiling */ + gboolean tools_thread; + /* suspend machinery, fields protected by suspend_semaphore */ MonoSemType suspend_semaphore; int suspend_count; @@ -155,6 +165,12 @@ typedef struct { /* IO layer handle for this thread */ /* Set when the thread is started, or in _wapi_thread_duplicate () */ HANDLE handle; + + /* Asynchronous service request. This flag is meant to be consumed by the multiplexing signal handlers to discover what sort of work they need to do. + * Use the mono_threads_add_async_job and mono_threads_consume_async_jobs APIs to modify this flag. + * In the future the signaling should be part of the API, but for now, it's only for massaging the bits. + */ + volatile gint32 service_requests; } MonoThreadInfo; typedef struct { @@ -187,16 +203,22 @@ typedef struct { gboolean (*thread_state_init_from_handle) (MonoThreadUnwindState *tctx, MonoThreadInfo *info); } MonoThreadInfoRuntimeCallbacks; +static inline gboolean +mono_threads_filter_tools_threads (THREAD_INFO_TYPE *info) +{ + return !((MonoThreadInfo*)info)->tools_thread; +} + /* Requires the world to be stoped */ -#define FOREACH_THREAD(thread) MONO_LLS_FOREACH (mono_thread_info_list_head (), thread, THREAD_INFO_TYPE*) +#define FOREACH_THREAD(thread) MONO_LLS_FOREACH_FILTERED (mono_thread_info_list_head (), thread, mono_threads_filter_tools_threads, THREAD_INFO_TYPE*) #define END_FOREACH_THREAD MONO_LLS_END_FOREACH /* Snapshot iteration. */ -#define FOREACH_THREAD_SAFE(thread) MONO_LLS_FOREACH_SAFE (mono_thread_info_list_head (), thread, THREAD_INFO_TYPE*) +#define FOREACH_THREAD_SAFE(thread) MONO_LLS_FOREACH_FILTERED_SAFE (mono_thread_info_list_head (), thread, mono_threads_filter_tools_threads, THREAD_INFO_TYPE*) #define END_FOREACH_THREAD_SAFE MONO_LLS_END_FOREACH_SAFE #define mono_thread_info_get_tid(info) ((MonoNativeThreadId)((MonoThreadInfo*)info)->node.key) @@ -302,6 +324,21 @@ mono_thread_info_exit (void); HANDLE mono_thread_info_open_handle (void); +gpointer +mono_thread_info_prepare_interrupt (HANDLE thread_handle); + +void +mono_thread_info_finish_interrupt (gpointer wait_handle); + +void +mono_thread_info_interrupt (HANDLE thread_handle); + +void +mono_thread_info_self_interrupt (void); + +void +mono_thread_info_clear_interruption (void); + HANDLE mono_threads_create_thread (LPTHREAD_START_ROUTINE start, gpointer arg, guint32 stack_size, guint32 creation_flags, MonoNativeThreadId *out_tid); @@ -311,13 +348,26 @@ mono_threads_get_max_stack_size (void) MONO_INTERNAL; HANDLE mono_threads_open_thread_handle (HANDLE handle, MonoNativeThreadId tid) MONO_INTERNAL; +/* +This is the async job submission/consumption API. +XXX: This is a PROVISIONAL API only meant to be used by the statistical profiler. +If you want to use/extend it anywhere else, understand that you'll have to do some API design work to better fit this puppy. +*/ +gboolean +mono_threads_add_async_job (THREAD_INFO_TYPE *info, MonoAsyncJob job) MONO_INTERNAL; + +MonoAsyncJob +mono_threads_consume_async_jobs (void) MONO_INTERNAL; + +void +mono_threads_attach_tools_thread (void); + + #if !defined(HOST_WIN32) -#if !defined(__MACH__) /*Use this instead of pthread_kill */ int mono_threads_pthread_kill (THREAD_INFO_TYPE *info, int signum) MONO_INTERNAL; -#endif #endif /* !defined(HOST_WIN32) */ @@ -339,6 +389,10 @@ void mono_threads_core_unregister (THREAD_INFO_TYPE *info) MONO_INTERNAL; HANDLE mono_threads_core_open_handle (void) MONO_INTERNAL; HANDLE mono_threads_core_open_thread_handle (HANDLE handle, MonoNativeThreadId tid) MONO_INTERNAL; void mono_threads_core_set_name (MonoNativeThreadId tid, const char *name) MONO_INTERNAL; +gpointer mono_threads_core_prepare_interrupt (HANDLE thread_handle); +void mono_threads_core_finish_interrupt (gpointer wait_handle); +void mono_threads_core_self_interrupt (void); +void mono_threads_core_clear_interruption (void); MonoNativeThreadId mono_native_thread_id_get (void) MONO_INTERNAL; diff --git a/mono/utils/sha1.h b/mono/utils/sha1.h index 63eb2beffb..588518266c 100644 --- a/mono/utils/sha1.h +++ b/mono/utils/sha1.h @@ -21,7 +21,7 @@ typedef struct { guint8 buffer[SHA1_BLOCK_LENGTH]; } SHA1_CTX; -__BEGIN_DECLS +G_BEGIN_DECLS void SHA1Init(SHA1_CTX *); void SHA1Pad(SHA1_CTX *); void SHA1Transform(guint32 [5], const guint8 [SHA1_BLOCK_LENGTH]); @@ -31,7 +31,7 @@ char *SHA1End(SHA1_CTX *, char *); char *SHA1File(const char *, char *); char *SHA1FileChunk(const char *, char *, off_t, off_t); char *SHA1Data(const guint8 *, size_t, char *); -__END_DECLS +G_END_DECLS #define HTONDIGEST(x) do { \ x[0] = htonl(x[0]); \ diff --git a/msvc/eglib.vcxproj b/msvc/eglib.vcxproj index cbafcdd631..3d1db4be7f 100644 --- a/msvc/eglib.vcxproj +++ b/msvc/eglib.vcxproj @@ -1,6 +1,14 @@  + + Debug + Win32 + + + Debug + x64 + Debug Win32 @@ -9,6 +17,14 @@ Debug x64 + + Release + Win32 + + + Release + x64 + Release Win32 @@ -29,51 +45,107 @@ Unicode v110 + + StaticLibrary + Unicode + v110 + StaticLibrary Unicode v110 + + StaticLibrary + Unicode + v110 + StaticLibrary Unicode v110 + + StaticLibrary + Unicode + v110 + StaticLibrary Unicode v110 + + StaticLibrary + Unicode + v110 + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 $(Platform)\lib\ $(Platform)\obj\$(ProjectName)\$(Configuration)\ + $(Platform)\lib\ + $(Platform)\obj\$(ProjectName)\$(Configuration)\ $(Platform)\lib\ $(Platform)\obj\$(ProjectName)\$(Configuration)\ + $(Platform)\lib\ + $(Platform)\obj\$(ProjectName)\$(Configuration)\ $(Platform)\lib\ $(Platform)\obj\$(ProjectName)\$(Configuration)\ + $(Platform)\lib\ + $(Platform)\obj\$(ProjectName)\$(Configuration)\ $(Platform)\lib\ $(Platform)\obj\$(ProjectName)\$(Configuration)\ + $(Platform)\lib\ + $(Platform)\obj\$(ProjectName)\$(Configuration)\ - copy ..\eglib\winconfig.h ..\eglib\config.h + winsetup.bat + + + Disabled + ../eglib/src;../eglib;%(AdditionalIncludeDirectories) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + EditAndContinue + + + + + winsetup.bat Disabled @@ -89,7 +161,21 @@ - copy ..\eglib\winconfig.h ..\eglib\config.h + winsetup.bat + + + MinSpace + ../eglib/src;../eglib;%(AdditionalIncludeDirectories) + MultiThreadedDLL + + + Level4 + ProgramDatabase + + + + + winsetup.bat MinSpace @@ -103,7 +189,26 @@ - copy ..\eglib\winconfig.h ..\eglib\config.h + winsetup.bat + + + X64 + + + Disabled + ../eglib/src;../eglib;%(AdditionalIncludeDirectories) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level4 + ProgramDatabase + + + + + winsetup.bat X64 @@ -122,7 +227,24 @@ - copy ..\eglib\winconfig.h ..\eglib\config.h + winsetup.bat + + + X64 + + + MinSpace + ../eglib/src;../eglib;%(AdditionalIncludeDirectories) + MultiThreadedDLL + + + Level4 + ProgramDatabase + + + + + winsetup.bat X64 @@ -182,4 +304,4 @@ - \ No newline at end of file + diff --git a/msvc/genmdesc.vcxproj b/msvc/genmdesc.vcxproj index d3c7511cd4..c247eb4299 100644 --- a/msvc/genmdesc.vcxproj +++ b/msvc/genmdesc.vcxproj @@ -1,6 +1,14 @@  + + Debug + Win32 + + + Debug + x64 + Debug Win32 @@ -9,6 +17,14 @@ Debug x64 + + Release + Win32 + + + Release + x64 + Release Win32 @@ -18,6 +34,7 @@ x64 + {B7098DFA-31E6-4006-8A15-1C9A4E925149} genmdesc @@ -29,50 +46,94 @@ Unicode v110 + + Application + false + Unicode + v110 + Application false Unicode v110 + + Application + false + Unicode + v110 + Application false Unicode v110 + + Application + false + Unicode + v110 + Application false Unicode v110 + + Application + false + Unicode + v110 + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 $(Platform)\bin\ $(Platform)\obj\$(ProjectName)\ + $(Platform)\bin\ + $(Platform)\obj\$(ProjectName)\ $(Platform)\bin\ $(Platform)\obj\$(ProjectName)\ + $(Platform)\bin\ + $(Platform)\obj\$(ProjectName)\ $(Platform)\bin\ $(Platform)\obj\$(ProjectName)\ + $(Platform)\bin\ + $(Platform)\obj\$(ProjectName)\ $(Platform)\bin\ $(Platform)\obj\$(ProjectName)\ + $(Platform)\bin\ + $(Platform)\obj\$(ProjectName)\ @@ -117,6 +178,49 @@ runmdesc.bat "$(TargetPath)" $(Platform) + + + + + + + .\./VSDependancies/genmdesc___Win32_Debug/genmdesc.tlb + + + + + Disabled + ..\libgc\include;..\;..\mono\;..\eglib\src;%(AdditionalIncludeDirectories) + _DEBUG;_CRT_SECURE_NO_DEPRECATE;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + true + EditAndContinue + CompileAsC + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + false + + + eglib.lib;libmonoutils.lib;%(AdditionalDependencies) + true + $(Platform)\lib;%(AdditionalLibraryDirectories) + true + Console + MachineX86 + + + runmdesc.bat "$(TargetPath)" $(Platform) + + @@ -131,7 +235,51 @@ Disabled ..\libgc\include;..\;..\mono\;..\eglib\src;%(AdditionalIncludeDirectories) - _DEBUG;__x86_64__;TARGET_AMD64;WIN64;_WIN64;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;_CONSOLE;HAVE_CONFIG_H;WINVER=0x0500;_WIN32_WINNT=0x0500;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) + _DEBUG;__x86_64__;TARGET_AMD64;WIN64;_WIN64;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;_CONSOLE;HAVE_CONFIG_H;WINVER=0x0502;_WIN32_WINNT=0x0502;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + + + Level3 + true + ProgramDatabase + CompileAsC + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + false + + + eglib.lib;libmonoutils.lib;%(AdditionalDependencies) + true + $(Platform)\lib;%(AdditionalLibraryDirectories) + true + Console + MachineX64 + + + runmdesc.bat "$(TargetPath)" $(Platform) + + + + + + + + + X64 + .\./VSDependancies/genmdesc___Win32_Debug/genmdesc.tlb + + + + + Disabled + ..\libgc\include;..\;..\mono\;..\eglib\src;%(AdditionalIncludeDirectories) + _DEBUG;__x86_64__;TARGET_AMD64;WIN64;_WIN64;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;_CONSOLE;HAVE_CONFIG_H;WINVER=0x0502;_WIN32_WINNT=0x0502;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -203,6 +351,48 @@ runmdesc.bat "$(TargetPath)" $(Platform) + + + + + + + .\Release/genmdesc.tlb + + + + + MinSpace + OnlyExplicitInline + ..\libgc\include;..\;..\mono\;..\eglib\src;%(AdditionalIncludeDirectories) + NDEBUG;_CRT_SECURE_NO_DEPRECATE;_CONSOLE;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + + + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + false + + + eglib.lib;libmonoutils.lib;%(AdditionalDependencies) + true + $(Platform)\lib;%(AdditionalLibraryDirectories) + Console + MachineX86 + true + + + runmdesc.bat "$(TargetPath)" $(Platform) + + @@ -218,7 +408,51 @@ MinSpace OnlyExplicitInline ..\libgc\include;..\;..\mono\;..\eglib\src;%(AdditionalIncludeDirectories) - NDEBUG;__x86_64__;TARGET_AMD64;WIN64;_WIN64;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;_CONSOLE;HAVE_CONFIG_H;WINVER=0x0500;_WIN32_WINNT=0x0500;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) + NDEBUG;__x86_64__;TARGET_AMD64;WIN64;_WIN64;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;_CONSOLE;HAVE_CONFIG_H;WINVER=0x0502;_WIN32_WINNT=0x0502;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + + + Level3 + true + CompileAsC + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + false + + + eglib.lib;libmonoutils.lib;%(AdditionalDependencies) + true + $(Platform)\lib;%(AdditionalLibraryDirectories) + Console + MachineX64 + true + + + runmdesc.bat "$(TargetPath)" $(Platform) + + + + + + + + + X64 + .\Release/genmdesc.tlb + + + + + MinSpace + OnlyExplicitInline + ..\libgc\include;..\;..\mono\;..\eglib\src;%(AdditionalIncludeDirectories) + NDEBUG;__x86_64__;TARGET_AMD64;WIN64;_WIN64;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;_CONSOLE;HAVE_CONFIG_H;WINVER=0x0502;_WIN32_WINNT=0x0502;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) true MultiThreadedDLL true @@ -254,19 +488,37 @@ true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + true %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + true %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + %(AdditionalIncludeDirectories) @@ -274,19 +526,37 @@ true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + true %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + true %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + %(AdditionalIncludeDirectories) @@ -294,19 +564,37 @@ true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + true %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + true %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + %(AdditionalIncludeDirectories) @@ -314,19 +602,37 @@ true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + true %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) true + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + + true %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + %(AdditionalIncludeDirectories) %(PreprocessorDefinitions) + %(AdditionalIncludeDirectories) + %(PreprocessorDefinitions) + + @@ -338,4 +644,4 @@ - \ No newline at end of file + diff --git a/msvc/libgc.vcxproj b/msvc/libgc.vcxproj index 08bcfa0ba8..4871cc2e3c 100644 --- a/msvc/libgc.vcxproj +++ b/msvc/libgc.vcxproj @@ -1,6 +1,14 @@  + + Debug + Win32 + + + Debug + x64 + Debug Win32 @@ -9,6 +17,14 @@ Debug x64 + + Release + Win32 + + + Release + x64 + Release Win32 @@ -29,53 +45,113 @@ Unicode v110 + + StaticLibrary + Unicode + v110 + StaticLibrary Unicode v110 + + StaticLibrary + Unicode + v110 + StaticLibrary Unicode v110 + + StaticLibrary + Unicode + v110 + StaticLibrary Unicode v110 + + StaticLibrary + Unicode + v110 + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 $(Platform)\lib\ $(Platform)\obj\$(ProjectName)\$(Configuration)\ + $(Platform)\lib\ + $(Platform)\obj\$(ProjectName)\$(Configuration)\ $(Platform)\lib\ $(Platform)\obj\$(ProjectName)\$(Configuration)\ + $(Platform)\lib\ + $(Platform)\obj\$(ProjectName)\$(Configuration)\ $(Platform)\lib\ $(Platform)\obj\$(ProjectName)\$(Configuration)\ + $(Platform)\lib\ + $(Platform)\obj\$(ProjectName)\$(Configuration)\ $(Platform)\lib\ $(Platform)\obj\$(ProjectName)\$(Configuration)\ + $(Platform)\lib\ + $(Platform)\obj\$(ProjectName)\$(Configuration)\ Disabled ..\libgc\include;%(AdditionalIncludeDirectories) - _DEBUG;__i386__;TARGET_X86;i386;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;__STDC__;PACKAGE_NAME="libgc-mono";PACKAGE_TARNAME="libgc-mono";PACKAGE_VERSION="6.6";PACKAGE_STRING="libgc-mono 6.6";PACKAGE_BUGREPORT="Hans_Boehm%40hp.com";GC_WIN32_THREADS=1;NO_GETENV=1;GC_INSIDE_DLL=1;GC_NOT_DLL=1;STDC_HEADERS=1;HAVE_SYS_TYPES_H=1;HAVE_SYS_STAT_H=1;HAVE_STDLIB_H=1;HAVE_STRING_H=1;HAVE_MEMORY_H=1;HAVE_STRINGS_H=1;HAVE_INTTYPES_H=1;HAVE_STDINT_H=1;HAVE_UNISTD_H=1;SILENT=1;NO_SIGNALS=1;NO_EXECUTE_PERMISSION=1;JAVA_FINALIZATION=1;GC_GCJ_SUPPORT=1;ATOMIC_UNCOLLECTABLE=1;_IN_LIBGC=1;WINVER=0x0500;_WIN32_WINNT=0x0500;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) + _DEBUG;__i386__;TARGET_X86;i386;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;__STDC__;PACKAGE_NAME="libgc-mono";PACKAGE_TARNAME="libgc-mono";PACKAGE_VERSION="6.6";PACKAGE_STRING="libgc-mono 6.6";PACKAGE_BUGREPORT="Hans_Boehm%40hp.com";GC_WIN32_THREADS=1;NO_GETENV=1;GC_INSIDE_DLL=1;GC_NOT_DLL=1;STDC_HEADERS=1;HAVE_SYS_TYPES_H=1;HAVE_SYS_STAT_H=1;HAVE_STDLIB_H=1;HAVE_STRING_H=1;HAVE_MEMORY_H=1;HAVE_STRINGS_H=1;HAVE_INTTYPES_H=1;HAVE_STDINT_H=1;HAVE_UNISTD_H=1;SILENT=1;NO_SIGNALS=1;NO_EXECUTE_PERMISSION=1;JAVA_FINALIZATION=1;GC_GCJ_SUPPORT=1;ATOMIC_UNCOLLECTABLE=1;_IN_LIBGC=1;WINVER=0x0502;_WIN32_WINNT=0x0502;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + + + $(OutDir)vc80.pdb + ProgramDatabase + CompileAsC + 4311;4312;4996;4005;%(DisableSpecificWarnings) + + + $(OutDir)libgc.lib + + + + + Disabled + ..\libgc\include;%(AdditionalIncludeDirectories) + _DEBUG;__i386__;TARGET_X86;i386;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;__STDC__;PACKAGE_NAME="libgc-mono";PACKAGE_TARNAME="libgc-mono";PACKAGE_VERSION="6.6";PACKAGE_STRING="libgc-mono 6.6";PACKAGE_BUGREPORT="Hans_Boehm%40hp.com";GC_WIN32_THREADS=1;NO_GETENV=1;GC_INSIDE_DLL=1;GC_NOT_DLL=1;STDC_HEADERS=1;HAVE_SYS_TYPES_H=1;HAVE_SYS_STAT_H=1;HAVE_STDLIB_H=1;HAVE_STRING_H=1;HAVE_MEMORY_H=1;HAVE_STRINGS_H=1;HAVE_INTTYPES_H=1;HAVE_STDINT_H=1;HAVE_UNISTD_H=1;SILENT=1;NO_SIGNALS=1;NO_EXECUTE_PERMISSION=1;JAVA_FINALIZATION=1;GC_GCJ_SUPPORT=1;ATOMIC_UNCOLLECTABLE=1;_IN_LIBGC=1;WINVER=0x0502;_WIN32_WINNT=0x0502;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -95,7 +171,24 @@ MinSpace ..\libgc\include;%(AdditionalIncludeDirectories) - NDEBUG;__i386__;TARGET_X86;i386;i386;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;__STDC__;PACKAGE_NAME="libgc-mono";PACKAGE_TARNAME="libgc-mono";PACKAGE_VERSION="6.6";PACKAGE_STRING="libgc-mono 6.6";PACKAGE_BUGREPORT="Hans_Boehm%40hp.com";GC_WIN32_THREADS=1;NO_GETENV=1;GC_INSIDE_DLL=1;GC_NOT_DLL=1;STDC_HEADERS=1;HAVE_SYS_TYPES_H=1;HAVE_SYS_STAT_H=1;HAVE_STDLIB_H=1;HAVE_STRING_H=1;HAVE_MEMORY_H=1;HAVE_STRINGS_H=1;HAVE_INTTYPES_H=1;HAVE_STDINT_H=1;HAVE_UNISTD_H=1;SILENT=1;NO_SIGNALS=1;NO_EXECUTE_PERMISSION=1;JAVA_FINALIZATION=1;GC_GCJ_SUPPORT=1;ATOMIC_UNCOLLECTABLE=1;_IN_LIBGC=1;WINVER=0x0500;_WIN32_WINNT=0x0500;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) + NDEBUG;__i386__;TARGET_X86;i386;i386;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;__STDC__;PACKAGE_NAME="libgc-mono";PACKAGE_TARNAME="libgc-mono";PACKAGE_VERSION="6.6";PACKAGE_STRING="libgc-mono 6.6";PACKAGE_BUGREPORT="Hans_Boehm%40hp.com";GC_WIN32_THREADS=1;NO_GETENV=1;GC_INSIDE_DLL=1;GC_NOT_DLL=1;STDC_HEADERS=1;HAVE_SYS_TYPES_H=1;HAVE_SYS_STAT_H=1;HAVE_STDLIB_H=1;HAVE_STRING_H=1;HAVE_MEMORY_H=1;HAVE_STRINGS_H=1;HAVE_INTTYPES_H=1;HAVE_STDINT_H=1;HAVE_UNISTD_H=1;SILENT=1;NO_SIGNALS=1;NO_EXECUTE_PERMISSION=1;JAVA_FINALIZATION=1;GC_GCJ_SUPPORT=1;ATOMIC_UNCOLLECTABLE=1;_IN_LIBGC=1;WINVER=0x0502;_WIN32_WINNT=0x0502;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + $(OutDir)vc80.pdb + ProgramDatabase + CompileAsC + + + $(OutDir)libgc.lib + + + + + MinSpace + ..\libgc\include;%(AdditionalIncludeDirectories) + NDEBUG;__i386__;TARGET_X86;i386;i386;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;__STDC__;PACKAGE_NAME="libgc-mono";PACKAGE_TARNAME="libgc-mono";PACKAGE_VERSION="6.6";PACKAGE_STRING="libgc-mono 6.6";PACKAGE_BUGREPORT="Hans_Boehm%40hp.com";GC_WIN32_THREADS=1;NO_GETENV=1;GC_INSIDE_DLL=1;GC_NOT_DLL=1;STDC_HEADERS=1;HAVE_SYS_TYPES_H=1;HAVE_SYS_STAT_H=1;HAVE_STDLIB_H=1;HAVE_STRING_H=1;HAVE_MEMORY_H=1;HAVE_STRINGS_H=1;HAVE_INTTYPES_H=1;HAVE_STDINT_H=1;HAVE_UNISTD_H=1;SILENT=1;NO_SIGNALS=1;NO_EXECUTE_PERMISSION=1;JAVA_FINALIZATION=1;GC_GCJ_SUPPORT=1;ATOMIC_UNCOLLECTABLE=1;_IN_LIBGC=1;WINVER=0x0502;_WIN32_WINNT=0x0502;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -115,7 +208,30 @@ Disabled ..\libgc\include;%(AdditionalIncludeDirectories) - _DEBUG;__x86_64__;WIN64;_WIN64;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;__STDC__;PACKAGE_NAME="libgc-mono";PACKAGE_TARNAME="libgc-mono";PACKAGE_VERSION="6.6";PACKAGE_STRING="libgc-mono 6.6";PACKAGE_BUGREPORT="Hans_Boehm%40hp.com";GC_WIN32_THREADS=1;NO_GETENV=1;GC_INSIDE_DLL=1;GC_NOT_DLL=1;STDC_HEADERS=1;HAVE_SYS_TYPES_H=1;HAVE_SYS_STAT_H=1;HAVE_STDLIB_H=1;HAVE_STRING_H=1;HAVE_MEMORY_H=1;HAVE_STRINGS_H=1;HAVE_INTTYPES_H=1;HAVE_STDINT_H=1;HAVE_UNISTD_H=1;SILENT=1;NO_SIGNALS=1;NO_EXECUTE_PERMISSION=1;JAVA_FINALIZATION=1;GC_GCJ_SUPPORT=1;ATOMIC_UNCOLLECTABLE=1;_IN_LIBGC=1;WINVER=0x0500;_WIN32_WINNT=0x0500;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024 + _DEBUG;__x86_64__;WIN64;_WIN64;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;__STDC__;PACKAGE_NAME="libgc-mono";PACKAGE_TARNAME="libgc-mono";PACKAGE_VERSION="6.6";PACKAGE_STRING="libgc-mono 6.6";PACKAGE_BUGREPORT="Hans_Boehm%40hp.com";GC_WIN32_THREADS=1;NO_GETENV=1;GC_INSIDE_DLL=1;GC_NOT_DLL=1;STDC_HEADERS=1;HAVE_SYS_TYPES_H=1;HAVE_SYS_STAT_H=1;HAVE_STDLIB_H=1;HAVE_STRING_H=1;HAVE_MEMORY_H=1;HAVE_STRINGS_H=1;HAVE_INTTYPES_H=1;HAVE_STDINT_H=1;HAVE_UNISTD_H=1;SILENT=1;NO_SIGNALS=1;NO_EXECUTE_PERMISSION=1;JAVA_FINALIZATION=1;GC_GCJ_SUPPORT=1;ATOMIC_UNCOLLECTABLE=1;_IN_LIBGC=1;WINVER=0x0502;_WIN32_WINNT=0x0502;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024 + true + EnableFastChecks + MultiThreadedDebugDLL + true + + + $(OutDir)vc80.pdb + ProgramDatabase + CompileAsC + 4311;4312;4996;4005;%(DisableSpecificWarnings) + + + $(OutDir)libgc.lib + + + + + X64 + + + Disabled + ..\libgc\include;%(AdditionalIncludeDirectories) + _DEBUG;__x86_64__;WIN64;_WIN64;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;__STDC__;PACKAGE_NAME="libgc-mono";PACKAGE_TARNAME="libgc-mono";PACKAGE_VERSION="6.6";PACKAGE_STRING="libgc-mono 6.6";PACKAGE_BUGREPORT="Hans_Boehm%40hp.com";GC_WIN32_THREADS=1;NO_GETENV=1;GC_INSIDE_DLL=1;GC_NOT_DLL=1;STDC_HEADERS=1;HAVE_SYS_TYPES_H=1;HAVE_SYS_STAT_H=1;HAVE_STDLIB_H=1;HAVE_STRING_H=1;HAVE_MEMORY_H=1;HAVE_STRINGS_H=1;HAVE_INTTYPES_H=1;HAVE_STDINT_H=1;HAVE_UNISTD_H=1;SILENT=1;NO_SIGNALS=1;NO_EXECUTE_PERMISSION=1;JAVA_FINALIZATION=1;GC_GCJ_SUPPORT=1;ATOMIC_UNCOLLECTABLE=1;_IN_LIBGC=1;WINVER=0x0502;_WIN32_WINNT=0x0502;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024 true EnableFastChecks MultiThreadedDebugDLL @@ -138,7 +254,27 @@ MinSpace ..\libgc\include;%(AdditionalIncludeDirectories) - NDEBUG;__x86_64__;WIN64;_WIN64;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;__STDC__;PACKAGE_NAME="libgc-mono";PACKAGE_TARNAME="libgc-mono";PACKAGE_VERSION="6.6";PACKAGE_STRING="libgc-mono 6.6";PACKAGE_BUGREPORT="Hans_Boehm%40hp.com";GC_WIN32_THREADS=1;NO_GETENV=1;GC_INSIDE_DLL=1;GC_NOT_DLL=1;STDC_HEADERS=1;HAVE_SYS_TYPES_H=1;HAVE_SYS_STAT_H=1;HAVE_STDLIB_H=1;HAVE_STRING_H=1;HAVE_MEMORY_H=1;HAVE_STRINGS_H=1;HAVE_INTTYPES_H=1;HAVE_STDINT_H=1;HAVE_UNISTD_H=1;SILENT=1;NO_SIGNALS=1;NO_EXECUTE_PERMISSION=1;JAVA_FINALIZATION=1;GC_GCJ_SUPPORT=1;ATOMIC_UNCOLLECTABLE=1;_IN_LIBGC=1;WINVER=0x0500;_WIN32_WINNT=0x0500;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) + NDEBUG;__x86_64__;WIN64;_WIN64;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;__STDC__;PACKAGE_NAME="libgc-mono";PACKAGE_TARNAME="libgc-mono";PACKAGE_VERSION="6.6";PACKAGE_STRING="libgc-mono 6.6";PACKAGE_BUGREPORT="Hans_Boehm%40hp.com";GC_WIN32_THREADS=1;NO_GETENV=1;GC_INSIDE_DLL=1;GC_NOT_DLL=1;STDC_HEADERS=1;HAVE_SYS_TYPES_H=1;HAVE_SYS_STAT_H=1;HAVE_STDLIB_H=1;HAVE_STRING_H=1;HAVE_MEMORY_H=1;HAVE_STRINGS_H=1;HAVE_INTTYPES_H=1;HAVE_STDINT_H=1;HAVE_UNISTD_H=1;SILENT=1;NO_SIGNALS=1;NO_EXECUTE_PERMISSION=1;JAVA_FINALIZATION=1;GC_GCJ_SUPPORT=1;ATOMIC_UNCOLLECTABLE=1;_IN_LIBGC=1;WINVER=0x0502;_WIN32_WINNT=0x0502;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + $(OutDir)vc80.pdb + ProgramDatabase + CompileAsC + + + $(OutDir)libgc.lib + + + + + X64 + + + MinSpace + ..\libgc\include;%(AdditionalIncludeDirectories) + NDEBUG;__x86_64__;WIN64;_WIN64;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;__STDC__;PACKAGE_NAME="libgc-mono";PACKAGE_TARNAME="libgc-mono";PACKAGE_VERSION="6.6";PACKAGE_STRING="libgc-mono 6.6";PACKAGE_BUGREPORT="Hans_Boehm%40hp.com";GC_WIN32_THREADS=1;NO_GETENV=1;GC_INSIDE_DLL=1;GC_NOT_DLL=1;STDC_HEADERS=1;HAVE_SYS_TYPES_H=1;HAVE_SYS_STAT_H=1;HAVE_STDLIB_H=1;HAVE_STRING_H=1;HAVE_MEMORY_H=1;HAVE_STRINGS_H=1;HAVE_INTTYPES_H=1;HAVE_STDINT_H=1;HAVE_UNISTD_H=1;SILENT=1;NO_SIGNALS=1;NO_EXECUTE_PERMISSION=1;JAVA_FINALIZATION=1;GC_GCJ_SUPPORT=1;ATOMIC_UNCOLLECTABLE=1;_IN_LIBGC=1;WINVER=0x0502;_WIN32_WINNT=0x0502;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) MultiThreadedDLL true diff --git a/msvc/libmonoruntime.vcxproj b/msvc/libmonoruntime.vcxproj index 3635bdae2d..cc68a31014 100644 --- a/msvc/libmonoruntime.vcxproj +++ b/msvc/libmonoruntime.vcxproj @@ -57,6 +57,7 @@ + @@ -98,9 +99,6 @@ - - - @@ -111,7 +109,9 @@ + + @@ -466,4 +466,4 @@ - \ No newline at end of file + diff --git a/msvc/libtest.vcxproj b/msvc/libtest.vcxproj index 0fa69f3a15..8e35a6e765 100644 --- a/msvc/libtest.vcxproj +++ b/msvc/libtest.vcxproj @@ -18,6 +18,7 @@ x64 + {5A435710-E6D2-4DD4-9B3F-A7239A32C6F4} libtest @@ -199,4 +200,4 @@ - \ No newline at end of file + diff --git a/msvc/mono.def b/msvc/mono.def index 61d1779c33..30cd8151b6 100644 --- a/msvc/mono.def +++ b/msvc/mono.def @@ -84,6 +84,7 @@ mono_class_from_mono_type mono_class_from_name mono_class_from_name_case mono_class_from_typeref +mono_class_from_typeref_checked mono_class_get mono_class_get_byref_type mono_class_get_com_object_class @@ -161,10 +162,19 @@ mono_context_get mono_context_get_desc mono_context_init mono_context_set +mono_counter_get_name +mono_counter_get_section +mono_counter_get_size +mono_counter_get_type +mono_counter_get_unit +mono_counter_get_variance mono_counters_cleanup mono_counters_dump mono_counters_enable +mono_counters_foreach mono_counters_register +mono_counters_register_with_size +mono_counters_sample mono_custom_attrs_construct mono_custom_attrs_free mono_custom_attrs_from_assembly @@ -209,6 +219,7 @@ mono_debug_symfile_is_loaded mono_debug_symfile_lookup_locals mono_debug_symfile_lookup_location mono_debug_symfile_lookup_method +mono_debugger_agent_register_transport mono_debugger_insert_breakpoint mono_debugger_method_has_breakpoint mono_debugger_run_finally @@ -250,6 +261,7 @@ mono_domain_try_unload mono_domain_unload mono_dwarf_escape_path mono_emit_native_call +mono_enable_debug_domain_unload mono_environment_exitcode_get mono_environment_exitcode_set mono_error_cleanup @@ -325,6 +337,9 @@ mono_gc_out_of_memory mono_gc_reference_queue_add mono_gc_reference_queue_free mono_gc_reference_queue_new +mono_gc_register_finalizer_callbacks +mono_gc_toggleref_add +mono_gc_toggleref_register_callback mono_gc_walk_heap mono_gc_wbarrier_arrayref_copy mono_gc_wbarrier_generic_nostore @@ -537,7 +552,7 @@ mono_metadata_guid_heap mono_metadata_implmap_from_method mono_metadata_init mono_metadata_interfaces_from_typedef -mono_metadata_load_generic_param_constraints +mono_metadata_load_generic_param_constraints_checked mono_metadata_load_generic_params mono_metadata_locate mono_metadata_locate_token @@ -689,6 +704,7 @@ mono_profiler_install_thread_name mono_profiler_install_transition mono_profiler_load mono_profiler_set_events +mono_profiler_set_statistical_mode mono_property_get_flags mono_property_get_get_method mono_property_get_name @@ -705,6 +721,7 @@ mono_property_set_value mono_ptr_class_get mono_raise_exception mono_realloc_native_code +mono_reflection_assembly_get_assembly mono_reflection_free_type_info mono_reflection_get_custom_attrs mono_reflection_get_custom_attrs_blob @@ -737,6 +754,7 @@ mono_runtime_resource_check_limit mono_runtime_resource_limit mono_runtime_resource_set_callback mono_runtime_run_main +mono_runtime_set_main_args mono_runtime_set_shutting_down mono_security_core_clr_get_options mono_security_core_clr_require_elevated_permissions @@ -749,6 +767,7 @@ mono_sem_wait mono_set_assemblies_path mono_set_break_policy mono_set_config_dir +mono_set_crash_chaining mono_set_defaults mono_set_dirs mono_set_is_debugger_attached @@ -777,6 +796,7 @@ mono_signature_vararg_start mono_signbit_double mono_signbit_float mono_stack_walk +mono_stack_walk_async_safe mono_stack_walk_no_il mono_store_remote_field mono_store_remote_field_new @@ -784,6 +804,7 @@ mono_string_chars mono_string_equal mono_string_from_bstr mono_string_from_utf16 +mono_string_from_utf32 mono_string_hash mono_string_intern mono_string_is_interned @@ -792,8 +813,10 @@ mono_string_new mono_string_new_len mono_string_new_size mono_string_new_utf16 +mono_string_new_utf32 mono_string_new_wrapper mono_string_to_utf16 +mono_string_to_utf32 mono_string_to_utf8 mono_string_to_utf8_checked mono_stringify_assembly_name @@ -803,9 +826,20 @@ mono_thread_cleanup mono_thread_create mono_thread_current mono_thread_detach +mono_thread_detach_if_exiting mono_thread_exit mono_thread_get_main mono_thread_get_undeniable_exception +mono_thread_info_clear_interruption +mono_thread_info_exit +mono_thread_info_finish_interrupt +mono_thread_info_get_stack_bounds +mono_thread_info_interrupt +mono_thread_info_open_handle +mono_thread_info_prepare_interrupt +mono_thread_info_self_interrupt +mono_thread_info_tls_get +mono_thread_info_tls_set mono_thread_init mono_thread_is_foreign mono_thread_manage @@ -813,13 +847,22 @@ mono_thread_new_init mono_thread_set_main mono_thread_set_manage_callback mono_thread_stop +mono_threads_attach_tools_thread +mono_threads_core_clear_interruption +mono_threads_core_finish_interrupt +mono_threads_core_prepare_interrupt +mono_threads_core_self_interrupt +mono_threads_create_thread mono_threads_get_default_stacksize mono_threads_request_thread_dump mono_threads_set_default_stacksize mono_tls_key_get_offset mono_tls_key_set_offset mono_trace_set_level_string +mono_trace_set_log_handler mono_trace_set_mask_string +mono_trace_set_print_handler +mono_trace_set_printerr_handler mono_type_create_from_typespec mono_type_full_name mono_type_generic_inst_is_valuetype diff --git a/msvc/mono.props b/msvc/mono.props index 7fe3206e24..ffec2840f2 100644 --- a/msvc/mono.props +++ b/msvc/mono.props @@ -1,4 +1,4 @@ - + $(MSBuildProjectDirectory)\.. @@ -9,10 +9,11 @@ - __default_codegen__;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;HAVE_CONFIG_H;GC_NOT_DLL;WIN32_THREADS;WINVER=0x0500;_WIN32_WINNT=0x0500;_WIN32_IE=0x0501;_UNICODE;UNICODE;WIN32_THREADS;FD_SETSIZE=1024;$(PreprocessorDefinitions) + __default_codegen__;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_DEPRECATE;HAVE_CONFIG_H;GC_NOT_DLL;WIN32_THREADS;WINVER=0x0502;_WIN32_WINNT=0x0502;_WIN32_IE=0x0501;_UNICODE;UNICODE;WIN32_THREADS;FD_SETSIZE=1024;$(PreprocessorDefinitions);_WINSOCKAPI_ + 4273;4005 Mswsock.lib;ws2_32.lib;ole32.lib;oleaut32.lib;psapi.lib;version.lib;advapi32.lib;winmm.lib;kernel32.lib;$(AdditionalDependencies) - \ No newline at end of file + diff --git a/msvc/monoposixhelper.vcxproj b/msvc/monoposixhelper.vcxproj index f771bbb15e..04d54d9ffb 100644 --- a/msvc/monoposixhelper.vcxproj +++ b/msvc/monoposixhelper.vcxproj @@ -83,7 +83,7 @@ Disabled ..\eglib\src;..\;%(AdditionalIncludeDirectories) - _DEBUG;__i386__;TARGET_X86;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;HAVE_CONFIG_H;%(PreprocessorDefinitions) + _DEBUG;__i386__;TARGET_X86;_WIN32_WINNT=0x0502;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;HAVE_CONFIG_H;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL diff --git a/msvc/profiler-logging.vcxproj b/msvc/profiler-logging.vcxproj index 2d28de5510..b457654279 100644 --- a/msvc/profiler-logging.vcxproj +++ b/msvc/profiler-logging.vcxproj @@ -118,7 +118,7 @@ Disabled ..\libgc\include;..\;..\mono\;..\mono\jit;..\mono\eglib\src;..\..\mono\eglib\src;%(AdditionalIncludeDirectories) - TARGET_X86;_DEBUG;__i386__;TARGET_X86;i386;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;GC_NOT_DLL;HAVE_CONFIG_H;WINVER=0x0500;_WIN32_WINNT=0x0500;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) + TARGET_X86;_DEBUG;__i386__;TARGET_X86;i386;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;GC_NOT_DLL;HAVE_CONFIG_H;WINVER=0x0502;_WIN32_WINNT=0x0502;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -140,7 +140,7 @@ Disabled ..\libgc\include;..\;..\mono\;..\mono\jit;..\mono\eglib\src;..\..\mono\eglib\src;%(AdditionalIncludeDirectories) - TARGET_X86;_DEBUG;__i386__;TARGET_X86;i386;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;GC_NOT_DLL;HAVE_CONFIG_H;WINVER=0x0500;_WIN32_WINNT=0x0500;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) + TARGET_X86;_DEBUG;__i386__;TARGET_X86;i386;WIN32;_WIN32;__WIN32__;_WINDOWS;WINDOWS;HOST_WIN32;TARGET_WIN32;_CRT_SECURE_NO_DEPRECATE;GC_NOT_DLL;HAVE_CONFIG_H;WINVER=0x0502;_WIN32_WINNT=0x0502;_WIN32_IE=0x0501;WIN32_THREADS;FD_SETSIZE=1024;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL diff --git a/msvc/winsetup.bat b/msvc/winsetup.bat index 33a72f6b1b..f67a854569 100755 --- a/msvc/winsetup.bat +++ b/msvc/winsetup.bat @@ -1,6 +1,9 @@ @echo off cd .. +if exist config.h if not exist cygconfig.h copy config.h cygconfig.h +if exist eglib\config.h if not exist eglib\cygconfig.h copy eglib\config.h eglib\cygconfig.h copy winconfig.h config.h +copy eglib\winconfig.h eglib\config.h goto end :error echo fatal error: the VSDepenancies directory was not found in the "mono" directory diff --git a/po/mcs/de.gmo b/po/mcs/de.gmo index 1c73791731..5df9f21340 100644 Binary files a/po/mcs/de.gmo and b/po/mcs/de.gmo differ diff --git a/po/mcs/de.po b/po/mcs/de.po index ba0d3117d6..4432068a75 100644 --- a/po/mcs/de.po +++ b/po/mcs/de.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: http://www.mono-project.com/Bugs\n" -"POT-Creation-Date: 2014-10-04 10:45+0100\n" +"POT-Creation-Date: 2015-01-12 17:26+0000\n" "PO-Revision-Date: 2008-09-26 15:14+0100\n" "Last-Translator: Daniel Nauck \n" "Language-Team: http://www.mono-project.de\n" @@ -30,7 +30,7 @@ msgid "" "mismatch" msgstr "" -#: mcs/mcs/anonymous.cs:1054 mcs/mcs/ecore.cs:5630 +#: mcs/mcs/anonymous.cs:1054 mcs/mcs/ecore.cs:5670 #, csharp-format msgid "Delegate `{0}' does not take `{1}' arguments" msgstr "" @@ -87,7 +87,7 @@ msgstr "Kann Typ `{0}'<...> nicht finden" msgid "An expression tree cannot contain an anonymous method expression" msgstr "" -#: mcs/mcs/anonymous.cs:2023 +#: mcs/mcs/anonymous.cs:2021 #, csharp-format msgid "" "`{0}': An anonymous type cannot have multiple properties with the same name" @@ -419,47 +419,53 @@ msgstr "" msgid "Duplicate named attribute `{0}' argument" msgstr "" -#: mcs/mcs/attribute.cs:860 +#: mcs/mcs/attribute.cs:859 +#, csharp-format +msgid "" +"First argument of a security attribute `{0}' must be a valid SecurityAction" +msgstr "" + +#: mcs/mcs/attribute.cs:864 #, csharp-format msgid "Security attribute `{0}' has an invalid SecurityAction value `{1}'" msgstr "" -#: mcs/mcs/attribute.cs:867 +#: mcs/mcs/attribute.cs:871 #, csharp-format msgid "" "SecurityAction value `{0}' is invalid for security attributes applied to an " "assembly" msgstr "" -#: mcs/mcs/attribute.cs:871 +#: mcs/mcs/attribute.cs:875 #, csharp-format msgid "" "SecurityAction value `{0}' is invalid for security attributes applied to a " "type or a method" msgstr "" -#: mcs/mcs/attribute.cs:1018 +#: mcs/mcs/attribute.cs:1043 #, csharp-format msgid "" "The attribute `{0}' is not valid on this declaration type. It is valid on " "`{1}' declarations only" msgstr "" -#: mcs/mcs/attribute.cs:1040 +#: mcs/mcs/attribute.cs:1065 #, csharp-format msgid "The argument to the `{0}' attribute must be a valid identifier" msgstr "" -#: mcs/mcs/attribute.cs:1059 +#: mcs/mcs/attribute.cs:1084 msgid "Unmanaged type `ByValArray' is only valid for fields" msgstr "" -#: mcs/mcs/attribute.cs:1320 +#: mcs/mcs/attribute.cs:1345 #, csharp-format msgid "The attribute `{0}' cannot be applied multiple times" msgstr "" -#: mcs/mcs/attribute.cs:1626 +#: mcs/mcs/attribute.cs:1651 #, csharp-format msgid "`{0}' is obsolete: `{1}'" msgstr "`{0}' ist veraltet: `{1}'" @@ -470,114 +476,114 @@ msgid "" "`struct', `interface', or `void' keyword" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:1589 mcs/mcs/cs-tokenizer.cs:1652 +#: mcs/mcs/cs-tokenizer.cs:1597 mcs/mcs/cs-tokenizer.cs:1660 msgid "Invalid number" msgstr "Ungültige Zahl" -#: mcs/mcs/cs-tokenizer.cs:1867 +#: mcs/mcs/cs-tokenizer.cs:1875 #, csharp-format msgid "Unrecognized escape sequence `\\{0}'" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:1886 +#: mcs/mcs/cs-tokenizer.cs:1894 msgid "Unrecognized escape sequence" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2151 +#: mcs/mcs/cs-tokenizer.cs:2159 msgid "Filename, single-line comment or end-of-line expected" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2199 +#: mcs/mcs/cs-tokenizer.cs:2207 #, fuzzy msgid "Missing identifier to pre-processor directive" msgstr "Ungültige Präprozessor Direktive" -#: mcs/mcs/cs-tokenizer.cs:2209 mcs/mcs/cs-tokenizer.cs:2213 +#: mcs/mcs/cs-tokenizer.cs:2217 mcs/mcs/cs-tokenizer.cs:2221 #, csharp-format msgid "Identifier expected: {0}" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2721 +#: mcs/mcs/cs-tokenizer.cs:2729 #, fuzzy msgid "Integral constant is too large" msgstr "Numerische Konstante ist zu lang" -#: mcs/mcs/cs-tokenizer.cs:2726 +#: mcs/mcs/cs-tokenizer.cs:2734 msgid "Invalid preprocessor directive" msgstr "Ungültige Präprozessor Direktive" -#: mcs/mcs/cs-tokenizer.cs:2733 +#: mcs/mcs/cs-tokenizer.cs:2741 #, csharp-format msgid "Unexpected processor directive ({0})" msgstr "Unerwartete Prozessor Direktive ({0})" -#: mcs/mcs/cs-tokenizer.cs:2739 +#: mcs/mcs/cs-tokenizer.cs:2747 msgid "" "Cannot define or undefine preprocessor symbols after first token in file" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2745 +#: mcs/mcs/cs-tokenizer.cs:2753 msgid "" "Preprocessor directives must appear as the first non-whitespace character on " "a line" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2750 +#: mcs/mcs/cs-tokenizer.cs:2758 msgid "Single-line comment or end-of-line expected" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2795 mcs/mcs/cs-tokenizer.cs:3832 +#: mcs/mcs/cs-tokenizer.cs:2803 mcs/mcs/cs-tokenizer.cs:3840 msgid "Expected `#endif' directive" msgstr "`#endif' Direktive erwartet" -#: mcs/mcs/cs-tokenizer.cs:2828 mcs/mcs/cs-tokenizer.cs:2849 -#: mcs/mcs/cs-tokenizer.cs:2880 mcs/mcs/cs-tokenizer.cs:3830 +#: mcs/mcs/cs-tokenizer.cs:2836 mcs/mcs/cs-tokenizer.cs:2857 +#: mcs/mcs/cs-tokenizer.cs:2888 mcs/mcs/cs-tokenizer.cs:3838 msgid "#endregion directive expected" msgstr "`#endregion' Direktive erwartet" -#: mcs/mcs/cs-tokenizer.cs:2929 +#: mcs/mcs/cs-tokenizer.cs:2937 msgid "Wrong preprocessor directive" msgstr "Falsche Präprozessor Direktive" -#: mcs/mcs/cs-tokenizer.cs:2941 +#: mcs/mcs/cs-tokenizer.cs:2949 #, csharp-format msgid "#error: '{0}'" msgstr "#Fehler: '{0}'" -#: mcs/mcs/cs-tokenizer.cs:2959 +#: mcs/mcs/cs-tokenizer.cs:2967 msgid "The line number specified for #line directive is missing or invalid" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:3021 mcs/mcs/cs-tokenizer.cs:3673 +#: mcs/mcs/cs-tokenizer.cs:3029 mcs/mcs/cs-tokenizer.cs:3681 msgid "Newline in constant" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:3048 +#: mcs/mcs/cs-tokenizer.cs:3056 msgid "Unterminated string literal" msgstr "Nicht beendetes Zeichenfolgeliteral" -#: mcs/mcs/cs-tokenizer.cs:3125 +#: mcs/mcs/cs-tokenizer.cs:3133 msgid "Identifier too long (limit is 512 chars)" msgstr "Der Bezeichner ist zu lang. (Maximal 512 Zeichen)" -#: mcs/mcs/cs-tokenizer.cs:3511 +#: mcs/mcs/cs-tokenizer.cs:3519 msgid "End-of-file found, '*/' expected" msgstr "Dateiende gefunden. `*/' erwartet." -#: mcs/mcs/cs-tokenizer.cs:3622 +#: mcs/mcs/cs-tokenizer.cs:3630 msgid "Keyword, identifier, or string expected after verbatim specifier: @" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:3643 +#: mcs/mcs/cs-tokenizer.cs:3651 #, fuzzy, csharp-format msgid "Unexpected character `{0}'" msgstr "`{0}' erwartet" -#: mcs/mcs/cs-tokenizer.cs:3668 +#: mcs/mcs/cs-tokenizer.cs:3676 msgid "Empty character literal" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:3689 +#: mcs/mcs/cs-tokenizer.cs:3697 msgid "Too many characters in character literal" msgstr "" @@ -585,7 +591,7 @@ msgstr "" msgid "The operation overflows at compile time in checked mode" msgstr "" -#: mcs/mcs/cfold.cs:329 mcs/mcs/expression.cs:4291 +#: mcs/mcs/cfold.cs:329 mcs/mcs/expression.cs:4927 #, csharp-format msgid "Operator `{0}' is ambiguous on operands of type `{1}' and `{2}'" msgstr "" @@ -653,426 +659,424 @@ msgstr "" msgid "The RequiredAttribute attribute is not permitted on C# types" msgstr "" -#: mcs/mcs/class.cs:1155 +#: mcs/mcs/class.cs:981 +#, fuzzy, csharp-format +msgid "'{0}': Structs cannot have instance property or field initializers" +msgstr "`{0}': Instanzfeldinitialisierungen können nicht in Strukturen sein" + +#: mcs/mcs/class.cs:1162 #, csharp-format msgid "Class `{0}' cannot derive from the dynamic type" msgstr "" -#: mcs/mcs/class.cs:1172 +#: mcs/mcs/class.cs:1179 #, csharp-format msgid "`{0}' is already listed in interface list" msgstr "" -#: mcs/mcs/class.cs:1180 +#: mcs/mcs/class.cs:1187 #, csharp-format msgid "" "Inconsistent accessibility: base interface `{0}' is less accessible than " "interface `{1}'" msgstr "" -#: mcs/mcs/class.cs:1186 +#: mcs/mcs/class.cs:1193 #, csharp-format msgid "Type `{0}' in interface list is not an interface" msgstr "" -#: mcs/mcs/class.cs:1188 +#: mcs/mcs/class.cs:1195 #, csharp-format msgid "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')" msgstr "" -#: mcs/mcs/class.cs:1191 +#: mcs/mcs/class.cs:1198 #, csharp-format msgid "`{0}': Base class `{1}' must be specified as first" msgstr "" -#: mcs/mcs/class.cs:1252 +#: mcs/mcs/class.cs:1259 #, csharp-format msgid "" "The operator `{0}' requires a matching operator `{1}' to also be defined" msgstr "" -#: mcs/mcs/class.cs:1507 +#: mcs/mcs/class.cs:1526 #, csharp-format msgid "Partial declarations of `{0}' must not specify different base classes" msgstr "" -#: mcs/mcs/class.cs:1542 +#: mcs/mcs/class.cs:1561 msgid "" "Only one part of a partial type can declare primary constructor parameters" msgstr "" -#: mcs/mcs/class.cs:1559 +#: mcs/mcs/class.cs:1578 #, csharp-format msgid "" "Inherited interface `{0}' causes a cycle in the interface hierarchy of `{1}'" msgstr "" -#: mcs/mcs/class.cs:1566 +#: mcs/mcs/class.cs:1585 #, csharp-format msgid "Circular base class dependency involving `{0}' and `{1}'" msgstr "" -#: mcs/mcs/class.cs:1576 +#: mcs/mcs/class.cs:1595 #, fuzzy msgid "Implemented interfaces cannot have arguments" msgstr "`{0}': Instanzfeldinitialisierungen können nicht in Strukturen sein" -#: mcs/mcs/class.cs:1905 +#: mcs/mcs/class.cs:1924 #, fuzzy, csharp-format msgid "`{0}': cannot implement a dynamic interface `{1}'" msgstr "`{0}' implementiert den Schnittstellenmember `{1}' nicht" -#: mcs/mcs/class.cs:1920 +#: mcs/mcs/class.cs:1939 #, csharp-format msgid "" "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some " "type parameter substitutions" msgstr "" -#: mcs/mcs/class.cs:1944 +#: mcs/mcs/class.cs:1963 #, csharp-format msgid "" "A generic type cannot derive from `{0}' because it is an attribute class" msgstr "" -#: mcs/mcs/class.cs:2048 +#: mcs/mcs/class.cs:2067 msgid "" "Two indexers have different names; the IndexerName attribute must be used " "with the same name on every indexer within a type" msgstr "" -#: mcs/mcs/class.cs:2306 +#: mcs/mcs/class.cs:2325 #, csharp-format msgid "A static member `{0}' cannot be marked as override, virtual or abstract" msgstr "" -#: mcs/mcs/class.cs:2313 +#: mcs/mcs/class.cs:2332 #, csharp-format msgid "A member `{0}' marked as override cannot be marked as new or virtual" msgstr "" -#: mcs/mcs/class.cs:2325 +#: mcs/mcs/class.cs:2344 #, csharp-format msgid "`{0}' cannot be both extern and abstract" msgstr "" -#: mcs/mcs/class.cs:2330 +#: mcs/mcs/class.cs:2349 #, csharp-format msgid "`{0}' cannot be both abstract and sealed" msgstr "`{0}' Eine Klasse kann nicht gleichzeitig statisch und versiegelt sein" -#: mcs/mcs/class.cs:2335 +#: mcs/mcs/class.cs:2354 #, csharp-format msgid "The abstract method `{0}' cannot be marked virtual" msgstr "" -#: mcs/mcs/class.cs:2341 +#: mcs/mcs/class.cs:2360 #, csharp-format msgid "`{0}' is abstract but it is declared in the non-abstract class `{1}'" msgstr "" -#: mcs/mcs/class.cs:2349 +#: mcs/mcs/class.cs:2368 #, csharp-format msgid "`{0}': virtual or abstract members cannot be private" msgstr "" -#: mcs/mcs/class.cs:2356 +#: mcs/mcs/class.cs:2375 #, csharp-format msgid "`{0}' cannot be sealed because it is not an override" msgstr "" -#: mcs/mcs/class.cs:2405 +#: mcs/mcs/class.cs:2424 #, csharp-format msgid "`{0}': containing type does not implement interface `{1}'" msgstr "" -#: mcs/mcs/class.cs:2602 +#: mcs/mcs/class.cs:2621 #, csharp-format msgid "Type parameter `{0}' has same name as containing type, or method" msgstr "" -#: mcs/mcs/class.cs:2610 +#: mcs/mcs/class.cs:2629 #, csharp-format msgid "`{0}': member names cannot be the same as their enclosing type" msgstr "" -#: mcs/mcs/class.cs:2685 +#: mcs/mcs/class.cs:2707 #, csharp-format msgid "" "Primary constructor of type `{0}' has parameter of same name as containing " "type" msgstr "" -#: mcs/mcs/class.cs:2693 +#: mcs/mcs/class.cs:2715 #, csharp-format msgid "" "Primary constructor of type `{0}' has parameter of same name as type " "parameter `{1}'" msgstr "" -#: mcs/mcs/class.cs:2759 +#: mcs/mcs/class.cs:2781 msgid "" "The class System.Object cannot have a base class or implement an interface." msgstr "" -#: mcs/mcs/class.cs:2768 +#: mcs/mcs/class.cs:2790 #, csharp-format msgid "Attribute `{0}' is only valid on classes derived from System.Attribute" msgstr "" -#: mcs/mcs/class.cs:2773 +#: mcs/mcs/class.cs:2795 msgid "" "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods " "or attribute classes" msgstr "" -#: mcs/mcs/class.cs:2802 +#: mcs/mcs/class.cs:2824 #, csharp-format msgid "`{0}': an abstract class cannot be sealed or static" msgstr "`{0}': Eine abstrakte Klasse darf nicht versiegelt oder statisch sein" -#: mcs/mcs/class.cs:2806 +#: mcs/mcs/class.cs:2828 #, csharp-format msgid "`{0}': a class cannot be both static and sealed" msgstr "" -#: mcs/mcs/class.cs:2811 +#: mcs/mcs/class.cs:2833 #, fuzzy, csharp-format msgid "`{0}': Static classes cannot have primary constructor" msgstr "`{0}': Statische Klassen können keinen Destruktor enthalten" -#: mcs/mcs/class.cs:2817 +#: mcs/mcs/class.cs:2839 #, csharp-format msgid "`{0}': Static classes cannot contain user-defined operators" msgstr "" "`{0}': Statische Klassen können keine benutzerdefinierten Operatoren " "beinhalten" -#: mcs/mcs/class.cs:2822 +#: mcs/mcs/class.cs:2844 #, csharp-format msgid "`{0}': Static classes cannot contain destructor" msgstr "`{0}': Statische Klassen können keinen Destruktor enthalten" -#: mcs/mcs/class.cs:2827 +#: mcs/mcs/class.cs:2849 #, csharp-format msgid "`{0}': cannot declare indexers in a static class" msgstr "" -#: mcs/mcs/class.cs:2835 +#: mcs/mcs/class.cs:2857 #, csharp-format msgid "`{0}': Static classes cannot have instance constructors" msgstr "" -#: mcs/mcs/class.cs:2839 +#: mcs/mcs/class.cs:2861 #, csharp-format msgid "`{0}': cannot declare instance members in a static class" msgstr "" -#: mcs/mcs/class.cs:2881 +#: mcs/mcs/class.cs:2903 #, fuzzy, csharp-format msgid "`{0}': Cannot derive from type parameter `{1}'" msgstr "`{0}' implementiert den Schnittstellenmember `{1}' nicht" -#: mcs/mcs/class.cs:2885 +#: mcs/mcs/class.cs:2907 #, csharp-format msgid "`{0}': Cannot derive from static class `{1}'" msgstr "" -#: mcs/mcs/class.cs:2889 +#: mcs/mcs/class.cs:2911 #, csharp-format msgid "`{0}': cannot derive from sealed type `{1}'" msgstr "" -#: mcs/mcs/class.cs:2892 +#: mcs/mcs/class.cs:2914 #, csharp-format msgid "" "Static class `{0}' cannot derive from type `{1}'. Static classes must derive " "from object" msgstr "" -#: mcs/mcs/class.cs:2903 +#: mcs/mcs/class.cs:2925 #, csharp-format msgid "`{0}' cannot derive from special class `{1}'" msgstr "" -#: mcs/mcs/class.cs:2913 +#: mcs/mcs/class.cs:2935 #, csharp-format msgid "" "Inconsistent accessibility: base class `{0}' is less accessible than class " "`{1}'" msgstr "" -#: mcs/mcs/class.cs:2921 +#: mcs/mcs/class.cs:2943 #, csharp-format msgid "Static class `{0}' cannot implement interfaces" msgstr "" -#: mcs/mcs/class.cs:3032 mcs/mcs/class.cs:3046 +#: mcs/mcs/class.cs:3054 mcs/mcs/class.cs:3068 #, csharp-format msgid "Struct member `{0}' of type `{1}' causes a cycle in the struct layout" msgstr "" -#: mcs/mcs/class.cs:3150 -#, fuzzy, csharp-format -msgid "" -"`{0}': Structs without explicit constructors cannot contain members with " -"initializers" -msgstr "`{0}': Statische Klassen können keinen Destruktor enthalten" - -#: mcs/mcs/class.cs:3339 +#: mcs/mcs/class.cs:3353 #, csharp-format msgid "Do not override `{0}'. Use destructor syntax instead" msgstr "" -#: mcs/mcs/class.cs:3342 +#: mcs/mcs/class.cs:3356 #, csharp-format msgid "`{0}' is marked as an override but no suitable {1} found to override" msgstr "" -#: mcs/mcs/class.cs:3348 +#: mcs/mcs/class.cs:3362 #, csharp-format msgid "`{0}': cannot override because `{1}' is not an event" msgstr "" -#: mcs/mcs/class.cs:3351 +#: mcs/mcs/class.cs:3365 #, csharp-format msgid "`{0}': cannot override because `{1}' is not a property" msgstr "" -#: mcs/mcs/class.cs:3354 +#: mcs/mcs/class.cs:3368 #, csharp-format msgid "`{0}': cannot override because `{1}' is not a method" msgstr "" -#: mcs/mcs/class.cs:3373 +#: mcs/mcs/class.cs:3387 #, csharp-format msgid "" "`{0}' cannot override inherited members `{1}' and `{2}' because they have " "the same signature when used in type `{3}'" msgstr "" -#: mcs/mcs/class.cs:3426 mcs/mcs/field.cs:203 +#: mcs/mcs/class.cs:3440 mcs/mcs/field.cs:203 #, csharp-format msgid "`{0}' hides inherited abstract member `{1}'" msgstr "" -#: mcs/mcs/class.cs:3450 +#: mcs/mcs/class.cs:3464 #, csharp-format msgid "" "`{0}': cannot override inherited member `{1}' because it is not marked " "virtual, abstract or override" msgstr "" -#: mcs/mcs/class.cs:3458 +#: mcs/mcs/class.cs:3472 #, csharp-format msgid "`{0}': cannot override inherited member `{1}' because it is sealed" msgstr "" -#: mcs/mcs/class.cs:3467 +#: mcs/mcs/class.cs:3481 #, csharp-format msgid "`{0}': type must be `{1}' to match overridden member `{2}'" msgstr "" -#: mcs/mcs/class.cs:3470 +#: mcs/mcs/class.cs:3484 #, csharp-format msgid "`{0}': return type must be `{1}' to match overridden member `{2}'" msgstr "" -#: mcs/mcs/class.cs:3538 +#: mcs/mcs/class.cs:3552 #, csharp-format msgid "A partial method `{0}' cannot explicitly implement an interface" msgstr "" -#: mcs/mcs/class.cs:3544 +#: mcs/mcs/class.cs:3558 #, csharp-format msgid "The type `{0}' in explicit interface declaration is not an interface" msgstr "" -#: mcs/mcs/class.cs:3579 +#: mcs/mcs/class.cs:3593 #, csharp-format msgid "" "Inconsistent accessibility: parameter type `{0}' is less accessible than " "indexer `{1}'" msgstr "" -#: mcs/mcs/class.cs:3583 +#: mcs/mcs/class.cs:3597 #, csharp-format msgid "" "Inconsistent accessibility: parameter type `{0}' is less accessible than " "operator `{1}'" msgstr "" -#: mcs/mcs/class.cs:3587 +#: mcs/mcs/class.cs:3601 #, csharp-format msgid "" "Inconsistent accessibility: parameter type `{0}' is less accessible than " "method `{1}'" msgstr "" -#: mcs/mcs/class.cs:3647 +#: mcs/mcs/class.cs:3661 #, csharp-format msgid "" "`{0}': cannot change access modifiers when overriding `{1}' inherited member " "`{2}'" msgstr "" -#: mcs/mcs/class.cs:3656 +#: mcs/mcs/class.cs:3670 #, fuzzy, csharp-format msgid "`{0}': static types cannot be used as return types" msgstr "" "`{0}': Statische Klassen können keine benutzerdefinierten Operatoren " "beinhalten" -#: mcs/mcs/class.cs:3717 +#: mcs/mcs/class.cs:3731 #, csharp-format msgid "" "`{0}': Cannot specify constraints for overrides and explicit interface " "implementation methods" msgstr "" -#: mcs/mcs/class.cs:3781 +#: mcs/mcs/class.cs:3795 #, csharp-format msgid "New virtual member `{0}' is declared in a sealed class `{1}'" msgstr "" -#: mcs/mcs/class.cs:3796 +#: mcs/mcs/class.cs:3810 msgid "Inconsistent accessibility: property type `" msgstr "" -#: mcs/mcs/class.cs:3801 +#: mcs/mcs/class.cs:3815 msgid "Inconsistent accessibility: indexer return type `" msgstr "" -#: mcs/mcs/class.cs:3807 mcs/mcs/class.cs:3812 mcs/mcs/delegate.cs:171 +#: mcs/mcs/class.cs:3821 mcs/mcs/class.cs:3826 mcs/mcs/delegate.cs:171 msgid "Inconsistent accessibility: return type `" msgstr "" -#: mcs/mcs/class.cs:3817 +#: mcs/mcs/class.cs:3831 #, csharp-format msgid "" "Inconsistent accessibility: event type `{0}' is less accessible than event " "`{1}'" msgstr "" -#: mcs/mcs/class.cs:3821 +#: mcs/mcs/class.cs:3835 msgid "Inconsistent accessibility: field type `" msgstr "" -#: mcs/mcs/class.cs:3833 +#: mcs/mcs/class.cs:3847 #, csharp-format msgid "" "Parameters or local variables of type `{0}' cannot be declared in async " "methods or iterators" msgstr "" -#: mcs/mcs/class.cs:3837 +#: mcs/mcs/class.cs:3851 #, csharp-format msgid "" "Local variables of type `{0}' cannot be used inside anonymous methods, " "lambda expressions or query expressions" msgstr "" -#: mcs/mcs/class.cs:3841 +#: mcs/mcs/class.cs:3855 #, csharp-format msgid "Field or property cannot be of type `{0}'" msgstr "" @@ -1248,7 +1252,14 @@ msgstr "" msgid "An expression tree cannot contain a dynamic operation" msgstr "" -#: mcs/mcs/dynamic.cs:311 +#: mcs/mcs/dynamic.cs:295 +#, fuzzy +msgid "Declaration expression cannot be used in this context" +msgstr "" +"Die `new()'-Einschränkung kann nicht mit der `struct'-Einschränkung genutzt " +"werden" + +#: mcs/mcs/dynamic.cs:318 msgid "" "Dynamic operation cannot be compiled without `Microsoft.CSharp.dll' assembly " "reference" @@ -1315,73 +1326,74 @@ msgstr "" msgid "The operation in question is undefined on void pointers" msgstr "" -#: mcs/mcs/ecore.cs:517 mcs/mcs/statement.cs:3908 mcs/mcs/statement.cs:3910 +#: mcs/mcs/ecore.cs:519 mcs/mcs/statement.cs:3908 mcs/mcs/statement.cs:3910 #, csharp-format msgid "Internal compiler error: {0}" msgstr "" -#: mcs/mcs/ecore.cs:579 mcs/mcs/expression.cs:7260 mcs/mcs/expression.cs:7268 +#: mcs/mcs/ecore.cs:581 mcs/mcs/expression.cs:1825 mcs/mcs/expression.cs:7868 +#: mcs/mcs/expression.cs:7876 msgid "A constant value is expected" msgstr "" -#: mcs/mcs/ecore.cs:591 +#: mcs/mcs/ecore.cs:593 msgid "" "An attribute argument must be a constant expression, typeof expression or " "array creation expression" msgstr "" -#: mcs/mcs/ecore.cs:594 +#: mcs/mcs/ecore.cs:596 #, csharp-format msgid "" "Attribute constructor parameter has type `{0}', which is not a valid " "attribute parameter type" msgstr "" -#: mcs/mcs/ecore.cs:779 +#: mcs/mcs/ecore.cs:785 #, csharp-format msgid "The class `{0}' has no constructors defined" msgstr "" -#: mcs/mcs/ecore.cs:980 +#: mcs/mcs/ecore.cs:998 #, csharp-format msgid "The `{0}' operator cannot be applied to operand of type `{1}'" msgstr "" -#: mcs/mcs/ecore.cs:986 +#: mcs/mcs/ecore.cs:1004 msgid "An expression tree cannot contain an unsafe pointer operation" msgstr "" -#: mcs/mcs/ecore.cs:991 +#: mcs/mcs/ecore.cs:1009 #, fuzzy msgid "An expression tree cannot contain a null propagating operator" msgstr "" "`{0}': Statische Klassen können keine benutzerdefinierten Operatoren " "beinhalten" -#: mcs/mcs/ecore.cs:1083 +#: mcs/mcs/ecore.cs:1105 #, csharp-format msgid "`{0}' is a `{1}' but a `{2}' was expected" msgstr "" -#: mcs/mcs/ecore.cs:1116 +#: mcs/mcs/ecore.cs:1138 #, csharp-format msgid "Expression denotes a `{0}', where a `{1}' was expected" msgstr "" -#: mcs/mcs/ecore.cs:1126 +#: mcs/mcs/ecore.cs:1148 msgid "Pointers and fixed size buffers may only be used in an unsafe context" msgstr "" -#: mcs/mcs/ecore.cs:2546 +#: mcs/mcs/ecore.cs:2568 msgid "Unbound generic name is not valid in this context" msgstr "" -#: mcs/mcs/ecore.cs:2623 +#: mcs/mcs/ecore.cs:2645 #, csharp-format msgid "The name `{0}' does not exist in the current context" msgstr "" -#: mcs/mcs/ecore.cs:2700 +#: mcs/mcs/ecore.cs:2722 #, fuzzy, csharp-format msgid "" "Dynamic keyword requires `{0}' to be defined. Are you missing System.Core." @@ -1390,28 +1402,28 @@ msgstr "" "Der Typ oder Namespacename `{0}' konnte nicht gefunden werden. Fehlt eine " "using-Direktive oder ein Assemblyverweis?" -#: mcs/mcs/ecore.cs:2776 +#: mcs/mcs/ecore.cs:2798 #, csharp-format msgid "" "A local variable `{0}' cannot be used before it is declared. Consider " "renaming the local variable when it hides the member `{1}'" msgstr "" -#: mcs/mcs/ecore.cs:2791 mcs/mcs/ecore.cs:2834 +#: mcs/mcs/ecore.cs:2813 mcs/mcs/ecore.cs:2856 #, csharp-format msgid "`{0}' conflicts with a declaration in a child block" msgstr "" -#: mcs/mcs/ecore.cs:2855 +#: mcs/mcs/ecore.cs:2877 #, csharp-format msgid "A local variable `{0}' cannot be used before it is declared" msgstr "" -#: mcs/mcs/ecore.cs:3008 +#: mcs/mcs/ecore.cs:3030 msgid "System.Void cannot be used from C#. Consider using `void'" msgstr "" -#: mcs/mcs/ecore.cs:3171 +#: mcs/mcs/ecore.cs:3193 #, fuzzy, csharp-format msgid "" "The type or namespace name `{0}' could not be found in the global namespace. " @@ -1420,7 +1432,7 @@ msgstr "" "Der Typ oder Namespacename `{0}' konnte im globalen Namesapce nicht gefunden " "werden. Fehlt ein Assemblyverweis?" -#: mcs/mcs/ecore.cs:3175 +#: mcs/mcs/ecore.cs:3197 #, fuzzy, csharp-format msgid "" "The type or namespace name `{0}' does not exist in the namespace `{1}'. Are " @@ -1429,128 +1441,128 @@ msgstr "" "Der Typ oder Namespacename `{0}' existiert nicht im Namespace `{1}'. Fehlt " "ein Assemblyverweis?" -#: mcs/mcs/ecore.cs:3424 +#: mcs/mcs/ecore.cs:3446 #, csharp-format msgid "Cannot call an abstract base member `{0}'" msgstr "" -#: mcs/mcs/ecore.cs:3431 +#: mcs/mcs/ecore.cs:3453 #, csharp-format msgid "" "Cannot access protected member `{0}' via a qualifier of type `{1}'. The " "qualifier must be of type `{2}' or derived from it" msgstr "" -#: mcs/mcs/ecore.cs:3471 +#: mcs/mcs/ecore.cs:3493 #, csharp-format msgid "" "Fields of static readonly field `{0}' cannot be assigned to (except in a " "static constructor or a variable initializer)" msgstr "" -#: mcs/mcs/ecore.cs:3474 +#: mcs/mcs/ecore.cs:3496 #, csharp-format msgid "" "Members of readonly field `{0}' cannot be modified (except in a constructor " "or a variable initializer)" msgstr "" -#: mcs/mcs/ecore.cs:3483 +#: mcs/mcs/ecore.cs:3505 #, csharp-format msgid "" "Members of value type `{0}' cannot be assigned using a property `{1}' object " "initializer" msgstr "" -#: mcs/mcs/ecore.cs:3487 +#: mcs/mcs/ecore.cs:3509 #, csharp-format msgid "" "Cannot modify a value type return value of `{0}'. Consider storing the value " "in a temporary variable" msgstr "" -#: mcs/mcs/ecore.cs:3500 +#: mcs/mcs/ecore.cs:3522 #, fuzzy, csharp-format msgid "Cannot assign to members of `{0}' because it is a `{1}'" msgstr "" "NULL kann nicht in `{0}' konvertiert werden, da dies ein Werttyp ist, der " "nicht auf NULL festgelegt werden kann" -#: mcs/mcs/ecore.cs:3526 +#: mcs/mcs/ecore.cs:3548 #, csharp-format msgid "" "Static member `{0}' cannot be accessed with an instance reference, qualify " "it with a type name instead" msgstr "" -#: mcs/mcs/ecore.cs:3541 +#: mcs/mcs/ecore.cs:3563 #, csharp-format msgid "" "A field initializer cannot reference the nonstatic field, method, or " "property `{0}'" msgstr "" -#: mcs/mcs/ecore.cs:3547 +#: mcs/mcs/ecore.cs:3569 msgid "Constructor initializer cannot access primary constructor parameters" msgstr "" -#: mcs/mcs/ecore.cs:3549 +#: mcs/mcs/ecore.cs:3571 #, csharp-format msgid "" "An object reference is required to access primary constructor parameter `{0}'" msgstr "" -#: mcs/mcs/ecore.cs:3554 +#: mcs/mcs/ecore.cs:3576 #, csharp-format msgid "An object reference is required to access non-static member `{0}'" msgstr "" -#: mcs/mcs/ecore.cs:3565 +#: mcs/mcs/ecore.cs:3587 #, csharp-format msgid "" "Cannot access a nonstatic member of outer type `{0}' via nested type `{1}'" msgstr "" -#: mcs/mcs/ecore.cs:3593 +#: mcs/mcs/ecore.cs:3615 msgid "Cannot modify the result of an unboxing conversion" msgstr "Das Ergebnis einer Unboxing-Konvertierung kann nicht geändert werden" -#: mcs/mcs/ecore.cs:3762 +#: mcs/mcs/ecore.cs:3784 #, csharp-format msgid "" "Type `{0}' does not contain a member `{1}' and the best extension method " "overload `{2}' has some invalid arguments" msgstr "" -#: mcs/mcs/ecore.cs:3767 +#: mcs/mcs/ecore.cs:3789 #, csharp-format msgid "Extension method instance type `{0}' cannot be converted to `{1}'" msgstr "" -#: mcs/mcs/ecore.cs:3915 +#: mcs/mcs/ecore.cs:3937 msgid "An expression tree cannot contain an expression with method group" msgstr "" -#: mcs/mcs/ecore.cs:3921 +#: mcs/mcs/ecore.cs:3943 msgid "" "Partial methods with only a defining declaration or removed conditional " "methods cannot be used in an expression tree" msgstr "" -#: mcs/mcs/ecore.cs:3972 +#: mcs/mcs/ecore.cs:3994 #, csharp-format msgid "" "Cannot convert method group `{0}' to non-delegate type `{1}'. Consider using " "parentheses to invoke the method" msgstr "" -#: mcs/mcs/ecore.cs:4711 +#: mcs/mcs/ecore.cs:4733 #, csharp-format msgid "" "The type `{0}' does not contain a constructor that takes `{1}' arguments" msgstr "" -#: mcs/mcs/ecore.cs:5412 +#: mcs/mcs/ecore.cs:5452 #, csharp-format msgid "" "Type `{0}' does not contain a member `{1}' and the best extension method " @@ -1558,202 +1570,202 @@ msgid "" "without the extension method syntax" msgstr "" -#: mcs/mcs/ecore.cs:5451 +#: mcs/mcs/ecore.cs:5491 #, csharp-format msgid "" "The call is ambiguous between the following methods or properties: `{0}' and " "`{1}'" msgstr "" -#: mcs/mcs/ecore.cs:5514 +#: mcs/mcs/ecore.cs:5554 #, csharp-format msgid "" "The best overloaded collection initalizer method `{0}' cannot have `ref' or " "`out' modifier" msgstr "" -#: mcs/mcs/ecore.cs:5518 +#: mcs/mcs/ecore.cs:5558 #, csharp-format msgid "" "The best overloaded collection initalizer method `{0}' has some invalid " "arguments" msgstr "" -#: mcs/mcs/ecore.cs:5521 +#: mcs/mcs/ecore.cs:5561 #, csharp-format msgid "Delegate `{0}' has some invalid arguments" msgstr "" -#: mcs/mcs/ecore.cs:5525 +#: mcs/mcs/ecore.cs:5565 #, csharp-format msgid "The best overloaded method match for `{0}' has some invalid arguments" msgstr "" -#: mcs/mcs/ecore.cs:5534 +#: mcs/mcs/ecore.cs:5574 #, csharp-format msgid "" "Argument `#{0}' does not require `{1}' modifier. Consider removing `{1}' " "modifier" msgstr "" -#: mcs/mcs/ecore.cs:5537 +#: mcs/mcs/ecore.cs:5577 #, csharp-format msgid "Argument `#{0}' is missing `{1}' modifier" msgstr "" -#: mcs/mcs/ecore.cs:5554 +#: mcs/mcs/ecore.cs:5594 #, csharp-format msgid "Argument `#{0}' cannot convert `{1}' expression to type `{2}'" msgstr "" -#: mcs/mcs/ecore.cs:5606 +#: mcs/mcs/ecore.cs:5646 #, csharp-format msgid "" "The type arguments for method `{0}' cannot be inferred from the usage. Try " "specifying the type arguments explicitly" msgstr "" -#: mcs/mcs/ecore.cs:5635 +#: mcs/mcs/ecore.cs:5675 #, csharp-format msgid "No overload for method `{0}' takes `{1}' arguments" msgstr "" -#: mcs/mcs/ecore.cs:5728 +#: mcs/mcs/ecore.cs:5778 #, csharp-format msgid "The delegate `{0}' does not contain a parameter named `{1}'" msgstr "" -#: mcs/mcs/ecore.cs:5733 +#: mcs/mcs/ecore.cs:5783 #, csharp-format msgid "" "The best overloaded method match for `{0}' does not contain a parameter " "named `{1}'" msgstr "" -#: mcs/mcs/ecore.cs:5743 +#: mcs/mcs/ecore.cs:5793 #, csharp-format msgid "" "Named argument `{0}' cannot be used for a parameter which has positional " "argument specified" msgstr "" -#: mcs/mcs/ecore.cs:6091 +#: mcs/mcs/ecore.cs:6155 msgid "" "You cannot use fixed size buffers contained in unfixed expressions. Try " "using the fixed statement" msgstr "" -#: mcs/mcs/ecore.cs:6096 +#: mcs/mcs/ecore.cs:6160 #, csharp-format msgid "`{0}': Fixed size buffers can only be accessed through locals or fields" msgstr "" -#: mcs/mcs/ecore.cs:6178 +#: mcs/mcs/ecore.cs:6242 #, csharp-format msgid "" "A static readonly field `{0}' cannot be passed ref or out (except in a " "static constructor)" msgstr "" -#: mcs/mcs/ecore.cs:6181 +#: mcs/mcs/ecore.cs:6245 #, csharp-format msgid "" "A readonly field `{0}' cannot be passed ref or out (except in a constructor)" msgstr "" -#: mcs/mcs/ecore.cs:6195 +#: mcs/mcs/ecore.cs:6259 #, csharp-format msgid "" "Fields of static readonly field `{0}' cannot be passed ref or out (except in " "a static constructor)" msgstr "" -#: mcs/mcs/ecore.cs:6198 +#: mcs/mcs/ecore.cs:6262 #, csharp-format msgid "" "Members of readonly field `{0}' cannot be passed ref or out (except in a " "constructor)" msgstr "" -#: mcs/mcs/ecore.cs:6205 +#: mcs/mcs/ecore.cs:6269 #, csharp-format msgid "" "A static readonly field `{0}' cannot be assigned to (except in a static " "constructor or a variable initializer)" msgstr "" -#: mcs/mcs/ecore.cs:6208 +#: mcs/mcs/ecore.cs:6272 #, csharp-format msgid "" "A readonly field `{0}' cannot be assigned to (except in a constructor or a " "variable initializer)" msgstr "" -#: mcs/mcs/ecore.cs:6275 +#: mcs/mcs/ecore.cs:6339 #, fuzzy, csharp-format msgid "Use of possibly unassigned field `{0}'" msgstr "Verwendung eines möglicherweise nicht zugewiesenen Feldes `" -#: mcs/mcs/ecore.cs:6655 +#: mcs/mcs/ecore.cs:6719 #, fuzzy, csharp-format msgid "Property or event `{0}' is not supported by the C# language" msgstr "" "Die Eigenschaft `{0}' wird von der C# Sprache nicht unterstützt. Rufen Sie " "die `{1}'-Accessormethode direkt auf." -#: mcs/mcs/ecore.cs:6886 +#: mcs/mcs/ecore.cs:6950 #, csharp-format msgid "A range variable `{0}' may not be passes as `ref' or `out' parameter" msgstr "" -#: mcs/mcs/ecore.cs:6974 +#: mcs/mcs/ecore.cs:7038 #, csharp-format msgid "" "The property or indexer `{0}' cannot be used in this context because it " "lacks the `get' accessor" msgstr "" -#: mcs/mcs/ecore.cs:6981 +#: mcs/mcs/ecore.cs:7045 #, csharp-format msgid "" "The property or indexer `{0}' cannot be used in this context because the get " "accessor is inaccessible" msgstr "" -#: mcs/mcs/ecore.cs:7000 +#: mcs/mcs/ecore.cs:7064 #, csharp-format msgid "Property or indexer `{0}' cannot be assigned to (it is read-only)" msgstr "" -#: mcs/mcs/ecore.cs:7008 +#: mcs/mcs/ecore.cs:7072 #, csharp-format msgid "" "The property or indexer `{0}' cannot be used in this context because the set " "accessor is inaccessible" msgstr "" -#: mcs/mcs/ecore.cs:7185 +#: mcs/mcs/ecore.cs:7249 #, csharp-format msgid "" "The event `{0}' can only appear on the left hand side of `+=' or `-=' " "operator" msgstr "" -#: mcs/mcs/ecore.cs:7189 +#: mcs/mcs/ecore.cs:7253 #, csharp-format msgid "" "The event `{0}' can only appear on the left hand side of += or -= when used " "outside of the type `{1}'" msgstr "" -#: mcs/mcs/ecore.cs:7361 +#: mcs/mcs/ecore.cs:7425 #, csharp-format msgid "" "An implicitly typed local variable declaration cannot be initialized with " "`{0}'" msgstr "" -#: mcs/mcs/ecore.cs:7375 +#: mcs/mcs/ecore.cs:7439 msgid "" "The contextual keyword `var' may only appear within a local variable " "declaration" @@ -1821,255 +1833,277 @@ msgid "" "method, or method group" msgstr "" -#: mcs/mcs/expression.cs:1820 +#: mcs/mcs/expression.cs:2213 +#, fuzzy, csharp-format +msgid "`{0}' is not a valid pattern member" +msgstr "`{0}' implementiert den Schnittstellenmember `{1}' nicht" + +#: mcs/mcs/expression.cs:2220 +#, csharp-format +msgid "Property `{0}.get' accessor is required" +msgstr "" + +#: mcs/mcs/expression.cs:2353 #, csharp-format msgid "" "The `as' operator cannot be used with a non-reference type parameter `{0}'. " "Consider adding `class' or a reference type constraint" msgstr "" -#: mcs/mcs/expression.cs:1824 +#: mcs/mcs/expression.cs:2357 #, csharp-format msgid "The `as' operator cannot be used with a non-nullable value type `{0}'" msgstr "" -#: mcs/mcs/expression.cs:1858 +#: mcs/mcs/expression.cs:2391 #, csharp-format msgid "Cannot convert type `{0}' to `{1}' via a built-in conversion" msgstr "" -#: mcs/mcs/expression.cs:1899 +#: mcs/mcs/expression.cs:2432 #, csharp-format msgid "Cannot convert to static type `{0}'" msgstr "" -#: mcs/mcs/expression.cs:2009 +#: mcs/mcs/expression.cs:2535 +#, fuzzy +msgid "An expression tree cannot contain a declaration expression" +msgstr "" +"`{0}': Statische Klassen können keine benutzerdefinierten Operatoren " +"beinhalten" + +#: mcs/mcs/expression.cs:2632 msgid "" "The `default value' operator cannot be applied to an operand of a static type" msgstr "" -#: mcs/mcs/expression.cs:2686 +#: mcs/mcs/expression.cs:3314 #, csharp-format msgid "Operator `{0}' cannot be applied to operands of type `{1}' and `{2}'" msgstr "" -#: mcs/mcs/expression.cs:3492 +#: mcs/mcs/expression.cs:4120 msgid "To cast a negative value, you must enclose the value in parentheses" msgstr "" -#: mcs/mcs/expression.cs:3585 +#: mcs/mcs/expression.cs:4213 #, csharp-format msgid "" "Expression must be implicitly convertible to Boolean or its type `{0}' must " "define operator `{1}'" msgstr "" -#: mcs/mcs/expression.cs:5183 +#: mcs/mcs/expression.cs:5819 #, csharp-format msgid "" "A user-defined operator `{0}' must have each parameter type and return type " "of the same type in order to be applicable as a short circuit operator" msgstr "" -#: mcs/mcs/expression.cs:5193 +#: mcs/mcs/expression.cs:5829 #, csharp-format msgid "" "The type `{0}' must have operator `true' and operator `false' defined when " "`{1}' is used as a short circuit operator" msgstr "" -#: mcs/mcs/expression.cs:5568 +#: mcs/mcs/expression.cs:6204 #, csharp-format msgid "" "Type of conditional expression cannot be determined as `{0}' and `{1}' " "convert implicitly to each other" msgstr "" -#: mcs/mcs/expression.cs:5580 +#: mcs/mcs/expression.cs:6216 #, csharp-format msgid "" "Type of conditional expression cannot be determined because there is no " "implicit conversion between `{0}' and `{1}'" msgstr "" -#: mcs/mcs/expression.cs:5926 +#: mcs/mcs/expression.cs:6562 #, fuzzy, csharp-format msgid "Use of unassigned local variable `{0}'" msgstr "Verwendung der nicht zugewiesenen lokalen Variable `" -#: mcs/mcs/expression.cs:5946 +#: mcs/mcs/expression.cs:6585 #, csharp-format msgid "" "Cannot use fixed local `{0}' inside an anonymous method, lambda expression " "or query expression" msgstr "" -#: mcs/mcs/expression.cs:6131 +#: mcs/mcs/expression.cs:6603 +#, fuzzy, csharp-format +msgid "Cannot use uninitialized variable `{0}'" +msgstr "Verwendung der nicht zugewiesenen lokalen Variable `" + +#: mcs/mcs/expression.cs:6775 #, csharp-format msgid "" "Parameter `{0}' cannot be used inside `{1}' when using `ref' or `out' " "modifier" msgstr "" -#: mcs/mcs/expression.cs:6201 +#: mcs/mcs/expression.cs:6845 #, csharp-format msgid "Use of unassigned out parameter `{0}'" msgstr "" -#: mcs/mcs/expression.cs:6405 +#: mcs/mcs/expression.cs:7049 #, fuzzy, csharp-format msgid "Cannot invoke a non-delegate type `{0}'" msgstr "Kann Typ `{0}'<...> nicht finden" -#: mcs/mcs/expression.cs:6416 +#: mcs/mcs/expression.cs:7060 #, csharp-format msgid "The member `{0}' cannot be used as method or delegate" msgstr "" -#: mcs/mcs/expression.cs:6438 +#: mcs/mcs/expression.cs:7082 msgid "" "Do not directly call your base class Finalize method. It is called " "automatically from your destructor" msgstr "" -#: mcs/mcs/expression.cs:6440 +#: mcs/mcs/expression.cs:7084 msgid "" "Destructors and object.Finalize cannot be called directly. Consider calling " "IDisposable.Dispose if available" msgstr "" -#: mcs/mcs/expression.cs:6469 +#: mcs/mcs/expression.cs:7113 #, csharp-format msgid "" "The base call to method `{0}' cannot be dynamically dispatched. Consider " "casting the dynamic arguments or eliminating the base access" msgstr "" -#: mcs/mcs/expression.cs:6562 +#: mcs/mcs/expression.cs:7206 #, csharp-format msgid "`{0}': cannot explicitly call operator or accessor" msgstr "" -#: mcs/mcs/expression.cs:6752 +#: mcs/mcs/expression.cs:7396 #, csharp-format msgid "Unsafe type `{0}' cannot be used in an object creation expression" msgstr "" -#: mcs/mcs/expression.cs:6775 +#: mcs/mcs/expression.cs:7419 #, csharp-format msgid "" "Cannot create an instance of the variable type `{0}' because it does not " "have the new() constraint" msgstr "" -#: mcs/mcs/expression.cs:6781 +#: mcs/mcs/expression.cs:7425 #, csharp-format msgid "" "`{0}': cannot provide arguments when creating an instance of a variable type" msgstr "" -#: mcs/mcs/expression.cs:6790 +#: mcs/mcs/expression.cs:7434 #, csharp-format msgid "Cannot create an instance of the static class `{0}'" msgstr "" -#: mcs/mcs/expression.cs:6802 +#: mcs/mcs/expression.cs:7446 #, csharp-format msgid "Cannot create an instance of the abstract class or interface `{0}'" msgstr "" -#: mcs/mcs/expression.cs:7111 +#: mcs/mcs/expression.cs:7719 msgid "" "An implicitly typed local variable declarator cannot use an array initializer" msgstr "" -#: mcs/mcs/expression.cs:7274 mcs/mcs/expression.cs:7299 +#: mcs/mcs/expression.cs:7882 mcs/mcs/expression.cs:7907 #, csharp-format msgid "An array initializer of length `{0}' was expected" msgstr "" -#: mcs/mcs/expression.cs:7290 +#: mcs/mcs/expression.cs:7898 msgid "" "Array initializers can only be used in a variable or field initializer. Try " "using a new expression instead" msgstr "" -#: mcs/mcs/expression.cs:7307 +#: mcs/mcs/expression.cs:7915 msgid "A nested array initializer was expected" msgstr "" -#: mcs/mcs/expression.cs:7354 +#: mcs/mcs/expression.cs:7962 msgid "An expression tree cannot contain a multidimensional array initializer" msgstr "" -#: mcs/mcs/expression.cs:7390 +#: mcs/mcs/expression.cs:7998 msgid "Cannot create an array with a negative size" msgstr "" -#: mcs/mcs/expression.cs:7482 +#: mcs/mcs/expression.cs:8090 msgid "" "Can only use array initializer expressions to assign to array types. Try " "using a new expression instead" msgstr "" -#: mcs/mcs/expression.cs:7906 +#: mcs/mcs/expression.cs:8514 msgid "" "The type of an implicitly typed array cannot be inferred from the " "initializer. Try specifying array type explicitly" msgstr "" -#: mcs/mcs/expression.cs:8061 +#: mcs/mcs/expression.cs:8669 msgid "" "The `this' object cannot be used before all of its fields are assigned to" msgstr "" -#: mcs/mcs/expression.cs:8067 +#: mcs/mcs/expression.cs:8675 msgid "" "Keyword `this' is not valid in a static property, static method, or static " "field initializer" msgstr "" -#: mcs/mcs/expression.cs:8070 +#: mcs/mcs/expression.cs:8678 msgid "" "Anonymous methods inside structs cannot access instance members of `this'. " "Consider copying `this' to a local variable outside the anonymous method and " "using the local instead" msgstr "" -#: mcs/mcs/expression.cs:8073 +#: mcs/mcs/expression.cs:8681 msgid "Keyword `this' is not available in the current context" msgstr "" -#: mcs/mcs/expression.cs:8149 +#: mcs/mcs/expression.cs:8757 msgid "Cannot take the address of `this' because it is read-only" msgstr "" -#: mcs/mcs/expression.cs:8151 +#: mcs/mcs/expression.cs:8759 msgid "Cannot pass `this' as a ref or out argument because it is read-only" msgstr "" -#: mcs/mcs/expression.cs:8153 +#: mcs/mcs/expression.cs:8761 msgid "Cannot assign to `this' because it is read-only" msgstr "" -#: mcs/mcs/expression.cs:8221 +#: mcs/mcs/expression.cs:8829 msgid "The __arglist construct is valid only within a variable argument method" msgstr "" -#: mcs/mcs/expression.cs:8282 +#: mcs/mcs/expression.cs:8890 msgid "An expression tree cannot contain a method with variable arguments" msgstr "" -#: mcs/mcs/expression.cs:8550 +#: mcs/mcs/expression.cs:9158 msgid "The typeof operator cannot be used on the dynamic type" msgstr "" -#: mcs/mcs/expression.cs:8591 +#: mcs/mcs/expression.cs:9199 #, csharp-format msgid "`{0}': an attribute argument cannot use type parameters" msgstr "" -#: mcs/mcs/expression.cs:8806 +#: mcs/mcs/expression.cs:9414 #, csharp-format msgid "" "`{0}' does not have a predefined size, therefore sizeof can only be used in " @@ -2077,34 +2111,34 @@ msgid "" "SizeOf)" msgstr "" -#: mcs/mcs/expression.cs:8871 +#: mcs/mcs/expression.cs:9479 #, csharp-format msgid "Alias `{0}' not found" msgstr "Alias `{0}' wurde nicht gefunden" -#: mcs/mcs/expression.cs:8912 +#: mcs/mcs/expression.cs:9520 msgid "" "The namespace alias qualifier `::' cannot be used to invoke a method. " "Consider using `.' instead" msgstr "" -#: mcs/mcs/expression.cs:9002 +#: mcs/mcs/expression.cs:9610 msgid "Cannot perform member binding on `null' value" msgstr "" -#: mcs/mcs/expression.cs:9156 +#: mcs/mcs/expression.cs:9764 #, csharp-format msgid "" "`{0}': cannot reference a type through an expression. Consider using `{1}' " "instead" msgstr "" -#: mcs/mcs/expression.cs:9236 +#: mcs/mcs/expression.cs:9844 #, csharp-format msgid "A nested type cannot be specified through a type parameter `{0}'" msgstr "" -#: mcs/mcs/expression.cs:9244 +#: mcs/mcs/expression.cs:9852 #, fuzzy, csharp-format msgid "" "Alias `{0}' cannot be used with `::' since it denotes a type. Consider " @@ -2113,131 +2147,131 @@ msgstr "" "Der Alias `{0}' kann nicht mit '::' verwendet werden, da der Alias auf einen " "Typ verweist. Verwenden Sie '.' stattdessen." -#: mcs/mcs/expression.cs:9314 +#: mcs/mcs/expression.cs:9922 #, csharp-format msgid "The nested type `{0}' does not exist in the type `{1}'" msgstr "" -#: mcs/mcs/expression.cs:9338 +#: mcs/mcs/expression.cs:9946 #, csharp-format msgid "" "Type `{0}' does not contain a definition for `{1}' and no extension method " "`{1}' of type `{0}' could be found. Are you missing {2}?" msgstr "" -#: mcs/mcs/expression.cs:9617 +#: mcs/mcs/expression.cs:10225 #, csharp-format msgid "Cannot apply indexing with [] to an expression of type `{0}'" msgstr "" -#: mcs/mcs/expression.cs:9630 +#: mcs/mcs/expression.cs:10238 msgid "A pointer must be indexed by only one value" msgstr "" -#: mcs/mcs/expression.cs:9686 +#: mcs/mcs/expression.cs:10294 msgid "An element access expression cannot use named argument" msgstr "" -#: mcs/mcs/expression.cs:9788 +#: mcs/mcs/expression.cs:10396 #, csharp-format msgid "Wrong number of indexes `{0}' inside [], expected `{1}'" msgstr "" -#: mcs/mcs/expression.cs:10211 +#: mcs/mcs/expression.cs:10819 msgid "" "The indexer base access cannot be dynamically dispatched. Consider casting " "the dynamic arguments or eliminating the base access" msgstr "" -#: mcs/mcs/expression.cs:10301 +#: mcs/mcs/expression.cs:10909 msgid "An expression tree may not contain a base access" msgstr "" -#: mcs/mcs/expression.cs:10319 +#: mcs/mcs/expression.cs:10927 msgid "Keyword `base' is not available in a static method" msgstr "" -#: mcs/mcs/expression.cs:10321 +#: mcs/mcs/expression.cs:10929 msgid "Keyword `base' is not available in the current context" msgstr "" -#: mcs/mcs/expression.cs:10359 +#: mcs/mcs/expression.cs:10967 msgid "" "A property, indexer or dynamic member access may not be passed as `ref' or " "`out' parameter" msgstr "" -#: mcs/mcs/expression.cs:10697 +#: mcs/mcs/expression.cs:11312 #, csharp-format msgid "Array elements cannot be of type `{0}'" msgstr "" -#: mcs/mcs/expression.cs:10700 +#: mcs/mcs/expression.cs:11315 #, csharp-format msgid "Array elements cannot be of static type `{0}'" msgstr "" -#: mcs/mcs/expression.cs:10876 +#: mcs/mcs/expression.cs:11491 msgid "Cannot use a negative size with stackalloc" msgstr "" -#: mcs/mcs/expression.cs:10880 +#: mcs/mcs/expression.cs:11495 msgid "Cannot use stackalloc in finally or catch" msgstr "" -#: mcs/mcs/expression.cs:11035 +#: mcs/mcs/expression.cs:11650 #, csharp-format msgid "" "Member `{0}' cannot be initialized. An object initializer may only be used " "for fields, or properties" msgstr "" -#: mcs/mcs/expression.cs:11043 +#: mcs/mcs/expression.cs:11658 #, csharp-format msgid "" "Static field or property `{0}' cannot be assigned in an object initializer" msgstr "" -#: mcs/mcs/expression.cs:11149 +#: mcs/mcs/expression.cs:11764 #, fuzzy msgid "Expression tree cannot contain a dictionary initializer" msgstr "" "`{0}': Statische Klassen können keine benutzerdefinierten Operatoren " "beinhalten" -#: mcs/mcs/expression.cs:11264 +#: mcs/mcs/expression.cs:11879 #, csharp-format msgid "" "A field or property `{0}' cannot be initialized with a collection object " "initializer because type `{1}' does not implement `{2}' interface" msgstr "" -#: mcs/mcs/expression.cs:11275 +#: mcs/mcs/expression.cs:11890 #, csharp-format msgid "Inconsistent `{0}' member declaration" msgstr "" -#: mcs/mcs/expression.cs:11283 +#: mcs/mcs/expression.cs:11898 #, csharp-format msgid "" "An object initializer includes more than one member `{0}' initialization" msgstr "" -#: mcs/mcs/expression.cs:11301 +#: mcs/mcs/expression.cs:11916 #, csharp-format msgid "Cannot initialize object of type `{0}' with a collection initializer" msgstr "" -#: mcs/mcs/expression.cs:11446 +#: mcs/mcs/expression.cs:12061 msgid "" "Object and collection initializers cannot be used to instantiate a delegate" msgstr "" -#: mcs/mcs/expression.cs:11634 +#: mcs/mcs/expression.cs:12249 msgid "Anonymous types cannot be used in this expression" msgstr "" -#: mcs/mcs/expression.cs:11728 +#: mcs/mcs/expression.cs:12343 #, csharp-format msgid "An anonymous type property `{0}' cannot be initialized with `{1}'" msgstr "" @@ -2298,12 +2332,12 @@ msgid "" "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit" msgstr "" -#: mcs/mcs/field.cs:671 +#: mcs/mcs/field.cs:685 #, csharp-format msgid "`{0}': A volatile field cannot be of the type `{1}'" msgstr "" -#: mcs/mcs/field.cs:676 +#: mcs/mcs/field.cs:690 #, fuzzy, csharp-format msgid "`{0}': A field cannot be both volatile and readonly" msgstr "`{0}' Eine Klasse kann nicht gleichzeitig statisch und versiegelt sein" @@ -2401,35 +2435,35 @@ msgstr "" msgid "The {2} type parameter `{0}' must be {3} valid on `{1}{4}'" msgstr "" -#: mcs/mcs/generic.cs:2205 +#: mcs/mcs/generic.cs:2211 #, csharp-format msgid "`{0}': static classes cannot be used as generic arguments" msgstr "" -#: mcs/mcs/generic.cs:2212 +#: mcs/mcs/generic.cs:2218 #, csharp-format msgid "The type `{0}' may not be used as a type argument" msgstr "" -#: mcs/mcs/generic.cs:2306 +#: mcs/mcs/generic.cs:2312 msgid "Variant type parameters can only be used with interfaces and delegates" msgstr "" -#: mcs/mcs/generic.cs:2375 +#: mcs/mcs/generic.cs:2381 #, csharp-format msgid "" "Partial method declarations of `{0}' have inconsistent constraints for type " "parameter `{1}'" msgstr "" -#: mcs/mcs/generic.cs:2391 +#: mcs/mcs/generic.cs:2397 #, csharp-format msgid "" "Partial declarations of `{0}' have inconsistent constraints for type " "parameter `{1}'" msgstr "" -#: mcs/mcs/generic.cs:2575 +#: mcs/mcs/generic.cs:2581 #, fuzzy, csharp-format msgid "" "The type `{0}' must be a reference type in order to use it as type parameter " @@ -2438,7 +2472,7 @@ msgstr "" "Der Typ `{0}' muss ein Referenztyp sein, damit er als `{1}'-Parameter in " "generischen Typ oder in der generischen Methode `{2}' verwendet werden kann." -#: mcs/mcs/generic.cs:2585 +#: mcs/mcs/generic.cs:2591 #, fuzzy, csharp-format msgid "" "The type `{0}' must be a non-nullable value type in order to use it as type " @@ -2447,14 +2481,14 @@ msgstr "" "Der Typ `{0}' darf keine NULL-Werte zulassen, wenn er als `{1}'-Parameter im " "generischen Typ oder in der generischen Methode `{2}' verwendet werden soll." -#: mcs/mcs/generic.cs:2646 +#: mcs/mcs/generic.cs:2652 #, csharp-format msgid "" "The type `{0}' must have a public parameterless constructor in order to use " "it as parameter `{1}' in the generic type or method `{2}'" msgstr "" -#: mcs/mcs/generic.cs:2702 +#: mcs/mcs/generic.cs:2708 #, fuzzy, csharp-format msgid "" "The type `{0}' cannot be used as type parameter `{1}' in the generic type or " @@ -2464,7 +2498,7 @@ msgstr "" "Der Typ `{0}' muss ein Referenztyp sein, damit er als `{1}'-Parameter in " "generischen Typ oder in der generischen Methode `{2}' verwendet werden kann." -#: mcs/mcs/generic.cs:2708 +#: mcs/mcs/generic.cs:2714 #, fuzzy, csharp-format msgid "" "The type `{0}' cannot be used as type parameter `{1}' in the generic type or " @@ -2474,7 +2508,7 @@ msgstr "" "Der Typ `{0}' muss ein Referenztyp sein, damit er als `{1}'-Parameter in " "generischen Typ oder in der generischen Methode `{2}' verwendet werden kann." -#: mcs/mcs/generic.cs:2712 +#: mcs/mcs/generic.cs:2718 #, fuzzy, csharp-format msgid "" "The type `{0}' cannot be used as type parameter `{1}' in the generic type or " @@ -2483,7 +2517,7 @@ msgstr "" "Der Typ `{0}' muss ein Referenztyp sein, damit er als `{1}'-Parameter in " "generischen Typ oder in der generischen Methode `{2}' verwendet werden kann." -#: mcs/mcs/generic.cs:2717 +#: mcs/mcs/generic.cs:2723 #, fuzzy, csharp-format msgid "" "The type `{0}' cannot be used as type parameter `{1}' in the generic type or " @@ -2492,7 +2526,7 @@ msgstr "" "Der Typ `{0}' muss ein Referenztyp sein, damit er als `{1}'-Parameter in " "generischen Typ oder in der generischen Methode `{2}' verwendet werden kann." -#: mcs/mcs/generic.cs:2722 +#: mcs/mcs/generic.cs:2728 #, fuzzy, csharp-format msgid "" "The type `{0}' cannot be used as type parameter `{1}' in the generic type or " @@ -2536,7 +2570,7 @@ msgstr "" msgid "Iterators cannot have unsafe parameters or yield types" msgstr "" -#: mcs/mcs/iterators.cs:1214 mcs/mcs/statement.cs:6090 +#: mcs/mcs/iterators.cs:1214 mcs/mcs/statement.cs:6148 msgid "Unsafe code may not appear in iterators" msgstr "" @@ -2865,135 +2899,126 @@ msgstr "" msgid "`{0}': Struct constructors cannot call base constructors" msgstr "`{0}': Statische Klassen können keinen Destruktor enthalten" -#: mcs/mcs/method.cs:1516 +#: mcs/mcs/method.cs:1507 #, csharp-format msgid "Constructor `{0}' cannot call itself" msgstr "" -#: mcs/mcs/method.cs:1667 -#, csharp-format -msgid "`{0}': The static constructor must be parameterless" -msgstr "" - -#: mcs/mcs/method.cs:1688 -msgid "Structs cannot contain explicit parameterless constructors" -msgstr "" - -#: mcs/mcs/method.cs:1714 +#: mcs/mcs/method.cs:1693 #, fuzzy, csharp-format msgid "" "`{0}': Structs with primary constructor cannot specify default constructor " "initializer" msgstr "`{0}': Statische Klassen können keinen Destruktor enthalten" -#: mcs/mcs/method.cs:1717 +#: mcs/mcs/method.cs:1696 #, fuzzy, csharp-format msgid "" "`{0}': Instance constructor of type with primary constructor must specify " "`this' constructor initializer" msgstr "`{0}': Statische Klassen können keinen Destruktor enthalten" -#: mcs/mcs/method.cs:1753 +#: mcs/mcs/method.cs:1732 #, csharp-format msgid "" "`{0}': A class with the ComImport attribute cannot have a user-defined " "constructor" msgstr "" -#: mcs/mcs/method.cs:2005 +#: mcs/mcs/method.cs:1984 #, fuzzy, csharp-format msgid "`{0}' is an accessor not found in interface member `{1}{2}'" msgstr "`{0}' implementiert den Schnittstellenmember `{1}' nicht" -#: mcs/mcs/method.cs:2011 +#: mcs/mcs/method.cs:1990 #, csharp-format msgid "" "`{0}.{1}' in explicit interface declaration is not a member of interface" msgstr "" -#: mcs/mcs/method.cs:2019 +#: mcs/mcs/method.cs:1998 #, csharp-format msgid "" "`{0}' explicit method implementation cannot implement `{1}' because it is an " "accessor" msgstr "" -#: mcs/mcs/method.cs:2029 +#: mcs/mcs/method.cs:2008 #, fuzzy, csharp-format msgid "Method `{0}' cannot implement interface accessor `{1}'" msgstr "`{0}' implementiert den Schnittstellenmember `{1}' nicht" -#: mcs/mcs/method.cs:2036 +#: mcs/mcs/method.cs:2015 #, csharp-format msgid "" "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use " "an explicit interface implementation" msgstr "" -#: mcs/mcs/method.cs:2043 +#: mcs/mcs/method.cs:2022 #, fuzzy, csharp-format msgid "" "Accessor `{0}' must be declared public to implement interface member `{1}'" msgstr "`{0}' implementiert den Schnittstellenmember `{1}' nicht" -#: mcs/mcs/method.cs:2063 +#: mcs/mcs/method.cs:2042 #, csharp-format msgid "" "`{0}': the explicit interface implementation cannot introduce the params " "modifier" msgstr "" -#: mcs/mcs/method.cs:2407 +#: mcs/mcs/method.cs:2386 #, csharp-format msgid "" "Attribute `{0}' is not valid on property or event accessors. It is valid on " "`{1}' declarations only" msgstr "" -#: mcs/mcs/method.cs:2640 +#: mcs/mcs/method.cs:2623 #, csharp-format msgid "User-defined operator `{0}' must be declared static and public" msgstr "" -#: mcs/mcs/method.cs:2684 +#: mcs/mcs/method.cs:2667 msgid "" "User-defined operator cannot take an object of the enclosing type and " "convert to an object of the enclosing type" msgstr "" -#: mcs/mcs/method.cs:2695 +#: mcs/mcs/method.cs:2678 msgid "User-defined conversion must convert to or from the enclosing type" msgstr "" -#: mcs/mcs/method.cs:2701 +#: mcs/mcs/method.cs:2684 #, csharp-format msgid "" "User-defined conversion `{0}' cannot convert to or from the dynamic type" msgstr "" -#: mcs/mcs/method.cs:2708 +#: mcs/mcs/method.cs:2691 #, csharp-format msgid "" "User-defined conversion `{0}' cannot convert to or from an interface type" msgstr "" -#: mcs/mcs/method.cs:2715 +#: mcs/mcs/method.cs:2698 #, csharp-format msgid "User-defined conversion `{0}' cannot convert to or from a base class" msgstr "" -#: mcs/mcs/method.cs:2721 +#: mcs/mcs/method.cs:2704 #, csharp-format msgid "User-defined conversion `{0}' cannot convert to or from a derived class" msgstr "" -#: mcs/mcs/method.cs:2728 +#: mcs/mcs/method.cs:2711 msgid "" "Overloaded shift operator must have the type of the first operand be the " "containing type, and the type of the second operand must be int" msgstr "" -#: mcs/mcs/method.cs:2737 +#: mcs/mcs/method.cs:2720 msgid "" "The return type for ++ or -- operator must be the containing type or derived " "from the containing type" @@ -3001,20 +3026,20 @@ msgstr "" "Der Rückgabetyp für die Operatoren ++ und -- muss der enthaltene Typ sein " "oder vom enthaltenen Typ abgeleitet sein" -#: mcs/mcs/method.cs:2742 +#: mcs/mcs/method.cs:2725 msgid "The parameter type for ++ or -- operator must be the containing type" msgstr "Der Parameter für den ++ oder -- Operator muss der enthaltene Typ sein" -#: mcs/mcs/method.cs:2749 +#: mcs/mcs/method.cs:2732 #, fuzzy msgid "The parameter type of a unary operator must be the containing type" msgstr "Der Parameter für den ++ oder -- Operator muss der enthaltene Typ sein" -#: mcs/mcs/method.cs:2757 +#: mcs/mcs/method.cs:2740 msgid "The return type of operator True or False must be bool" msgstr "" -#: mcs/mcs/method.cs:2772 +#: mcs/mcs/method.cs:2755 #, fuzzy msgid "One of the parameters of a binary operator must be the containing type" msgstr "Der Parameter für den ++ oder -- Operator muss der enthaltene Typ sein" @@ -3029,47 +3054,47 @@ msgstr "" msgid "The imported type `{0}' is defined multiple times" msgstr "" -#: mcs/mcs/namespace.cs:748 mcs/mcs/namespace.cs:760 +#: mcs/mcs/namespace.cs:762 mcs/mcs/namespace.cs:774 msgid "" "A using clause must precede all other namespace elements except extern alias " "declarations" msgstr "" -#: mcs/mcs/namespace.cs:776 +#: mcs/mcs/namespace.cs:790 #, csharp-format msgid "The using alias `{0}' appeared previously in this namespace" msgstr "" -#: mcs/mcs/namespace.cs:813 mcs/mcs/namespace.cs:836 +#: mcs/mcs/namespace.cs:827 mcs/mcs/namespace.cs:850 #, csharp-format msgid "The namespace `{0}' already contains a definition for `{1}'" msgstr "" -#: mcs/mcs/namespace.cs:1076 +#: mcs/mcs/namespace.cs:1090 #, csharp-format msgid "Namespace `{0}' contains a definition with same name as alias `{1}'" msgstr "" -#: mcs/mcs/namespace.cs:1129 +#: mcs/mcs/namespace.cs:1143 #, csharp-format msgid "`{0}' is an ambiguous reference between `{1}' and `{2}'" msgstr "" -#: mcs/mcs/namespace.cs:1391 +#: mcs/mcs/namespace.cs:1405 #, csharp-format msgid "" "`{0}' is not a static class. A using namespace directive can only be applied " "to static classes or namespace" msgstr "" -#: mcs/mcs/namespace.cs:1400 +#: mcs/mcs/namespace.cs:1414 #, csharp-format msgid "" "`{0}' is a type not a namespace. A using namespace directive can only be " "applied to namespaces" msgstr "" -#: mcs/mcs/namespace.cs:1423 +#: mcs/mcs/namespace.cs:1437 #, csharp-format msgid "The extern alias `{0}' was not specified in -reference option" msgstr "" @@ -3357,7 +3382,7 @@ msgstr "" msgid "Cannot set the `IndexerName' attribute on an indexer marked override" msgstr "" -#: mcs/mcs/module.cs:338 +#: mcs/mcs/module.cs:473 #, csharp-format msgid "Value specified for the argument to `{0}' is not valid" msgstr "" @@ -3453,7 +3478,7 @@ msgid "" "clause nested inside of the innermost catch clause" msgstr "" -#: mcs/mcs/statement.cs:1806 mcs/mcs/statement.cs:6623 +#: mcs/mcs/statement.cs:1806 mcs/mcs/statement.cs:6681 msgid "The type caught or thrown must be derived from System.Exception" msgstr "" @@ -3536,51 +3561,51 @@ msgstr "" msgid "`{0}': not all code paths return a value" msgstr "" -#: mcs/mcs/statement.cs:4532 +#: mcs/mcs/statement.cs:4546 #, csharp-format msgid "The label `{0}' already occurs in this switch statement" msgstr "" -#: mcs/mcs/statement.cs:4659 +#: mcs/mcs/statement.cs:4673 #, csharp-format msgid "" "Control cannot fall out of switch statement through final case label `{0}'" msgstr "" -#: mcs/mcs/statement.cs:4662 +#: mcs/mcs/statement.cs:4676 #, csharp-format msgid "Control cannot fall through from one case label `{0}' to another" msgstr "" -#: mcs/mcs/statement.cs:5072 +#: mcs/mcs/statement.cs:5113 #, csharp-format msgid "" "A switch expression of type `{0}' cannot be converted to an integral type, " "bool, char, string, enum or nullable type" msgstr "" -#: mcs/mcs/statement.cs:5856 +#: mcs/mcs/statement.cs:5914 #, csharp-format msgid "`{0}' is not a reference type as required by the lock statement" msgstr "" -#: mcs/mcs/statement.cs:6237 +#: mcs/mcs/statement.cs:6295 msgid "The type of locals declared in a fixed statement must be a pointer type" msgstr "" -#: mcs/mcs/statement.cs:6253 +#: mcs/mcs/statement.cs:6311 msgid "" "The right hand side of a fixed statement assignment may not be a cast " "expression" msgstr "" -#: mcs/mcs/statement.cs:6323 +#: mcs/mcs/statement.cs:6381 msgid "" "You cannot use the fixed statement to take the address of an already fixed " "expression" msgstr "" -#: mcs/mcs/statement.cs:6484 +#: mcs/mcs/statement.cs:6542 #, fuzzy msgid "" "The `await' operator cannot be used in the filter expression of a catch " @@ -3589,28 +3614,28 @@ msgstr "" "Die `new()'-Einschränkung kann nicht mit der `struct'-Einschränkung genutzt " "werden" -#: mcs/mcs/statement.cs:7056 +#: mcs/mcs/statement.cs:7114 #, csharp-format msgid "" "A previous catch clause already catches all exceptions of this or a super " "type `{0}'" msgstr "" -#: mcs/mcs/statement.cs:7285 +#: mcs/mcs/statement.cs:7343 #, csharp-format msgid "" "`{0}': type used in a using statement must be implicitly convertible to " "`System.IDisposable'" msgstr "" -#: mcs/mcs/statement.cs:7697 +#: mcs/mcs/statement.cs:7755 #, csharp-format msgid "" "foreach statement requires that the return type `{0}' of `{1}' must have a " "suitable public MoveNext method and public Current property" msgstr "" -#: mcs/mcs/statement.cs:7741 +#: mcs/mcs/statement.cs:7799 #, csharp-format msgid "" "foreach statement cannot operate on variables of type `{0}' because it " @@ -3618,18 +3643,18 @@ msgid "" "implementation" msgstr "" -#: mcs/mcs/statement.cs:7763 +#: mcs/mcs/statement.cs:7821 #, csharp-format msgid "" "foreach statement cannot operate on variables of type `{0}' because it does " "not contain a definition for `{1}' or is inaccessible" msgstr "" -#: mcs/mcs/statement.cs:7998 +#: mcs/mcs/statement.cs:8056 msgid "Use of null is not valid in this context" msgstr "" -#: mcs/mcs/statement.cs:8010 +#: mcs/mcs/statement.cs:8068 #, csharp-format msgid "Foreach statement cannot operate on a `{0}'" msgstr "" @@ -3672,9 +3697,6 @@ msgid "" "managed type `{0}'" msgstr "" -#~ msgid "`{0}': Structs cannot have instance field initializers" -#~ msgstr "`{0}': Instanzfeldinitialisierungen können nicht in Strukturen sein" - #~ msgid "" #~ "The type or namespace name `{0}' could not be found. Are you missing a " #~ "using directive or an assembly reference?" diff --git a/po/mcs/es.gmo b/po/mcs/es.gmo index 5d4cb8646d..9cd3f38f71 100644 Binary files a/po/mcs/es.gmo and b/po/mcs/es.gmo differ diff --git a/po/mcs/es.po.REMOVED.git-id b/po/mcs/es.po.REMOVED.git-id index f1fd225f3e..bd60c1bc8f 100644 --- a/po/mcs/es.po.REMOVED.git-id +++ b/po/mcs/es.po.REMOVED.git-id @@ -1 +1 @@ -3570b86595a878b0745b54f3ccc72637434cc3b1 \ No newline at end of file +ec0c928a96fed6ffc6899065f084b1f712755b7a \ No newline at end of file diff --git a/po/mcs/ja.gmo b/po/mcs/ja.gmo index fc76c0dd15..82971a8745 100644 Binary files a/po/mcs/ja.gmo and b/po/mcs/ja.gmo differ diff --git a/po/mcs/ja.po.REMOVED.git-id b/po/mcs/ja.po.REMOVED.git-id index 9004b7498d..333e62463a 100644 --- a/po/mcs/ja.po.REMOVED.git-id +++ b/po/mcs/ja.po.REMOVED.git-id @@ -1 +1 @@ -911d9deefe1097825008605487e04b73096bf784 \ No newline at end of file +599d51ddc4936d374e21ae07a35117d56fb34385 \ No newline at end of file diff --git a/po/mcs/mcs.pot b/po/mcs/mcs.pot index 8b991cf865..fb78e38d9f 100644 --- a/po/mcs/mcs.pot +++ b/po/mcs/mcs.pot @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: mono 3.10.0\n" +"Project-Id-Version: mono 3.12.0\n" "Report-Msgid-Bugs-To: http://www.mono-project.com/Bugs\n" -"POT-Creation-Date: 2014-10-04 10:45+0100\n" +"POT-Creation-Date: 2015-01-12 17:26+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -34,7 +34,7 @@ msgid "" "mismatch" msgstr "" -#: mcs/mcs/anonymous.cs:1054 mcs/mcs/ecore.cs:5630 +#: mcs/mcs/anonymous.cs:1054 mcs/mcs/ecore.cs:5670 #, csharp-format msgid "Delegate `{0}' does not take `{1}' arguments" msgstr "" @@ -91,7 +91,7 @@ msgstr "" msgid "An expression tree cannot contain an anonymous method expression" msgstr "" -#: mcs/mcs/anonymous.cs:2023 +#: mcs/mcs/anonymous.cs:2021 #, csharp-format msgid "" "`{0}': An anonymous type cannot have multiple properties with the same name" @@ -413,47 +413,53 @@ msgstr "" msgid "Duplicate named attribute `{0}' argument" msgstr "" -#: mcs/mcs/attribute.cs:860 +#: mcs/mcs/attribute.cs:859 +#, csharp-format +msgid "" +"First argument of a security attribute `{0}' must be a valid SecurityAction" +msgstr "" + +#: mcs/mcs/attribute.cs:864 #, csharp-format msgid "Security attribute `{0}' has an invalid SecurityAction value `{1}'" msgstr "" -#: mcs/mcs/attribute.cs:867 +#: mcs/mcs/attribute.cs:871 #, csharp-format msgid "" "SecurityAction value `{0}' is invalid for security attributes applied to an " "assembly" msgstr "" -#: mcs/mcs/attribute.cs:871 +#: mcs/mcs/attribute.cs:875 #, csharp-format msgid "" "SecurityAction value `{0}' is invalid for security attributes applied to a " "type or a method" msgstr "" -#: mcs/mcs/attribute.cs:1018 +#: mcs/mcs/attribute.cs:1043 #, csharp-format msgid "" "The attribute `{0}' is not valid on this declaration type. It is valid on " "`{1}' declarations only" msgstr "" -#: mcs/mcs/attribute.cs:1040 +#: mcs/mcs/attribute.cs:1065 #, csharp-format msgid "The argument to the `{0}' attribute must be a valid identifier" msgstr "" -#: mcs/mcs/attribute.cs:1059 +#: mcs/mcs/attribute.cs:1084 msgid "Unmanaged type `ByValArray' is only valid for fields" msgstr "" -#: mcs/mcs/attribute.cs:1320 +#: mcs/mcs/attribute.cs:1345 #, csharp-format msgid "The attribute `{0}' cannot be applied multiple times" msgstr "" -#: mcs/mcs/attribute.cs:1626 +#: mcs/mcs/attribute.cs:1651 #, csharp-format msgid "`{0}' is obsolete: `{1}'" msgstr "" @@ -464,112 +470,112 @@ msgid "" "`struct', `interface', or `void' keyword" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:1589 mcs/mcs/cs-tokenizer.cs:1652 +#: mcs/mcs/cs-tokenizer.cs:1597 mcs/mcs/cs-tokenizer.cs:1660 msgid "Invalid number" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:1867 +#: mcs/mcs/cs-tokenizer.cs:1875 #, csharp-format msgid "Unrecognized escape sequence `\\{0}'" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:1886 +#: mcs/mcs/cs-tokenizer.cs:1894 msgid "Unrecognized escape sequence" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2151 +#: mcs/mcs/cs-tokenizer.cs:2159 msgid "Filename, single-line comment or end-of-line expected" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2199 +#: mcs/mcs/cs-tokenizer.cs:2207 msgid "Missing identifier to pre-processor directive" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2209 mcs/mcs/cs-tokenizer.cs:2213 +#: mcs/mcs/cs-tokenizer.cs:2217 mcs/mcs/cs-tokenizer.cs:2221 #, csharp-format msgid "Identifier expected: {0}" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2721 +#: mcs/mcs/cs-tokenizer.cs:2729 msgid "Integral constant is too large" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2726 +#: mcs/mcs/cs-tokenizer.cs:2734 msgid "Invalid preprocessor directive" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2733 +#: mcs/mcs/cs-tokenizer.cs:2741 #, csharp-format msgid "Unexpected processor directive ({0})" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2739 +#: mcs/mcs/cs-tokenizer.cs:2747 msgid "" "Cannot define or undefine preprocessor symbols after first token in file" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2745 +#: mcs/mcs/cs-tokenizer.cs:2753 msgid "" "Preprocessor directives must appear as the first non-whitespace character on " "a line" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2750 +#: mcs/mcs/cs-tokenizer.cs:2758 msgid "Single-line comment or end-of-line expected" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2795 mcs/mcs/cs-tokenizer.cs:3832 +#: mcs/mcs/cs-tokenizer.cs:2803 mcs/mcs/cs-tokenizer.cs:3840 msgid "Expected `#endif' directive" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2828 mcs/mcs/cs-tokenizer.cs:2849 -#: mcs/mcs/cs-tokenizer.cs:2880 mcs/mcs/cs-tokenizer.cs:3830 +#: mcs/mcs/cs-tokenizer.cs:2836 mcs/mcs/cs-tokenizer.cs:2857 +#: mcs/mcs/cs-tokenizer.cs:2888 mcs/mcs/cs-tokenizer.cs:3838 msgid "#endregion directive expected" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2929 +#: mcs/mcs/cs-tokenizer.cs:2937 msgid "Wrong preprocessor directive" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2941 +#: mcs/mcs/cs-tokenizer.cs:2949 #, csharp-format msgid "#error: '{0}'" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:2959 +#: mcs/mcs/cs-tokenizer.cs:2967 msgid "The line number specified for #line directive is missing or invalid" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:3021 mcs/mcs/cs-tokenizer.cs:3673 +#: mcs/mcs/cs-tokenizer.cs:3029 mcs/mcs/cs-tokenizer.cs:3681 msgid "Newline in constant" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:3048 +#: mcs/mcs/cs-tokenizer.cs:3056 msgid "Unterminated string literal" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:3125 +#: mcs/mcs/cs-tokenizer.cs:3133 msgid "Identifier too long (limit is 512 chars)" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:3511 +#: mcs/mcs/cs-tokenizer.cs:3519 msgid "End-of-file found, '*/' expected" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:3622 +#: mcs/mcs/cs-tokenizer.cs:3630 msgid "Keyword, identifier, or string expected after verbatim specifier: @" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:3643 +#: mcs/mcs/cs-tokenizer.cs:3651 #, csharp-format msgid "Unexpected character `{0}'" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:3668 +#: mcs/mcs/cs-tokenizer.cs:3676 msgid "Empty character literal" msgstr "" -#: mcs/mcs/cs-tokenizer.cs:3689 +#: mcs/mcs/cs-tokenizer.cs:3697 msgid "Too many characters in character literal" msgstr "" @@ -577,7 +583,7 @@ msgstr "" msgid "The operation overflows at compile time in checked mode" msgstr "" -#: mcs/mcs/cfold.cs:329 mcs/mcs/expression.cs:4291 +#: mcs/mcs/cfold.cs:329 mcs/mcs/expression.cs:4927 #, csharp-format msgid "Operator `{0}' is ambiguous on operands of type `{1}' and `{2}'" msgstr "" @@ -645,421 +651,419 @@ msgstr "" msgid "The RequiredAttribute attribute is not permitted on C# types" msgstr "" -#: mcs/mcs/class.cs:1155 +#: mcs/mcs/class.cs:981 +#, csharp-format +msgid "'{0}': Structs cannot have instance property or field initializers" +msgstr "" + +#: mcs/mcs/class.cs:1162 #, csharp-format msgid "Class `{0}' cannot derive from the dynamic type" msgstr "" -#: mcs/mcs/class.cs:1172 +#: mcs/mcs/class.cs:1179 #, csharp-format msgid "`{0}' is already listed in interface list" msgstr "" -#: mcs/mcs/class.cs:1180 +#: mcs/mcs/class.cs:1187 #, csharp-format msgid "" "Inconsistent accessibility: base interface `{0}' is less accessible than " "interface `{1}'" msgstr "" -#: mcs/mcs/class.cs:1186 +#: mcs/mcs/class.cs:1193 #, csharp-format msgid "Type `{0}' in interface list is not an interface" msgstr "" -#: mcs/mcs/class.cs:1188 +#: mcs/mcs/class.cs:1195 #, csharp-format msgid "`{0}': Classes cannot have multiple base classes (`{1}' and `{2}')" msgstr "" -#: mcs/mcs/class.cs:1191 +#: mcs/mcs/class.cs:1198 #, csharp-format msgid "`{0}': Base class `{1}' must be specified as first" msgstr "" -#: mcs/mcs/class.cs:1252 +#: mcs/mcs/class.cs:1259 #, csharp-format msgid "" "The operator `{0}' requires a matching operator `{1}' to also be defined" msgstr "" -#: mcs/mcs/class.cs:1507 +#: mcs/mcs/class.cs:1526 #, csharp-format msgid "Partial declarations of `{0}' must not specify different base classes" msgstr "" -#: mcs/mcs/class.cs:1542 +#: mcs/mcs/class.cs:1561 msgid "" "Only one part of a partial type can declare primary constructor parameters" msgstr "" -#: mcs/mcs/class.cs:1559 +#: mcs/mcs/class.cs:1578 #, csharp-format msgid "" "Inherited interface `{0}' causes a cycle in the interface hierarchy of `{1}'" msgstr "" -#: mcs/mcs/class.cs:1566 +#: mcs/mcs/class.cs:1585 #, csharp-format msgid "Circular base class dependency involving `{0}' and `{1}'" msgstr "" -#: mcs/mcs/class.cs:1576 +#: mcs/mcs/class.cs:1595 msgid "Implemented interfaces cannot have arguments" msgstr "" -#: mcs/mcs/class.cs:1905 +#: mcs/mcs/class.cs:1924 #, csharp-format msgid "`{0}': cannot implement a dynamic interface `{1}'" msgstr "" -#: mcs/mcs/class.cs:1920 +#: mcs/mcs/class.cs:1939 #, csharp-format msgid "" "`{0}' cannot implement both `{1}' and `{2}' because they may unify for some " "type parameter substitutions" msgstr "" -#: mcs/mcs/class.cs:1944 +#: mcs/mcs/class.cs:1963 #, csharp-format msgid "" "A generic type cannot derive from `{0}' because it is an attribute class" msgstr "" -#: mcs/mcs/class.cs:2048 +#: mcs/mcs/class.cs:2067 msgid "" "Two indexers have different names; the IndexerName attribute must be used " "with the same name on every indexer within a type" msgstr "" -#: mcs/mcs/class.cs:2306 +#: mcs/mcs/class.cs:2325 #, csharp-format msgid "A static member `{0}' cannot be marked as override, virtual or abstract" msgstr "" -#: mcs/mcs/class.cs:2313 +#: mcs/mcs/class.cs:2332 #, csharp-format msgid "A member `{0}' marked as override cannot be marked as new or virtual" msgstr "" -#: mcs/mcs/class.cs:2325 +#: mcs/mcs/class.cs:2344 #, csharp-format msgid "`{0}' cannot be both extern and abstract" msgstr "" -#: mcs/mcs/class.cs:2330 +#: mcs/mcs/class.cs:2349 #, csharp-format msgid "`{0}' cannot be both abstract and sealed" msgstr "" -#: mcs/mcs/class.cs:2335 +#: mcs/mcs/class.cs:2354 #, csharp-format msgid "The abstract method `{0}' cannot be marked virtual" msgstr "" -#: mcs/mcs/class.cs:2341 +#: mcs/mcs/class.cs:2360 #, csharp-format msgid "`{0}' is abstract but it is declared in the non-abstract class `{1}'" msgstr "" -#: mcs/mcs/class.cs:2349 +#: mcs/mcs/class.cs:2368 #, csharp-format msgid "`{0}': virtual or abstract members cannot be private" msgstr "" -#: mcs/mcs/class.cs:2356 +#: mcs/mcs/class.cs:2375 #, csharp-format msgid "`{0}' cannot be sealed because it is not an override" msgstr "" -#: mcs/mcs/class.cs:2405 +#: mcs/mcs/class.cs:2424 #, csharp-format msgid "`{0}': containing type does not implement interface `{1}'" msgstr "" -#: mcs/mcs/class.cs:2602 +#: mcs/mcs/class.cs:2621 #, csharp-format msgid "Type parameter `{0}' has same name as containing type, or method" msgstr "" -#: mcs/mcs/class.cs:2610 +#: mcs/mcs/class.cs:2629 #, csharp-format msgid "`{0}': member names cannot be the same as their enclosing type" msgstr "" -#: mcs/mcs/class.cs:2685 +#: mcs/mcs/class.cs:2707 #, csharp-format msgid "" "Primary constructor of type `{0}' has parameter of same name as containing " "type" msgstr "" -#: mcs/mcs/class.cs:2693 +#: mcs/mcs/class.cs:2715 #, csharp-format msgid "" "Primary constructor of type `{0}' has parameter of same name as type " "parameter `{1}'" msgstr "" -#: mcs/mcs/class.cs:2759 +#: mcs/mcs/class.cs:2781 msgid "" "The class System.Object cannot have a base class or implement an interface." msgstr "" -#: mcs/mcs/class.cs:2768 +#: mcs/mcs/class.cs:2790 #, csharp-format msgid "Attribute `{0}' is only valid on classes derived from System.Attribute" msgstr "" -#: mcs/mcs/class.cs:2773 +#: mcs/mcs/class.cs:2795 msgid "" "Attribute `System.Diagnostics.ConditionalAttribute' is only valid on methods " "or attribute classes" msgstr "" -#: mcs/mcs/class.cs:2802 +#: mcs/mcs/class.cs:2824 #, csharp-format msgid "`{0}': an abstract class cannot be sealed or static" msgstr "" -#: mcs/mcs/class.cs:2806 +#: mcs/mcs/class.cs:2828 #, csharp-format msgid "`{0}': a class cannot be both static and sealed" msgstr "" -#: mcs/mcs/class.cs:2811 +#: mcs/mcs/class.cs:2833 #, csharp-format msgid "`{0}': Static classes cannot have primary constructor" msgstr "" -#: mcs/mcs/class.cs:2817 +#: mcs/mcs/class.cs:2839 #, csharp-format msgid "`{0}': Static classes cannot contain user-defined operators" msgstr "" -#: mcs/mcs/class.cs:2822 +#: mcs/mcs/class.cs:2844 #, csharp-format msgid "`{0}': Static classes cannot contain destructor" msgstr "" -#: mcs/mcs/class.cs:2827 +#: mcs/mcs/class.cs:2849 #, csharp-format msgid "`{0}': cannot declare indexers in a static class" msgstr "" -#: mcs/mcs/class.cs:2835 +#: mcs/mcs/class.cs:2857 #, csharp-format msgid "`{0}': Static classes cannot have instance constructors" msgstr "" -#: mcs/mcs/class.cs:2839 +#: mcs/mcs/class.cs:2861 #, csharp-format msgid "`{0}': cannot declare instance members in a static class" msgstr "" -#: mcs/mcs/class.cs:2881 +#: mcs/mcs/class.cs:2903 #, csharp-format msgid "`{0}': Cannot derive from type parameter `{1}'" msgstr "" -#: mcs/mcs/class.cs:2885 +#: mcs/mcs/class.cs:2907 #, csharp-format msgid "`{0}': Cannot derive from static class `{1}'" msgstr "" -#: mcs/mcs/class.cs:2889 +#: mcs/mcs/class.cs:2911 #, csharp-format msgid "`{0}': cannot derive from sealed type `{1}'" msgstr "" -#: mcs/mcs/class.cs:2892 +#: mcs/mcs/class.cs:2914 #, csharp-format msgid "" "Static class `{0}' cannot derive from type `{1}'. Static classes must derive " "from object" msgstr "" -#: mcs/mcs/class.cs:2903 +#: mcs/mcs/class.cs:2925 #, csharp-format msgid "`{0}' cannot derive from special class `{1}'" msgstr "" -#: mcs/mcs/class.cs:2913 +#: mcs/mcs/class.cs:2935 #, csharp-format msgid "" "Inconsistent accessibility: base class `{0}' is less accessible than class " "`{1}'" msgstr "" -#: mcs/mcs/class.cs:2921 +#: mcs/mcs/class.cs:2943 #, csharp-format msgid "Static class `{0}' cannot implement interfaces" msgstr "" -#: mcs/mcs/class.cs:3032 mcs/mcs/class.cs:3046 +#: mcs/mcs/class.cs:3054 mcs/mcs/class.cs:3068 #, csharp-format msgid "Struct member `{0}' of type `{1}' causes a cycle in the struct layout" msgstr "" -#: mcs/mcs/class.cs:3150 -#, csharp-format -msgid "" -"`{0}': Structs without explicit constructors cannot contain members with " -"initializers" -msgstr "" - -#: mcs/mcs/class.cs:3339 +#: mcs/mcs/class.cs:3353 #, csharp-format msgid "Do not override `{0}'. Use destructor syntax instead" msgstr "" -#: mcs/mcs/class.cs:3342 +#: mcs/mcs/class.cs:3356 #, csharp-format msgid "`{0}' is marked as an override but no suitable {1} found to override" msgstr "" -#: mcs/mcs/class.cs:3348 +#: mcs/mcs/class.cs:3362 #, csharp-format msgid "`{0}': cannot override because `{1}' is not an event" msgstr "" -#: mcs/mcs/class.cs:3351 +#: mcs/mcs/class.cs:3365 #, csharp-format msgid "`{0}': cannot override because `{1}' is not a property" msgstr "" -#: mcs/mcs/class.cs:3354 +#: mcs/mcs/class.cs:3368 #, csharp-format msgid "`{0}': cannot override because `{1}' is not a method" msgstr "" -#: mcs/mcs/class.cs:3373 +#: mcs/mcs/class.cs:3387 #, csharp-format msgid "" "`{0}' cannot override inherited members `{1}' and `{2}' because they have " "the same signature when used in type `{3}'" msgstr "" -#: mcs/mcs/class.cs:3426 mcs/mcs/field.cs:203 +#: mcs/mcs/class.cs:3440 mcs/mcs/field.cs:203 #, csharp-format msgid "`{0}' hides inherited abstract member `{1}'" msgstr "" -#: mcs/mcs/class.cs:3450 +#: mcs/mcs/class.cs:3464 #, csharp-format msgid "" "`{0}': cannot override inherited member `{1}' because it is not marked " "virtual, abstract or override" msgstr "" -#: mcs/mcs/class.cs:3458 +#: mcs/mcs/class.cs:3472 #, csharp-format msgid "`{0}': cannot override inherited member `{1}' because it is sealed" msgstr "" -#: mcs/mcs/class.cs:3467 +#: mcs/mcs/class.cs:3481 #, csharp-format msgid "`{0}': type must be `{1}' to match overridden member `{2}'" msgstr "" -#: mcs/mcs/class.cs:3470 +#: mcs/mcs/class.cs:3484 #, csharp-format msgid "`{0}': return type must be `{1}' to match overridden member `{2}'" msgstr "" -#: mcs/mcs/class.cs:3538 +#: mcs/mcs/class.cs:3552 #, csharp-format msgid "A partial method `{0}' cannot explicitly implement an interface" msgstr "" -#: mcs/mcs/class.cs:3544 +#: mcs/mcs/class.cs:3558 #, csharp-format msgid "The type `{0}' in explicit interface declaration is not an interface" msgstr "" -#: mcs/mcs/class.cs:3579 +#: mcs/mcs/class.cs:3593 #, csharp-format msgid "" "Inconsistent accessibility: parameter type `{0}' is less accessible than " "indexer `{1}'" msgstr "" -#: mcs/mcs/class.cs:3583 +#: mcs/mcs/class.cs:3597 #, csharp-format msgid "" "Inconsistent accessibility: parameter type `{0}' is less accessible than " "operator `{1}'" msgstr "" -#: mcs/mcs/class.cs:3587 +#: mcs/mcs/class.cs:3601 #, csharp-format msgid "" "Inconsistent accessibility: parameter type `{0}' is less accessible than " "method `{1}'" msgstr "" -#: mcs/mcs/class.cs:3647 +#: mcs/mcs/class.cs:3661 #, csharp-format msgid "" "`{0}': cannot change access modifiers when overriding `{1}' inherited member " "`{2}'" msgstr "" -#: mcs/mcs/class.cs:3656 +#: mcs/mcs/class.cs:3670 #, csharp-format msgid "`{0}': static types cannot be used as return types" msgstr "" -#: mcs/mcs/class.cs:3717 +#: mcs/mcs/class.cs:3731 #, csharp-format msgid "" "`{0}': Cannot specify constraints for overrides and explicit interface " "implementation methods" msgstr "" -#: mcs/mcs/class.cs:3781 +#: mcs/mcs/class.cs:3795 #, csharp-format msgid "New virtual member `{0}' is declared in a sealed class `{1}'" msgstr "" -#: mcs/mcs/class.cs:3796 +#: mcs/mcs/class.cs:3810 msgid "Inconsistent accessibility: property type `" msgstr "" -#: mcs/mcs/class.cs:3801 +#: mcs/mcs/class.cs:3815 msgid "Inconsistent accessibility: indexer return type `" msgstr "" -#: mcs/mcs/class.cs:3807 mcs/mcs/class.cs:3812 mcs/mcs/delegate.cs:171 +#: mcs/mcs/class.cs:3821 mcs/mcs/class.cs:3826 mcs/mcs/delegate.cs:171 msgid "Inconsistent accessibility: return type `" msgstr "" -#: mcs/mcs/class.cs:3817 +#: mcs/mcs/class.cs:3831 #, csharp-format msgid "" "Inconsistent accessibility: event type `{0}' is less accessible than event " "`{1}'" msgstr "" -#: mcs/mcs/class.cs:3821 +#: mcs/mcs/class.cs:3835 msgid "Inconsistent accessibility: field type `" msgstr "" -#: mcs/mcs/class.cs:3833 +#: mcs/mcs/class.cs:3847 #, csharp-format msgid "" "Parameters or local variables of type `{0}' cannot be declared in async " "methods or iterators" msgstr "" -#: mcs/mcs/class.cs:3837 +#: mcs/mcs/class.cs:3851 #, csharp-format msgid "" "Local variables of type `{0}' cannot be used inside anonymous methods, " "lambda expressions or query expressions" msgstr "" -#: mcs/mcs/class.cs:3841 +#: mcs/mcs/class.cs:3855 #, csharp-format msgid "Field or property cannot be of type `{0}'" msgstr "" @@ -1234,7 +1238,11 @@ msgstr "" msgid "An expression tree cannot contain a dynamic operation" msgstr "" -#: mcs/mcs/dynamic.cs:311 +#: mcs/mcs/dynamic.cs:295 +msgid "Declaration expression cannot be used in this context" +msgstr "" + +#: mcs/mcs/dynamic.cs:318 msgid "" "Dynamic operation cannot be compiled without `Microsoft.CSharp.dll' assembly " "reference" @@ -1301,231 +1309,232 @@ msgstr "" msgid "The operation in question is undefined on void pointers" msgstr "" -#: mcs/mcs/ecore.cs:517 mcs/mcs/statement.cs:3908 mcs/mcs/statement.cs:3910 +#: mcs/mcs/ecore.cs:519 mcs/mcs/statement.cs:3908 mcs/mcs/statement.cs:3910 #, csharp-format msgid "Internal compiler error: {0}" msgstr "" -#: mcs/mcs/ecore.cs:579 mcs/mcs/expression.cs:7260 mcs/mcs/expression.cs:7268 +#: mcs/mcs/ecore.cs:581 mcs/mcs/expression.cs:1825 mcs/mcs/expression.cs:7868 +#: mcs/mcs/expression.cs:7876 msgid "A constant value is expected" msgstr "" -#: mcs/mcs/ecore.cs:591 +#: mcs/mcs/ecore.cs:593 msgid "" "An attribute argument must be a constant expression, typeof expression or " "array creation expression" msgstr "" -#: mcs/mcs/ecore.cs:594 +#: mcs/mcs/ecore.cs:596 #, csharp-format msgid "" "Attribute constructor parameter has type `{0}', which is not a valid " "attribute parameter type" msgstr "" -#: mcs/mcs/ecore.cs:779 +#: mcs/mcs/ecore.cs:785 #, csharp-format msgid "The class `{0}' has no constructors defined" msgstr "" -#: mcs/mcs/ecore.cs:980 +#: mcs/mcs/ecore.cs:998 #, csharp-format msgid "The `{0}' operator cannot be applied to operand of type `{1}'" msgstr "" -#: mcs/mcs/ecore.cs:986 +#: mcs/mcs/ecore.cs:1004 msgid "An expression tree cannot contain an unsafe pointer operation" msgstr "" -#: mcs/mcs/ecore.cs:991 +#: mcs/mcs/ecore.cs:1009 msgid "An expression tree cannot contain a null propagating operator" msgstr "" -#: mcs/mcs/ecore.cs:1083 +#: mcs/mcs/ecore.cs:1105 #, csharp-format msgid "`{0}' is a `{1}' but a `{2}' was expected" msgstr "" -#: mcs/mcs/ecore.cs:1116 +#: mcs/mcs/ecore.cs:1138 #, csharp-format msgid "Expression denotes a `{0}', where a `{1}' was expected" msgstr "" -#: mcs/mcs/ecore.cs:1126 +#: mcs/mcs/ecore.cs:1148 msgid "Pointers and fixed size buffers may only be used in an unsafe context" msgstr "" -#: mcs/mcs/ecore.cs:2546 +#: mcs/mcs/ecore.cs:2568 msgid "Unbound generic name is not valid in this context" msgstr "" -#: mcs/mcs/ecore.cs:2623 +#: mcs/mcs/ecore.cs:2645 #, csharp-format msgid "The name `{0}' does not exist in the current context" msgstr "" -#: mcs/mcs/ecore.cs:2700 +#: mcs/mcs/ecore.cs:2722 #, csharp-format msgid "" "Dynamic keyword requires `{0}' to be defined. Are you missing System.Core." "dll assembly reference?" msgstr "" -#: mcs/mcs/ecore.cs:2776 +#: mcs/mcs/ecore.cs:2798 #, csharp-format msgid "" "A local variable `{0}' cannot be used before it is declared. Consider " "renaming the local variable when it hides the member `{1}'" msgstr "" -#: mcs/mcs/ecore.cs:2791 mcs/mcs/ecore.cs:2834 +#: mcs/mcs/ecore.cs:2813 mcs/mcs/ecore.cs:2856 #, csharp-format msgid "`{0}' conflicts with a declaration in a child block" msgstr "" -#: mcs/mcs/ecore.cs:2855 +#: mcs/mcs/ecore.cs:2877 #, csharp-format msgid "A local variable `{0}' cannot be used before it is declared" msgstr "" -#: mcs/mcs/ecore.cs:3008 +#: mcs/mcs/ecore.cs:3030 msgid "System.Void cannot be used from C#. Consider using `void'" msgstr "" -#: mcs/mcs/ecore.cs:3171 +#: mcs/mcs/ecore.cs:3193 #, csharp-format msgid "" "The type or namespace name `{0}' could not be found in the global namespace. " "Are you missing {1} assembly reference?" msgstr "" -#: mcs/mcs/ecore.cs:3175 +#: mcs/mcs/ecore.cs:3197 #, csharp-format msgid "" "The type or namespace name `{0}' does not exist in the namespace `{1}'. Are " "you missing {2} assembly reference?" msgstr "" -#: mcs/mcs/ecore.cs:3424 +#: mcs/mcs/ecore.cs:3446 #, csharp-format msgid "Cannot call an abstract base member `{0}'" msgstr "" -#: mcs/mcs/ecore.cs:3431 +#: mcs/mcs/ecore.cs:3453 #, csharp-format msgid "" "Cannot access protected member `{0}' via a qualifier of type `{1}'. The " "qualifier must be of type `{2}' or derived from it" msgstr "" -#: mcs/mcs/ecore.cs:3471 +#: mcs/mcs/ecore.cs:3493 #, csharp-format msgid "" "Fields of static readonly field `{0}' cannot be assigned to (except in a " "static constructor or a variable initializer)" msgstr "" -#: mcs/mcs/ecore.cs:3474 +#: mcs/mcs/ecore.cs:3496 #, csharp-format msgid "" "Members of readonly field `{0}' cannot be modified (except in a constructor " "or a variable initializer)" msgstr "" -#: mcs/mcs/ecore.cs:3483 +#: mcs/mcs/ecore.cs:3505 #, csharp-format msgid "" "Members of value type `{0}' cannot be assigned using a property `{1}' object " "initializer" msgstr "" -#: mcs/mcs/ecore.cs:3487 +#: mcs/mcs/ecore.cs:3509 #, csharp-format msgid "" "Cannot modify a value type return value of `{0}'. Consider storing the value " "in a temporary variable" msgstr "" -#: mcs/mcs/ecore.cs:3500 +#: mcs/mcs/ecore.cs:3522 #, csharp-format msgid "Cannot assign to members of `{0}' because it is a `{1}'" msgstr "" -#: mcs/mcs/ecore.cs:3526 +#: mcs/mcs/ecore.cs:3548 #, csharp-format msgid "" "Static member `{0}' cannot be accessed with an instance reference, qualify " "it with a type name instead" msgstr "" -#: mcs/mcs/ecore.cs:3541 +#: mcs/mcs/ecore.cs:3563 #, csharp-format msgid "" "A field initializer cannot reference the nonstatic field, method, or " "property `{0}'" msgstr "" -#: mcs/mcs/ecore.cs:3547 +#: mcs/mcs/ecore.cs:3569 msgid "Constructor initializer cannot access primary constructor parameters" msgstr "" -#: mcs/mcs/ecore.cs:3549 +#: mcs/mcs/ecore.cs:3571 #, csharp-format msgid "" "An object reference is required to access primary constructor parameter `{0}'" msgstr "" -#: mcs/mcs/ecore.cs:3554 +#: mcs/mcs/ecore.cs:3576 #, csharp-format msgid "An object reference is required to access non-static member `{0}'" msgstr "" -#: mcs/mcs/ecore.cs:3565 +#: mcs/mcs/ecore.cs:3587 #, csharp-format msgid "" "Cannot access a nonstatic member of outer type `{0}' via nested type `{1}'" msgstr "" -#: mcs/mcs/ecore.cs:3593 +#: mcs/mcs/ecore.cs:3615 msgid "Cannot modify the result of an unboxing conversion" msgstr "" -#: mcs/mcs/ecore.cs:3762 +#: mcs/mcs/ecore.cs:3784 #, csharp-format msgid "" "Type `{0}' does not contain a member `{1}' and the best extension method " "overload `{2}' has some invalid arguments" msgstr "" -#: mcs/mcs/ecore.cs:3767 +#: mcs/mcs/ecore.cs:3789 #, csharp-format msgid "Extension method instance type `{0}' cannot be converted to `{1}'" msgstr "" -#: mcs/mcs/ecore.cs:3915 +#: mcs/mcs/ecore.cs:3937 msgid "An expression tree cannot contain an expression with method group" msgstr "" -#: mcs/mcs/ecore.cs:3921 +#: mcs/mcs/ecore.cs:3943 msgid "" "Partial methods with only a defining declaration or removed conditional " "methods cannot be used in an expression tree" msgstr "" -#: mcs/mcs/ecore.cs:3972 +#: mcs/mcs/ecore.cs:3994 #, csharp-format msgid "" "Cannot convert method group `{0}' to non-delegate type `{1}'. Consider using " "parentheses to invoke the method" msgstr "" -#: mcs/mcs/ecore.cs:4711 +#: mcs/mcs/ecore.cs:4733 #, csharp-format msgid "" "The type `{0}' does not contain a constructor that takes `{1}' arguments" msgstr "" -#: mcs/mcs/ecore.cs:5412 +#: mcs/mcs/ecore.cs:5452 #, csharp-format msgid "" "Type `{0}' does not contain a member `{1}' and the best extension method " @@ -1533,200 +1542,200 @@ msgid "" "without the extension method syntax" msgstr "" -#: mcs/mcs/ecore.cs:5451 +#: mcs/mcs/ecore.cs:5491 #, csharp-format msgid "" "The call is ambiguous between the following methods or properties: `{0}' and " "`{1}'" msgstr "" -#: mcs/mcs/ecore.cs:5514 +#: mcs/mcs/ecore.cs:5554 #, csharp-format msgid "" "The best overloaded collection initalizer method `{0}' cannot have `ref' or " "`out' modifier" msgstr "" -#: mcs/mcs/ecore.cs:5518 +#: mcs/mcs/ecore.cs:5558 #, csharp-format msgid "" "The best overloaded collection initalizer method `{0}' has some invalid " "arguments" msgstr "" -#: mcs/mcs/ecore.cs:5521 +#: mcs/mcs/ecore.cs:5561 #, csharp-format msgid "Delegate `{0}' has some invalid arguments" msgstr "" -#: mcs/mcs/ecore.cs:5525 +#: mcs/mcs/ecore.cs:5565 #, csharp-format msgid "The best overloaded method match for `{0}' has some invalid arguments" msgstr "" -#: mcs/mcs/ecore.cs:5534 +#: mcs/mcs/ecore.cs:5574 #, csharp-format msgid "" "Argument `#{0}' does not require `{1}' modifier. Consider removing `{1}' " "modifier" msgstr "" -#: mcs/mcs/ecore.cs:5537 +#: mcs/mcs/ecore.cs:5577 #, csharp-format msgid "Argument `#{0}' is missing `{1}' modifier" msgstr "" -#: mcs/mcs/ecore.cs:5554 +#: mcs/mcs/ecore.cs:5594 #, csharp-format msgid "Argument `#{0}' cannot convert `{1}' expression to type `{2}'" msgstr "" -#: mcs/mcs/ecore.cs:5606 +#: mcs/mcs/ecore.cs:5646 #, csharp-format msgid "" "The type arguments for method `{0}' cannot be inferred from the usage. Try " "specifying the type arguments explicitly" msgstr "" -#: mcs/mcs/ecore.cs:5635 +#: mcs/mcs/ecore.cs:5675 #, csharp-format msgid "No overload for method `{0}' takes `{1}' arguments" msgstr "" -#: mcs/mcs/ecore.cs:5728 +#: mcs/mcs/ecore.cs:5778 #, csharp-format msgid "The delegate `{0}' does not contain a parameter named `{1}'" msgstr "" -#: mcs/mcs/ecore.cs:5733 +#: mcs/mcs/ecore.cs:5783 #, csharp-format msgid "" "The best overloaded method match for `{0}' does not contain a parameter " "named `{1}'" msgstr "" -#: mcs/mcs/ecore.cs:5743 +#: mcs/mcs/ecore.cs:5793 #, csharp-format msgid "" "Named argument `{0}' cannot be used for a parameter which has positional " "argument specified" msgstr "" -#: mcs/mcs/ecore.cs:6091 +#: mcs/mcs/ecore.cs:6155 msgid "" "You cannot use fixed size buffers contained in unfixed expressions. Try " "using the fixed statement" msgstr "" -#: mcs/mcs/ecore.cs:6096 +#: mcs/mcs/ecore.cs:6160 #, csharp-format msgid "`{0}': Fixed size buffers can only be accessed through locals or fields" msgstr "" -#: mcs/mcs/ecore.cs:6178 +#: mcs/mcs/ecore.cs:6242 #, csharp-format msgid "" "A static readonly field `{0}' cannot be passed ref or out (except in a " "static constructor)" msgstr "" -#: mcs/mcs/ecore.cs:6181 +#: mcs/mcs/ecore.cs:6245 #, csharp-format msgid "" "A readonly field `{0}' cannot be passed ref or out (except in a constructor)" msgstr "" -#: mcs/mcs/ecore.cs:6195 +#: mcs/mcs/ecore.cs:6259 #, csharp-format msgid "" "Fields of static readonly field `{0}' cannot be passed ref or out (except in " "a static constructor)" msgstr "" -#: mcs/mcs/ecore.cs:6198 +#: mcs/mcs/ecore.cs:6262 #, csharp-format msgid "" "Members of readonly field `{0}' cannot be passed ref or out (except in a " "constructor)" msgstr "" -#: mcs/mcs/ecore.cs:6205 +#: mcs/mcs/ecore.cs:6269 #, csharp-format msgid "" "A static readonly field `{0}' cannot be assigned to (except in a static " "constructor or a variable initializer)" msgstr "" -#: mcs/mcs/ecore.cs:6208 +#: mcs/mcs/ecore.cs:6272 #, csharp-format msgid "" "A readonly field `{0}' cannot be assigned to (except in a constructor or a " "variable initializer)" msgstr "" -#: mcs/mcs/ecore.cs:6275 +#: mcs/mcs/ecore.cs:6339 #, csharp-format msgid "Use of possibly unassigned field `{0}'" msgstr "" -#: mcs/mcs/ecore.cs:6655 +#: mcs/mcs/ecore.cs:6719 #, csharp-format msgid "Property or event `{0}' is not supported by the C# language" msgstr "" -#: mcs/mcs/ecore.cs:6886 +#: mcs/mcs/ecore.cs:6950 #, csharp-format msgid "A range variable `{0}' may not be passes as `ref' or `out' parameter" msgstr "" -#: mcs/mcs/ecore.cs:6974 +#: mcs/mcs/ecore.cs:7038 #, csharp-format msgid "" "The property or indexer `{0}' cannot be used in this context because it " "lacks the `get' accessor" msgstr "" -#: mcs/mcs/ecore.cs:6981 +#: mcs/mcs/ecore.cs:7045 #, csharp-format msgid "" "The property or indexer `{0}' cannot be used in this context because the get " "accessor is inaccessible" msgstr "" -#: mcs/mcs/ecore.cs:7000 +#: mcs/mcs/ecore.cs:7064 #, csharp-format msgid "Property or indexer `{0}' cannot be assigned to (it is read-only)" msgstr "" -#: mcs/mcs/ecore.cs:7008 +#: mcs/mcs/ecore.cs:7072 #, csharp-format msgid "" "The property or indexer `{0}' cannot be used in this context because the set " "accessor is inaccessible" msgstr "" -#: mcs/mcs/ecore.cs:7185 +#: mcs/mcs/ecore.cs:7249 #, csharp-format msgid "" "The event `{0}' can only appear on the left hand side of `+=' or `-=' " "operator" msgstr "" -#: mcs/mcs/ecore.cs:7189 +#: mcs/mcs/ecore.cs:7253 #, csharp-format msgid "" "The event `{0}' can only appear on the left hand side of += or -= when used " "outside of the type `{1}'" msgstr "" -#: mcs/mcs/ecore.cs:7361 +#: mcs/mcs/ecore.cs:7425 #, csharp-format msgid "" "An implicitly typed local variable declaration cannot be initialized with " "`{0}'" msgstr "" -#: mcs/mcs/ecore.cs:7375 +#: mcs/mcs/ecore.cs:7439 msgid "" "The contextual keyword `var' may only appear within a local variable " "declaration" @@ -1794,255 +1803,274 @@ msgid "" "method, or method group" msgstr "" -#: mcs/mcs/expression.cs:1820 +#: mcs/mcs/expression.cs:2213 +#, csharp-format +msgid "`{0}' is not a valid pattern member" +msgstr "" + +#: mcs/mcs/expression.cs:2220 +#, csharp-format +msgid "Property `{0}.get' accessor is required" +msgstr "" + +#: mcs/mcs/expression.cs:2353 #, csharp-format msgid "" "The `as' operator cannot be used with a non-reference type parameter `{0}'. " "Consider adding `class' or a reference type constraint" msgstr "" -#: mcs/mcs/expression.cs:1824 +#: mcs/mcs/expression.cs:2357 #, csharp-format msgid "The `as' operator cannot be used with a non-nullable value type `{0}'" msgstr "" -#: mcs/mcs/expression.cs:1858 +#: mcs/mcs/expression.cs:2391 #, csharp-format msgid "Cannot convert type `{0}' to `{1}' via a built-in conversion" msgstr "" -#: mcs/mcs/expression.cs:1899 +#: mcs/mcs/expression.cs:2432 #, csharp-format msgid "Cannot convert to static type `{0}'" msgstr "" -#: mcs/mcs/expression.cs:2009 +#: mcs/mcs/expression.cs:2535 +msgid "An expression tree cannot contain a declaration expression" +msgstr "" + +#: mcs/mcs/expression.cs:2632 msgid "" "The `default value' operator cannot be applied to an operand of a static type" msgstr "" -#: mcs/mcs/expression.cs:2686 +#: mcs/mcs/expression.cs:3314 #, csharp-format msgid "Operator `{0}' cannot be applied to operands of type `{1}' and `{2}'" msgstr "" -#: mcs/mcs/expression.cs:3492 +#: mcs/mcs/expression.cs:4120 msgid "To cast a negative value, you must enclose the value in parentheses" msgstr "" -#: mcs/mcs/expression.cs:3585 +#: mcs/mcs/expression.cs:4213 #, csharp-format msgid "" "Expression must be implicitly convertible to Boolean or its type `{0}' must " "define operator `{1}'" msgstr "" -#: mcs/mcs/expression.cs:5183 +#: mcs/mcs/expression.cs:5819 #, csharp-format msgid "" "A user-defined operator `{0}' must have each parameter type and return type " "of the same type in order to be applicable as a short circuit operator" msgstr "" -#: mcs/mcs/expression.cs:5193 +#: mcs/mcs/expression.cs:5829 #, csharp-format msgid "" "The type `{0}' must have operator `true' and operator `false' defined when " "`{1}' is used as a short circuit operator" msgstr "" -#: mcs/mcs/expression.cs:5568 +#: mcs/mcs/expression.cs:6204 #, csharp-format msgid "" "Type of conditional expression cannot be determined as `{0}' and `{1}' " "convert implicitly to each other" msgstr "" -#: mcs/mcs/expression.cs:5580 +#: mcs/mcs/expression.cs:6216 #, csharp-format msgid "" "Type of conditional expression cannot be determined because there is no " "implicit conversion between `{0}' and `{1}'" msgstr "" -#: mcs/mcs/expression.cs:5926 +#: mcs/mcs/expression.cs:6562 #, csharp-format msgid "Use of unassigned local variable `{0}'" msgstr "" -#: mcs/mcs/expression.cs:5946 +#: mcs/mcs/expression.cs:6585 #, csharp-format msgid "" "Cannot use fixed local `{0}' inside an anonymous method, lambda expression " "or query expression" msgstr "" -#: mcs/mcs/expression.cs:6131 +#: mcs/mcs/expression.cs:6603 +#, csharp-format +msgid "Cannot use uninitialized variable `{0}'" +msgstr "" + +#: mcs/mcs/expression.cs:6775 #, csharp-format msgid "" "Parameter `{0}' cannot be used inside `{1}' when using `ref' or `out' " "modifier" msgstr "" -#: mcs/mcs/expression.cs:6201 +#: mcs/mcs/expression.cs:6845 #, csharp-format msgid "Use of unassigned out parameter `{0}'" msgstr "" -#: mcs/mcs/expression.cs:6405 +#: mcs/mcs/expression.cs:7049 #, csharp-format msgid "Cannot invoke a non-delegate type `{0}'" msgstr "" -#: mcs/mcs/expression.cs:6416 +#: mcs/mcs/expression.cs:7060 #, csharp-format msgid "The member `{0}' cannot be used as method or delegate" msgstr "" -#: mcs/mcs/expression.cs:6438 +#: mcs/mcs/expression.cs:7082 msgid "" "Do not directly call your base class Finalize method. It is called " "automatically from your destructor" msgstr "" -#: mcs/mcs/expression.cs:6440 +#: mcs/mcs/expression.cs:7084 msgid "" "Destructors and object.Finalize cannot be called directly. Consider calling " "IDisposable.Dispose if available" msgstr "" -#: mcs/mcs/expression.cs:6469 +#: mcs/mcs/expression.cs:7113 #, csharp-format msgid "" "The base call to method `{0}' cannot be dynamically dispatched. Consider " "casting the dynamic arguments or eliminating the base access" msgstr "" -#: mcs/mcs/expression.cs:6562 +#: mcs/mcs/expression.cs:7206 #, csharp-format msgid "`{0}': cannot explicitly call operator or accessor" msgstr "" -#: mcs/mcs/expression.cs:6752 +#: mcs/mcs/expression.cs:7396 #, csharp-format msgid "Unsafe type `{0}' cannot be used in an object creation expression" msgstr "" -#: mcs/mcs/expression.cs:6775 +#: mcs/mcs/expression.cs:7419 #, csharp-format msgid "" "Cannot create an instance of the variable type `{0}' because it does not " "have the new() constraint" msgstr "" -#: mcs/mcs/expression.cs:6781 +#: mcs/mcs/expression.cs:7425 #, csharp-format msgid "" "`{0}': cannot provide arguments when creating an instance of a variable type" msgstr "" -#: mcs/mcs/expression.cs:6790 +#: mcs/mcs/expression.cs:7434 #, csharp-format msgid "Cannot create an instance of the static class `{0}'" msgstr "" -#: mcs/mcs/expression.cs:6802 +#: mcs/mcs/expression.cs:7446 #, csharp-format msgid "Cannot create an instance of the abstract class or interface `{0}'" msgstr "" -#: mcs/mcs/expression.cs:7111 +#: mcs/mcs/expression.cs:7719 msgid "" "An implicitly typed local variable declarator cannot use an array initializer" msgstr "" -#: mcs/mcs/expression.cs:7274 mcs/mcs/expression.cs:7299 +#: mcs/mcs/expression.cs:7882 mcs/mcs/expression.cs:7907 #, csharp-format msgid "An array initializer of length `{0}' was expected" msgstr "" -#: mcs/mcs/expression.cs:7290 +#: mcs/mcs/expression.cs:7898 msgid "" "Array initializers can only be used in a variable or field initializer. Try " "using a new expression instead" msgstr "" -#: mcs/mcs/expression.cs:7307 +#: mcs/mcs/expression.cs:7915 msgid "A nested array initializer was expected" msgstr "" -#: mcs/mcs/expression.cs:7354 +#: mcs/mcs/expression.cs:7962 msgid "An expression tree cannot contain a multidimensional array initializer" msgstr "" -#: mcs/mcs/expression.cs:7390 +#: mcs/mcs/expression.cs:7998 msgid "Cannot create an array with a negative size" msgstr "" -#: mcs/mcs/expression.cs:7482 +#: mcs/mcs/expression.cs:8090 msgid "" "Can only use array initializer expressions to assign to array types. Try " "using a new expression instead" msgstr "" -#: mcs/mcs/expression.cs:7906 +#: mcs/mcs/expression.cs:8514 msgid "" "The type of an implicitly typed array cannot be inferred from the " "initializer. Try specifying array type explicitly" msgstr "" -#: mcs/mcs/expression.cs:8061 +#: mcs/mcs/expression.cs:8669 msgid "" "The `this' object cannot be used before all of its fields are assigned to" msgstr "" -#: mcs/mcs/expression.cs:8067 +#: mcs/mcs/expression.cs:8675 msgid "" "Keyword `this' is not valid in a static property, static method, or static " "field initializer" msgstr "" -#: mcs/mcs/expression.cs:8070 +#: mcs/mcs/expression.cs:8678 msgid "" "Anonymous methods inside structs cannot access instance members of `this'. " "Consider copying `this' to a local variable outside the anonymous method and " "using the local instead" msgstr "" -#: mcs/mcs/expression.cs:8073 +#: mcs/mcs/expression.cs:8681 msgid "Keyword `this' is not available in the current context" msgstr "" -#: mcs/mcs/expression.cs:8149 +#: mcs/mcs/expression.cs:8757 msgid "Cannot take the address of `this' because it is read-only" msgstr "" -#: mcs/mcs/expression.cs:8151 +#: mcs/mcs/expression.cs:8759 msgid "Cannot pass `this' as a ref or out argument because it is read-only" msgstr "" -#: mcs/mcs/expression.cs:8153 +#: mcs/mcs/expression.cs:8761 msgid "Cannot assign to `this' because it is read-only" msgstr "" -#: mcs/mcs/expression.cs:8221 +#: mcs/mcs/expression.cs:8829 msgid "The __arglist construct is valid only within a variable argument method" msgstr "" -#: mcs/mcs/expression.cs:8282 +#: mcs/mcs/expression.cs:8890 msgid "An expression tree cannot contain a method with variable arguments" msgstr "" -#: mcs/mcs/expression.cs:8550 +#: mcs/mcs/expression.cs:9158 msgid "The typeof operator cannot be used on the dynamic type" msgstr "" -#: mcs/mcs/expression.cs:8591 +#: mcs/mcs/expression.cs:9199 #, csharp-format msgid "`{0}': an attribute argument cannot use type parameters" msgstr "" -#: mcs/mcs/expression.cs:8806 +#: mcs/mcs/expression.cs:9414 #, csharp-format msgid "" "`{0}' does not have a predefined size, therefore sizeof can only be used in " @@ -2050,162 +2078,162 @@ msgid "" "SizeOf)" msgstr "" -#: mcs/mcs/expression.cs:8871 +#: mcs/mcs/expression.cs:9479 #, csharp-format msgid "Alias `{0}' not found" msgstr "" -#: mcs/mcs/expression.cs:8912 +#: mcs/mcs/expression.cs:9520 msgid "" "The namespace alias qualifier `::' cannot be used to invoke a method. " "Consider using `.' instead" msgstr "" -#: mcs/mcs/expression.cs:9002 +#: mcs/mcs/expression.cs:9610 msgid "Cannot perform member binding on `null' value" msgstr "" -#: mcs/mcs/expression.cs:9156 +#: mcs/mcs/expression.cs:9764 #, csharp-format msgid "" "`{0}': cannot reference a type through an expression. Consider using `{1}' " "instead" msgstr "" -#: mcs/mcs/expression.cs:9236 +#: mcs/mcs/expression.cs:9844 #, csharp-format msgid "A nested type cannot be specified through a type parameter `{0}'" msgstr "" -#: mcs/mcs/expression.cs:9244 +#: mcs/mcs/expression.cs:9852 #, csharp-format msgid "" "Alias `{0}' cannot be used with `::' since it denotes a type. Consider " "replacing `::' with `.'" msgstr "" -#: mcs/mcs/expression.cs:9314 +#: mcs/mcs/expression.cs:9922 #, csharp-format msgid "The nested type `{0}' does not exist in the type `{1}'" msgstr "" -#: mcs/mcs/expression.cs:9338 +#: mcs/mcs/expression.cs:9946 #, csharp-format msgid "" "Type `{0}' does not contain a definition for `{1}' and no extension method " "`{1}' of type `{0}' could be found. Are you missing {2}?" msgstr "" -#: mcs/mcs/expression.cs:9617 +#: mcs/mcs/expression.cs:10225 #, csharp-format msgid "Cannot apply indexing with [] to an expression of type `{0}'" msgstr "" -#: mcs/mcs/expression.cs:9630 +#: mcs/mcs/expression.cs:10238 msgid "A pointer must be indexed by only one value" msgstr "" -#: mcs/mcs/expression.cs:9686 +#: mcs/mcs/expression.cs:10294 msgid "An element access expression cannot use named argument" msgstr "" -#: mcs/mcs/expression.cs:9788 +#: mcs/mcs/expression.cs:10396 #, csharp-format msgid "Wrong number of indexes `{0}' inside [], expected `{1}'" msgstr "" -#: mcs/mcs/expression.cs:10211 +#: mcs/mcs/expression.cs:10819 msgid "" "The indexer base access cannot be dynamically dispatched. Consider casting " "the dynamic arguments or eliminating the base access" msgstr "" -#: mcs/mcs/expression.cs:10301 +#: mcs/mcs/expression.cs:10909 msgid "An expression tree may not contain a base access" msgstr "" -#: mcs/mcs/expression.cs:10319 +#: mcs/mcs/expression.cs:10927 msgid "Keyword `base' is not available in a static method" msgstr "" -#: mcs/mcs/expression.cs:10321 +#: mcs/mcs/expression.cs:10929 msgid "Keyword `base' is not available in the current context" msgstr "" -#: mcs/mcs/expression.cs:10359 +#: mcs/mcs/expression.cs:10967 msgid "" "A property, indexer or dynamic member access may not be passed as `ref' or " "`out' parameter" msgstr "" -#: mcs/mcs/expression.cs:10697 +#: mcs/mcs/expression.cs:11312 #, csharp-format msgid "Array elements cannot be of type `{0}'" msgstr "" -#: mcs/mcs/expression.cs:10700 +#: mcs/mcs/expression.cs:11315 #, csharp-format msgid "Array elements cannot be of static type `{0}'" msgstr "" -#: mcs/mcs/expression.cs:10876 +#: mcs/mcs/expression.cs:11491 msgid "Cannot use a negative size with stackalloc" msgstr "" -#: mcs/mcs/expression.cs:10880 +#: mcs/mcs/expression.cs:11495 msgid "Cannot use stackalloc in finally or catch" msgstr "" -#: mcs/mcs/expression.cs:11035 +#: mcs/mcs/expression.cs:11650 #, csharp-format msgid "" "Member `{0}' cannot be initialized. An object initializer may only be used " "for fields, or properties" msgstr "" -#: mcs/mcs/expression.cs:11043 +#: mcs/mcs/expression.cs:11658 #, csharp-format msgid "" "Static field or property `{0}' cannot be assigned in an object initializer" msgstr "" -#: mcs/mcs/expression.cs:11149 +#: mcs/mcs/expression.cs:11764 msgid "Expression tree cannot contain a dictionary initializer" msgstr "" -#: mcs/mcs/expression.cs:11264 +#: mcs/mcs/expression.cs:11879 #, csharp-format msgid "" "A field or property `{0}' cannot be initialized with a collection object " "initializer because type `{1}' does not implement `{2}' interface" msgstr "" -#: mcs/mcs/expression.cs:11275 +#: mcs/mcs/expression.cs:11890 #, csharp-format msgid "Inconsistent `{0}' member declaration" msgstr "" -#: mcs/mcs/expression.cs:11283 +#: mcs/mcs/expression.cs:11898 #, csharp-format msgid "" "An object initializer includes more than one member `{0}' initialization" msgstr "" -#: mcs/mcs/expression.cs:11301 +#: mcs/mcs/expression.cs:11916 #, csharp-format msgid "Cannot initialize object of type `{0}' with a collection initializer" msgstr "" -#: mcs/mcs/expression.cs:11446 +#: mcs/mcs/expression.cs:12061 msgid "" "Object and collection initializers cannot be used to instantiate a delegate" msgstr "" -#: mcs/mcs/expression.cs:11634 +#: mcs/mcs/expression.cs:12249 msgid "Anonymous types cannot be used in this expression" msgstr "" -#: mcs/mcs/expression.cs:11728 +#: mcs/mcs/expression.cs:12343 #, csharp-format msgid "An anonymous type property `{0}' cannot be initialized with `{1}'" msgstr "" @@ -2266,12 +2294,12 @@ msgid "" "Fixed size buffer `{0}' of length `{1}' and type `{2}' exceeded 2^31 limit" msgstr "" -#: mcs/mcs/field.cs:671 +#: mcs/mcs/field.cs:685 #, csharp-format msgid "`{0}': A volatile field cannot be of the type `{1}'" msgstr "" -#: mcs/mcs/field.cs:676 +#: mcs/mcs/field.cs:690 #, csharp-format msgid "`{0}': A field cannot be both volatile and readonly" msgstr "" @@ -2365,56 +2393,56 @@ msgstr "" msgid "The {2} type parameter `{0}' must be {3} valid on `{1}{4}'" msgstr "" -#: mcs/mcs/generic.cs:2205 +#: mcs/mcs/generic.cs:2211 #, csharp-format msgid "`{0}': static classes cannot be used as generic arguments" msgstr "" -#: mcs/mcs/generic.cs:2212 +#: mcs/mcs/generic.cs:2218 #, csharp-format msgid "The type `{0}' may not be used as a type argument" msgstr "" -#: mcs/mcs/generic.cs:2306 +#: mcs/mcs/generic.cs:2312 msgid "Variant type parameters can only be used with interfaces and delegates" msgstr "" -#: mcs/mcs/generic.cs:2375 +#: mcs/mcs/generic.cs:2381 #, csharp-format msgid "" "Partial method declarations of `{0}' have inconsistent constraints for type " "parameter `{1}'" msgstr "" -#: mcs/mcs/generic.cs:2391 +#: mcs/mcs/generic.cs:2397 #, csharp-format msgid "" "Partial declarations of `{0}' have inconsistent constraints for type " "parameter `{1}'" msgstr "" -#: mcs/mcs/generic.cs:2575 +#: mcs/mcs/generic.cs:2581 #, csharp-format msgid "" "The type `{0}' must be a reference type in order to use it as type parameter " "`{1}' in the generic type or method `{2}'" msgstr "" -#: mcs/mcs/generic.cs:2585 +#: mcs/mcs/generic.cs:2591 #, csharp-format msgid "" "The type `{0}' must be a non-nullable value type in order to use it as type " "parameter `{1}' in the generic type or method `{2}'" msgstr "" -#: mcs/mcs/generic.cs:2646 +#: mcs/mcs/generic.cs:2652 #, csharp-format msgid "" "The type `{0}' must have a public parameterless constructor in order to use " "it as parameter `{1}' in the generic type or method `{2}'" msgstr "" -#: mcs/mcs/generic.cs:2702 +#: mcs/mcs/generic.cs:2708 #, csharp-format msgid "" "The type `{0}' cannot be used as type parameter `{1}' in the generic type or " @@ -2422,7 +2450,7 @@ msgid "" "`{3}'" msgstr "" -#: mcs/mcs/generic.cs:2708 +#: mcs/mcs/generic.cs:2714 #, csharp-format msgid "" "The type `{0}' cannot be used as type parameter `{1}' in the generic type or " @@ -2430,21 +2458,21 @@ msgid "" "`{3}'" msgstr "" -#: mcs/mcs/generic.cs:2712 +#: mcs/mcs/generic.cs:2718 #, csharp-format msgid "" "The type `{0}' cannot be used as type parameter `{1}' in the generic type or " "method `{2}'. The nullable type `{0}' does not satisfy constraint `{3}'" msgstr "" -#: mcs/mcs/generic.cs:2717 +#: mcs/mcs/generic.cs:2723 #, csharp-format msgid "" "The type `{0}' cannot be used as type parameter `{1}' in the generic type or " "method `{2}'. There is no boxing conversion from `{0}' to `{3}'" msgstr "" -#: mcs/mcs/generic.cs:2722 +#: mcs/mcs/generic.cs:2728 #, csharp-format msgid "" "The type `{0}' cannot be used as type parameter `{1}' in the generic type or " @@ -2486,7 +2514,7 @@ msgstr "" msgid "Iterators cannot have unsafe parameters or yield types" msgstr "" -#: mcs/mcs/iterators.cs:1214 mcs/mcs/statement.cs:6090 +#: mcs/mcs/iterators.cs:1214 mcs/mcs/statement.cs:6148 msgid "Unsafe code may not appear in iterators" msgstr "" @@ -2803,153 +2831,144 @@ msgstr "" msgid "`{0}': Struct constructors cannot call base constructors" msgstr "" -#: mcs/mcs/method.cs:1516 +#: mcs/mcs/method.cs:1507 #, csharp-format msgid "Constructor `{0}' cannot call itself" msgstr "" -#: mcs/mcs/method.cs:1667 -#, csharp-format -msgid "`{0}': The static constructor must be parameterless" -msgstr "" - -#: mcs/mcs/method.cs:1688 -msgid "Structs cannot contain explicit parameterless constructors" -msgstr "" - -#: mcs/mcs/method.cs:1714 +#: mcs/mcs/method.cs:1693 #, csharp-format msgid "" "`{0}': Structs with primary constructor cannot specify default constructor " "initializer" msgstr "" -#: mcs/mcs/method.cs:1717 +#: mcs/mcs/method.cs:1696 #, csharp-format msgid "" "`{0}': Instance constructor of type with primary constructor must specify " "`this' constructor initializer" msgstr "" -#: mcs/mcs/method.cs:1753 +#: mcs/mcs/method.cs:1732 #, csharp-format msgid "" "`{0}': A class with the ComImport attribute cannot have a user-defined " "constructor" msgstr "" -#: mcs/mcs/method.cs:2005 +#: mcs/mcs/method.cs:1984 #, csharp-format msgid "`{0}' is an accessor not found in interface member `{1}{2}'" msgstr "" -#: mcs/mcs/method.cs:2011 +#: mcs/mcs/method.cs:1990 #, csharp-format msgid "" "`{0}.{1}' in explicit interface declaration is not a member of interface" msgstr "" -#: mcs/mcs/method.cs:2019 +#: mcs/mcs/method.cs:1998 #, csharp-format msgid "" "`{0}' explicit method implementation cannot implement `{1}' because it is an " "accessor" msgstr "" -#: mcs/mcs/method.cs:2029 +#: mcs/mcs/method.cs:2008 #, csharp-format msgid "Method `{0}' cannot implement interface accessor `{1}'" msgstr "" -#: mcs/mcs/method.cs:2036 +#: mcs/mcs/method.cs:2015 #, csharp-format msgid "" "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use " "an explicit interface implementation" msgstr "" -#: mcs/mcs/method.cs:2043 +#: mcs/mcs/method.cs:2022 #, csharp-format msgid "" "Accessor `{0}' must be declared public to implement interface member `{1}'" msgstr "" -#: mcs/mcs/method.cs:2063 +#: mcs/mcs/method.cs:2042 #, csharp-format msgid "" "`{0}': the explicit interface implementation cannot introduce the params " "modifier" msgstr "" -#: mcs/mcs/method.cs:2407 +#: mcs/mcs/method.cs:2386 #, csharp-format msgid "" "Attribute `{0}' is not valid on property or event accessors. It is valid on " "`{1}' declarations only" msgstr "" -#: mcs/mcs/method.cs:2640 +#: mcs/mcs/method.cs:2623 #, csharp-format msgid "User-defined operator `{0}' must be declared static and public" msgstr "" -#: mcs/mcs/method.cs:2684 +#: mcs/mcs/method.cs:2667 msgid "" "User-defined operator cannot take an object of the enclosing type and " "convert to an object of the enclosing type" msgstr "" -#: mcs/mcs/method.cs:2695 +#: mcs/mcs/method.cs:2678 msgid "User-defined conversion must convert to or from the enclosing type" msgstr "" -#: mcs/mcs/method.cs:2701 +#: mcs/mcs/method.cs:2684 #, csharp-format msgid "" "User-defined conversion `{0}' cannot convert to or from the dynamic type" msgstr "" -#: mcs/mcs/method.cs:2708 +#: mcs/mcs/method.cs:2691 #, csharp-format msgid "" "User-defined conversion `{0}' cannot convert to or from an interface type" msgstr "" -#: mcs/mcs/method.cs:2715 +#: mcs/mcs/method.cs:2698 #, csharp-format msgid "User-defined conversion `{0}' cannot convert to or from a base class" msgstr "" -#: mcs/mcs/method.cs:2721 +#: mcs/mcs/method.cs:2704 #, csharp-format msgid "User-defined conversion `{0}' cannot convert to or from a derived class" msgstr "" -#: mcs/mcs/method.cs:2728 +#: mcs/mcs/method.cs:2711 msgid "" "Overloaded shift operator must have the type of the first operand be the " "containing type, and the type of the second operand must be int" msgstr "" -#: mcs/mcs/method.cs:2737 +#: mcs/mcs/method.cs:2720 msgid "" "The return type for ++ or -- operator must be the containing type or derived " "from the containing type" msgstr "" -#: mcs/mcs/method.cs:2742 +#: mcs/mcs/method.cs:2725 msgid "The parameter type for ++ or -- operator must be the containing type" msgstr "" -#: mcs/mcs/method.cs:2749 +#: mcs/mcs/method.cs:2732 msgid "The parameter type of a unary operator must be the containing type" msgstr "" -#: mcs/mcs/method.cs:2757 +#: mcs/mcs/method.cs:2740 msgid "The return type of operator True or False must be bool" msgstr "" -#: mcs/mcs/method.cs:2772 +#: mcs/mcs/method.cs:2755 msgid "One of the parameters of a binary operator must be the containing type" msgstr "" @@ -2963,47 +2982,47 @@ msgstr "" msgid "The imported type `{0}' is defined multiple times" msgstr "" -#: mcs/mcs/namespace.cs:748 mcs/mcs/namespace.cs:760 +#: mcs/mcs/namespace.cs:762 mcs/mcs/namespace.cs:774 msgid "" "A using clause must precede all other namespace elements except extern alias " "declarations" msgstr "" -#: mcs/mcs/namespace.cs:776 +#: mcs/mcs/namespace.cs:790 #, csharp-format msgid "The using alias `{0}' appeared previously in this namespace" msgstr "" -#: mcs/mcs/namespace.cs:813 mcs/mcs/namespace.cs:836 +#: mcs/mcs/namespace.cs:827 mcs/mcs/namespace.cs:850 #, csharp-format msgid "The namespace `{0}' already contains a definition for `{1}'" msgstr "" -#: mcs/mcs/namespace.cs:1076 +#: mcs/mcs/namespace.cs:1090 #, csharp-format msgid "Namespace `{0}' contains a definition with same name as alias `{1}'" msgstr "" -#: mcs/mcs/namespace.cs:1129 +#: mcs/mcs/namespace.cs:1143 #, csharp-format msgid "`{0}' is an ambiguous reference between `{1}' and `{2}'" msgstr "" -#: mcs/mcs/namespace.cs:1391 +#: mcs/mcs/namespace.cs:1405 #, csharp-format msgid "" "`{0}' is not a static class. A using namespace directive can only be applied " "to static classes or namespace" msgstr "" -#: mcs/mcs/namespace.cs:1400 +#: mcs/mcs/namespace.cs:1414 #, csharp-format msgid "" "`{0}' is a type not a namespace. A using namespace directive can only be " "applied to namespaces" msgstr "" -#: mcs/mcs/namespace.cs:1423 +#: mcs/mcs/namespace.cs:1437 #, csharp-format msgid "The extern alias `{0}' was not specified in -reference option" msgstr "" @@ -3290,7 +3309,7 @@ msgstr "" msgid "Cannot set the `IndexerName' attribute on an indexer marked override" msgstr "" -#: mcs/mcs/module.cs:338 +#: mcs/mcs/module.cs:473 #, csharp-format msgid "Value specified for the argument to `{0}' is not valid" msgstr "" @@ -3386,7 +3405,7 @@ msgid "" "clause nested inside of the innermost catch clause" msgstr "" -#: mcs/mcs/statement.cs:1806 mcs/mcs/statement.cs:6623 +#: mcs/mcs/statement.cs:1806 mcs/mcs/statement.cs:6681 msgid "The type caught or thrown must be derived from System.Exception" msgstr "" @@ -3467,78 +3486,78 @@ msgstr "" msgid "`{0}': not all code paths return a value" msgstr "" -#: mcs/mcs/statement.cs:4532 +#: mcs/mcs/statement.cs:4546 #, csharp-format msgid "The label `{0}' already occurs in this switch statement" msgstr "" -#: mcs/mcs/statement.cs:4659 +#: mcs/mcs/statement.cs:4673 #, csharp-format msgid "" "Control cannot fall out of switch statement through final case label `{0}'" msgstr "" -#: mcs/mcs/statement.cs:4662 +#: mcs/mcs/statement.cs:4676 #, csharp-format msgid "Control cannot fall through from one case label `{0}' to another" msgstr "" -#: mcs/mcs/statement.cs:5072 +#: mcs/mcs/statement.cs:5113 #, csharp-format msgid "" "A switch expression of type `{0}' cannot be converted to an integral type, " "bool, char, string, enum or nullable type" msgstr "" -#: mcs/mcs/statement.cs:5856 +#: mcs/mcs/statement.cs:5914 #, csharp-format msgid "`{0}' is not a reference type as required by the lock statement" msgstr "" -#: mcs/mcs/statement.cs:6237 +#: mcs/mcs/statement.cs:6295 msgid "The type of locals declared in a fixed statement must be a pointer type" msgstr "" -#: mcs/mcs/statement.cs:6253 +#: mcs/mcs/statement.cs:6311 msgid "" "The right hand side of a fixed statement assignment may not be a cast " "expression" msgstr "" -#: mcs/mcs/statement.cs:6323 +#: mcs/mcs/statement.cs:6381 msgid "" "You cannot use the fixed statement to take the address of an already fixed " "expression" msgstr "" -#: mcs/mcs/statement.cs:6484 +#: mcs/mcs/statement.cs:6542 msgid "" "The `await' operator cannot be used in the filter expression of a catch " "clause" msgstr "" -#: mcs/mcs/statement.cs:7056 +#: mcs/mcs/statement.cs:7114 #, csharp-format msgid "" "A previous catch clause already catches all exceptions of this or a super " "type `{0}'" msgstr "" -#: mcs/mcs/statement.cs:7285 +#: mcs/mcs/statement.cs:7343 #, csharp-format msgid "" "`{0}': type used in a using statement must be implicitly convertible to " "`System.IDisposable'" msgstr "" -#: mcs/mcs/statement.cs:7697 +#: mcs/mcs/statement.cs:7755 #, csharp-format msgid "" "foreach statement requires that the return type `{0}' of `{1}' must have a " "suitable public MoveNext method and public Current property" msgstr "" -#: mcs/mcs/statement.cs:7741 +#: mcs/mcs/statement.cs:7799 #, csharp-format msgid "" "foreach statement cannot operate on variables of type `{0}' because it " @@ -3546,18 +3565,18 @@ msgid "" "implementation" msgstr "" -#: mcs/mcs/statement.cs:7763 +#: mcs/mcs/statement.cs:7821 #, csharp-format msgid "" "foreach statement cannot operate on variables of type `{0}' because it does " "not contain a definition for `{1}' or is inaccessible" msgstr "" -#: mcs/mcs/statement.cs:7998 +#: mcs/mcs/statement.cs:8056 msgid "Use of null is not valid in this context" msgstr "" -#: mcs/mcs/statement.cs:8010 +#: mcs/mcs/statement.cs:8068 #, csharp-format msgid "Foreach statement cannot operate on a `{0}'" msgstr "" diff --git a/po/mcs/pt_BR.gmo b/po/mcs/pt_BR.gmo index c7fbcacf71..6ba2cfd0b3 100644 Binary files a/po/mcs/pt_BR.gmo and b/po/mcs/pt_BR.gmo differ diff --git a/po/mcs/pt_BR.po.REMOVED.git-id b/po/mcs/pt_BR.po.REMOVED.git-id index 94567c2d3d..3aad7ff16f 100644 --- a/po/mcs/pt_BR.po.REMOVED.git-id +++ b/po/mcs/pt_BR.po.REMOVED.git-id @@ -1 +1 @@ -2d09752de9b10e607d5084fe2b67556c4d79b277 \ No newline at end of file +3d10fb75162effca5e8993b9079b9c431722ec8d \ No newline at end of file diff --git a/runtime/Makefile.am b/runtime/Makefile.am index 2d9c2886db..ca34a6f396 100644 --- a/runtime/Makefile.am +++ b/runtime/Makefile.am @@ -168,7 +168,7 @@ CLEANFILES = etc/mono/config # depend on $(symlinks) to ensure 'etc/mono' directory exists etc/mono/config: ../data/config Makefile $(symlinks) d=`cd ../support && pwd`; \ - sed 's,target="$(prefix)/lib/libMonoPosixHelper$(libsuffix)",target="'$$d'/libMonoPosixHelper.la",' ../data/config > $@t + sed 's,target="$(prefix)/$(reloc_libdir)/libMonoPosixHelper$(libsuffix)",target="'$$d'/libMonoPosixHelper.la",' ../data/config > $@t if test -z "$(libgdiplus_loc)"; then :; else \ sed 's,target="$(libgdiplus_install_loc)",target="$(libgdiplus_loc)",' $@t > $@tt; \ mv -f $@tt $@t; fi diff --git a/runtime/Makefile.in b/runtime/Makefile.in index f6d292b288..0ea17f8dfa 100644 --- a/runtime/Makefile.in +++ b/runtime/Makefile.in @@ -628,7 +628,7 @@ test: mcs-do-test-profiles # depend on $(symlinks) to ensure 'etc/mono' directory exists etc/mono/config: ../data/config Makefile $(symlinks) d=`cd ../support && pwd`; \ - sed 's,target="$(prefix)/lib/libMonoPosixHelper$(libsuffix)",target="'$$d'/libMonoPosixHelper.la",' ../data/config > $@t + sed 's,target="$(prefix)/$(reloc_libdir)/libMonoPosixHelper$(libsuffix)",target="'$$d'/libMonoPosixHelper.la",' ../data/config > $@t if test -z "$(libgdiplus_loc)"; then :; else \ sed 's,target="$(libgdiplus_install_loc)",target="$(libgdiplus_loc)",' $@t > $@tt; \ mv -f $@tt $@t; fi diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 93adea143e..be62dd633e 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -76,6 +76,7 @@ scripts_4_0 = \ prj2make$(SCRIPT_SUFFIX) \ soapsuds$(SCRIPT_SUFFIX) \ caspol$(SCRIPT_SUFFIX) \ + cert-sync$(SCRIPT_SUFFIX) \ cert2spc$(SCRIPT_SUFFIX) \ certmgr$(SCRIPT_SUFFIX) \ chktrust$(SCRIPT_SUFFIX) \ @@ -164,11 +165,7 @@ EXTRA_DIST = \ get-cygwin-deps.sh \ mono-configuration-crypto.in -if USE_JIT mono_interp = mono -else -mono_interp = mint -endif if HOST_WIN32 if CROSS_COMPILING diff --git a/scripts/Makefile.in b/scripts/Makefile.in index ba7bc6e642..032c9f64e7 100644 --- a/scripts/Makefile.in +++ b/scripts/Makefile.in @@ -408,6 +408,7 @@ scripts_4_0 = \ prj2make$(SCRIPT_SUFFIX) \ soapsuds$(SCRIPT_SUFFIX) \ caspol$(SCRIPT_SUFFIX) \ + cert-sync$(SCRIPT_SUFFIX) \ cert2spc$(SCRIPT_SUFFIX) \ certmgr$(SCRIPT_SUFFIX) \ chktrust$(SCRIPT_SUFFIX) \ @@ -495,8 +496,7 @@ EXTRA_DIST = \ get-cygwin-deps.sh \ mono-configuration-crypto.in -@USE_JIT_FALSE@mono_interp = mint -@USE_JIT_TRUE@mono_interp = mono +mono_interp = mono @CROSS_COMPILING_FALSE@@HOST_WIN32_TRUE@plat_bindir = $(shell cygpath -m $(libdir)) @CROSS_COMPILING_TRUE@@HOST_WIN32_TRUE@plat_bindir = $(bindir) @HOST_WIN32_FALSE@plat_bindir = $(bindir) diff --git a/tools/locale-builder/Driver.cs b/tools/locale-builder/Driver.cs index 1a44d5eb7e..f42f5cf90b 100644 --- a/tools/locale-builder/Driver.cs +++ b/tools/locale-builder/Driver.cs @@ -1073,10 +1073,14 @@ namespace Mono.Tools.LocaleBuilder // Apply global rule first el = node.SelectSingleNode ("dayPeriods/dayPeriodContext/dayPeriodWidth[@type='wide']/dayPeriod[@type='am']"); + // Manual edits for exact .net compatiblity switch (ci.Name) { case "en-AU": df.AMDesignator = "AM"; break; + case "en-NZ": + df.AMDesignator = "a.m."; + break; default: if (el != null) df.AMDesignator = el.InnerText; @@ -1092,6 +1096,9 @@ namespace Mono.Tools.LocaleBuilder case "en-AU": df.PMDesignator = "PM"; break; + case "en-NZ": + df.PMDesignator = "p.m."; + break; default: if (el != null) df.PMDesignator = el.InnerText; diff --git a/winconfig.h b/winconfig.h index 0c690d3a35..e233d24a85 100644 --- a/winconfig.h +++ b/winconfig.h @@ -1,6 +1,10 @@ /* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ +#ifndef _MSC_VER +#include "cygconfig.h" +#else + /* The architecture this is running on */ #if defined(_M_IA64) #define ARCHITECTURE "ia64" @@ -13,11 +17,7 @@ #endif #if _WIN32_WINNT < 0x0502 -/* Required for Vectored Exception Handling. - Interlocked* functions are also not available in XP SP1 and below -*/ -#undef _WIN32_WINNT -#define _WIN32_WINNT 0x0502 +#error "Mono requires WinXP SP2 or later" #endif /* _WIN32_WINNT < 0x0502 */ /* @@ -198,9 +198,7 @@ /* #undef HAVE_GETPRIORITY */ /* Define to 1 if you have the `GetProcessId' function. */ -#if (_WIN32_WINNT >= 0x0502) #define HAVE_GETPROCESSID 1 -#endif /* Define to 1 if you have the `getpwnam_r' function. */ /* #undef HAVE_GETPWNAM_R */ @@ -635,4 +633,5 @@ /* #undef USE_MONO_MUTEX */ /* Version number of package */ -#define VERSION "2.11" +#define VERSION "3.12.0" +#endif