From: Marek Safar Date: Mon, 16 Jun 2014 10:52:45 +0000 (+0200) Subject: Merge pull request #1099 from jsportaro/master X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=8f53ba7970cd38449d5bb86801559d4e62b14510;hp=159f2dc89d2d46403c535ca4f7a4675d021df244;p=mono.git Merge pull request #1099 from jsportaro/master Added fix for Bug 11630 --- diff --git a/Makefile.am b/Makefile.am index 3542279772d..7d2251fd640 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,7 @@ ACLOCAL_AMFLAGS = -I m4 +AM_CFLAGS = $(WERROR_CFLAGS) + MONOTOUCH_SUBDIRS = $(libgc_dir) eglib/src mono if CROSS_COMPILING diff --git a/acinclude.m4 b/acinclude.m4 index 16fecf7f860..5216cd14a5e 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -22,7 +22,7 @@ if test x$GCC != xyes; then dolt_supported=no fi case $host in -i?86-*-linux*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-linux* \ +i?86-*-linux*|i?86-apple-darwin*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-linux* \ |amd64-*-freebsd*|i?86-*-freebsd*|ia64-*-freebsd*|arm*-*-linux*|sparc*-*-linux*|mips*-*-linux*|x86_64-apple-darwin*|aarch64*) pic_options='-fPIC' ;; @@ -158,7 +158,7 @@ modeok=false tagok=false for arg in "$[]@"; do case "$arg" in - --silent) ;; + --silent) ;; --mode=compile) modeok=true ;; --tag=CC|--tag=CXX) tagok=true ;; --quiet) ;; diff --git a/configure.ac b/configure.ac index 696bf15ead0..6d06c9227ec 100644 --- a/configure.ac +++ b/configure.ac @@ -59,6 +59,9 @@ CFLAGS_FOR_LIBGC=$CFLAGS CPPFLAGS_FOR_EGLIB=$CPPFLAGS CFLAGS_FOR_EGLIB=$CFLAGS +# libgc uses some deprecated APIs +CFLAGS_FOR_LIBGC="$CFLAGS -Wno-deprecated-declarations" + # # These are the flags that need to be stored in the mono.pc file for # compiling code that will embed Mono @@ -673,6 +676,12 @@ AC_ARG_WITH(crosspkgdir, [ --with-crosspkgdir=/path/to/pkg-config/dir Chan fi ) +AC_ARG_ENABLE(werror, [ --enable-werror Pass -Werror to the C compiler], werror_flag=$enableval, werror_flag=no) +if test x$werror_flag = xyes; then + WERROR_CFLAGS="-Werror" +fi +AC_SUBST([WERROR_CFLAGS]) + ac_configure_args="$ac_configure_args \"CPPFLAGS_FOR_EGLIB=$EGLIB_CPPFLAGS\" \"CFLAGS_FOR_EGLIB=$CFLAGS_FOR_EGLIB\"" AC_CONFIG_SUBDIRS(eglib) diff --git a/eglib/Makefile.am b/eglib/Makefile.am index b7e5cd63894..84cc8353c99 100644 --- a/eglib/Makefile.am +++ b/eglib/Makefile.am @@ -1,5 +1,7 @@ ACLOCAL_AMFLAGS = -I m4 +AM_CFLAGS = $(WERROR_CFLAGS) + if HOST_WIN32 SUBDIRS = m4 src else diff --git a/eglib/acinclude.m4 b/eglib/acinclude.m4 index 526d00c1be7..5216cd14a5e 100644 --- a/eglib/acinclude.m4 +++ b/eglib/acinclude.m4 @@ -22,8 +22,8 @@ if test x$GCC != xyes; then dolt_supported=no fi case $host in -i?86-*-linux*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-linux* \ -|amd64-*-freebsd*|i?86-*-freebsd*|ia64-*-freebsd*|arm*-*-linux*|sparc*-*-linux*|mips*-*-linux*) +i?86-*-linux*|i?86-apple-darwin*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-linux* \ +|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*) diff --git a/eglib/configure.ac b/eglib/configure.ac index fab57247699..80600f8565f 100644 --- a/eglib/configure.ac +++ b/eglib/configure.ac @@ -235,6 +235,12 @@ AC_ARG_WITH(crosspkgdir, [ --with-crosspkgdir=/path/to/pkg-config/dir Chan fi ) +AC_ARG_ENABLE(werror, [ --enable-werror Pass -Werror to the C compiler], werror_flag=$enableval, werror_flag=no) +if test x$werror_flag = xyes; then + WERROR_CFLAGS="-Werror" +fi +AC_SUBST([WERROR_CFLAGS]) + AC_SUBST(GPOINTER_TO_INT) AC_SUBST(GPOINTER_TO_UINT) AC_SUBST(GINT_TO_POINTER) diff --git a/eglib/src/Makefile.am b/eglib/src/Makefile.am index 0d0e90354ee..70d519ea225 100644 --- a/eglib/src/Makefile.am +++ b/eglib/src/Makefile.am @@ -1,5 +1,7 @@ noinst_LTLIBRARIES = libeglib.la libeglib-static.la +AM_CFLAGS = $(WERROR_CFLAGS) + win_files = \ eglib-config.hw \ gdate-win32.c gdir-win32.c gfile-win32.c gmisc-win32.c \ @@ -30,6 +32,7 @@ libeglib_la_SOURCES = \ garray.c \ gbytearray.c \ gerror.c \ + vasprintf.h \ ghashtable.c \ giconv.c \ gmem.c \ diff --git a/eglib/src/gerror.c b/eglib/src/gerror.c index 790c388c7ad..2ec089c9956 100644 --- a/eglib/src/gerror.c +++ b/eglib/src/gerror.c @@ -30,6 +30,8 @@ #include #include +#include "vasprintf.h" + GError * g_error_new (gpointer domain, gint code, const char *format, ...) { diff --git a/eglib/src/glib.h b/eglib/src/glib.h index cf54676312d..30c2d7adb8f 100644 --- a/eglib/src/glib.h +++ b/eglib/src/glib.h @@ -49,12 +49,6 @@ G_BEGIN_DECLS -#ifdef G_OS_WIN32 -/* MSC and Cross-compilatin will use this */ -int vasprintf (char **strp, const char *fmt, va_list ap); -#endif - - /* * Basic data types */ diff --git a/eglib/src/goutput.c b/eglib/src/goutput.c index aff9f460c57..73ef1f383de 100644 --- a/eglib/src/goutput.c +++ b/eglib/src/goutput.c @@ -31,6 +31,8 @@ #include #include +#include "vasprintf.h" + /* The current fatal levels, error is always fatal */ static GLogLevelFlags fatal = G_LOG_LEVEL_ERROR; diff --git a/eglib/src/gstr.c b/eglib/src/gstr.c index 335ccff9365..3e976c5a2ed 100644 --- a/eglib/src/gstr.c +++ b/eglib/src/gstr.c @@ -32,6 +32,8 @@ #include #include +#include "vasprintf.h" + /* This is not a macro, because I dont want to put _GNU_SOURCE in the glib.h header */ gchar * g_strndup (const gchar *str, gsize n) diff --git a/eglib/src/sort.frag.h b/eglib/src/sort.frag.h index 2cf5a9ba1f3..6dc1950ae4e 100644 --- a/eglib/src/sort.frag.h +++ b/eglib/src/sort.frag.h @@ -88,12 +88,24 @@ merge_lists (list_node *first, list_node *second, GCompareFunc func) static inline list_node * sweep_up (struct sort_info *si, list_node *list, int upto) { +#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406) + /* + * GCC incorrectly thinks we're writing below si->ranks array bounds. + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#endif + int i; for (i = si->min_rank; i < upto; ++i) { list = merge_lists (si->ranks [i], list, si->func); si->ranks [i] = NULL; } return list; + +#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406) +#pragma GCC diagnostic pop +#endif } /* @@ -124,6 +136,14 @@ sweep_up (struct sort_info *si, list_node *list, int upto) static inline void insert_list (struct sort_info *si, list_node* list, int rank) { +#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406) + /* + * GCC incorrectly thinks we're writing below si->ranks array bounds. + */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Warray-bounds" +#endif + int i; if (rank > si->n_ranks) { @@ -149,6 +169,10 @@ insert_list (struct sort_info *si, list_node* list, int rank) si->n_ranks = i + 1; si->min_rank = i; si->ranks [i] = list; + +#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406) +#pragma GCC diagnostic pop +#endif } #undef stringify2 diff --git a/eglib/src/vasprintf.h b/eglib/src/vasprintf.h new file mode 100644 index 00000000000..3d294541a5b --- /dev/null +++ b/eglib/src/vasprintf.h @@ -0,0 +1,11 @@ +#ifndef __VASPRINTF_H +#define __VASPRINTF_H + +#include +#include + +#ifndef HAVE_VASPRINTF +int vasprintf(char **ret, const char *fmt, va_list ap); +#endif + +#endif /* __VASPRINTF_H */ diff --git a/eglib/test/file.c b/eglib/test/file.c index 411c9452966..19276c990c6 100644 --- a/eglib/test/file.c +++ b/eglib/test/file.c @@ -115,7 +115,7 @@ test_file () #ifndef G_OS_WIN32 /* FIXME */ gchar *sympath; - gint ignored; + gint ignored G_GNUC_UNUSED; #endif res = g_file_test (NULL, 0); diff --git a/ikvm-native/jni.c b/ikvm-native/jni.c index dec858e131f..e638db1d76f 100644 --- a/ikvm-native/jni.c +++ b/ikvm-native/jni.c @@ -486,11 +486,15 @@ static void* JNIEnv_vtable[] = 0 // jlong JNICALL GetDirectBufferCapacity(jobject buf); }; -JNIEXPORT void** JNICALL ikvm_GetJNIEnvVTable() +void** ikvm_GetJNIEnvVTable(void); + +JNIEXPORT void** JNICALL ikvm_GetJNIEnvVTable(void) { return JNIEnv_vtable; } +void* JNICALL ikvm_MarshalDelegate(void* p); + JNIEXPORT void* JNICALL ikvm_MarshalDelegate(void* p) { return p; @@ -498,6 +502,8 @@ JNIEXPORT void* JNICALL ikvm_MarshalDelegate(void* p) typedef jint (JNICALL *PJNI_ONLOAD)(JavaVM* vm, void* reserved); +jint JNICALL ikvm_CallOnLoad(PJNI_ONLOAD method, JavaVM* vm, void* reserved); + JNIEXPORT jint JNICALL ikvm_CallOnLoad(PJNI_ONLOAD method, JavaVM* vm, void* reserved) { return method(vm, reserved); diff --git a/ikvm-native/os.c b/ikvm-native/os.c index 9f2115f712b..43531ae0ea5 100644 --- a/ikvm-native/os.c +++ b/ikvm-native/os.c @@ -61,16 +61,22 @@ #include #include "jni.h" + void* JNICALL ikvm_LoadLibrary(char* psz); + JNIEXPORT void* JNICALL ikvm_LoadLibrary(char* psz) { return g_module_open(psz, 0); } + void JNICALL ikvm_FreeLibrary(GModule* handle); + JNIEXPORT void JNICALL ikvm_FreeLibrary(GModule* handle) { g_module_close(handle); } + void* JNICALL ikvm_GetProcAddress(GModule* handle, char* name, jint argc); + JNIEXPORT void* JNICALL ikvm_GetProcAddress(GModule* handle, char* name, jint argc) { void *symbol; @@ -83,16 +89,22 @@ return NULL; } + void* JNICALL ikvm_mmap(int fd, jboolean writeable, jboolean copy_on_write, jlong position, jint size); + JNIEXPORT void* JNICALL ikvm_mmap(int fd, jboolean writeable, jboolean copy_on_write, jlong position, jint size) { return mmap(0, size, writeable ? PROT_WRITE | PROT_READ : PROT_READ, copy_on_write ? MAP_PRIVATE : MAP_SHARED, fd, position); } + int JNICALL ikvm_munmap(void* address, jint size); + JNIEXPORT int JNICALL ikvm_munmap(void* address, jint size) { return munmap(address, size); } + int JNICALL ikvm_msync(void* address, jint size); + JNIEXPORT int JNICALL ikvm_msync(void* address, jint size) { #if defined(__native_client__) && defined(USE_NEWLIB) diff --git a/libgc/Makefile.am b/libgc/Makefile.am index 49dbe4be81c..a53aafcbf3e 100644 --- a/libgc/Makefile.am +++ b/libgc/Makefile.am @@ -68,7 +68,7 @@ libmonogc_static_la_LDFLAGS = -static EXTRA_DIST += alpha_mach_dep.S mips_sgi_mach_dep.s sparc_mach_dep.S -AM_CFLAGS = @GC_CFLAGS@ +AM_CFLAGS = $(WERROR_CFLAGS) @GC_CFLAGS@ if CPLUSPLUS extra_checks = test_cpp diff --git a/libgc/acinclude.m4 b/libgc/acinclude.m4 index 526d00c1be7..5216cd14a5e 100644 --- a/libgc/acinclude.m4 +++ b/libgc/acinclude.m4 @@ -22,8 +22,8 @@ if test x$GCC != xyes; then dolt_supported=no fi case $host in -i?86-*-linux*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-linux* \ -|amd64-*-freebsd*|i?86-*-freebsd*|ia64-*-freebsd*|arm*-*-linux*|sparc*-*-linux*|mips*-*-linux*) +i?86-*-linux*|i?86-apple-darwin*|x86_64-*-linux*|powerpc-*-linux*|powerpc64-*-linux* \ +|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*) diff --git a/libgc/configure.ac b/libgc/configure.ac index 837e2cb9f15..7dc04985a90 100644 --- a/libgc/configure.ac +++ b/libgc/configure.ac @@ -531,6 +531,12 @@ fi AC_ARG_ENABLE(quiet-build, [ --enable-quiet-build Enable quiet libgc build (on by default)], enable_quiet_build=$enableval, enable_quiet_build=yes) AM_CONDITIONAL(USE_LIBDIR, test -z "$with_cross_host") +AC_ARG_ENABLE(werror, [ --enable-werror Pass -Werror to the C compiler], werror_flag=$enableval, werror_flag=no) +if test x$werror_flag = xyes; then + WERROR_CFLAGS="-Werror" +fi +AC_SUBST([WERROR_CFLAGS]) + if test "${multilib}" = "yes"; then multilib_arg="--enable-multilib" else diff --git a/libgc/mark_rts.c b/libgc/mark_rts.c index 4074879a71a..b3e996a29c2 100644 --- a/libgc/mark_rts.c +++ b/libgc/mark_rts.c @@ -375,8 +375,15 @@ ptr_t GC_approx_sp() /* doing something wrong. */ # ifdef _MSC_VER # pragma warning(disable:4172) +# endif +# if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 408) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wreturn-local-addr" # endif return((ptr_t)(&dummy)); +# if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 408) +# pragma GCC diagnostic pop +# endif # ifdef _MSC_VER # pragma warning(default:4172) # endif diff --git a/man/mprof-report.1 b/man/mprof-report.1 index de40af60d8e..4b1b7816817 100644 --- a/man/mprof-report.1 +++ b/man/mprof-report.1 @@ -211,6 +211,15 @@ The following commands are available: .IP \[bu] 2 \f[I]heapshot\f[]: perform a heapshot as soon as possible .RE +.IP \[bu] 2 +\f[I]counters\f[]: sample counters values every 1 second. This allow +a really lightweight way to have insight in some of the runtime key +metrics. Counters displayed in non verbose mode are : Methods from AOT, +Methods JITted using mono JIT, Methods JITted using LLVM, Total time +spent JITting (sec), User Time, System Time, Total Time, Working Set, +Private Bytes, Virtual Bytes, Page Faults and CPU Load Average (1min, +5min and 15min). +.RE .SS Analyzing the profile data .PP Currently there is a command line program (\f[I]mprof-report\f[]) @@ -284,6 +293,16 @@ where \f[I]MODE\f[] can be: .IP \[bu] 2 \f[I]bytes\f[]: the total number of bytes used by objects of the given type +.PP +To change the sort order of counters, use the option: +.PP +\f[B]--counters-sort=MODE\f[] +.PP +where \f[I]MODE\f[] can be: +.IP \[bu] 2 +\f[I]time\f[]: sort values by time then category +.IP \[bu] 2 +\f[I]category\f[]: sort values by category then time .SS Selecting what data to report .PP The profiler by default collects data about many runtime subsystems @@ -319,6 +338,8 @@ version \f[I]thread\f[]: thread information .IP \[bu] 2 \f[I]heapshot\f[]: live heap usage at heap shots +.IP \[bu] 2 +\f[I]counters\f[]: counters samples .PP It is possible to limit some of the data displayed to a timeframe of the program execution with the option: diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms.X11Internal/X11Display.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms.X11Internal/X11Display.cs index 43b39dcd4fc..a15b747d188 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms.X11Internal/X11Display.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms.X11Internal/X11Display.cs @@ -104,7 +104,7 @@ namespace System.Windows.Forms.X11Internal { { if (display == IntPtr.Zero) { throw new ArgumentNullException("Display", - "Could not open display (X-Server required. Check you DISPLAY environment variable)"); + "Could not open display (X-Server required. Check your DISPLAY environment variable)"); } this.display = display; diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs index e05a093aac5..1f3af258464 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs @@ -552,7 +552,7 @@ namespace System.Windows.Forms { ErrorHandler = new XErrorHandler(HandleError); XSetErrorHandler(ErrorHandler); } else { - throw new ArgumentNullException("Display", "Could not open display (X-Server required. Check you DISPLAY environment variable)"); + throw new ArgumentNullException("Display", "Could not open display (X-Server required. Check your DISPLAY environment variable)"); } } #endregion // Internal Methods diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11GTK.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11GTK.cs index 77e89c4975a..b8820a9bed0 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11GTK.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11GTK.cs @@ -708,7 +708,7 @@ namespace System.Windows.Forms { ErrorHandler = new XErrorHandler (HandleError); XSetErrorHandler (ErrorHandler); } else { - throw new ArgumentNullException ("Display", "Could not open display (X-Server required. Check you DISPLAY environment variable)"); + throw new ArgumentNullException ("Display", "Could not open display (X-Server required. Check your DISPLAY environment variable)"); } } #endregion // Internal Methods diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ILInterpreter.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ILInterpreter.cs index e0175f36bdf..b4d6073819c 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ILInterpreter.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/ILInterpreter.cs @@ -23,67 +23,347 @@ namespace Mono.Debugger.Soft // IL_0008: br IL_000d // IL_000d: ldloc.0 // IL_000e: ret + // ... or returns a simple constant: + // IL_0000: ldc.i4 1024 + // IL_0005: conv.i8 + // IL_0006: ret if (args != null && args.Length != 0) - throw new NotSupportedException (); + throw new NotSupportedException (); + if (method.IsStatic || method.DeclaringType.IsValueType || this_val == null || !(this_val is ObjectMirror)) throw new NotSupportedException (); var instructions = body.Instructions; - if (instructions.Count > 16) + if (instructions.Count < 1 || instructions.Count > 16) throw new NotSupportedException (); - Value[] stack = new Value [16]; + var stack = new Value [16]; + var ins = instructions [0]; Value locals_0 = null; - Value res = null; - - int sp = 0; int ins_count = 0; - var ins = instructions [0]; + int sp = 0; + while (ins != null) { if (ins_count > 16) throw new NotImplementedException (); - ins_count ++; + var next = ins.Next; + ins_count++; var op = ins.OpCode; if (op == OpCodes.Nop) { } else if (op == OpCodes.Ldarg_0) { - if (sp > 0) + if (sp != 0) throw new NotSupportedException (); + stack [sp++] = this_val; } else if (op == OpCodes.Ldfld) { if (sp != 1) throw new NotSupportedException (); - var obj = (ObjectMirror)stack [--sp]; - var field = (FieldInfoMirror)ins.Operand; + + var obj = (ObjectMirror) stack [--sp]; + var field = (FieldInfoMirror) ins.Operand; try { stack [sp++] = obj.GetValue (field); } catch (ArgumentException) { throw new NotSupportedException (); } + } else if (op == OpCodes.Ldc_I4_0) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 0); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_1) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 1); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_2) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 2); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_3) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 3); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_4) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 4); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_5) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 5); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_6) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 6); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_7) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 7); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_8) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, 8); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_M1) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, -1); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I4_S) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_I8) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_R4) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Ldc_R8) { + if (sp != 0) + throw new NotSupportedException (); + + try { + stack [sp++] = new PrimitiveValue (method.VirtualMachine, ins.Operand); + } catch (ArgumentException) { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_I) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToInt32 (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_I1) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToSByte (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_U1) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToByte (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_I2) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToInt16 (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_U2) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt16 (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_I4) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToInt32 (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_U4) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt32 (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_I8) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToInt64 (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_U8) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt64 (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_R4) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToSingle (primitive.Value)); + } catch { + throw new NotSupportedException (); + } + } else if (op == OpCodes.Conv_R8) { + if (sp != 1) + throw new NotSupportedException (); + + try { + var primitive = (PrimitiveValue) stack [--sp]; + stack [sp++] = new PrimitiveValue (method.VirtualMachine, Convert.ToDouble (primitive.Value)); + } catch { + throw new NotSupportedException (); + } } else if (op == OpCodes.Stloc_0) { if (sp != 1) throw new NotSupportedException (); + locals_0 = stack [--sp]; } else if (op == OpCodes.Br) { - next = (ILInstruction)ins.Operand; + next = (ILInstruction) ins.Operand; } else if (op == OpCodes.Ldloc_0) { if (sp != 0) throw new NotSupportedException (); + stack [sp++] = locals_0; } else if (op == OpCodes.Ret) { - if (sp == 0) - res = null; - else - res = stack [--sp]; - break; + if (sp > 0) { + var res = stack [--sp]; + + var primitive = res as PrimitiveValue; + if (method.ReturnType.IsPrimitive && primitive != null) { + // cast the primitive value to the return type + try { + switch (method.ReturnType.CSharpName) { + case "double": res = new PrimitiveValue (method.VirtualMachine, Convert.ToDouble (primitive.Value)); break; + case "float": res = new PrimitiveValue (method.VirtualMachine, Convert.ToSingle (primitive.Value)); break; + case "ulong": res = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt64 (primitive.Value)); break; + case "long": res = new PrimitiveValue (method.VirtualMachine, Convert.ToInt64 (primitive.Value)); break; + case "uint": res = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt32 (primitive.Value)); break; + case "int": res = new PrimitiveValue (method.VirtualMachine, Convert.ToInt32 (primitive.Value)); break; + case "ushort": res = new PrimitiveValue (method.VirtualMachine, Convert.ToUInt16 (primitive.Value)); break; + case "short": res = new PrimitiveValue (method.VirtualMachine, Convert.ToInt16 (primitive.Value)); break; + case "sbyte": res = new PrimitiveValue (method.VirtualMachine, Convert.ToSByte (primitive.Value)); break; + case "byte": res = new PrimitiveValue (method.VirtualMachine, Convert.ToByte (primitive.Value)); break; + case "char": res = new PrimitiveValue (method.VirtualMachine, Convert.ToChar (primitive.Value)); break; + case "bool": res = new PrimitiveValue (method.VirtualMachine, Convert.ToBoolean (primitive.Value)); break; + } + } catch { + throw new NotSupportedException (); + } + } + + return res; + } + + return null; } else { throw new NotSupportedException (); } + ins = next; } - return res; + return null; } } } diff --git a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/PrimitiveValue.cs b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/PrimitiveValue.cs index 696f6493f40..2e9c806f8bb 100644 --- a/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/PrimitiveValue.cs +++ b/mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/PrimitiveValue.cs @@ -22,8 +22,11 @@ namespace Mono.Debugger.Soft public override bool Equals (object obj) { if (value == obj) return true; - if (obj != null && obj is PrimitiveValue) - return value == (obj as PrimitiveValue).Value; + + var primitive = obj as PrimitiveValue; + if (primitive != null) + return value == primitive.Value; + return base.Equals (obj); } diff --git a/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafeMemoryMappedViewHandle.cs b/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafeMemoryMappedViewHandle.cs index b7cf6b04c72..73f12afc504 100644 --- a/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafeMemoryMappedViewHandle.cs +++ b/mcs/class/System.Core/Microsoft.Win32.SafeHandles/SafeMemoryMappedViewHandle.cs @@ -37,14 +37,17 @@ using Microsoft.Win32.SafeHandles; namespace Microsoft.Win32.SafeHandles { public sealed class SafeMemoryMappedViewHandle : SafeBuffer { - internal SafeMemoryMappedViewHandle (IntPtr handle, long size) : base (true) { - this.handle = handle; + IntPtr mmap_handle; + + internal SafeMemoryMappedViewHandle (IntPtr mmap_handle, IntPtr base_address, long size) : base (true) { + this.mmap_handle = mmap_handle; + this.handle = base_address; Initialize ((ulong)size); } protected override bool ReleaseHandle () { if (this.handle != (IntPtr) (-1)) - return MemoryMapImpl.Unmap (this.handle, ByteLength); + return MemoryMapImpl.Unmap (this.mmap_handle); throw new NotImplementedException (); } } diff --git a/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedFile.cs b/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedFile.cs index 7fa4586a44b..feaaa5ab984 100644 --- a/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedFile.cs +++ b/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedFile.cs @@ -32,464 +32,84 @@ using System.IO; using System.Collections.Generic; using Microsoft.Win32.SafeHandles; using System.Runtime.InteropServices; - - -#if !MOBILE -using Mono.Unix.Native; -using Mono.Unix; -#else using System.Runtime.CompilerServices; -#endif + namespace System.IO.MemoryMappedFiles { - internal static partial class MemoryMapImpl { - static Exception ArgumentCapacity () - { - return new ArgumentException ("A positive capacity must be specified for a Memory Mapped File backed by an empty file."); - } - - static Exception CapacitySmallerThanSize () - { - return new ArgumentOutOfRangeException ("The capacity may not be smaller than the file size."); - } - } - - -#if !MOBILE - partial class MemoryMapImpl { - // - // Turns the FileMode into the first half of open(2) flags - // - static OpenFlags ToUnixMode (FileMode mode) - { - switch (mode){ - case FileMode.CreateNew: - return OpenFlags.O_CREAT | OpenFlags.O_EXCL; - - case FileMode.Create: - return OpenFlags.O_CREAT | OpenFlags.O_TRUNC; - - case FileMode.OpenOrCreate: - return OpenFlags.O_CREAT; - - case FileMode.Truncate: - return OpenFlags.O_TRUNC; - - case FileMode.Append: - return OpenFlags.O_APPEND; - default: - case FileMode.Open: - return 0; - } - } - - // - // Turns the MemoryMappedFileAccess into the second half of open(2) flags - // - static OpenFlags ToUnixMode (MemoryMappedFileAccess access) - { - switch (access){ - case MemoryMappedFileAccess.CopyOnWrite: - case MemoryMappedFileAccess.ReadWriteExecute: - case MemoryMappedFileAccess.ReadWrite: - return OpenFlags.O_RDWR; - - case MemoryMappedFileAccess.Write: - return OpenFlags.O_WRONLY; - - case MemoryMappedFileAccess.ReadExecute: - case MemoryMappedFileAccess.Read: - default: - return OpenFlags.O_RDONLY; - } - } - - static MmapProts ToUnixProts (MemoryMappedFileAccess access) - { - switch (access){ - case MemoryMappedFileAccess.ReadWrite: - return MmapProts.PROT_WRITE | MmapProts.PROT_READ; - - case MemoryMappedFileAccess.Write: - return MmapProts.PROT_WRITE; - - case MemoryMappedFileAccess.CopyOnWrite: - return MmapProts.PROT_WRITE | MmapProts.PROT_READ; - - case MemoryMappedFileAccess.ReadExecute: - return MmapProts.PROT_EXEC; - - case MemoryMappedFileAccess.ReadWriteExecute: - return MmapProts.PROT_WRITE | MmapProts.PROT_READ | MmapProts.PROT_EXEC; - - case MemoryMappedFileAccess.Read: - default: - return MmapProts.PROT_READ; - } - } - - internal static int Open (string path, FileMode mode, ref long capacity, MemoryMappedFileAccess access) - { - if (MonoUtil.IsUnix){ - Stat buf; - - int result = Syscall.stat (path, out buf); - - if (mode == FileMode.Truncate || mode == FileMode.Append || mode == FileMode.Open){ - if (result == -1) - UnixMarshal.ThrowExceptionForLastError (); - } - if (mode == FileMode.CreateNew && result == 0) - throw new IOException ("The file already exists"); - - if (result == 0){ - if (capacity == 0) { - // Special files such as FIFOs, sockets, and devices can - // have a size of 0. Specifying a capacity for these - // also makes little sense, so don't do the check if the - // file is one of these. - if (buf.st_size == 0 && - (buf.st_mode & (FilePermissions.S_IFCHR | - FilePermissions.S_IFBLK | - FilePermissions.S_IFIFO | - FilePermissions.S_IFSOCK)) == 0) { - throw ArgumentCapacity (); - } - - capacity = buf.st_size; - } else if (capacity < buf.st_size) { - throw CapacitySmallerThanSize (); - } - } else { - if (mode == FileMode.CreateNew){ - if (capacity == 0) - throw ArgumentCapacity (); - } - } - - int fd = Syscall.open (path, ToUnixMode (mode) | ToUnixMode (access), FilePermissions.DEFFILEMODE); - - if (fd == -1) - UnixMarshal.ThrowExceptionForLastError (); - return fd; - } - - throw new NotImplementedException (); - } - - internal static void CloseFD (int fd) { - Syscall.close (fd); - } - - internal static void Flush (int fd) { - if (MonoUtil.IsUnix) - Syscall.fsync (fd); - else - throw new NotImplementedException ("Not implemented on Windows"); - - } - - static int pagesize; - - internal static unsafe void Map (int file_handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr map_addr, out int offset_diff) - { - if (!MonoUtil.IsUnix) - throw new NotImplementedException ("Not implemented on windows."); - - if (pagesize == 0) - pagesize = Syscall.getpagesize (); - - Stat buf; - Syscall.fstat (file_handle, out buf); - long fsize = buf.st_size; - - if (size == 0 || size > fsize) - size = fsize; - - // Align offset - long real_offset = offset & ~(pagesize - 1); - - offset_diff = (int)(offset - real_offset); - - // FIXME: Need to determine the unix fd for the file, Handle is only - // equal to it by accident - // - // The new API no longer uses FileStream everywhere, but exposes instead - // the filename (with one exception), we could move this API to use - // file descriptors instead of the FileStream plus its Handle. - // - map_addr = Syscall.mmap (IntPtr.Zero, (ulong) size, - ToUnixProts (access), - access == MemoryMappedFileAccess.CopyOnWrite ? MmapFlags.MAP_PRIVATE : MmapFlags.MAP_SHARED, - file_handle, real_offset); - - if (map_addr == (IntPtr)(-1)) - throw new IOException ("mmap failed for fd#" + file_handle + "(" + offset + ", " + size + ")"); - } - - internal static bool Unmap (IntPtr map_addr, ulong map_size) - { - if (!MonoUtil.IsUnix) - return false; - return Syscall.munmap (map_addr, map_size) == 0; - } - - static void ConfigureUnixFD (IntPtr handle, HandleInheritability h) - { - // TODO: Mono.Posix is lacking O_CLOEXEC definitions for fcntl. - } - - - [DllImport("kernel32", SetLastError = true)] - static extern bool SetHandleInformation (IntPtr hObject, int dwMask, int dwFlags); - static void ConfigureWindowsFD (IntPtr handle, HandleInheritability h) - { - SetHandleInformation (handle, 1 /* FLAG_INHERIT */, h == HandleInheritability.None ? 0 : 1); - } - - internal static void ConfigureFD (IntPtr handle, HandleInheritability inheritability) - { - if (MonoUtil.IsUnix) - ConfigureUnixFD (handle, inheritability); - else - ConfigureWindowsFD (handle, inheritability); - } - - } -#else - partial class MemoryMapImpl { - [DllImport ("libc")] - static extern int fsync (int fd); - - [DllImport ("libc")] - static extern int close (int fd); - - [DllImport ("libc")] - static extern int fcntl (int fd, int cmd, int arg0); - - //XXX check if android off_t is 64bits or not. on iOS / darwin it is. - [DllImport ("libc")] - static extern IntPtr mmap (IntPtr addr, IntPtr len, int prot, int flags, int fd, long offset); - - [DllImport ("libc")] - static extern int munmap (IntPtr addr, IntPtr size); - - [DllImport ("libc", SetLastError=true)] - static extern int open (string path, int flags, int access); - -#if MONODROID - [DllImport ("__Internal")] - static extern int monodroid_getpagesize (); - - static int getpagesize () - { - return monodroid_getpagesize (); - } -#else - [DllImport ("libc")] - static extern int getpagesize (); -#endif - + internal static class MemoryMapImpl { [MethodImplAttribute (MethodImplOptions.InternalCall)] - static extern long mono_filesize_from_path (string str); + static extern IntPtr OpenFileInternal (string path, FileMode mode, string mapName, out long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, out int error); [MethodImplAttribute (MethodImplOptions.InternalCall)] - static extern long mono_filesize_from_fd (int fd); - - //Values valid on iOS/OSX and android ndk r6 - const int F_GETFD = 1; - const int F_SETFD = 2; - const int FD_CLOEXEC = 1; - const int DEFFILEMODE = 0x666; - - const int O_RDONLY = 0x0; - const int O_WRONLY = 0x1; - const int O_RDWR = 0x2; + static extern IntPtr OpenHandleInternal (IntPtr handle, string mapName, out long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, out int error); - const int PROT_READ = 0x1; - const int PROT_WRITE = 0x2; - const int PROT_EXEC = 0x4; - - const int MAP_PRIVATE = 0x2; - const int MAP_SHARED = 0x1; - - const int EINVAL = 22; - -#if MONODROID - const int O_CREAT = 0x040; - const int O_TRUNC = 0x080; - const int O_EXCL = 0x200; - - const int ENAMETOOLONG = 63; -#else - /* MONOTOUCH - usr/include/sys/fcntl.h */ - const int O_CREAT = 0x0200; - const int O_TRUNC = 0x0400; - const int O_EXCL = 0x0800; - - // usr/include/sys/errno.h - const int ENAMETOOLONG = 63; -#endif + [MethodImplAttribute (MethodImplOptions.InternalCall)] + internal extern static void CloseMapping (IntPtr handle); - static int ToUnixMode (FileMode mode) - { - switch (mode) { - case FileMode.CreateNew: - return O_CREAT | O_EXCL; - - case FileMode.Create: - return O_CREAT | O_TRUNC; - - case FileMode.OpenOrCreate: - return O_CREAT; - - case FileMode.Truncate: - return O_TRUNC; - default: - case FileMode.Open: - return 0; - } - } + [MethodImplAttribute (MethodImplOptions.InternalCall)] + internal extern static void Flush (IntPtr file_handle); - // - // Turns the MemoryMappedFileAccess into the second half of open(2) flags - // - static int ToUnixMode (MemoryMappedFileAccess access) - { - switch (access) { - case MemoryMappedFileAccess.CopyOnWrite: - case MemoryMappedFileAccess.ReadWriteExecute: - case MemoryMappedFileAccess.ReadWrite: - return O_RDWR; - - case MemoryMappedFileAccess.Write: - return O_WRONLY; + [MethodImplAttribute (MethodImplOptions.InternalCall)] + internal extern static void ConfigureHandleInheritability (IntPtr handle, HandleInheritability inheritability); - case MemoryMappedFileAccess.ReadExecute: - case MemoryMappedFileAccess.Read: - default: - return O_RDONLY; - } - } + [MethodImplAttribute (MethodImplOptions.InternalCall)] + internal extern static bool Unmap (IntPtr mmap_handle); - static int ToUnixProts (MemoryMappedFileAccess access) - { - switch (access){ - case MemoryMappedFileAccess.ReadWrite: - return PROT_WRITE | PROT_READ; - - case MemoryMappedFileAccess.Write: - return PROT_WRITE; - - case MemoryMappedFileAccess.CopyOnWrite: - return PROT_WRITE | PROT_READ; - - case MemoryMappedFileAccess.ReadExecute: - return PROT_EXEC; - - case MemoryMappedFileAccess.ReadWriteExecute: - return PROT_WRITE | PROT_READ | PROT_EXEC; - - case MemoryMappedFileAccess.Read: + [MethodImplAttribute (MethodImplOptions.InternalCall)] + extern static int MapInternal (IntPtr handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr mmap_handle, out IntPtr base_address); + + internal static void Map (IntPtr handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr mmap_handle, out IntPtr base_address) + { + int error = MapInternal (handle, offset, ref size, access, out mmap_handle, out base_address); + if (error != 0) + throw CreateException (error, ""); + } + + static Exception CreateException (int error, string path) { + switch (error){ + case 1: + return new ArgumentException ("A positive capacity must be specified for a Memory Mapped File backed by an empty file."); + case 2: + return new ArgumentOutOfRangeException ("The capacity may not be smaller than the file size."); + case 3: + return new FileNotFoundException (path); + case 4: + return new IOException ("The file already exists"); + case 5: + return new PathTooLongException (); + case 6: + return new IOException ("Could not open file"); + case 7: + return new ArgumentException ("Capacity must be bigger than zero for non-file mappings"); + case 8: + return new ArgumentException ("Invalid FileMode value."); + case 9: + return new IOException ("Could not map file"); default: - return PROT_READ; + return new IOException ("Failed with unknown error code " + error); } } - static void ThrowErrorFromErrno (int errno) + internal static IntPtr OpenFile (string path, FileMode mode, string mapName, out long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options) { - switch (errno) { - case EINVAL: throw new ArgumentException (); - case ENAMETOOLONG: throw new PathTooLongException (); - default: throw new IOException ("Failed with errno " + errno); - } - } - - internal static int Open (string path, FileMode mode, ref long capacity, MemoryMappedFileAccess access) - { - long file_size = mono_filesize_from_path (path); - - Console.WriteLine ("{0} is {1} big", path, file_size); - if (mode == FileMode.Truncate || mode == FileMode.Append || mode == FileMode.Open){ - if (file_size < 0) - throw new FileNotFoundException (path); - if (capacity == 0) - capacity = file_size; - if (capacity < file_size) - throw CapacitySmallerThanSize (); - } else { - if (mode == FileMode.CreateNew){ - if (file_size >= 0) - throw new IOException ("The file already exists"); - if (capacity == 0) - throw ArgumentCapacity (); - } - } - - int fd = open (path, ToUnixMode (mode) | ToUnixMode (access), DEFFILEMODE); - - if (fd == -1) - ThrowErrorFromErrno (Marshal.GetLastWin32Error ()); - return fd; - } - - internal static void CloseFD (int fd) - { - close (fd); - } - - internal static void Flush (int fd) - { - fsync (fd); - } - - internal static bool Unmap (IntPtr map_addr, ulong map_size) - { - return munmap (map_addr, (IntPtr)map_size) == 0; - } - - static int pagesize; - - internal static unsafe void Map (int file_handle, long offset, ref long size, MemoryMappedFileAccess access, out IntPtr map_addr, out int offset_diff) - { - if (pagesize == 0) - pagesize = getpagesize (); - - long fsize = mono_filesize_from_fd (file_handle); - if (fsize < 0) - throw new FileNotFoundException (); - - if (size == 0 || size > fsize) - size = fsize; - - // Align offset - long real_offset = offset & ~(pagesize - 1); - - offset_diff = (int)(offset - real_offset); - - map_addr = mmap (IntPtr.Zero, (IntPtr) size, - ToUnixProts (access), - access == MemoryMappedFileAccess.CopyOnWrite ? MAP_PRIVATE : MAP_SHARED, - file_handle, real_offset); - - if (map_addr == (IntPtr)(-1)) - throw new IOException ("mmap failed for fd#" + file_handle + "(" + offset + ", " + size + ")"); + int error = 0; + IntPtr res = OpenFileInternal (path, mode, mapName, out capacity, access, options, out error); + if (error != 0) + throw CreateException (error, path); + return res; } - internal static void ConfigureFD (IntPtr handle, HandleInheritability inheritability) + internal static IntPtr OpenHandle (IntPtr handle, string mapName, out long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options) { - int fd = (int)handle; - int flags = fcntl (fd, F_GETFD, 0); - if (inheritability == HandleInheritability.None) - flags &= ~FD_CLOEXEC; - else - flags |= FD_CLOEXEC; - fcntl (fd, F_SETFD, flags); + int error = 0; + IntPtr res = OpenHandleInternal (handle, mapName, out capacity, access, options, out error); + if (error != 0) + throw CreateException (error, ""); + return res; } - } -#endif + public class MemoryMappedFile : IDisposable { MemoryMappedFileAccess fileAccess; @@ -504,7 +124,7 @@ namespace System.IO.MemoryMappedFiles // FileStream stream; bool keepOpen; - int unix_fd; + IntPtr handle; public static MemoryMappedFile CreateFromFile (string path) { @@ -513,7 +133,21 @@ namespace System.IO.MemoryMappedFiles public static MemoryMappedFile CreateFromFile (string path, FileMode mode) { - return CreateFromFile (path, mode, null, 0, MemoryMappedFileAccess.ReadWrite); + long capacity = 0; + if (path == null) + throw new ArgumentNullException ("path"); + if (path.Length == 0) + throw new ArgumentException ("path"); + if (mode == FileMode.Append) + throw new ArgumentException ("mode"); + + IntPtr handle = MemoryMapImpl.OpenFile (path, mode, null, out capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages); + + return new MemoryMappedFile () { + handle = handle, + fileAccess = MemoryMappedFileAccess.ReadWrite, + fileCapacity = capacity + }; } public static MemoryMappedFile CreateFromFile (string path, FileMode mode, string mapName) @@ -539,26 +173,21 @@ namespace System.IO.MemoryMappedFiles if (capacity < 0) throw new ArgumentOutOfRangeException ("capacity"); - int fd = MemoryMapImpl.Open (path, mode, ref capacity, access); + IntPtr handle = MemoryMapImpl.OpenFile (path, mode, mapName, out capacity, access, MemoryMappedFileOptions.DelayAllocatePages); return new MemoryMappedFile () { - unix_fd = fd, + handle = handle, fileAccess = access, name = mapName, fileCapacity = capacity }; } -#if MOBILE - public static MemoryMappedFile CreateFromFile (FileStream fileStream, string mapName, long capacity, MemoryMappedFileAccess access, - HandleInheritability inheritability, - bool leaveOpen) -#else + [MonoLimitation ("memoryMappedFileSecurity is currently ignored")] public static MemoryMappedFile CreateFromFile (FileStream fileStream, string mapName, long capacity, MemoryMappedFileAccess access, MemoryMappedFileSecurity memoryMappedFileSecurity, HandleInheritability inheritability, bool leaveOpen) -#endif { if (fileStream == null) throw new ArgumentNullException ("fileStream"); @@ -567,86 +196,92 @@ namespace System.IO.MemoryMappedFiles if ((!MonoUtil.IsUnix && capacity == 0 && fileStream.Length == 0) || (capacity > fileStream.Length)) throw new ArgumentException ("capacity"); - MemoryMapImpl.ConfigureFD (fileStream.Handle, inheritability); + IntPtr handle = MemoryMapImpl.OpenHandle (fileStream.Handle, mapName, out capacity, access, MemoryMappedFileOptions.DelayAllocatePages); + + MemoryMapImpl.ConfigureHandleInheritability (handle, inheritability); return new MemoryMappedFile () { - stream = fileStream, + handle = handle, fileAccess = access, name = mapName, fileCapacity = capacity, + + stream = fileStream, keepOpen = leaveOpen }; } - [MonoLimitation ("CreateNew requires that mapName be a file name on Unix")] + + static MemoryMappedFile CoreShmCreate (string mapName, long capacity, MemoryMappedFileAccess access, + MemoryMappedFileOptions options, MemoryMappedFileSecurity memoryMappedFileSecurity, + HandleInheritability inheritability, FileMode mode) + { + if (mapName != null && mapName.Length == 0) + throw new ArgumentException ("mapName"); + if (capacity < 0) + throw new ArgumentOutOfRangeException ("capacity"); + + IntPtr handle = MemoryMapImpl.OpenFile (null, mode, mapName, out capacity, access, options); + + return new MemoryMappedFile () { + handle = handle, + fileAccess = access, + name = mapName, + fileCapacity = capacity + }; + } + + [MonoLimitation ("Named mappings scope is process local")] public static MemoryMappedFile CreateNew (string mapName, long capacity) { -#if MOBILE - return CreateNew (mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, 0); -#else - return CreateNew (mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, null, 0); -#endif + return CreateNew (mapName, capacity, MemoryMappedFileAccess.ReadWrite, MemoryMappedFileOptions.DelayAllocatePages, null, HandleInheritability.None); } - [MonoLimitation ("CreateNew requires that mapName be a file name on Unix")] + [MonoLimitation ("Named mappings scope is process local")] public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access) { -#if MOBILE - return CreateNew (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, 0); -#else - return CreateNew (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, null, 0); -#endif + return CreateNew (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, null, HandleInheritability.None); } -#if MOBILE - public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access, - MemoryMappedFileOptions options, - HandleInheritability handleInheritability) -#else - [MonoLimitation ("CreateNew requires that mapName be a file name on Unix; options and memoryMappedFileSecurity are ignored")] + [MonoLimitation ("Named mappings scope is process local; options and memoryMappedFileSecurity are ignored")] public static MemoryMappedFile CreateNew (string mapName, long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, MemoryMappedFileSecurity memoryMappedFileSecurity, HandleInheritability inheritability) -#endif { - return CreateFromFile (mapName, FileMode.CreateNew, mapName, capacity, access); + return CoreShmCreate (mapName, capacity, access, options, memoryMappedFileSecurity, inheritability, FileMode.CreateNew); } - [MonoLimitation ("CreateOrOpen requires that mapName be a file name on Unix")] + [MonoLimitation ("Named mappings scope is process local")] public static MemoryMappedFile CreateOrOpen (string mapName, long capacity) { return CreateOrOpen (mapName, capacity, MemoryMappedFileAccess.ReadWrite); } - [MonoLimitation ("CreateOrOpen requires that mapName be a file name on Unix")] + [MonoLimitation ("Named mappings scope is process local")] public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access) { - return CreateFromFile (mapName, FileMode.OpenOrCreate, mapName, capacity, access); + return CreateOrOpen (mapName, capacity, access, MemoryMappedFileOptions.DelayAllocatePages, null, HandleInheritability.None); } - [MonoTODO] -#if MOBILE - public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, HandleInheritability inheritability) -#else + [MonoLimitation ("Named mappings scope is process local")] public static MemoryMappedFile CreateOrOpen (string mapName, long capacity, MemoryMappedFileAccess access, MemoryMappedFileOptions options, MemoryMappedFileSecurity memoryMappedFileSecurity, HandleInheritability inheritability) -#endif { - throw new NotImplementedException (); + return CoreShmCreate (mapName, capacity, access, options, memoryMappedFileSecurity, inheritability, FileMode.OpenOrCreate); } - [MonoTODO] + [MonoLimitation ("Named mappings scope is process local")] public static MemoryMappedFile OpenExisting (string mapName) { throw new NotImplementedException (); } - [MonoTODO] + [MonoLimitation ("Named mappings scope is process local")] public static MemoryMappedFile OpenExisting (string mapName, MemoryMappedFileRights desiredAccessRights) { throw new NotImplementedException (); } - [MonoTODO] + [MonoLimitation ("Named mappings scope is process local")] public static MemoryMappedFile OpenExisting (string mapName, MemoryMappedFileRights desiredAccessRights, HandleInheritability inheritability) { throw new NotImplementedException (); @@ -654,7 +289,7 @@ namespace System.IO.MemoryMappedFiles public MemoryMappedViewStream CreateViewStream () { - return CreateViewStream (0, 0); + return CreateViewStream (0, 0);//FIXME this is wrong } public MemoryMappedViewStream CreateViewStream (long offset, long size) @@ -664,7 +299,7 @@ namespace System.IO.MemoryMappedFiles public MemoryMappedViewStream CreateViewStream (long offset, long size, MemoryMappedFileAccess access) { - return new MemoryMappedViewStream (stream != null ? (int)stream.Handle : unix_fd, offset, size, access); + return new MemoryMappedViewStream (handle, offset, size, access); } public MemoryMappedViewAccessor CreateViewAccessor () @@ -679,9 +314,7 @@ namespace System.IO.MemoryMappedFiles public MemoryMappedViewAccessor CreateViewAccessor (long offset, long size, MemoryMappedFileAccess access) { - int file_handle = stream != null ? (int) stream.Handle : unix_fd; - - return new MemoryMappedViewAccessor (file_handle, offset, size, access); + return new MemoryMappedViewAccessor (handle, offset, size, access); } MemoryMappedFile () @@ -699,17 +332,15 @@ namespace System.IO.MemoryMappedFiles if (stream != null){ if (keepOpen == false) stream.Close (); - unix_fd = -1; stream = null; } - if (unix_fd != -1) { - MemoryMapImpl.CloseFD (unix_fd); - unix_fd = -1; + if (handle != IntPtr.Zero) { + MemoryMapImpl.CloseMapping (handle); + handle = IntPtr.Zero; } } } -#if !MOBILE [MonoTODO] public MemoryMappedFileSecurity GetAccessControl () { @@ -721,7 +352,6 @@ namespace System.IO.MemoryMappedFiles { throw new NotImplementedException (); } -#endif [MonoTODO] public SafeMemoryMappedFileHandle SafeMemoryMappedFileHandle { diff --git a/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedViewAccessor.cs b/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedViewAccessor.cs index 0535337210d..c66acdb55c6 100644 --- a/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedViewAccessor.cs +++ b/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedViewAccessor.cs @@ -36,14 +36,12 @@ using Microsoft.Win32.SafeHandles; namespace System.IO.MemoryMappedFiles { public sealed class MemoryMappedViewAccessor : UnmanagedMemoryAccessor, IDisposable { - int file_handle; - IntPtr mmap_addr; - SafeMemoryMappedViewHandle handle; + IntPtr mmap_handle; + SafeMemoryMappedViewHandle safe_handle; - internal MemoryMappedViewAccessor (int file_handle, long offset, long size, MemoryMappedFileAccess access) + internal MemoryMappedViewAccessor (IntPtr handle, long offset, long size, MemoryMappedFileAccess access) { - this.file_handle = file_handle; - Create (offset, size, access); + Create (handle, offset, size, access); } static FileAccess ToFileAccess (MemoryMappedFileAccess access) @@ -64,19 +62,19 @@ namespace System.IO.MemoryMappedFiles } } - unsafe void Create (long offset, long size, MemoryMappedFileAccess access) + unsafe void Create (IntPtr handle, long offset, long size, MemoryMappedFileAccess access) { - int offset_diff; + IntPtr base_address; - MemoryMapImpl.Map (file_handle, offset, ref size, access, out mmap_addr, out offset_diff); + MemoryMapImpl.Map (handle, offset, ref size, access, out mmap_handle, out base_address); + safe_handle = new SafeMemoryMappedViewHandle (mmap_handle, base_address, size); - handle = new SafeMemoryMappedViewHandle ((IntPtr)((long)mmap_addr + offset_diff), size); - Initialize (handle, 0, size, ToFileAccess (access)); + Initialize (safe_handle, 0, size, ToFileAccess (access)); } public SafeMemoryMappedViewHandle SafeMemoryMappedViewHandle { get { - return handle; + return safe_handle; } } @@ -91,7 +89,7 @@ namespace System.IO.MemoryMappedFiles public void Flush () { - MemoryMapImpl.Flush (file_handle); + MemoryMapImpl.Flush (mmap_handle); } } } diff --git a/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedViewStream.cs b/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedViewStream.cs index 0f6aa75dc42..651e2d0d262 100644 --- a/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedViewStream.cs +++ b/mcs/class/System.Core/System.IO.MemoryMappedFiles/MemoryMappedViewStream.cs @@ -35,15 +35,12 @@ using Microsoft.Win32.SafeHandles; namespace System.IO.MemoryMappedFiles { public sealed class MemoryMappedViewStream : UnmanagedMemoryStream { - IntPtr mmap_addr; - ulong mmap_size; + IntPtr mmap_handle; object monitor; - int fd; - internal MemoryMappedViewStream (int fd, long offset, long size, MemoryMappedFileAccess access) { - this.fd = fd; + internal MemoryMappedViewStream (IntPtr handle, long offset, long size, MemoryMappedFileAccess access) { monitor = new Object (); - CreateStream (fd, offset, size, access); + CreateStream (handle, offset, size, access); } public SafeMemoryMappedViewHandle SafeMemoryMappedViewHandle { @@ -52,13 +49,13 @@ namespace System.IO.MemoryMappedFiles } } - unsafe void CreateStream (int fd, long offset, long size, MemoryMappedFileAccess access) + unsafe void CreateStream (IntPtr handle, long offset, long size, MemoryMappedFileAccess access) { - int offset_diff; - mmap_size = (ulong) size; - MemoryMapImpl.Map (fd, offset, ref size, access, out mmap_addr, out offset_diff); - FileAccess faccess; + IntPtr base_address; + + MemoryMapImpl.Map (handle, offset, ref size, access, out mmap_handle, out base_address); + FileAccess faccess; switch (access) { case MemoryMappedFileAccess.ReadWrite: faccess = FileAccess.ReadWrite; @@ -72,23 +69,23 @@ namespace System.IO.MemoryMappedFiles default: throw new NotImplementedException ("access mode " + access + " not supported."); } - Initialize ((byte*)mmap_addr + offset_diff, size, size, faccess); + Initialize ((byte*)base_address, size, size, faccess); } protected override void Dispose (bool disposing) { base.Dispose (disposing); lock (monitor) { - if (mmap_addr != (IntPtr)(-1)) { - MemoryMapImpl.Unmap (mmap_addr, mmap_size); - mmap_addr = (IntPtr)(-1); + if (mmap_handle != (IntPtr)(-1)) { + MemoryMapImpl.Unmap (mmap_handle); + mmap_handle = (IntPtr)(-1); } } } public override void Flush () { - MemoryMapImpl.Flush (fd); + MemoryMapImpl.Flush (mmap_handle); } } } diff --git a/mcs/class/System.Core/Test/System.IO.MemoryMappedFiles/MemoryMappedFileTest.cs b/mcs/class/System.Core/Test/System.IO.MemoryMappedFiles/MemoryMappedFileTest.cs index 5dee58b704b..8e47c0a8fff 100644 --- a/mcs/class/System.Core/Test/System.IO.MemoryMappedFiles/MemoryMappedFileTest.cs +++ b/mcs/class/System.Core/Test/System.IO.MemoryMappedFiles/MemoryMappedFileTest.cs @@ -51,6 +51,13 @@ namespace MonoTests.System.IO.MemoryMappedFiles { Assert.IsTrue (thrown); } + static int named_index; + static String MkNamedMapping () + { + return "test-" + named_index++; + } + + static string tempDir = Path.Combine (Path.GetTempPath (), typeof (MemoryMappedFileTest).FullName); string fname; @@ -206,6 +213,98 @@ namespace MonoTests.System.IO.MemoryMappedFiles { Assert.AreEqual ("Hello", s); } } + + + [Test] + public void NamedMappingToInvalidFile () + { + var fileName = Path.Combine (tempDir, "temp_file_123"); + if (File.Exists (fileName)) + File.Delete (fileName); + var memoryMappedFile90 = MemoryMappedFile.CreateNew (fileName, 4194304, MemoryMappedFileAccess.ReadWrite); + memoryMappedFile90.CreateViewStream (4186112, 3222, MemoryMappedFileAccess.Write); + } + + [Test] + public void CreateTheSameAreaTwiceShouldFail () + { + var name = MkNamedMapping (); + using (var m0 = MemoryMappedFile.CreateNew(name, 4096, MemoryMappedFileAccess.ReadWrite)) { + try { + using (var m1 = MemoryMappedFile.CreateNew (name, 4096, MemoryMappedFileAccess.ReadWrite)) { + Assert.Fail ("Must fail"); + } + } catch (IOException) {} + } + } + + [Test] + public void MapAFileToAMemoryAreaShouldFail () + { + var name = MkNamedMapping (); + using (var m0 = MemoryMappedFile.CreateNew(name, 4096, MemoryMappedFileAccess.ReadWrite)) { + try { + using (var m1 = MemoryMappedFile.CreateFromFile (fname, FileMode.OpenOrCreate, name)) { + Assert.Fail ("Must fail"); + } + } catch (IOException) {} + } + } + + [Test] + public void NamedMappingsShareMemoryArea () + { + var name = MkNamedMapping (); + using (var m0 = MemoryMappedFile.CreateNew(name, 4096, MemoryMappedFileAccess.ReadWrite)) { + using (var m1 = MemoryMappedFile.CreateOrOpen (name, 4096, MemoryMappedFileAccess.ReadWrite)) { + using (MemoryMappedViewAccessor v0 = m0.CreateViewAccessor (), v1 = m1.CreateViewAccessor ()) { + v0.Write (10, 0x12345); + Assert.AreEqual (0x12345, v1.ReadInt32 (10)); + } + } + } + } + + [Test] + public void NamedFileCanBeOpen () + { + var name = MkNamedMapping (); + using (var sw = new FileStream (fname, FileMode.Open)) { + byte[] b = new byte[20]; + for (int i = 0; i < 20; ++i) + b[i] = 0xFF; + sw.Write (b, 0, 20); + } + + using (var m0 = MemoryMappedFile.CreateFromFile (fname, FileMode.Open, name)) { + using (var m1 = MemoryMappedFile.CreateOrOpen (name, 4096)) { + using (MemoryMappedViewAccessor v0 = m0.CreateViewAccessor (), v1 = m1.CreateViewAccessor ()) { + v0.Write (10, 0x11223344); + Assert.AreEqual (0x11223344, v1.ReadInt32 (10)); + } + } + } + } + + [Test] + public void MapAtEdgeOfPage () + { + using (var f = new FileStream (fname, FileMode.Open)) { + var b = new byte [4096]; + for (int i = 0; i < 4096; ++i) + b[i] = 0xAA; + for (int i = 0; i < 2; ++i) + f.Write (b, 0, 4096); + } + var m0 = MemoryMappedFile.CreateFromFile (fname, FileMode.Open); + var v0 = m0.CreateViewAccessor (500, 4096); + var v1 = m0.CreateViewAccessor (0, 4096 * 2); + for (int i = 0; i < 4096; ++i) { + Assert.AreEqual (0xAA, v1.ReadByte (i + 500)); + v0.Write (i, (byte)0xFF); + Assert.AreEqual (0xFF, v1.ReadByte (i + 500)); + } + } } } diff --git a/mcs/class/System.Data/Mono.Data.SqlExpressions/Tokenizer.cs b/mcs/class/System.Data/Mono.Data.SqlExpressions/Tokenizer.cs index 3208718e7da..256da0cfa14 100644 --- a/mcs/class/System.Data/Mono.Data.SqlExpressions/Tokenizer.cs +++ b/mcs/class/System.Data/Mono.Data.SqlExpressions/Tokenizer.cs @@ -136,10 +136,10 @@ namespace Mono.Data.SqlExpressions { string str = sb.ToString (); - if (str.IndexOf(".") == -1) - return Int64.Parse (str); - else - return double.Parse (str); + if (str.IndexOf ('.') < 0) + return Int64.Parse (str, CultureInfo.InvariantCulture); + + return double.Parse (str, CultureInfo.InvariantCulture); } private char ProcessEscapes(char c) @@ -327,7 +327,7 @@ namespace Mono.Data.SqlExpressions { case '#': string date = ReadString ('#'); - val = DateTime.Parse (date); + val = DateTime.Parse (date, CultureInfo.InvariantCulture); return Token.DateLiteral; case '\'': diff --git a/mcs/class/System.Drawing/System.Drawing/Graphics.cs b/mcs/class/System.Drawing/System.Drawing/Graphics.cs index 827bdee0881..6e18fe690df 100644 --- a/mcs/class/System.Drawing/System.Drawing/Graphics.cs +++ b/mcs/class/System.Drawing/System.Drawing/Graphics.cs @@ -1744,7 +1744,7 @@ namespace System.Drawing if (GDIPlus.Display == IntPtr.Zero) { GDIPlus.Display = GDIPlus.XOpenDisplay (IntPtr.Zero); if (GDIPlus.Display == IntPtr.Zero) - throw new NotSupportedException ("Could not open display (X-Server required. Check you DISPLAY environment variable)"); + throw new NotSupportedException ("Could not open display (X-Server required. Check your DISPLAY environment variable)"); } if (hwnd == IntPtr.Zero) { hwnd = GDIPlus.XRootWindow (GDIPlus.Display, GDIPlus.XDefaultScreen (GDIPlus.Display)); 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 fd9e444f7ed..7f74497c60b 100644 --- a/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs +++ b/mcs/class/System.Net.Http/System.Net.Http/HttpClientHandler.cs @@ -327,6 +327,11 @@ namespace System.Net.Http var stream = await wrequest.GetRequestStreamAsync ().ConfigureAwait (false); await request.Content.CopyToAsync (stream).ConfigureAwait (false); + } else if (HttpMethod.Post.Equals (request.Method) || HttpMethod.Put.Equals (request.Method) || HttpMethod.Delete.Equals (request.Method)) { + // Explicitly set this to make sure we're sending a "Content-Length: 0" header. + // This fixes the issue that's been reported on the forums: + // http://forums.xamarin.com/discussion/17770/length-required-error-in-http-post-since-latest-release + wrequest.ContentLength = 0; } HttpWebResponse wresponse = null; diff --git a/mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs b/mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs index edcd18fe2a4..d2871f60875 100644 --- a/mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs +++ b/mcs/class/System.Net.Http/Test/System.Net.Http/HttpClientTest.cs @@ -533,6 +533,38 @@ namespace MonoTests.System.Net.Http } } + [Test] + public void Send_Complete_NoContent () + { + foreach (var method in new HttpMethod[] { HttpMethod.Post, HttpMethod.Put, HttpMethod.Delete }) { + bool? failed = null; + var listener = CreateListener (l => { + try { + var request = l.Request; + + Assert.AreEqual (2, request.Headers.Count, "#1"); + Assert.AreEqual ("0", request.Headers ["Content-Length"], "#1b"); + Assert.AreEqual (method.Method, request.HttpMethod, "#2"); + failed = false; + } catch { + failed = true; + } + }); + + try { + var client = new HttpClient (); + var request = new HttpRequestMessage (method, LocalServer); + var response = client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Result; + + Assert.AreEqual ("", response.Content.ReadAsStringAsync ().Result, "#100"); + Assert.AreEqual (HttpStatusCode.OK, response.StatusCode, "#101"); + Assert.AreEqual (false, failed, "#102"); + } finally { + listener.Close (); + } + } + } + [Test] public void Send_Complete_Error () { diff --git a/mcs/class/System.Xaml/Makefile b/mcs/class/System.Xaml/Makefile index 04ad2dda799..17d16132910 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, $(FRAMEWORK_VERSION_MAJOR)) +VALID_PROFILE := $(filter 4 monodroid monotouch, $(FRAMEWORK_VERSION_MAJOR)) ifndef VALID_PROFILE LIBRARY_NAME = dummy-System.Xaml.dll NO_INSTALL = yes diff --git a/mcs/class/System.Xaml/System.Windows.Markup/AmbientAttribute.cs b/mcs/class/System.Xaml/System.Windows.Markup/AmbientAttribute.cs index ff55aefc7cf..003f0c789e3 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/AmbientAttribute.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/AmbientAttribute.cs @@ -31,9 +31,7 @@ using System.Xaml.Schema; namespace System.Windows.Markup { [AttributeUsage (AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Property, Inherited = true)] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public sealed class AmbientAttribute : Attribute { } diff --git a/mcs/class/System.Xaml/System.Windows.Markup/ArrayExtension.cs b/mcs/class/System.Xaml/System.Windows.Markup/ArrayExtension.cs index 7a99b796010..e3da18695d9 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/ArrayExtension.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/ArrayExtension.cs @@ -32,9 +32,7 @@ namespace System.Windows.Markup { [MarkupExtensionReturnType (typeof (Array))] [ContentProperty ("Items")] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyPresentationFramework_3_5)] -#endif public class ArrayExtension : MarkupExtension { public ArrayExtension () @@ -62,9 +60,7 @@ namespace System.Windows.Markup public Type Type { get; set; } IList items; -#if !NET_2_1 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)] -#endif public IList Items { get { return items; } } diff --git a/mcs/class/System.Xaml/System.Windows.Markup/ConstructorArgumentAttribute.cs b/mcs/class/System.Xaml/System.Windows.Markup/ConstructorArgumentAttribute.cs index 69a8b3f0ba6..7708fe7c078 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/ConstructorArgumentAttribute.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/ConstructorArgumentAttribute.cs @@ -25,9 +25,7 @@ using System; namespace System.Windows.Markup { [AttributeUsage (AttributeTargets.Property, AllowMultiple = false, Inherited = false)] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public sealed class ConstructorArgumentAttribute : Attribute { public ConstructorArgumentAttribute (string argumentName) diff --git a/mcs/class/System.Xaml/System.Windows.Markup/ContentPropertyAttribute.cs b/mcs/class/System.Xaml/System.Windows.Markup/ContentPropertyAttribute.cs index f772a2bd82e..5b3c078b70d 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/ContentPropertyAttribute.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/ContentPropertyAttribute.cs @@ -29,9 +29,7 @@ namespace System.Windows.Markup // member regardless of this attribute. [AttributeUsage (AttributeTargets.Class, AllowMultiple = false, Inherited = true)] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public sealed class ContentPropertyAttribute : Attribute { public ContentPropertyAttribute () diff --git a/mcs/class/System.Xaml/System.Windows.Markup/ContentWrapperAttribute.cs b/mcs/class/System.Xaml/System.Windows.Markup/ContentWrapperAttribute.cs index 12e10c5e151..d64a2a9645b 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/ContentWrapperAttribute.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/ContentWrapperAttribute.cs @@ -25,9 +25,7 @@ using System; namespace System.Windows.Markup { [AttributeUsage (AttributeTargets.Class, AllowMultiple = true, Inherited = true)] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public sealed class ContentWrapperAttribute : Attribute { public ContentWrapperAttribute (Type contentWrapper) @@ -36,7 +34,8 @@ namespace System.Windows.Markup } public Type ContentWrapper { get; private set; } -#if !NET_2_1 + +#if !__MOBILE__ public override Object TypeId { get { return this; } } diff --git a/mcs/class/System.Xaml/System.Windows.Markup/DateTimeValueSerializer.cs b/mcs/class/System.Xaml/System.Windows.Markup/DateTimeValueSerializer.cs index 5556e7f43c1..720a3517dcc 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/DateTimeValueSerializer.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/DateTimeValueSerializer.cs @@ -28,9 +28,7 @@ using System.Globalization; namespace System.Windows.Markup { -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public class DateTimeValueSerializer : ValueSerializer { const DateTimeStyles styles = DateTimeStyles.RoundtripKind | DateTimeStyles.NoCurrentDateDefault | DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite; diff --git a/mcs/class/System.Xaml/System.Windows.Markup/DependsOnAttribute.cs b/mcs/class/System.Xaml/System.Windows.Markup/DependsOnAttribute.cs index f49ce4fb5be..361df14ed60 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/DependsOnAttribute.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/DependsOnAttribute.cs @@ -25,9 +25,7 @@ using System; namespace System.Windows.Markup { [AttributeUsage (AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = true)] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public sealed class DependsOnAttribute : Attribute { public DependsOnAttribute (string name) @@ -37,7 +35,7 @@ namespace System.Windows.Markup public string Name { get; private set; } -#if !NET_2_1 +#if !__MOBILE__ // really? I doubt it should be overriden. public override Object TypeId { get { return this; } diff --git a/mcs/class/System.Xaml/System.Windows.Markup/DictionaryKeyPropertyAttribute.cs b/mcs/class/System.Xaml/System.Windows.Markup/DictionaryKeyPropertyAttribute.cs index df7f4482bdc..1664fe23a8d 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/DictionaryKeyPropertyAttribute.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/DictionaryKeyPropertyAttribute.cs @@ -25,9 +25,7 @@ using System; namespace System.Windows.Markup { [AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public sealed class DictionaryKeyPropertyAttribute : Attribute { public DictionaryKeyPropertyAttribute (string name) diff --git a/mcs/class/System.Xaml/System.Windows.Markup/IComponentConnector.cs b/mcs/class/System.Xaml/System.Windows.Markup/IComponentConnector.cs index 8b143b92791..5e6081628fd 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/IComponentConnector.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/IComponentConnector.cs @@ -28,9 +28,7 @@ using System.Xaml.Schema; namespace System.Windows.Markup { -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public interface IComponentConnector { void Connect (int connectionId, object target); diff --git a/mcs/class/System.Xaml/System.Windows.Markup/INameScope.cs b/mcs/class/System.Xaml/System.Windows.Markup/INameScope.cs index 5c142ec0afa..3035a7cbc17 100644 --- a/mcs/class/System.Xaml/System.Windows.Markup/INameScope.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/INameScope.cs @@ -25,9 +25,7 @@ using System.Collections.Generic; namespace System.Windows.Markup { -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public interface INameScope { object FindName (string name); diff --git a/mcs/class/System.Xaml/System.Windows.Markup/IProvideValueTarget.cs b/mcs/class/System.Xaml/System.Windows.Markup/IProvideValueTarget.cs index 65c124bfc36..6a44ce005d1 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/IProvideValueTarget.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/IProvideValueTarget.cs @@ -28,9 +28,7 @@ using System.Xaml.Schema; namespace System.Windows.Markup { -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyPresentationFramework_3_5)] -#endif public interface IProvideValueTarget { object TargetObject { get; } diff --git a/mcs/class/System.Xaml/System.Windows.Markup/IUriContext.cs b/mcs/class/System.Xaml/System.Windows.Markup/IUriContext.cs index 7ace4b70cd7..252ab6964cd 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/IUriContext.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/IUriContext.cs @@ -28,9 +28,7 @@ using System.Xaml.Schema; namespace System.Windows.Markup { -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyPresentationCore_3_5)] -#endif public interface IUriContext { Uri BaseUri { get; set; } diff --git a/mcs/class/System.Xaml/System.Windows.Markup/IValueSerializerContext.cs b/mcs/class/System.Xaml/System.Windows.Markup/IValueSerializerContext.cs index 011c32e983a..bfc1e0a3720 100644 --- a/mcs/class/System.Xaml/System.Windows.Markup/IValueSerializerContext.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/IValueSerializerContext.cs @@ -29,9 +29,7 @@ using System.Xaml; namespace System.Windows.Markup { -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public interface IValueSerializerContext : ITypeDescriptorContext, IServiceProvider { ValueSerializer GetValueSerializerFor (PropertyDescriptor descriptor); diff --git a/mcs/class/System.Xaml/System.Windows.Markup/IXamlTypeResolver.cs b/mcs/class/System.Xaml/System.Windows.Markup/IXamlTypeResolver.cs index c78be097471..563387c8421 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/IXamlTypeResolver.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/IXamlTypeResolver.cs @@ -28,9 +28,7 @@ using System.Xaml.Schema; namespace System.Windows.Markup { -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public interface IXamlTypeResolver { Type Resolve (string qualifiedTypeName); diff --git a/mcs/class/System.Xaml/System.Windows.Markup/MarkupExtension.cs b/mcs/class/System.Xaml/System.Windows.Markup/MarkupExtension.cs index 9277a3ca7ac..f79cefd6e02 100644 --- a/mcs/class/System.Xaml/System.Windows.Markup/MarkupExtension.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/MarkupExtension.cs @@ -29,9 +29,7 @@ using System.Xaml.Schema; namespace System.Windows.Markup { -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public abstract class MarkupExtension { public abstract object ProvideValue (IServiceProvider serviceProvider); diff --git a/mcs/class/System.Xaml/System.Windows.Markup/NameScopePropertyAttribute.cs b/mcs/class/System.Xaml/System.Windows.Markup/NameScopePropertyAttribute.cs index 3ecd55b2001..8e33e017cfc 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/NameScopePropertyAttribute.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/NameScopePropertyAttribute.cs @@ -25,9 +25,7 @@ using System; namespace System.Windows.Markup { [AttributeUsage (AttributeTargets.Class, AllowMultiple = false, Inherited = true)] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public sealed class NameScopePropertyAttribute : Attribute { public NameScopePropertyAttribute (string name) diff --git a/mcs/class/System.Xaml/System.Windows.Markup/NullExtension.cs b/mcs/class/System.Xaml/System.Windows.Markup/NullExtension.cs index 9aef4b4d78f..19cd2cbf598 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/NullExtension.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/NullExtension.cs @@ -29,9 +29,7 @@ using System.Xaml.Schema; namespace System.Windows.Markup { [MarkupExtensionReturnType (typeof (Object))] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyPresentationFramework_3_5)] -#endif public class NullExtension : MarkupExtension { public override Object ProvideValue (IServiceProvider serviceProvider) diff --git a/mcs/class/System.Xaml/System.Windows.Markup/RootNamespaceAttribute.cs b/mcs/class/System.Xaml/System.Windows.Markup/RootNamespaceAttribute.cs index 392968b4328..040f1945a7a 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/RootNamespaceAttribute.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/RootNamespaceAttribute.cs @@ -25,9 +25,7 @@ using System; namespace System.Windows.Markup { [AttributeUsage (AttributeTargets.Assembly)] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public sealed class RootNamespaceAttribute : Attribute { public RootNamespaceAttribute (string nameSpace) diff --git a/mcs/class/System.Xaml/System.Windows.Markup/RuntimeNamePropertyAttribute.cs b/mcs/class/System.Xaml/System.Windows.Markup/RuntimeNamePropertyAttribute.cs index ccd2cbc95bf..44c3706b502 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/RuntimeNamePropertyAttribute.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/RuntimeNamePropertyAttribute.cs @@ -25,9 +25,7 @@ using System; namespace System.Windows.Markup { [AttributeUsage (AttributeTargets.Class)] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public sealed class RuntimeNamePropertyAttribute : Attribute { public RuntimeNamePropertyAttribute (string name) diff --git a/mcs/class/System.Xaml/System.Windows.Markup/StaticExtension.cs b/mcs/class/System.Xaml/System.Windows.Markup/StaticExtension.cs index 465ba56521d..24df4f5a169 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/StaticExtension.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/StaticExtension.cs @@ -30,9 +30,7 @@ namespace System.Windows.Markup { [MarkupExtensionReturnType (typeof (object))] [TypeConverter (typeof (StaticExtensionConverter))] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyPresentationFramework_3_5)] -#endif public class StaticExtension : MarkupExtension { public StaticExtension () diff --git a/mcs/class/System.Xaml/System.Windows.Markup/TrimSurroundingWhitespaceAttribute.cs b/mcs/class/System.Xaml/System.Windows.Markup/TrimSurroundingWhitespaceAttribute.cs index bf4309d6e33..371e3e06f8e 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/TrimSurroundingWhitespaceAttribute.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/TrimSurroundingWhitespaceAttribute.cs @@ -31,9 +31,7 @@ using System.Xaml.Schema; namespace System.Windows.Markup { [AttributeUsage (AttributeTargets.Class, AllowMultiple = false, Inherited = true)] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public sealed class TrimSurroundingWhitespaceAttribute : Attribute { } diff --git a/mcs/class/System.Xaml/System.Windows.Markup/TypeExtension.cs b/mcs/class/System.Xaml/System.Windows.Markup/TypeExtension.cs index 00af705581e..42da7a13783 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/TypeExtension.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/TypeExtension.cs @@ -30,9 +30,7 @@ namespace System.Windows.Markup { [MarkupExtensionReturnType (typeof (Type))] [TypeConverter (typeof (TypeExtensionConverter))] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyPresentationFramework_3_5)] -#endif public class TypeExtension : MarkupExtension { public TypeExtension () @@ -56,9 +54,7 @@ namespace System.Windows.Markup [ConstructorArgument ("type")] [DefaultValue (null)] public Type Type { get; set; } -#if !NET_2_1 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)] -#endif public string TypeName { get; set; } public override object ProvideValue (IServiceProvider serviceProvider) diff --git a/mcs/class/System.Xaml/System.Windows.Markup/UidPropertyAttribute.cs b/mcs/class/System.Xaml/System.Windows.Markup/UidPropertyAttribute.cs index bd66ca26145..1898e16a207 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/UidPropertyAttribute.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/UidPropertyAttribute.cs @@ -31,9 +31,7 @@ using System.Xaml.Schema; namespace System.Windows.Markup { [AttributeUsage (AttributeTargets.Class, AllowMultiple = false)] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public sealed class UidPropertyAttribute : Attribute { public UidPropertyAttribute (string name) diff --git a/mcs/class/System.Xaml/System.Windows.Markup/ValueSerializer.cs b/mcs/class/System.Xaml/System.Windows.Markup/ValueSerializer.cs index bee7ad65908..45adefabec7 100644 --- a/mcs/class/System.Xaml/System.Windows.Markup/ValueSerializer.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/ValueSerializer.cs @@ -32,24 +32,19 @@ using System.Xaml.Schema; namespace System.Windows.Markup { -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public abstract class ValueSerializer { -#if !NET_2_1 public static ValueSerializer GetSerializerFor (PropertyDescriptor descriptor) { return GetSerializerFor (descriptor, null); } -#endif public static ValueSerializer GetSerializerFor (Type type) { return GetSerializerFor (type, null); } -#if !NET_2_1 // untested public static ValueSerializer GetSerializerFor (PropertyDescriptor descriptor, IValueSerializerContext context) { @@ -63,7 +58,6 @@ namespace System.Windows.Markup return new TypeConverterValueSerializer (tc); return null; } -#endif public static ValueSerializer GetSerializerFor (Type type, IValueSerializerContext context) { diff --git a/mcs/class/System.Xaml/System.Windows.Markup/ValueSerializerAttribute.cs b/mcs/class/System.Xaml/System.Windows.Markup/ValueSerializerAttribute.cs index fdb4e951e2f..37dec5262a9 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/ValueSerializerAttribute.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/ValueSerializerAttribute.cs @@ -31,9 +31,7 @@ using System.Xaml.Schema; namespace System.Windows.Markup { [AttributeUsage (AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Interface, AllowMultiple = false, Inherited = true)] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public sealed class ValueSerializerAttribute : Attribute { public ValueSerializerAttribute (string valueSerializerTypeName) diff --git a/mcs/class/System.Xaml/System.Windows.Markup/WhitespaceSignificantCollectionAttribute.cs b/mcs/class/System.Xaml/System.Windows.Markup/WhitespaceSignificantCollectionAttribute.cs index 893d79c1aa3..36cdf56aa28 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/WhitespaceSignificantCollectionAttribute.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/WhitespaceSignificantCollectionAttribute.cs @@ -31,9 +31,7 @@ using System.Xaml.Schema; namespace System.Windows.Markup { [AttributeUsage (AttributeTargets.Class, AllowMultiple = false, Inherited = true)] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public sealed class WhitespaceSignificantCollectionAttribute : Attribute { } diff --git a/mcs/class/System.Xaml/System.Windows.Markup/XmlLangPropertyAttribute.cs b/mcs/class/System.Xaml/System.Windows.Markup/XmlLangPropertyAttribute.cs index 18978a84645..4789120383b 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/XmlLangPropertyAttribute.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/XmlLangPropertyAttribute.cs @@ -31,9 +31,7 @@ using System.Xaml.Schema; namespace System.Windows.Markup { [AttributeUsage (AttributeTargets.Class, AllowMultiple = false)] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public sealed class XmlLangPropertyAttribute : Attribute { public XmlLangPropertyAttribute (string name) diff --git a/mcs/class/System.Xaml/System.Windows.Markup/XmlnsCompatibleWithAttribute.cs b/mcs/class/System.Xaml/System.Windows.Markup/XmlnsCompatibleWithAttribute.cs index e77ae359726..0e16db2f15d 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/XmlnsCompatibleWithAttribute.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/XmlnsCompatibleWithAttribute.cs @@ -31,9 +31,7 @@ using System.Xaml.Schema; namespace System.Windows.Markup { [AttributeUsage (AttributeTargets.Assembly, AllowMultiple = true)] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public sealed class XmlnsCompatibleWithAttribute : Attribute { public XmlnsCompatibleWithAttribute (string oldNamespace, string newNamespace) diff --git a/mcs/class/System.Xaml/System.Windows.Markup/XmlnsDefinitionAttribute.cs b/mcs/class/System.Xaml/System.Windows.Markup/XmlnsDefinitionAttribute.cs index 078623fb082..81be2dae73d 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/XmlnsDefinitionAttribute.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/XmlnsDefinitionAttribute.cs @@ -31,9 +31,7 @@ using System.Xaml.Schema; namespace System.Windows.Markup { [AttributeUsage (AttributeTargets.Assembly, AllowMultiple = true)] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public sealed class XmlnsDefinitionAttribute : Attribute { public XmlnsDefinitionAttribute (string xmlNamespace, string clrNamespace) diff --git a/mcs/class/System.Xaml/System.Windows.Markup/XmlnsPrefixAttribute.cs b/mcs/class/System.Xaml/System.Windows.Markup/XmlnsPrefixAttribute.cs index 4bdf0d97aff..c907c8eb427 100755 --- a/mcs/class/System.Xaml/System.Windows.Markup/XmlnsPrefixAttribute.cs +++ b/mcs/class/System.Xaml/System.Windows.Markup/XmlnsPrefixAttribute.cs @@ -31,9 +31,7 @@ using System.Xaml.Schema; namespace System.Windows.Markup { [AttributeUsage (AttributeTargets.Assembly, AllowMultiple = true)] -#if !NET_2_1 [System.Runtime.CompilerServices.TypeForwardedFrom (Consts.AssemblyWindowsBase)] -#endif public sealed class XmlnsPrefixAttribute : Attribute { public XmlnsPrefixAttribute (string xmlNamespace, string prefix) diff --git a/mcs/class/System.Xaml/System.Xaml/XamlDuplicateMemberException.cs b/mcs/class/System.Xaml/System.Xaml/XamlDuplicateMemberException.cs index e65e23faf1f..10e18587261 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlDuplicateMemberException.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlDuplicateMemberException.cs @@ -27,9 +27,7 @@ using System.Runtime.Serialization; namespace System.Xaml { -#if !NET_2_1 [Serializable] -#endif public class XamlDuplicateMemberException : XamlException { public XamlDuplicateMemberException () @@ -54,25 +52,21 @@ namespace System.Xaml { } -#if !NET_2_1 protected XamlDuplicateMemberException (SerializationInfo info, StreamingContext context) : base (info, context) { DuplicateMember = (XamlMember) info.GetValue ("member", typeof (XamlMember)); ParentType = (XamlType) info.GetValue ("type", typeof (XamlType)); } -#endif public XamlMember DuplicateMember { get; set; } public XamlType ParentType { get; set; } -#if !NET_2_1 public override void GetObjectData (SerializationInfo info, StreamingContext context) { base.GetObjectData (info, context); info.AddValue ("member", DuplicateMember); info.AddValue ("type", ParentType); } -#endif } } diff --git a/mcs/class/System.Xaml/System.Xaml/XamlException.cs b/mcs/class/System.Xaml/System.Xaml/XamlException.cs index ecccbb4ced5..669b2245ece 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlException.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlException.cs @@ -27,9 +27,7 @@ using System.Runtime.Serialization; namespace System.Xaml { -#if !NET_2_1 [Serializable] -#endif public class XamlException : Exception { public XamlException () @@ -63,14 +61,12 @@ namespace System.Xaml LinePosition = linePosition; } -#if !NET_2_1 protected XamlException (SerializationInfo info, StreamingContext context) : base (info, context) { LineNumber = info.GetInt32 ("lineNumber"); LinePosition = info.GetInt32 ("linePosition"); } -#endif public int LineNumber { get; protected internal set; } public int LinePosition { get; protected internal set; } @@ -78,12 +74,10 @@ namespace System.Xaml get { return FormatLine (base.Message, LineNumber, LinePosition); } } -#if !NET_2_1 public override void GetObjectData (SerializationInfo info, StreamingContext context) { info.AddValue ("lineNumber", LineNumber); info.AddValue ("linePosition", LinePosition); } -#endif } } diff --git a/mcs/class/System.Xaml/System.Xaml/XamlInternalException.cs b/mcs/class/System.Xaml/System.Xaml/XamlInternalException.cs index a24cffe420a..d98aa4c4df2 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlInternalException.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlInternalException.cs @@ -27,9 +27,7 @@ using System.Runtime.Serialization; namespace System.Xaml { -#if !NET_2_1 [Serializable] -#endif public class XamlInternalException : XamlException { public XamlInternalException () @@ -47,11 +45,9 @@ namespace System.Xaml { } -#if !NET_2_1 protected XamlInternalException (SerializationInfo info, StreamingContext context) : base (info, context) { } -#endif } } diff --git a/mcs/class/System.Xaml/System.Xaml/XamlMember.cs b/mcs/class/System.Xaml/System.Xaml/XamlMember.cs index 7b85eb322d5..ad03cbf6283 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlMember.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlMember.cs @@ -166,7 +166,6 @@ namespace System.Xaml get { return directive_ns ?? (DeclaringType == null ? null : DeclaringType.PreferredXamlNamespace); } } -#if !NET_2_1 public DesignerSerializationVisibility SerializationVisibility { get { var c= GetCustomAttributeProvider (); @@ -174,7 +173,6 @@ namespace System.Xaml return a != null ? a.Visibility : DesignerSerializationVisibility.Visible; } } -#endif public bool IsAttachable { get { return is_attachable; } diff --git a/mcs/class/System.Xaml/System.Xaml/XamlObjectReaderException.cs b/mcs/class/System.Xaml/System.Xaml/XamlObjectReaderException.cs index 89c64fe1adc..0bad880d68d 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlObjectReaderException.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlObjectReaderException.cs @@ -27,9 +27,7 @@ using System.Runtime.Serialization; namespace System.Xaml { -#if !NET_2_1 [Serializable] -#endif public class XamlObjectReaderException : XamlException { public XamlObjectReaderException () @@ -47,11 +45,9 @@ namespace System.Xaml { } -#if !NET_2_1 protected XamlObjectReaderException (SerializationInfo info, StreamingContext context) : base (info, context) { } -#endif } } diff --git a/mcs/class/System.Xaml/System.Xaml/XamlObjectWriterException.cs b/mcs/class/System.Xaml/System.Xaml/XamlObjectWriterException.cs index b5ce0b3b803..17708cc0344 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlObjectWriterException.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlObjectWriterException.cs @@ -27,9 +27,7 @@ using System.Runtime.Serialization; namespace System.Xaml { -#if !NET_2_1 [Serializable] -#endif public class XamlObjectWriterException : XamlException { public XamlObjectWriterException () @@ -47,11 +45,9 @@ namespace System.Xaml { } -#if !NET_2_1 protected XamlObjectWriterException (SerializationInfo info, StreamingContext context) : base (info, context) { } -#endif } } diff --git a/mcs/class/System.Xaml/System.Xaml/XamlObjectWriterSettings.cs b/mcs/class/System.Xaml/System.Xaml/XamlObjectWriterSettings.cs index 4ecbe75e6f7..a46dded4edf 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlObjectWriterSettings.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlObjectWriterSettings.cs @@ -25,7 +25,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Reflection; using System.Windows.Markup; -#if !NET_2_1 +#if !__MOBILE__ using System.Xaml.Permissions; #endif using System.Xaml.Schema; @@ -42,7 +42,7 @@ namespace System.Xaml : base (settings) { var s = settings; -#if !NET_2_1 +#if !__MOBILE__ AccessLevel = s.AccessLevel; #endif AfterBeginInitHandler = s.AfterBeginInitHandler; @@ -65,7 +65,7 @@ namespace System.Xaml public EventHandler BeforePropertiesHandler { get; set; } public EventHandler XamlSetValueHandler { get; set; } -#if !NET_2_1 +#if !__MOBILE__ [MonoTODO ("Ignored")] public XamlAccessLevel AccessLevel { get; set; } #endif diff --git a/mcs/class/System.Xaml/System.Xaml/XamlParseException.cs b/mcs/class/System.Xaml/System.Xaml/XamlParseException.cs index 1ae1667b53a..4bb8340a48a 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlParseException.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlParseException.cs @@ -27,9 +27,7 @@ using System.Runtime.Serialization; namespace System.Xaml { -#if !NET_2_1 [Serializable] -#endif public class XamlParseException : XamlException { public XamlParseException () @@ -47,11 +45,9 @@ namespace System.Xaml { } -#if !NET_2_1 protected XamlParseException (SerializationInfo info, StreamingContext context) : base (info, context) { } -#endif } } diff --git a/mcs/class/System.Xaml/System.Xaml/XamlSchemaContext.cs b/mcs/class/System.Xaml/System.Xaml/XamlSchemaContext.cs index de31e46de24..64cf91ea71c 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlSchemaContext.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlSchemaContext.cs @@ -57,10 +57,8 @@ namespace System.Xaml { if (referenceAssemblies != null) reference_assemblies = new List (referenceAssemblies); -#if !NET_2_1 else AppDomain.CurrentDomain.AssemblyLoad += OnAssemblyLoaded; -#endif if (settings == null) return; @@ -69,13 +67,11 @@ namespace System.Xaml SupportMarkupExtensionsWithDuplicateArity = settings.SupportMarkupExtensionsWithDuplicateArity; } -#if !NET_2_1 ~XamlSchemaContext () { if (reference_assemblies == null) AppDomain.CurrentDomain.AssemblyLoad -= OnAssemblyLoaded; } -#endif IList reference_assemblies; @@ -255,7 +251,6 @@ namespace System.Xaml return compat_nss.TryGetValue (xamlNamespace, out compatibleNamespace); } -#if !NET_2_1 void OnAssemblyLoaded (object o, AssemblyLoadEventArgs e) { if (reference_assemblies != null) @@ -270,8 +265,7 @@ namespace System.Xaml if (all_xaml_types != null) FillAllXamlTypes (e.LoadedAssembly); } -#endif - + // cache updater methods void FillXamlNamespaces (Assembly ass) { diff --git a/mcs/class/System.Xaml/System.Xaml/XamlSchemaException.cs b/mcs/class/System.Xaml/System.Xaml/XamlSchemaException.cs index 9681927b39b..78de4f8e482 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlSchemaException.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlSchemaException.cs @@ -27,9 +27,7 @@ using System.Runtime.Serialization; namespace System.Xaml { -#if !NET_2_1 [Serializable] -#endif public class XamlSchemaException : XamlException { public XamlSchemaException () @@ -47,11 +45,9 @@ namespace System.Xaml { } -#if !NET_2_1 protected XamlSchemaException (SerializationInfo info, StreamingContext context) : base (info, context) { } -#endif } } diff --git a/mcs/class/System.Xaml/System.Xaml/XamlServices.cs b/mcs/class/System.Xaml/System.Xaml/XamlServices.cs index cf686d8506f..c8026d195a4 100755 --- a/mcs/class/System.Xaml/System.Xaml/XamlServices.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlServices.cs @@ -71,13 +71,11 @@ namespace System.Xaml return sw.ToString (); } -#if !NET_2_1 public static void Save (string fileName, object instance) { using (var xw = XmlWriter.Create (fileName, new XmlWriterSettings () { OmitXmlDeclaration = true, Indent = true })) Save (xw, instance); } -#endif public static void Save (Stream stream, object instance) { diff --git a/mcs/class/System.Xaml/System.Xaml/XamlXmlWriterException.cs b/mcs/class/System.Xaml/System.Xaml/XamlXmlWriterException.cs index d784b9df2d0..ffa402cc7df 100644 --- a/mcs/class/System.Xaml/System.Xaml/XamlXmlWriterException.cs +++ b/mcs/class/System.Xaml/System.Xaml/XamlXmlWriterException.cs @@ -27,9 +27,7 @@ using System.Runtime.Serialization; namespace System.Xaml { -#if !NET_2_1 [Serializable] -#endif public class XamlXmlWriterException : XamlException { public XamlXmlWriterException () @@ -47,11 +45,9 @@ namespace System.Xaml { } -#if !NET_2_1 protected XamlXmlWriterException (SerializationInfo info, StreamingContext context) : base (info, context) { } -#endif } } diff --git a/mcs/class/System/System.Net/DigestClient.cs b/mcs/class/System/System.Net/DigestClient.cs index be618771eb9..f570a739650 100644 --- a/mcs/class/System/System.Net/DigestClient.cs +++ b/mcs/class/System/System.Net/DigestClient.cs @@ -181,7 +181,7 @@ namespace System.Net } value = header.Substring (beginQ, pos - beginQ); - pos += 2; + pos += useQuote ? 2 : 1; return true; } } diff --git a/mcs/class/System/System.Net/ServicePointManager.cs b/mcs/class/System/System.Net/ServicePointManager.cs index 26578856fae..66cdc7296fe 100644 --- a/mcs/class/System/System.Net/ServicePointManager.cs +++ b/mcs/class/System/System.Net/ServicePointManager.cs @@ -264,7 +264,6 @@ namespace System.Net throw new ArgumentException ("value"); maxServicePoints = value; - RecycleServicePoints (); } } @@ -329,9 +328,6 @@ namespace System.Net if (address == null) throw new ArgumentNullException ("address"); - if ((servicePoints.Count % 4) == 0) - RecycleServicePoints (); - var origAddress = new Uri (address.Scheme + "://" + address.Authority); bool usesProxy = false; @@ -378,41 +374,6 @@ namespace System.Net return sp; } - // Internal Methods - - static void RecycleServicePoints () - { - lock (servicePoints) { - var toRemove = new ArrayList (); - var idleList = new SortedDictionary (); - IDictionaryEnumerator e = servicePoints.GetEnumerator (); - while (e.MoveNext ()) { - ServicePoint sp = (ServicePoint) e.Value; - DateTime idleSince; - if (sp.CheckAvailableForRecycling (out idleSince)) { - toRemove.Add (e.Key); - continue; - } - - while (idleList.ContainsKey (idleSince)) - idleSince = idleSince.AddMilliseconds (1); - idleList.Add (idleSince, sp); - } - - for (int i = 0; i < toRemove.Count; i++) - servicePoints.Remove (toRemove [i]); - - if (maxServicePoints == 0 || servicePoints.Count <= maxServicePoints) - return; - - // get rid of the ones with the longest idle time - foreach (var sp in idleList.Values) { - if (servicePoints.Count <= maxServicePoints) - break; - servicePoints.Remove (sp); - } - } - } #if SECURITY_DEP internal class ChainValidationHelper { object sender; diff --git a/mcs/class/System/System.Net/SimpleAsyncResult.cs b/mcs/class/System/System.Net/SimpleAsyncResult.cs index 4d143153ddf..b18d2adf34a 100644 --- a/mcs/class/System/System.Net/SimpleAsyncResult.cs +++ b/mcs/class/System/System.Net/SimpleAsyncResult.cs @@ -159,18 +159,10 @@ namespace System.Net { if (!callbackDone && cb != null) { callbackDone = true; -// if (true || synch) - cb (this); -// else -// ThreadPool.QueueUserWorkItem (CB, null); + cb (this); } } - void CB (object unused) - { - cb (this); - } - internal void WaitUntilComplete () { if (IsCompleted) diff --git a/mcs/class/System/System.Net/WebConnectionGroup.cs b/mcs/class/System/System.Net/WebConnectionGroup.cs index 0348aeebe42..5e142154f91 100644 --- a/mcs/class/System/System.Net/WebConnectionGroup.cs +++ b/mcs/class/System/System.Net/WebConnectionGroup.cs @@ -70,14 +70,16 @@ namespace System.Net //TODO: abort requests or wait for them to finish lock (sPoint) { closing = true; - foreach (var cnc in connections) { - if (cnc.Connection == null) - continue; - cnc.Connection.Close (false); - cnc.Connection = null; + var iter = connections.First; + while (iter != null) { + var cnc = iter.Value.Connection; + var node = iter; + iter = iter.Next; + + connections.Remove (node); + cnc.Close (false); OnConnectionClosed (); } - connections.Clear (); } } @@ -120,7 +122,7 @@ namespace System.Net ConnectionState FindIdleConnection () { foreach (var cnc in connections) { - if (cnc.Busy || cnc.Connection == null) + if (cnc.Busy) continue; connections.Remove (cnc); @@ -140,7 +142,7 @@ namespace System.Net return cnc.Connection; } - if (sPoint.ConnectionLimit > connections.Count) { + if (sPoint.ConnectionLimit > connections.Count || connections.Count == 0) { created = true; cnc = new ConnectionState (this); connections.AddFirst (cnc); @@ -177,14 +179,11 @@ namespace System.Net } int count = 0; - for (var node = connections.First; node != null; node = node.Next) { - var cnc = node.Value; - - if (cnc.Connection == null) { - connections.Remove (node); - OnConnectionClosed (); - continue; - } + var iter = connections.First; + while (iter != null) { + var cnc = iter.Value; + var node = iter; + iter = iter.Next; ++count; if (cnc.Busy) @@ -205,7 +204,7 @@ namespace System.Net if (connectionsToClose == null) connectionsToClose = new List (); connectionsToClose.Add (cnc.Connection); - cnc.Connection = null; + connections.Remove (node); } recycled = connections.Count == 0; @@ -224,7 +223,10 @@ namespace System.Net } class ConnectionState : IWebConnectionState { - public WebConnection Connection; + public WebConnection Connection { + get; + private set; + } public WebConnectionGroup Group { get; diff --git a/mcs/class/corlib/System.Security.Claims/ClaimsPrincipal.cs b/mcs/class/corlib/System.Security.Claims/ClaimsPrincipal.cs index 9eea7eec8dc..cf1fe29e9d1 100644 --- a/mcs/class/corlib/System.Security.Claims/ClaimsPrincipal.cs +++ b/mcs/class/corlib/System.Security.Claims/ClaimsPrincipal.cs @@ -59,7 +59,7 @@ namespace System.Security.Claims { if (identities == null) throw new ArgumentNullException ("identities"); - identities = new List (identities); + this.identities = new List (identities); } public ClaimsPrincipal (IIdentity identity) diff --git a/mcs/class/corlib/System/AggregateException.cs b/mcs/class/corlib/System/AggregateException.cs index 067cd64d6f6..06bfc20324d 100644 --- a/mcs/class/corlib/System/AggregateException.cs +++ b/mcs/class/corlib/System/AggregateException.cs @@ -63,7 +63,7 @@ namespace System } public AggregateException (params Exception[] innerExceptions) - : this (string.Empty, innerExceptions) + : this (defaultMessage, innerExceptions) { } diff --git a/mcs/class/monodoc/Monodoc/generators/html/Ecma2Html.cs b/mcs/class/monodoc/Monodoc/generators/html/Ecma2Html.cs index c15c6137786..04353c45469 100644 --- a/mcs/class/monodoc/Monodoc/generators/html/Ecma2Html.cs +++ b/mcs/class/monodoc/Monodoc/generators/html/Ecma2Html.cs @@ -63,14 +63,21 @@ namespace Monodoc.Generators.Html public string Htmlize (XmlReader ecma_xml, XsltArgumentList args) { - EnsureTransform (); - - var output = new StringBuilder (); - ecma_transform.Transform (ecma_xml, - args, - XmlWriter.Create (output, ecma_transform.OutputSettings), - CreateDocumentResolver ()); - return output.ToString (); + try{ + EnsureTransform (); + + var output = new StringBuilder (); + ecma_transform.Transform (ecma_xml, + args, + XmlWriter.Create (output, ecma_transform.OutputSettings), + CreateDocumentResolver ()); + return output.ToString (); + } + catch(Exception x) + { + var msg = x.ToString (); + return msg; + } } protected virtual XmlResolver CreateDocumentResolver () @@ -81,21 +88,14 @@ namespace Monodoc.Generators.Html public string Export (Stream stream, Dictionary extraArgs) { - return Htmlize (XmlReader.Create (WrapStream (new StreamReader (stream), extraArgs)), extraArgs); + return Htmlize (XmlReader.Create (new StreamReader(stream)), extraArgs); } public string Export (string input, Dictionary extraArgs) { - return Htmlize (XmlReader.Create (WrapStream (new StringReader (input), extraArgs)), extraArgs); + return Htmlize (XmlReader.Create (new StringReader(input)), extraArgs); } - TextReader WrapStream (TextReader initialReader, Dictionary renderArgs) - { - string show; - if (renderArgs.TryGetValue ("show", out show) && show == "namespace") - return new AvoidCDataTextReader (initialReader); - return initialReader; - } static void EnsureTransform () { @@ -329,81 +329,5 @@ namespace Monodoc.Generators.Html } } } - - public class AvoidCDataTextReader : TextReader - { - static readonly char[] CDataPattern = new[] { - '<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[' - }; - static readonly char[] CDataClosingPattern = new[] { - ']', ']', '>' - }; - TextReader wrappedReader; - char[] backingArray = new char[9]; // " 0; - } else if (currentIndex == eofIndex) { - return false; - } - if (!inCData && PatternDetect (CDataPattern)) { - inCData = true; - ReadLength (CDataPattern.Length); - return EnsureBuffer (); - } - if (inCData && PatternDetect (CDataClosingPattern)) { - inCData = false; - ReadLength (CDataClosingPattern.Length); - return EnsureBuffer (); - } - - return true; - } - - bool PatternDetect (char[] pattern) - { - return backingArray[currentIndex] == pattern[0] && Enumerable.Range (1, pattern.Length - 1).All (i => backingArray[(currentIndex + i) % backingArray.Length] == pattern[i]); - } - } + } diff --git a/mcs/class/monodoc/Test/Monodoc.Generators/AvoidCDataTextReaderTests.cs b/mcs/class/monodoc/Test/Monodoc.Generators/AvoidCDataTextReaderTests.cs deleted file mode 100644 index 5ab8e84b809..00000000000 --- a/mcs/class/monodoc/Test/Monodoc.Generators/AvoidCDataTextReaderTests.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Xml; -using System.Collections.Generic; - -using NUnit.Framework; - -using Monodoc; -using Monodoc.Generators; -using Monodoc.Generators.Html; - -namespace MonoTests.Monodoc.Generators -{ - [TestFixture] - public class AvoidCDataTextReaderTest - { - void AssertSameInputOutput (string expected, string input) - { - var processed = new AvoidCDataTextReader (new StringReader (input)).ReadToEnd (); - Assert.AreEqual (expected, processed); - } - - [Test] - public void NoCDataXmlTest () - { - var input = @"Addressbook APIs. - Provides access to the system Address Book. - "; - - AssertSameInputOutput (input, input); - } - - [Test] - public void WithCDataXmlTest () - { - var input = @"Addressbook APIs. - "; - - AssertSameInputOutput (input.Replace ("", string.Empty), input); - } - - [Test] - public void PartialCDataXmlTest () - { - var input = @"Addressbook APIs. - "; - - AssertSameInputOutput (input, input); - } - - [Test] - public void FinishWithPartialCDataXmlTest () - { - var input = @"Addressbook APIs. - Provides access to the system Address Book. - Addressbook APIs. - Provides access to the system Address Book. - [] ArrayMember +} diff --git a/mcs/errors/Makefile b/mcs/errors/Makefile index e4660f8df86..f994abac1ea 100644 --- a/mcs/errors/Makefile +++ b/mcs/errors/Makefile @@ -21,7 +21,7 @@ DISTFILES = \ $(wildcard dlls/second/*.cs) TEST_SUPPORT_FILES = \ - CS0012-lib.dll CS0012-2-lib.dll CS0012-3-lib.dll CS0012-4-lib.dll CS0012-5-lib.dll CS0012-6-lib.dll CS0012-9-lib.dll CS0012-10-lib.dll CS0012-11-lib.dll CS0012-12-lib.dll CS0012-13-lib.dll CS0012-14-lib.dll CS0012-15-lib.dll CS0012-16-lib.dll CS0012-17-lib.dll CS0012-18-lib.dll CS0012-21-lib.dll CS0012-22-lib.dll CS0019-71-lib.dll CS0029-26-lib.dll \ + CS0012-lib.dll CS0012-2-lib.dll CS0012-3-lib.dll CS0012-4-lib.dll CS0012-5-lib.dll CS0012-6-lib.dll CS0012-9-lib.dll CS0012-10-lib.dll CS0012-11-lib.dll CS0012-12-lib.dll CS0012-13-lib.dll CS0012-14-lib.dll CS0012-15-lib.dll CS0012-16-lib.dll CS0012-17-lib.dll CS0012-18-lib.dll CS0012-21-lib.dll CS0012-22-lib.dll CS0012-23-lib.dll CS0019-71-lib.dll CS0029-26-lib.dll \ CS0103-2-lib.dll CS0118-2-lib.dll CS0122-8-lib.dll CS0122-10-lib.dll CS0122-14-lib.dll CS0122-15-lib.dll CS0122-19-lib.dll CS0122-35-lib.dll CS0122-36-lib.dll CS0143-lib.dll CS0144-3-lib.dll CS0165-19-lib.dll \ CS0205-3-lib.dll CS0246-29-lib.dll CS0229-3-lib.dll CS0229-4-lib.dll CS0266-25-lib.dll \ CS0315-2-lib.dll \ diff --git a/mcs/errors/cs0012-23.cs b/mcs/errors/cs0012-23.cs new file mode 100644 index 00000000000..a8b454ac67f --- /dev/null +++ b/mcs/errors/cs0012-23.cs @@ -0,0 +1,11 @@ +// CS0012: The type `Struct`1' is defined in an assembly that is not referenced. Consider adding a reference to assembly `CS0012-lib-missing, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' +// Line: 9 +// Compiler options: -r:CS0012-23-lib.dll + +public class C +{ + public static void Main () + { + var val = B.ArrayMember; + } +} \ No newline at end of file diff --git a/mcs/errors/cs0070-2.cs b/mcs/errors/cs0070-2.cs new file mode 100644 index 00000000000..95f9cdb61d8 --- /dev/null +++ b/mcs/errors/cs0070-2.cs @@ -0,0 +1,24 @@ +// CS0070: The event `A.evt' can only appear on the left hand side of += or -= when used outside of the type `A' +// Line: 22 + +using System; + +public static class EventExtensions +{ + public static void Raise (this EventHandler h) + { + } +} + +public class A +{ + public event EventHandler evt; +} + +public class B : A +{ + public void Run() + { + Action a = () => evt.Raise (); + } +} \ No newline at end of file diff --git a/mcs/errors/cs1984.cs b/mcs/errors/cs1984.cs deleted file mode 100644 index cf998413a14..00000000000 --- a/mcs/errors/cs1984.cs +++ /dev/null @@ -1,21 +0,0 @@ -// CS1984: The `await' operator cannot be used in the body of a finally clause -// Line: 13 - -using System; -using System.Threading.Tasks; - -class C -{ - public async Task Test () - { - try { - } finally { - await Call (); - } - } - - static Task Call () - { - return null; - } -} diff --git a/mcs/jay/main.c b/mcs/jay/main.c index b47867d3e33..fcac218b1df 100644 --- a/mcs/jay/main.c +++ b/mcs/jay/main.c @@ -256,11 +256,17 @@ unsigned n; return (p); } +#ifdef __GNUC__ +#define GNUC_UNUSED __attribute__((__unused__)) +#else +#define GNUC_UNUSED +#endif create_file_names() { int i, len; char *tmpdir; + int mkstemp_res GNUC_UNUSED; #if defined(_WIN32) && !defined(__CYGWIN32__) && !defined(__CYGWIN__) tmpdir = "."; @@ -303,9 +309,9 @@ create_file_names() prolog_file_name[len + 5] = 'p'; local_file_name[len + 5] = 'l'; - mkstemp(action_file_name); - mkstemp(prolog_file_name); - mkstemp(local_file_name); + mkstemp_res = mkstemp(action_file_name); + mkstemp_res = mkstemp(prolog_file_name); + mkstemp_res = mkstemp(local_file_name); len = strlen(file_prefix); diff --git a/mcs/mcs/async.cs b/mcs/mcs/async.cs index ea0d9c4a241..5d8f65053bf 100644 --- a/mcs/mcs/async.cs +++ b/mcs/mcs/async.cs @@ -74,10 +74,6 @@ namespace Mono.CSharp protected override Expression DoResolve (ResolveContext rc) { - if (rc.HasSet (ResolveContext.Options.FinallyScope)) { - rc.Report.Error (1984, loc, "The `await' operator cannot be used in the body of a finally clause"); - } - if (rc.HasSet (ResolveContext.Options.LockScope)) { rc.Report.Error (1996, loc, "The `await' operator cannot be used in the body of a lock statement"); diff --git a/mcs/mcs/codegen.cs b/mcs/mcs/codegen.cs index ff77e33340a..d310043c0b3 100644 --- a/mcs/mcs/codegen.cs +++ b/mcs/mcs/codegen.cs @@ -204,6 +204,8 @@ namespace Mono.CSharp } } + public LocalVariable AsyncThrowVariable { get; set; } + #endregion public void AddStatementEpilog (IExpressionCleanup cleanupExpression) diff --git a/mcs/mcs/expression.cs b/mcs/mcs/expression.cs index 6a750145162..96431ffa393 100644 --- a/mcs/mcs/expression.cs +++ b/mcs/mcs/expression.cs @@ -2611,14 +2611,10 @@ namespace Mono.CSharp public override void FlowAnalysis (FlowAnalysisContext fc) { if ((oper & Operator.LogicalMask) == 0) { - var fc_ontrue = fc.DefiniteAssignmentOnTrue; - var fc_onfalse = fc.DefiniteAssignmentOnFalse; fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment; left.FlowAnalysis (fc); fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment; right.FlowAnalysis (fc); - fc.DefiniteAssignmentOnTrue = fc_ontrue; - fc.DefiniteAssignmentOnFalse = fc_onfalse; return; } @@ -6766,7 +6762,7 @@ namespace Mono.CSharp if (!Emit (ec, v)) v.Emit (ec); } - + public override void EmitStatement (EmitContext ec) { LocalTemporary v = null; @@ -7569,7 +7565,9 @@ namespace Mono.CSharp public override void Emit (EmitContext ec) { - EmitToFieldSource (ec); + var await_field = EmitToFieldSource (ec); + if (await_field != null) + await_field.Emit (ec); } protected sealed override FieldExpr EmitToFieldSource (EmitContext ec) @@ -8817,7 +8815,7 @@ namespace Mono.CSharp // with disable flow analysis as we don't know whether left side expression // is used as variable or type // - if (expr is VariableReference || expr is ConstantExpr || expr is Linq.TransparentMemberAccess) { + if (expr is VariableReference || expr is ConstantExpr || expr is Linq.TransparentMemberAccess || expr is EventExpr) { expr = expr.Resolve (rc); } else if (expr is TypeParameterExpr) { expr.Error_UnexpectedKind (rc, flags, sn.Location); @@ -11066,6 +11064,20 @@ namespace Mono.CSharp return e; } + public override void Emit (EmitContext ec) + { + if (method == null && TypeSpec.IsValueType (type) && initializers.Initializers.Count > 1 && initializers.ContainsEmitWithAwait ()) { + var fe = ec.GetTemporaryField (type); + + if (!Emit (ec, fe)) + fe.Emit (ec); + + return; + } + + base.Emit (ec); + } + public override bool Emit (EmitContext ec, IMemoryLocation target) { bool left_on_stack; @@ -11082,6 +11094,8 @@ namespace Mono.CSharp LocalTemporary temp = null; instance = target as LocalTemporary; + if (instance == null) + instance = target as StackFieldExpr; if (instance == null) { if (!left_on_stack) { diff --git a/mcs/mcs/generic.cs b/mcs/mcs/generic.cs index 89fd1a2e6ac..d97c7f3b82a 100644 --- a/mcs/mcs/generic.cs +++ b/mcs/mcs/generic.cs @@ -1457,13 +1457,18 @@ namespace Mono.CSharp { if (tp != null) return Inflate (tp); - var ac = type as ArrayContainer; - if (ac != null) { - var et = Inflate (ac.Element); - if (et != ac.Element) - return ArrayContainer.MakeType (context.Module, et, ac.Rank); + var ec = type as ElementTypeSpec; + if (ec != null) { + var et = Inflate (ec.Element); + if (et != ec.Element) { + var ac = ec as ArrayContainer; + if (ac != null) + return ArrayContainer.MakeType (context.Module, et, ac.Rank); + + throw new NotImplementedException (); + } - return ac; + return ec; } if (type.Kind == MemberKind.MissingType) diff --git a/mcs/mcs/statement.cs b/mcs/mcs/statement.cs index 09d7414e43a..a09c4acd939 100644 --- a/mcs/mcs/statement.cs +++ b/mcs/mcs/statement.cs @@ -1781,9 +1781,20 @@ namespace Mono.CSharp { protected override void DoEmit (EmitContext ec) { - if (expr == null) - ec.Emit (OpCodes.Rethrow); - else { + if (expr == null) { + var atv = ec.AsyncThrowVariable; + if (atv != null) { + if (atv.HoistedVariant != null) { + atv.HoistedVariant.Emit (ec); + } else { + atv.Emit (ec); + } + + ec.Emit (OpCodes.Throw); + } else { + ec.Emit (OpCodes.Rethrow); + } + } else { expr.Emit (ec); ec.Emit (OpCodes.Throw); @@ -2175,13 +2186,13 @@ namespace Mono.CSharp { { li.CreateBuilder (ec); - if (Initializer != null) + if (Initializer != null && !IsUnreachable) ((ExpressionStatement) Initializer).EmitStatement (ec); if (declarators != null) { foreach (var d in declarators) { d.Variable.CreateBuilder (ec); - if (d.Initializer != null) { + if (d.Initializer != null && !IsUnreachable) { ec.Mark (d.Variable.Location); ((ExpressionStatement) d.Initializer).EmitStatement (ec); } @@ -2888,10 +2899,12 @@ namespace Mono.CSharp { DoEmit (ec); } - protected void EmitScopeInitializers (EmitContext ec) + public void EmitScopeInitializers (EmitContext ec) { foreach (Statement s in scope_initializers) s.Emit (ec); + + scope_initializers = null; } protected override bool DoFlowAnalysis (FlowAnalysisContext fc) @@ -2912,7 +2925,7 @@ namespace Mono.CSharp { end_unreachable = s.FlowAnalysis (fc); if (s.IsUnreachable) { - statements[startIndex] = new EmptyStatement (s.loc); + statements [startIndex] = RewriteUnreachableStatement (s); continue; } @@ -2939,7 +2952,7 @@ namespace Mono.CSharp { if (s.IsUnreachable) { s.FlowAnalysis (fc); - statements[startIndex] = new EmptyStatement (s.loc); + statements [startIndex] = RewriteUnreachableStatement (s); } } } @@ -2954,6 +2967,24 @@ namespace Mono.CSharp { return !Explicit.HasReachableClosingBrace; } + static Statement RewriteUnreachableStatement (Statement s) + { + // LAMESPEC: It's not clear whether declararion statement should be part of reachability + // analysis. Even csc report unreachable warning for it but it's actually used hence + // we try to emulate this behaviour + // + // Consider: + // goto L; + // int v; + // L: + // v = 1; + + if (s is BlockVariable) + return s; + + return new EmptyStatement (s.loc); + } + public void ScanGotoJump (Statement label) { int i; @@ -5457,7 +5488,7 @@ namespace Mono.CSharp { EmitTryBodyPrepare (ec); EmitTryBody (ec); - ec.BeginFinallyBlock (); + bool begin = EmitBeginFinallyBlock (ec); Label start_finally = ec.DefineLabel (); if (resume_points != null) { @@ -5485,7 +5516,8 @@ namespace Mono.CSharp { EmitFinallyBody (ec); } - ec.EndExceptionBlock (); + if (begin) + ec.EndExceptionBlock (); } public override void EmitForDispose (EmitContext ec, LocalBuilder pc, Label end, bool have_dispatcher) @@ -5559,6 +5591,12 @@ namespace Mono.CSharp { return res; } + protected virtual bool EmitBeginFinallyBlock (EmitContext ec) + { + ec.BeginFinallyBlock (); + return true; + } + public override Reachability MarkReachable (Reachability rc) { base.MarkReachable (rc); @@ -6391,17 +6429,25 @@ namespace Mono.CSharp { if (li != null) EmitCatchVariableStore (ec); - } else { - if (IsGeneral) - ec.BeginCatchBlock (ec.BuiltinTypes.Object); - else - ec.BeginCatchBlock (CatchType); - if (li != null) { - EmitCatchVariableStore (ec); + if (Block.HasAwait) { + Block.EmitScopeInitializers (ec); } else { - ec.Emit (OpCodes.Pop); + Block.Emit (ec); } + + return; + } + + if (IsGeneral) + ec.BeginCatchBlock (ec.BuiltinTypes.Object); + else + ec.BeginCatchBlock (CatchType); + + if (li != null) { + EmitCatchVariableStore (ec); + } else { + ec.Emit (OpCodes.Pop); } if (!Block.HasAwait) @@ -6421,7 +6467,7 @@ namespace Mono.CSharp { hoisted_temp = new LocalTemporary (li.Type); hoisted_temp.Store (ec); - // switch to assigning from the temporary variable and not from top of the stack + // switch to assignment from temporary variable and not from top of the stack assign.UpdateSource (hoisted_temp); } } @@ -6429,11 +6475,20 @@ namespace Mono.CSharp { public override bool Resolve (BlockContext bc) { using (bc.Set (ResolveContext.Options.CatchScope)) { - if (type_expr != null) { + if (type_expr == null) { + if (CreateExceptionVariable (bc.Module.Compiler.BuiltinTypes.Object)) { + Expression source = new EmptyExpression (li.Type); + assign = new CompilerAssign (new LocalVariableReference (li, Location.Null), source, Location.Null); + Block.AddScopeStatement (new StatementExpression (assign, Location.Null)); + } + } else { type = type_expr.ResolveAsType (bc); if (type == null) return false; + if (li == null) + CreateExceptionVariable (type); + if (type.BuiltinType != BuiltinTypeSpec.Type.Exception && !TypeSpec.IsBaseClass (type, bc.BuiltinTypes.Exception, false)) { bc.Report.Error (155, loc, "The type caught or thrown must be derived from System.Exception"); } else if (li != null) { @@ -6462,9 +6517,22 @@ namespace Mono.CSharp { } } + bool CreateExceptionVariable (TypeSpec type) + { + if (!Block.HasAwait) + return false; + + // TODO: Scan the block for rethrow expression + //if (!Block.HasRethrow) + // return; + + li = LocalVariable.CreateCompilerGenerated (type, block, Location.Null); + return true; + } + protected override bool DoFlowAnalysis (FlowAnalysisContext fc) { - if (li != null) { + if (li != null && !li.IsCompilerGenerated) { fc.SetVariableAssigned (li.VariableInfo, true); } @@ -6538,9 +6606,62 @@ namespace Mono.CSharp { stmt.Emit (ec); } + protected override bool EmitBeginFinallyBlock (EmitContext ec) + { + if (fini.HasAwait) + return false; + + return base.EmitBeginFinallyBlock (ec); + } + public override void EmitFinallyBody (EmitContext ec) { + StackFieldExpr exception_field; + + if (fini.HasAwait) { + // + // Emits catch block like + // + // catch (object temp) { + // this.exception_field = temp; + // } + // + var type = ec.BuiltinTypes.Object; + ec.BeginCatchBlock (type); + + var temp = ec.GetTemporaryLocal (type); + ec.Emit (OpCodes.Stloc, temp); + + exception_field = ec.GetTemporaryField (type); + ec.EmitThis (); + ec.Emit (OpCodes.Ldloc, temp); + exception_field.EmitAssignFromStack (ec); + + ec.EndExceptionBlock (); + + ec.FreeTemporaryLocal (temp, type); + } else { + exception_field = null; + } + fini.Emit (ec); + + if (exception_field != null) { + // + // Emits exception rethrow + // + // if (this.exception_field != null) + // throw this.exception_field; + // + exception_field.Emit (ec); + var skip_throw = ec.DefineLabel (); + ec.Emit (OpCodes.Brfalse_S, skip_throw); + exception_field.Emit (ec); + ec.Emit (OpCodes.Throw); + ec.MarkLabel (skip_throw); + + exception_field.IsAvailableForReuse = true; + } } protected override bool DoFlowAnalysis (FlowAnalysisContext fc) @@ -6745,13 +6866,20 @@ namespace Mono.CSharp { // 0 value is default label ec.MarkLabel (labels [0]); + ec.Emit (OpCodes.Br, end); + var atv = ec.AsyncThrowVariable; + Catch c = null; for (int i = 0; i < catch_sm.Count; ++i) { - ec.Emit (OpCodes.Br, end); + if (c != null && c.Block.HasReachableClosingBrace) + ec.Emit (OpCodes.Br, end); ec.MarkLabel (labels [i + 1]); - catch_sm [i].Block.Emit (ec); + c = catch_sm [i]; + ec.AsyncThrowVariable = c.Variable; + c.Block.Emit (ec); } + ec.AsyncThrowVariable = atv; ec.MarkLabel (end); } @@ -6828,6 +6956,7 @@ namespace Mono.CSharp { public VariableDeclaration (LocalVariable li, Location loc) : base (li) { + reachable = true; this.loc = loc; } @@ -7270,6 +7399,7 @@ namespace Mono.CSharp { public RuntimeDispose (LocalVariable lv, Location loc) : base (lv, loc) { + reachable = true; } protected override void CheckIDiposableConversion (BlockContext bc, LocalVariable li, Expression initializer) diff --git a/mcs/mcs/typespec.cs b/mcs/mcs/typespec.cs index 339addfd15e..0da8133fbd2 100644 --- a/mcs/mcs/typespec.cs +++ b/mcs/mcs/typespec.cs @@ -1936,6 +1936,11 @@ namespace Mono.CSharp return ac; } + + public override List ResolveMissingDependencies (MemberSpec caller) + { + return Element.ResolveMissingDependencies (caller); + } } class ReferenceContainer : ElementTypeSpec diff --git a/mcs/tests/gtest-615.cs b/mcs/tests/gtest-615.cs new file mode 100644 index 00000000000..f20ee5733e3 --- /dev/null +++ b/mcs/tests/gtest-615.cs @@ -0,0 +1,21 @@ +// Compiler options: -unsafe + +unsafe class X +{ + struct S + { + } + + public class N + { + S* s; + } +} + +public class C +{ + public static void Main () + { + new X.N (); + } +} \ No newline at end of file diff --git a/mcs/tests/test-895.cs b/mcs/tests/test-895.cs new file mode 100644 index 00000000000..bef7982680c --- /dev/null +++ b/mcs/tests/test-895.cs @@ -0,0 +1,21 @@ +using System; + +class X +{ + public void Test (int g, out int results) + { + if ((results = Foo (g > 0 ? 1 : 2)) != 4) + { + Console.WriteLine (results); + } + } + + int Foo (object o) + { + return 4; + } + + public static void Main () + { + } +} \ No newline at end of file diff --git a/mcs/tests/test-896.cs b/mcs/tests/test-896.cs new file mode 100644 index 00000000000..4336bf73141 --- /dev/null +++ b/mcs/tests/test-896.cs @@ -0,0 +1,13 @@ +using System; + +class Program +{ + public static void Main () + { + goto L1; + int z; + L1: + z = 3; + Console.WriteLine (z); + } +} \ No newline at end of file diff --git a/mcs/tests/test-async-15.cs b/mcs/tests/test-async-15.cs index a1da25f39d5..a3ae814086e 100644 --- a/mcs/tests/test-async-15.cs +++ b/mcs/tests/test-async-15.cs @@ -1,8 +1,8 @@ -// Compiler options: -langversion:future - using System; using System.Threading.Tasks; using System.Threading; +using System.Collections; +using System.Collections.Generic; interface IFoo { @@ -25,12 +25,28 @@ struct S : IFoo } } +struct S2 : IEnumerable +{ + public List Values; + + public void Add (int x) + { + if (Values == null) + Values = new List (); + + Values.Add(x); + } + + public IEnumerator GetEnumerator() + { + return Values as IEnumerator; + } +} + class Tester { async Task NewInitTestGen () where T : struct, IFoo { - int value = 9; - var s = new T () { Value = await Task.Factory.StartNew (() => 13).ConfigureAwait (false) }; @@ -40,6 +56,16 @@ class Tester return s; } + + static async Task NewInitCol () + { + var s = new S2 { + await Task.FromResult (1), + await Task.Factory.StartNew (() => 2) + }; + + return s.Values [0] + s.Values [1]; + } public static int Main () { @@ -51,6 +77,10 @@ class Tester if (t.Result.Value != 13) return 2; + + var v = NewInitCol ().Result; + if (v != 3) + return 3; return 0; } diff --git a/mcs/tests/test-async-63.cs b/mcs/tests/test-async-63.cs index bd3e5f0c317..4572d7e2eda 100644 --- a/mcs/tests/test-async-63.cs +++ b/mcs/tests/test-async-63.cs @@ -67,7 +67,7 @@ class C TestSingleAwait (false).Wait (); if (counter != 2) - return 1; + return 2; counter = 0; diff --git a/mcs/tests/test-async-65.cs b/mcs/tests/test-async-65.cs new file mode 100644 index 00000000000..39672366915 --- /dev/null +++ b/mcs/tests/test-async-65.cs @@ -0,0 +1,54 @@ +using System; +using System.Threading.Tasks; + +class C +{ + static int counter; + + public static async Task TestRethrow (Exception e) + { + try { + throw e; + } catch (ApplicationException) { + Console.WriteLine ("x1a"); + counter = 1; + await Task.Delay (1); + Console.WriteLine ("x2a"); + counter = 3; + throw; + } catch { + counter = 9; + await Task.Delay (1); + Console.WriteLine ("ga"); + throw; + } + } + + public static int Main () + { + var ex = new ApplicationException (); + try { + TestRethrow (ex).Wait (); + } catch (AggregateException e) { + if (e.InnerException != ex) + return 1; + } + + if (counter != 3) + return 2; + + var ex2 = new NotSupportedException (); + try { + TestRethrow (ex2).Wait (); + } catch (AggregateException e) { + if (e.InnerException != ex2) + return 3; + } + + if (counter != 9) + return 4; + + Console.WriteLine ("ok"); + return 0; + } +} diff --git a/mcs/tests/test-async-66.cs b/mcs/tests/test-async-66.cs new file mode 100644 index 00000000000..bbba0980228 --- /dev/null +++ b/mcs/tests/test-async-66.cs @@ -0,0 +1,42 @@ +using System; +using System.Threading.Tasks; + +class TestFinally +{ + static int counter; + + async static Task Test (bool throwException) + { + try { + if (throwException) + throw new ApplicationException (); + + ++counter; + System.Console.WriteLine (); + } finally { + counter += 10; + await Task.Delay (2); + counter += 100; + } + counter += 1000; + } + + static int Main () + { + Test (false).Wait (); + if (counter != 1111) + return 1; + + counter = 0; + try { + Test (true).Wait (); + return 2; + } catch (AggregateException) { + } + + if (counter != 110) + return 3; + + return 0; + } +} \ No newline at end of file diff --git a/mcs/tests/test-async-67.cs b/mcs/tests/test-async-67.cs new file mode 100644 index 00000000000..2348dc7ff7d --- /dev/null +++ b/mcs/tests/test-async-67.cs @@ -0,0 +1,24 @@ +using System; +using System.Threading.Tasks; + +class Test +{ + public static async Task Run () + { + return new int[] { + 1, await Task.Factory.StartNew (() => 2) + }; + } + + public static int Main () + { + var t = Run ().Result; + if (t [0] != 1) + return 1; + + if (t [1] != 2) + return 2; + + return 0; + } +} \ No newline at end of file diff --git a/mcs/tests/test-ex-filter-03.cs b/mcs/tests/test-ex-filter-03.cs new file mode 100644 index 00000000000..d2a3e910413 --- /dev/null +++ b/mcs/tests/test-ex-filter-03.cs @@ -0,0 +1,21 @@ +using System; + +class X +{ + public static int Main () + { + try { + bool x = true; + try { + throw new ApplicationException (); + } catch (NullReferenceException) if (x) { + throw; + } + + return 1; + } catch (ApplicationException) { + Console.WriteLine ("ok"); + return 0; + } + } +} \ No newline at end of file diff --git a/mcs/tests/test-ex-filter-04.cs b/mcs/tests/test-ex-filter-04.cs new file mode 100644 index 00000000000..122accb2eee --- /dev/null +++ b/mcs/tests/test-ex-filter-04.cs @@ -0,0 +1,74 @@ +using System; +using System.Threading.Tasks; + +class X +{ + static Exception ex = new ApplicationException (); + + public static int Main () + { + if (Test (5, null).Result != 5) + return 1; + + try { + Test (5, ex).Wait (); + return 2; + } catch (AggregateException ae) { + if (ae.InnerException != ex) + return 3; + } + + try { + Test (15, ex).Wait (); + return 4; + } catch (AggregateException ae) { + if (ae.InnerException != ex) + return 5; + } + + try { + TestGeneric (5).Wait (); + return 10; + } catch (AggregateException ae) { + if (ae.InnerException != ex) + return 11; + } + + try { + TestGeneric (15).Wait (); + return 12; + } catch (AggregateException ae) { + if (ae.InnerException != ex) + return 13; + } + + return 0; + } + + async static Task Test (int x, Exception e) + { + try { + Console.WriteLine (x); + if (e != null) + throw e; + } catch (Exception) if (x != 15) { + await Task.FromResult (0); + throw; + } + + return x; + } + + async static Task TestGeneric (int x) + { + try { + Console.WriteLine (x); + throw ex; + } catch if (x != 15) { + await Task.FromResult (0); + throw; + } + + return x; + } +} \ No newline at end of file diff --git a/mcs/tests/ver-il-net_4_5.xml b/mcs/tests/ver-il-net_4_5.xml index a372ef6ab23..97366458344 100644 --- a/mcs/tests/ver-il-net_4_5.xml +++ b/mcs/tests/ver-il-net_4_5.xml @@ -19155,6 +19155,26 @@ + + + + 7 + + + + + 7 + + + + + 8 + + + 7 + + + @@ -49941,6 +49961,32 @@ + + + + 47 + + + 10 + + + 2 + + + 7 + + + + + + + 15 + + + 7 + + + @@ -60343,7 +60389,7 @@ 33 - 82 + 107 7 @@ -60351,7 +60397,7 @@ - 306 + 298 10 @@ -60360,6 +60406,30 @@ 13 + + + 36 + + + 20 + + + + + 33 + + + + + 370 + + + 13 + + + 9 + + @@ -62763,7 +62833,7 @@ - 410 + 419 13 @@ -62794,6 +62864,74 @@ + + + + 161 + + + 7 + + + + + 363 + + + 13 + + + + + 41 + + + + + + + 41 + + + 95 + + + 7 + + + + + 277 + + + 13 + + + + + + + 33 + + + 53 + + + 7 + + + + + 239 + + + 13 + + + 9 + + + @@ -64282,6 +64420,51 @@ + + + + 52 + + + 7 + + + + + + + 253 + + + 49 + + + 41 + + + 7 + + + 11 + + + + + 281 + + + 13 + + + + + 250 + + + 13 + + + diff --git a/mcs/tools/linker/Mono.Linker.Steps/MarkStep.cs b/mcs/tools/linker/Mono.Linker.Steps/MarkStep.cs index 30b7779f586..430f2c2c885 100644 --- a/mcs/tools/linker/Mono.Linker.Steps/MarkStep.cs +++ b/mcs/tools/linker/Mono.Linker.Steps/MarkStep.cs @@ -290,12 +290,28 @@ namespace Mono.Linker.Steps { if (CheckProcessed (assembly)) return; + ProcessModule (assembly); + MarkCustomAttributes (assembly); foreach (ModuleDefinition module in assembly.Modules) MarkCustomAttributes (module); } + void ProcessModule (AssemblyDefinition assembly) + { + // Pre-mark if there is any methods as they need to be executed + // at assembly load time + foreach (TypeDefinition type in assembly.MainModule.Types) + { + if (type.Name == "" && type.HasMethods) + { + MarkType (type); + break; + } + } + } + protected void MarkField (FieldReference reference) { // if (IgnoreScope (reference.DeclaringType.Scope)) diff --git a/mcs/tools/linker/Mono.Linker/LinkContext.cs b/mcs/tools/linker/Mono.Linker/LinkContext.cs index 8d97f8dc150..c4d71083cd5 100644 --- a/mcs/tools/linker/Mono.Linker/LinkContext.cs +++ b/mcs/tools/linker/Mono.Linker/LinkContext.cs @@ -217,6 +217,14 @@ namespace Mono.Linker { case "mscorlib": case "Accessibility": case "Mono.Security": + // WPF + case "PresentationFramework": + case "PresentationCore": + case "WindowsBase": + case "UIAutomationProvider": + case "UIAutomationTypes": + case "PresentationUI": + case "ReachFramework": return true; default: return name.Name.StartsWith ("System") diff --git a/mono/io-layer/security.c b/mono/io-layer/security.c index 1d702d3188f..d1bf3d0362c 100644 --- a/mono/io-layer/security.c +++ b/mono/io-layer/security.c @@ -19,19 +19,6 @@ #include #include - -/* Disclaimers */ - -#if defined(__GNUC__) -#ifndef HAVE_GETRESUID - #warning getresuid not supported. WindowsImpersonationContext wont work -#endif -#ifndef HAVE_SETRESUID - #warning setresuid not supported. WindowsImpersonationContext wont work -#endif -#endif - - gboolean ImpersonateLoggedOnUser (gpointer handle) { diff --git a/mono/metadata/Makefile.am.in b/mono/metadata/Makefile.am.in index 92fc55dc658..70591c7ba41 100644 --- a/mono/metadata/Makefile.am.in +++ b/mono/metadata/Makefile.am.in @@ -193,7 +193,11 @@ common_sources = \ verify.c \ verify-internals.h \ wrapper-types.h \ - reflection-internals.h + reflection-internals.h \ + file-mmap-posix.c \ + file-mmap-windows.c \ + file-mmap.h + # These source files have compile time dependencies on GC code gc_dependent_sources = \ diff --git a/mono/metadata/boehm-gc.c b/mono/metadata/boehm-gc.c index f3c7685037b..ef498c60760 100644 --- a/mono/metadata/boehm-gc.c +++ b/mono/metadata/boehm-gc.c @@ -1245,6 +1245,7 @@ void mono_gc_pthread_exit (void *retval) { pthread_exit (retval); + g_assert_not_reached (); } #endif diff --git a/mono/metadata/file-mmap-posix.c b/mono/metadata/file-mmap-posix.c new file mode 100644 index 00000000000..6066136e65a --- /dev/null +++ b/mono/metadata/file-mmap-posix.c @@ -0,0 +1,514 @@ +/* + * file-mmap-posix.c: File mmap internal calls + * + * Author: + * Rodrigo Kumpera + * + * Copyright 2014 Xamarin Inc (http://www.xamarin.com) + */ + +#include + +#ifndef TARGET_WIN32 + +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_SYS_STAT_H +#include +#endif +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#if HAVE_SYS_MMAN_H +#include +#endif + +#include + + +#include +#include +#include +#include +#include +#include + +enum { + MMAP_KIND_FILE = 1, + MMAP_KIND_MEMORY = 2 +}; + +typedef struct { + int kind; + int ref_count; + gint64 capacity; + char *name; +} Handle; + +typedef struct { + Handle handle; + int fd; +} FileHandle; + +typedef struct { + Handle handle; + void *address; + size_t length; +} MemoryHandle; + +typedef struct { + void *address; + void *free_handle; + int kind; + size_t length; +} MmapHandle; + +enum { + BAD_CAPACITY_FOR_FILE_BACKED = 1, + CAPACITY_SMALLER_THAN_FILE_SIZE, + FILE_NOT_FOUND, + FILE_ALREADY_EXISTS, + PATH_TOO_LONG, + COULD_NOT_OPEN, + CAPACITY_MUST_BE_POSITIVE, + INVALID_FILE_MODE, + COULD_NOT_MAP_MEMORY +}; + +enum { + FILE_MODE_CREATE_NEW = 1, + FILE_MODE_CREATE = 2, + FILE_MODE_OPEN = 3, + FILE_MODE_OPEN_OR_CREATE = 4, + FILE_MODE_TRUNCATE = 5, + FILE_MODE_APPEND = 6, +}; + +enum { + MMAP_FILE_ACCESS_READ_WRITE = 0, + MMAP_FILE_ACCESS_READ = 1, + MMAP_FILE_ACCESS_WRITE = 2, + MMAP_FILE_ACCESS_COPY_ON_WRITE = 3, + MMAP_FILE_ACCESS_READ_EXECUTE = 4, + MMAP_FILE_ACCESS_READ_WRITE_EXECUTE = 5, +}; + + +static int mmap_init_state; +static mono_mutex_t named_regions_mutex; +static GHashTable *named_regions; + + +static gint64 +align_up_to_page_size (gint64 size) +{ + gint64 page_size = mono_pagesize (); + return (size + page_size - 1) & ~(page_size - 1); +} + +static gint64 +align_down_to_page_size (gint64 size) +{ + gint64 page_size = mono_pagesize (); + return size & ~(page_size - 1); +} + +static void +file_mmap_init (void) +{ +retry: + switch (mmap_init_state) { + case 0: + if (InterlockedCompareExchange (&mmap_init_state, 1, 0) != 0) + goto retry; + named_regions = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); + mono_mutex_init (&named_regions_mutex); + + mono_atomic_store_release (&mmap_init_state, 2); + break; + + case 1: + do { + g_usleep (1000); /* Been init'd by other threads, this is very rare. */ + } while (mmap_init_state != 2); + break; + case 2: + break; + default: + g_error ("Invalid init state %d", mmap_init_state); + } +} + +static void +named_regions_lock (void) +{ + file_mmap_init (); + mono_mutex_lock (&named_regions_mutex); +} + +static void +named_regions_unlock (void) +{ + mono_mutex_unlock (&named_regions_mutex); +} + + +static int +file_mode_to_unix (int mode) +{ + switch (mode) { + case FILE_MODE_CREATE_NEW: + return O_CREAT | O_EXCL; + case FILE_MODE_CREATE: + return O_CREAT | O_TRUNC; + case FILE_MODE_OPEN: + return 0; + case FILE_MODE_OPEN_OR_CREATE: + return O_CREAT; + case FILE_MODE_TRUNCATE: + return O_TRUNC; + case FILE_MODE_APPEND: + return O_APPEND; + default: + g_error ("unknown FileMode %d", mode); + } +} + +static int +access_mode_to_unix (int access) +{ + switch (access) { + case MMAP_FILE_ACCESS_READ_WRITE: + case MMAP_FILE_ACCESS_COPY_ON_WRITE: + case MMAP_FILE_ACCESS_READ_WRITE_EXECUTE: + return O_RDWR; + case MMAP_FILE_ACCESS_READ: + case MMAP_FILE_ACCESS_READ_EXECUTE: + return O_RDONLY; + case MMAP_FILE_ACCESS_WRITE: + return O_WRONLY; + default: + g_error ("unknown MemoryMappedFileAccess %d", access); + } +} + +static int +acess_to_mmap_flags (int access) +{ + switch (access) { + case MMAP_FILE_ACCESS_READ_WRITE: + return MONO_MMAP_WRITE | MONO_MMAP_READ | MONO_MMAP_SHARED; + + case MMAP_FILE_ACCESS_WRITE: + return MONO_MMAP_WRITE | MONO_MMAP_SHARED; + + case MMAP_FILE_ACCESS_COPY_ON_WRITE: + return MONO_MMAP_WRITE | MONO_MMAP_READ | MONO_MMAP_PRIVATE; + + case MMAP_FILE_ACCESS_READ_EXECUTE: + return MONO_MMAP_EXEC | MONO_MMAP_PRIVATE | MONO_MMAP_SHARED; + + case MMAP_FILE_ACCESS_READ_WRITE_EXECUTE: + return MONO_MMAP_WRITE | MONO_MMAP_READ | MONO_MMAP_EXEC | MONO_MMAP_SHARED; + + case MMAP_FILE_ACCESS_READ: + return MONO_MMAP_READ | MONO_MMAP_SHARED; + default: + g_error ("unknown MemoryMappedFileAccess %d", access); + } +} + +/* +XXX implement options +*/ +static void* +open_file_map (MonoString *path, int input_fd, int mode, gint64 *capacity, int access, int options, int *error) +{ + struct stat buf; + char *c_path = path ? mono_string_to_utf8 (path) : NULL; + FileHandle *handle = NULL; + int result, fd; + + if (path) + result = stat (c_path, &buf); + else + result = fstat (input_fd, &buf); + + if (mode == FILE_MODE_TRUNCATE || mode == FILE_MODE_APPEND || mode == FILE_MODE_OPEN) { + if (result == -1) { //XXX translate errno? + *error = FILE_NOT_FOUND; + goto done; + } + } + + if (mode == FILE_MODE_CREATE_NEW && result == 0) { + *error = FILE_ALREADY_EXISTS; + goto done; + } + + if (result == 0) { + if (*capacity == 0) { + /** + * Special files such as FIFOs, sockets, and devices can have a size of 0. Specifying a capacity for these + * also makes little sense, so don't do the check if th file is one of these. + */ + if (buf.st_size == 0 && (buf.st_mode & (S_IFCHR | S_IFBLK | S_IFIFO | S_IFSOCK)) == 0) { + *error = CAPACITY_SMALLER_THAN_FILE_SIZE; + goto done; + } + *capacity = buf.st_size; + } else if (*capacity < buf.st_size) { + *error = CAPACITY_SMALLER_THAN_FILE_SIZE; + goto done; + } + } else { + if (mode == FILE_MODE_CREATE_NEW && *capacity == 0) { + *error = CAPACITY_SMALLER_THAN_FILE_SIZE; + goto done; + } + } + + if (path) //FIXME use io portability? + fd = open (c_path, file_mode_to_unix (mode) | access_mode_to_unix (access), DEFFILEMODE); + else + fd = dup (input_fd); + + if (fd == -1) { //XXX translate errno? + *error = COULD_NOT_OPEN; + goto done; + } + + *capacity = align_up_to_page_size ((size_t)*capacity); + + if (*capacity > buf.st_size) + ftruncate (fd, (off_t)*capacity); + + handle = g_new0 (FileHandle, 1); + handle->handle.kind = MMAP_KIND_FILE; + handle->handle.ref_count = 1; + handle->handle.capacity = *capacity; + handle->fd = fd; + +done: + g_free (c_path); + return (void*)handle; +} + +static void* +open_memory_map (MonoString *mapName, int mode, gint64 *capacity, int access, int options, int *error) +{ + char *c_mapName; + MemoryHandle *handle; + if (*capacity <= 1) { + *error = CAPACITY_MUST_BE_POSITIVE; + return NULL; + } + + if (!(mode == FILE_MODE_CREATE_NEW || mode == FILE_MODE_OPEN_OR_CREATE || mode == FILE_MODE_OPEN)) { + *error = INVALID_FILE_MODE; + return NULL; + } + + c_mapName = mono_string_to_utf8 (mapName); + + named_regions_lock (); + handle = (MemoryHandle*)g_hash_table_lookup (named_regions, c_mapName); + if (handle) { + if (mode == FILE_MODE_CREATE_NEW) + *error = FILE_ALREADY_EXISTS; + + handle->handle.ref_count++; + //XXX should we ftruncate if the file is smaller than capacity? + } else { + if (mode == FILE_MODE_OPEN) + *error = FILE_NOT_FOUND; + + *capacity = align_up_to_page_size (*capacity); + + handle = g_new0 (MemoryHandle, 1); + handle->handle.kind = MMAP_KIND_MEMORY; + handle->handle.ref_count = 1; + handle->handle.capacity = *capacity; + handle->handle.name = g_strdup (c_mapName); + + //FIXME compute RWX from access + handle->address = mono_valloc (NULL, (size_t)*capacity, MONO_MMAP_READ | MONO_MMAP_WRITE | MONO_MMAP_PRIVATE | MONO_MMAP_ANON); + handle->length = (size_t)*capacity; + g_hash_table_insert (named_regions, handle->handle.name, handle); + } + + named_regions_unlock (); + + g_free (c_mapName); + return handle; +} + + +void * +mono_mmap_open_file (MonoString *path, int mode, MonoString *mapName, gint64 *capacity, int access, int options, int *error) +{ + g_assert (path || mapName); + + if (!mapName) + return open_file_map (path, -1, mode, capacity, access, options, error); + + if (path) { + FileHandle *file_handle; + char *c_mapName = mono_string_to_utf8 (mapName); + + named_regions_lock (); + file_handle = (FileHandle*)g_hash_table_lookup (named_regions, c_mapName); + if (file_handle) { + *error = FILE_ALREADY_EXISTS; + file_handle = NULL; + } else { + file_handle = open_file_map (path, -1, mode, capacity, access, options, error); + if (file_handle) { + file_handle->handle.name = g_strdup (c_mapName); + g_hash_table_insert (named_regions, file_handle->handle.name, file_handle); + } + } + named_regions_unlock (); + + g_free (c_mapName); + return file_handle; + } + + return open_memory_map (mapName, mode, capacity, access, options, error); +} + +void * +mono_mmap_open_handle (void *handle, MonoString *mapName, gint64 *capacity, int access, int options, int *error) +{ + FileHandle *file_handle; + char *c_mapName = mono_string_to_utf8 (mapName); + + named_regions_lock (); + file_handle = (FileHandle*)g_hash_table_lookup (named_regions, c_mapName); + if (file_handle) { + *error = FILE_ALREADY_EXISTS; + file_handle = NULL; + } else { + //XXX we're exploiting wapi HANDLE == FD equivalence. THIS IS FRAGILE, create a _wapi_handle_to_fd call + file_handle = open_file_map (NULL, GPOINTER_TO_INT (handle), FILE_MODE_OPEN, capacity, access, options, error); + file_handle->handle.name = g_strdup (c_mapName); + g_hash_table_insert (named_regions, file_handle->handle.name, file_handle); + } + named_regions_unlock (); + + g_free (c_mapName); + return file_handle; +} + +void +mono_mmap_close (void *mmap_handle) +{ + Handle *handle = mmap_handle; + + named_regions_lock (); + --handle->ref_count; + if (handle->ref_count == 0) { + if (handle->name) + g_hash_table_remove (named_regions, handle->name); + + g_free (handle->name); + if (handle->kind == MMAP_KIND_MEMORY) + mono_vfree (((MemoryHandle*)handle)->address, ((MemoryHandle*)handle)->length); + else + close (((FileHandle*)handle)->fd); + g_free (handle); + } + named_regions_unlock (); +} + +void +mono_mmap_configure_inheritability (void *mmap_handle, gboolean inheritability) +{ + FileHandle *h = mmap_handle; + int fd, flags; + + if (h->handle.kind != MMAP_KIND_FILE) + return; + + fd = h->fd; + flags = fcntl (fd, F_GETFD, 0); + if (inheritability) + flags &= ~FD_CLOEXEC; + else + flags |= FD_CLOEXEC; + fcntl (fd, F_SETFD, flags); +} + +void +mono_mmap_flush (void *mmap_handle) +{ + MmapHandle *h = mmap_handle; + + if (h) + msync (h->address, h->length, MS_SYNC); +} + +int +mono_mmap_map (void *handle, gint64 offset, gint64 *size, int access, void **mmap_handle, void **base_address) +{ + gint64 mmap_offset = 0; + Handle *h = handle; + MmapHandle res = { 0 }; + if (h->kind == MMAP_KIND_FILE) { + FileHandle *fh = (FileHandle*)h; + size_t eff_size = *size; + struct stat buf = { 0 }; + fstat (fh->fd, &buf); //FIXME error handling + + if (eff_size == 0 || eff_size > buf.st_size) + eff_size = buf.st_size; + *size = eff_size; + + mmap_offset = align_down_to_page_size (offset); + eff_size += (offset - mmap_offset); + //FIXME translate some interesting errno values + res.address = mono_file_map ((size_t)eff_size, acess_to_mmap_flags (access), fh->fd, mmap_offset, &res.free_handle); + res.length = eff_size; + res.kind = MMAP_KIND_FILE; + + } else { + MemoryHandle *mh = (MemoryHandle*)h; + size_t eff_size = *size; + + if (!eff_size) + eff_size = *size = mh->length; + mmap_offset = (size_t)mmap_offset; + res.address = (char*)mh->address + offset; + res.length = (size_t)size; + res.kind = MMAP_KIND_MEMORY; + } + + if (res.address) { + *mmap_handle = g_memdup (&res, sizeof (MmapHandle)); + *base_address = (char*)res.address + (offset - mmap_offset); + return 0; + } + + *mmap_handle = NULL; + *base_address = NULL; + return COULD_NOT_MAP_MEMORY; +} + +gboolean +mono_mmap_unmap (void *mmap_handle) +{ + int res = 0; + MmapHandle *h = mmap_handle; + + if (h->kind == MMAP_KIND_FILE) + res = mono_file_unmap (h->address, h->free_handle); + + g_free (h); + return res == 0; +} + +#endif diff --git a/mono/metadata/file-mmap-windows.c b/mono/metadata/file-mmap-windows.c new file mode 100644 index 00000000000..78203ad47a8 --- /dev/null +++ b/mono/metadata/file-mmap-windows.c @@ -0,0 +1,70 @@ +/* + * file-mmap-posix.c: File mmap internal calls + * + * Author: + * Rodrigo Kumpera + * + * Copyright 2014 Xamarin Inc (http://www.xamarin.com) + */ + +#include + +#ifdef TARGET_WIN32 + +#include +#include +#include + + +#include +#include + +void * +mono_mmap_open_file (MonoString *path, int mode, MonoString *mapName, gint64 *capacity, int access, int options, int *error) +{ + g_error ("No windows backend"); + return NULL; +} + +void * +mono_mmap_open_handle (void *handle, MonoString *mapName, gint64 *capacity, int access, int options, int *error) +{ + g_error ("No windows backend"); + return NULL; +} + +void +mono_mmap_close (void *mmap_handle) +{ + g_error ("No windows backend"); +} + +void +mono_mmap_configure_inheritability (void *mmap_handle, gboolean inheritability) +{ + g_error ("No windows backend"); +} + +void +mono_mmap_flush (void *mmap_handle) +{ + g_error ("No windows backend"); +} + + + +int +mono_mmap_map (void *handle, gint64 offset, gint64 *size, int access, void **mmap_handle, void **base_address) +{ + g_error ("No windows backend"); + return 0; +} + +gboolean +mono_mmap_unmap (void *mmap_handle) +{ + g_error ("No windows backend"); + return TRUE; +} + +#endif diff --git a/mono/metadata/file-mmap.h b/mono/metadata/file-mmap.h new file mode 100644 index 00000000000..1d750167254 --- /dev/null +++ b/mono/metadata/file-mmap.h @@ -0,0 +1,34 @@ +/* + * file-mmap.h: Managed mmap wrappers. + * + * Authors: + * Rodrigo Kumpera + * + * Copyright 2014 Xamarin Inc (http://www.xamarin.com) + */ + +#ifndef _MONO_METADATA_FILE_MMAP_H_ +#define _MONO_METADATA_FILE_MMAP_H_ + +#include +#include + +#include +#include +#include + +extern void mono_mmap_close (void *mmap_handle) MONO_INTERNAL; + +extern void mono_mmap_configure_inheritability (void *mmap_handle, gboolean inheritability) MONO_INTERNAL; + +extern void mono_mmap_flush (void *mmap_handle) MONO_INTERNAL; + +extern void *mono_mmap_open_file (MonoString *string, int mode, MonoString *mapName, gint64 *capacity, int access, int options, int *error) MONO_INTERNAL; + +extern void *mono_mmap_open_handle (void *handle, MonoString *mapName, gint64 *capacity, int access, int options, int *error) MONO_INTERNAL; + +extern int mono_mmap_map (void *handle, gint64 offset, gint64 *size, int access, void **mmap_handle, void **base_address) MONO_INTERNAL; + +extern gboolean mono_mmap_unmap (void *base_address) MONO_INTERNAL; + +#endif /* _MONO_METADATA_FILE_MMAP_H_ */ diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h index 0582798fc79..028319dcfe0 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -315,12 +315,14 @@ ICALL(INOW_1, "AddWatch", ves_icall_System_IO_InotifyWatcher_AddWatch) ICALL(INOW_2, "GetInotifyInstance", ves_icall_System_IO_InotifyWatcher_GetInotifyInstance) ICALL(INOW_3, "RemoveWatch", ves_icall_System_IO_InotifyWatcher_RemoveWatch) -#if defined (TARGET_IOS) || defined (TARGET_ANDROID) ICALL_TYPE(MMAPIMPL, "System.IO.MemoryMappedFiles.MemoryMapImpl", MMAPIMPL_1) -ICALL(MMAPIMPL_1, "mono_filesize_from_fd", mono_filesize_from_fd) -ICALL(MMAPIMPL_2, "mono_filesize_from_path", mono_filesize_from_path) -#endif - +ICALL(MMAPIMPL_1, "CloseMapping", mono_mmap_close) +ICALL(MMAPIMPL_2, "ConfigureHandleInheritability", mono_mmap_configure_inheritability) +ICALL(MMAPIMPL_3, "Flush", mono_mmap_flush) +ICALL(MMAPIMPL_4, "MapInternal", mono_mmap_map) +ICALL(MMAPIMPL_5, "OpenFileInternal", mono_mmap_open_file) +ICALL(MMAPIMPL_6, "OpenHandleInternal", mono_mmap_open_handle) +ICALL(MMAPIMPL_7, "Unmap", mono_mmap_unmap) ICALL_TYPE(MONOIO, "System.IO.MonoIO", MONOIO_1) ICALL(MONOIO_1, "Close(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Close) diff --git a/mono/metadata/icall.c b/mono/metadata/icall.c index b05892a7a2a..b320933a0a8 100644 --- a/mono/metadata/icall.c +++ b/mono/metadata/icall.c @@ -75,6 +75,7 @@ #include #include #include +#include #include #include #include diff --git a/mono/metadata/sgen-gc.c b/mono/metadata/sgen-gc.c index 52ceeaf9391..7ab1cb6c25b 100644 --- a/mono/metadata/sgen-gc.c +++ b/mono/metadata/sgen-gc.c @@ -3936,6 +3936,7 @@ mono_gc_pthread_exit (void *retval) { mono_thread_info_detach (); pthread_exit (retval); + g_assert_not_reached (); } #endif /* USE_PTHREAD_INTERCEPT */ diff --git a/mono/metadata/sgen-nursery-allocator.c b/mono/metadata/sgen-nursery-allocator.c index 8e3dc1820ee..4ac1aa0c211 100644 --- a/mono/metadata/sgen-nursery-allocator.c +++ b/mono/metadata/sgen-nursery-allocator.c @@ -414,7 +414,7 @@ par_alloc_from_fragment (SgenFragmentAllocator *allocator, SgenFragment *frag, s /*frag->next read must happen before the first CAS*/ mono_memory_write_barrier (); - /*Fail if the next done is removed concurrently and its CAS wins */ + /*Fail if the next node is removed concurrently and its CAS wins */ if (InterlockedCompareExchangePointer ((volatile gpointer*)&frag->next, mask (next, 1), next) != next) { continue; } @@ -424,7 +424,7 @@ par_alloc_from_fragment (SgenFragmentAllocator *allocator, SgenFragment *frag, s mono_memory_write_barrier (); /* Fail if the previous node was deleted and its CAS wins */ - if (InterlockedCompareExchangePointer ((volatile gpointer*)prev_ptr, next, frag) != frag) { + if (InterlockedCompareExchangePointer ((volatile gpointer*)prev_ptr, unmask (next), frag) != frag) { prev_ptr = find_previous_pointer_fragment (allocator, frag); continue; } diff --git a/mono/mini/cpu-x86.md b/mono/mini/cpu-x86.md index b239ed0e765..cc14b0dc152 100644 --- a/mono/mini/cpu-x86.md +++ b/mono/mini/cpu-x86.md @@ -149,7 +149,7 @@ call_membase: dest:a src1:b len:16 nacl:18 clob:c iconst: dest:i len:5 r4const: dest:f len:15 r8const: dest:f len:16 -store_membase_imm: dest:b len:10 +store_membase_imm: dest:b len:11 store_membase_reg: dest:b src1:i len:7 storei1_membase_imm: dest:b len:10 storei1_membase_reg: dest:b src1:y len:7 diff --git a/mono/mini/exceptions-amd64.c b/mono/mini/exceptions-amd64.c index bd9847c4172..a5cf1105680 100644 --- a/mono/mini/exceptions-amd64.c +++ b/mono/mini/exceptions-amd64.c @@ -48,7 +48,6 @@ static MonoW32ExceptionHandler segv_handler; LPTOP_LEVEL_EXCEPTION_FILTER mono_old_win_toplevel_exception_filter; void *mono_win_vectored_exception_handle; -extern gboolean mono_win_chained_exception_needs_run; #define W32_SEH_HANDLE_EX(_ex) \ if (_ex##_handler) _ex##_handler(0, ep, sctx) @@ -76,8 +75,13 @@ static LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) CONTEXT* ctx; MonoContext* sctx; LONG res; + MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); + + /* If the thread is not managed by the runtime return early */ + if (!jit_tls) + return EXCEPTION_CONTINUE_SEARCH; - mono_win_chained_exception_needs_run = FALSE; + jit_tls->mono_win_chained_exception_needs_run = FALSE; res = EXCEPTION_CONTINUE_EXECUTION; er = ep->ExceptionRecord; @@ -115,10 +119,11 @@ static LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) W32_SEH_HANDLE_EX(fpe); break; default: + jit_tls->mono_win_chained_exception_needs_run = TRUE; break; } - if (mono_win_chained_exception_needs_run) { + if (jit_tls->mono_win_chained_exception_needs_run) { /* Don't copy context back if we chained exception * as the handler may have modfied the EXCEPTION_POINTERS * directly. We don't pass sigcontext to chained handlers. diff --git a/mono/mini/exceptions-x86.c b/mono/mini/exceptions-x86.c index aa10aaad593..6b5c061a780 100644 --- a/mono/mini/exceptions-x86.c +++ b/mono/mini/exceptions-x86.c @@ -47,7 +47,6 @@ static MonoW32ExceptionHandler segv_handler; LPTOP_LEVEL_EXCEPTION_FILTER mono_old_win_toplevel_exception_filter; gpointer mono_win_vectored_exception_handle; -extern gboolean mono_win_chained_exception_needs_run; extern int (*gUnhandledExceptionHandler)(EXCEPTION_POINTERS*); #ifndef PROCESS_CALLBACK_FILTER_ENABLED @@ -196,8 +195,13 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) CONTEXT* ctx; struct sigcontext* sctx; LONG res; + MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); + + /* If the thread is not managed by the runtime return early */ + if (!jit_tls) + return EXCEPTION_CONTINUE_SEARCH; - mono_win_chained_exception_needs_run = FALSE; + jit_tls->mono_win_chained_exception_needs_run = FALSE; res = EXCEPTION_CONTINUE_EXECUTION; er = ep->ExceptionRecord; @@ -234,10 +238,11 @@ LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep) W32_SEH_HANDLE_EX(fpe); break; default: + jit_tls->mono_win_chained_exception_needs_run = TRUE; break; } - if (mono_win_chained_exception_needs_run) { + if (jit_tls->mono_win_chained_exception_needs_run) { /* Don't copy context back if we chained exception * as the handler may have modfied the EXCEPTION_POINTERS * directly. We don't pass sigcontext to chained handlers. @@ -849,6 +854,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, *lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~3); } +#ifndef MONO_X86_NO_PUSHES /* Pop arguments off the stack */ if (ji->has_arch_eh_info) { int stack_size; @@ -868,6 +874,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, #endif } } +#endif return TRUE; } else if (*lmf) { diff --git a/mono/mini/method-to-ir.c b/mono/mini/method-to-ir.c index 4a9c33d2953..e667acb1664 100644 --- a/mono/mini/method-to-ir.c +++ b/mono/mini/method-to-ir.c @@ -4526,11 +4526,6 @@ handle_delegate_ctor (MonoCompile *cfg, MonoClass *klass, MonoInst *target, Mono /* Set method field */ method_ins = emit_get_rgctx_method (cfg, context_used, method, MONO_RGCTX_INFO_METHOD); MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, obj->dreg, G_STRUCT_OFFSET (MonoDelegate, method), method_ins->dreg); - if (cfg->gen_write_barriers) { - dreg = alloc_preg (cfg); - EMIT_NEW_BIALU_IMM (cfg, ptr, OP_PADD_IMM, dreg, obj->dreg, G_STRUCT_OFFSET (MonoDelegate, method)); - emit_write_barrier (cfg, ptr, method_ins); - } /* * To avoid looking up the compiled code belonging to the target method * in mono_delegate_trampoline (), we allocate a per-domain memory slot to @@ -7787,6 +7782,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b EMIT_NEW_ARGLOAD (cfg, call->args [i], i); mono_arch_emit_call (cfg, call); + cfg->param_area = MAX(cfg->param_area, call->stack_usage); MONO_ADD_INS (bblock, (MonoInst*)call); } else { for (i = 0; i < num_args; ++i) diff --git a/mono/mini/mini-arm.c b/mono/mini/mini-arm.c index e6ebc8dea7e..6895e1fb3a1 100644 --- a/mono/mini/mini-arm.c +++ b/mono/mini/mini-arm.c @@ -4206,7 +4206,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) ARM_CMP_REG_IMM (code, tmpreg, 0, 0); buf [2] = code; ARM_B_COND (code, ARMCOND_NE, 0); - arm_patch (buf [2], buf [1]); + arm_patch (buf [2], buf [0]); arm_patch (buf [1], code); break; case OP_ATOMIC_ADD_NEW_I4: diff --git a/mono/mini/mini-arm.h b/mono/mini/mini-arm.h index cba8a33a744..131d4330016 100644 --- a/mono/mini/mini-arm.h +++ b/mono/mini/mini-arm.h @@ -124,6 +124,17 @@ * reproduceable results for benchmarks */ #define MONO_ARCH_CODE_ALIGNMENT 32 +/* Argument marshallings for calls between gsharedvt and normal code */ +typedef enum { + GSHAREDVT_ARG_NONE = 0, + GSHAREDVT_ARG_BYVAL_TO_BYREF = 1, + GSHAREDVT_ARG_BYREF_TO_BYVAL = 2, + GSHAREDVT_ARG_BYREF_TO_BYVAL_I1 = 3, + GSHAREDVT_ARG_BYREF_TO_BYVAL_I2 = 4, + GSHAREDVT_ARG_BYREF_TO_BYVAL_U1 = 5, + GSHAREDVT_ARG_BYREF_TO_BYVAL_U2 = 6 +} GSharedVtArgMarshal; + /* Return value marshalling for calls between gsharedvt and normal code */ typedef enum { GSHAREDVT_RET_NONE = 0, diff --git a/mono/mini/mini-gc.c b/mono/mini/mini-gc.c index 4934f49beaa..1566cb0d874 100644 --- a/mono/mini/mini-gc.c +++ b/mono/mini/mini-gc.c @@ -1871,7 +1871,11 @@ sp_offset_to_fp_offset (MonoCompile *cfg, int sp_offset) #elif defined(TARGET_X86) /* The offset is computed from the sp at the start of the call sequence */ g_assert (cfg->frame_reg == X86_EBP); +#ifdef MONO_X86_NO_PUSHES + return (- cfg->arch.sp_fp_offset + sp_offset); +#else return (- cfg->arch.sp_fp_offset - sp_offset); +#endif #else NOT_IMPLEMENTED; return -1; @@ -2058,7 +2062,11 @@ compute_frame_size (MonoCompile *cfg) #ifdef TARGET_AMD64 min_offset = MIN (min_offset, -cfg->arch.sp_fp_offset); #elif defined(TARGET_X86) +#ifdef MONO_X86_NO_PUSHES + min_offset = MIN (min_offset, -cfg->arch.sp_fp_offset); +#else min_offset = MIN (min_offset, - (cfg->arch.sp_fp_offset + cfg->arch.param_area_size)); +#endif #elif defined(TARGET_ARM) // FIXME: #elif defined(TARGET_s390X) diff --git a/mono/mini/mini-windows.c b/mono/mini/mini-windows.c index bb71ec48192..c43b1d0102f 100644 --- a/mono/mini/mini-windows.c +++ b/mono/mini/mini-windows.c @@ -50,8 +50,6 @@ #include "jit-icalls.h" -gboolean mono_win_chained_exception_needs_run; - void mono_runtime_install_handlers (void) { @@ -83,7 +81,8 @@ mono_runtime_cleanup_handlers (void) gboolean SIG_HANDLER_SIGNATURE (mono_chain_signal) { - mono_win_chained_exception_needs_run = TRUE; + MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); + jit_tls->mono_win_chained_exception_needs_run = TRUE; return TRUE; } diff --git a/mono/mini/mini-x86.c b/mono/mini/mini-x86.c index 02a6d1daa78..3de9b0be1a2 100644 --- a/mono/mini/mini-x86.c +++ b/mono/mini/mini-x86.c @@ -217,6 +217,8 @@ typedef struct { /* The index of the vret arg in the argument list */ int vret_arg_index; int vret_arg_offset; + /* Argument space popped by the callee */ + int callee_stack_pop; ArgInfo ret; ArgInfo sig_cookie; ArgInfo args [1]; @@ -593,6 +595,11 @@ get_call_info_internal (MonoGenericSharingContext *gsctx, CallInfo *cinfo, MonoM stack_size += cinfo->stack_align_amount; } + if (cinfo->vtype_retaddr) { + /* if the function returns a struct on stack, the called method already does a ret $0x4 */ + cinfo->callee_stack_pop = 4; + } + cinfo->stack_usage = stack_size; cinfo->reg_usage = gr; cinfo->freg_usage = fr; @@ -1209,6 +1216,10 @@ mono_arch_create_vars (MonoCompile *cfg) cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG); } +#ifdef MONO_X86_NO_PUSHES + cfg->arch.no_pushes = TRUE; +#endif + if (cfg->method->save_lmf) { cfg->create_lmf_var = TRUE; cfg->lmf_ir = TRUE; @@ -1267,9 +1278,17 @@ emit_sig_cookie (MonoCompile *cfg, MonoCallInst *call, CallInfo *cinfo) if (cfg->compile_aot) { sig_reg = mono_alloc_ireg (cfg); MONO_EMIT_NEW_SIGNATURECONST (cfg, sig_reg, tmp_sig); - MONO_EMIT_NEW_UNALU (cfg, OP_X86_PUSH, -1, sig_reg); + if (cfg->arch.no_pushes) { + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, cinfo->sig_cookie.offset, sig_reg); + } else { + MONO_EMIT_NEW_UNALU (cfg, OP_X86_PUSH, -1, sig_reg); + } } else { - MONO_EMIT_NEW_BIALU_IMM (cfg, OP_X86_PUSH_IMM, -1, -1, tmp_sig); + if (cfg->arch.no_pushes) { + MONO_EMIT_NEW_STORE_MEMBASE_IMM (cfg, OP_STORE_MEMBASE_IMM, X86_ESP, cinfo->sig_cookie.offset, tmp_sig); + } else { + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_X86_PUSH_IMM, -1, -1, tmp_sig); + } } } @@ -1394,6 +1413,9 @@ emit_gc_param_slot_def (MonoCompile *cfg, int sp_offset, MonoType *t) if (cfg->compute_gc_maps) { MonoInst *def; + /* Needs checking if the feature will be enabled again */ + g_assert (!cfg->arch.no_pushes); + /* On x86, the offsets are from the sp value before the start of the call sequence */ if (t == NULL) t = &mono_defaults.int_class->byval_arg; @@ -1416,11 +1438,12 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) sig_ret = mini_replace_type (sig->ret); cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig); + call->call_info = cinfo; if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG)) sentinelpos = sig->sentinelpos + (sig->hasthis ? 1 : 0); - if (cinfo->need_stack_align) { + if (cinfo->need_stack_align && !cfg->arch.no_pushes) { MONO_INST_NEW (cfg, arg, OP_SUB_IMM); arg->dreg = X86_ESP; arg->sreg1 = X86_ESP; @@ -1451,7 +1474,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) /* Handle the case where there are no implicit arguments */ if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG) && (n == sentinelpos)) { emit_sig_cookie (cfg, call, cinfo); - sp_offset += 4; + sp_offset = (cfg->arch.no_pushes) ? cinfo->sig_cookie.offset : (sp_offset + 4); emit_gc_param_slot_def (cfg, sp_offset, NULL); } @@ -1462,13 +1485,23 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) int argsize; if (cinfo->vtype_retaddr && cinfo->vret_arg_index == 1 && i == 0) { - /* Push the vret arg before the first argument */ MonoInst *vtarg; - MONO_INST_NEW (cfg, vtarg, OP_X86_PUSH); - vtarg->type = STACK_MP; - vtarg->sreg1 = call->vret_var->dreg; - MONO_ADD_INS (cfg->cbb, vtarg); - sp_offset += 4; + /* Push the vret arg before the first argument */ + if (cfg->arch.no_pushes) { + MONO_INST_NEW (cfg, vtarg, OP_STORE_MEMBASE_REG); + vtarg->type = STACK_MP; + vtarg->inst_destbasereg = X86_ESP; + vtarg->sreg1 = call->vret_var->dreg; + vtarg->inst_offset = cinfo->ret.offset; + MONO_ADD_INS (cfg->cbb, vtarg); + sp_offset = cinfo->ret.offset; + } else { + MONO_INST_NEW (cfg, vtarg, OP_X86_PUSH); + vtarg->type = STACK_MP; + vtarg->sreg1 = call->vret_var->dreg; + MONO_ADD_INS (cfg->cbb, vtarg); + sp_offset += 4; + } emit_gc_param_slot_def (cfg, sp_offset, NULL); } @@ -1521,48 +1554,70 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) MONO_ADD_INS (cfg->cbb, arg); if (ainfo->storage != ArgValuetypeInReg) { - sp_offset += size; + sp_offset = (cfg->arch.no_pushes) ? ainfo->offset : (sp_offset + size); emit_gc_param_slot_def (cfg, sp_offset, orig_type); } } } else { - argsize = 4; - switch (ainfo->storage) { case ArgOnStack: - arg->opcode = OP_X86_PUSH; if (!t->byref) { if (t->type == MONO_TYPE_R4) { - MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SUB_IMM, X86_ESP, X86_ESP, 4); - arg->opcode = OP_STORER4_MEMBASE_REG; - arg->inst_destbasereg = X86_ESP; - arg->inst_offset = 0; + if (cfg->arch.no_pushes) { + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER4_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg); + } else { + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SUB_IMM, X86_ESP, X86_ESP, 4); + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER4_MEMBASE_REG, X86_ESP, 0, in->dreg); + } argsize = 4; } else if (t->type == MONO_TYPE_R8) { - MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SUB_IMM, X86_ESP, X86_ESP, 8); - arg->opcode = OP_STORER8_MEMBASE_REG; - arg->inst_destbasereg = X86_ESP; - arg->inst_offset = 0; + if (cfg->arch.no_pushes) { + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER8_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg); + } else { + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SUB_IMM, X86_ESP, X86_ESP, 8); + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER8_MEMBASE_REG, X86_ESP, 0, in->dreg); + } argsize = 8; } else if (t->type == MONO_TYPE_I8 || t->type == MONO_TYPE_U8) { - arg->sreg1 ++; - MONO_EMIT_NEW_UNALU (cfg, OP_X86_PUSH, -1, in->dreg + 2); - sp_offset += 4; + if (cfg->arch.no_pushes) { + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset + 4, in->dreg + 2); + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg + 1); + } else { + MONO_EMIT_NEW_UNALU (cfg, OP_X86_PUSH, -1, in->dreg + 2); + MONO_EMIT_NEW_UNALU (cfg, OP_X86_PUSH, -1, in->dreg + 1); + sp_offset += 4; + } + argsize = 4; + } else { + if (cfg->arch.no_pushes) { + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg); + } else { + arg->opcode = OP_X86_PUSH; + MONO_ADD_INS (cfg->cbb, arg); + } + argsize = 4; } + } else { + if (cfg->arch.no_pushes) { + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, in->dreg); + } else { + arg->opcode = OP_X86_PUSH; + MONO_ADD_INS (cfg->cbb, arg); + } + argsize = 4; } break; case ArgInIReg: arg->opcode = OP_MOVE; arg->dreg = ainfo->reg; + MONO_ADD_INS (cfg->cbb, arg); argsize = 0; break; default: g_assert_not_reached (); } - - MONO_ADD_INS (cfg->cbb, arg); - sp_offset += argsize; + sp_offset = (cfg->arch.no_pushes) ? ainfo->offset : (sp_offset + argsize); if (cfg->compute_gc_maps) { if (argsize == 4) { @@ -1579,8 +1634,12 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) } } else { /* i8/r8 */ - for (j = 0; j < argsize; j += 4) - emit_gc_param_slot_def (cfg, sp_offset - j, NULL); + for (j = 0; j < argsize; j += 4) { + if (cfg->arch.no_pushes) + emit_gc_param_slot_def (cfg, sp_offset + j, NULL); + else + emit_gc_param_slot_def (cfg, sp_offset - j, NULL); + } } } } @@ -1588,7 +1647,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG) && (i == sentinelpos)) { /* Emit the signature cookie just before the implicit arguments */ emit_sig_cookie (cfg, call, cinfo); - sp_offset += 4; + sp_offset = (cfg->arch.no_pushes) ? cinfo->sig_cookie.offset : (sp_offset + 4); emit_gc_param_slot_def (cfg, sp_offset, NULL); } } @@ -1609,23 +1668,29 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) mono_call_inst_add_outarg_reg (cfg, call, vtarg->dreg, cinfo->ret.reg, FALSE); } else if (cinfo->vtype_retaddr && cinfo->vret_arg_index == 0) { - MonoInst *vtarg; - MONO_INST_NEW (cfg, vtarg, OP_X86_PUSH); - vtarg->type = STACK_MP; - vtarg->sreg1 = call->vret_var->dreg; - MONO_ADD_INS (cfg->cbb, vtarg); - sp_offset += 4; + if (cfg->arch.no_pushes) { + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, cinfo->ret.offset, call->vret_var->dreg); + sp_offset = cinfo->ret.offset; + } else { + MonoInst *vtarg; + MONO_INST_NEW (cfg, vtarg, OP_X86_PUSH); + vtarg->type = STACK_MP; + vtarg->sreg1 = call->vret_var->dreg; + MONO_ADD_INS (cfg->cbb, vtarg); + sp_offset += 4; + } emit_gc_param_slot_def (cfg, sp_offset, NULL); } /* if the function returns a struct on stack, the called method already does a ret $0x4 */ - if (cinfo->ret.storage != ArgValuetypeInReg) - cinfo->stack_usage -= 4; + if (!cfg->arch.no_pushes) + cinfo->stack_usage -= cinfo->callee_stack_pop; } call->stack_usage = cinfo->stack_usage; call->stack_align_amount = cinfo->stack_align_amount; - cfg->arch.param_area_size = MAX (cfg->arch.param_area_size, sp_offset); + if (!cfg->arch.no_pushes) + cfg->arch.param_area_size = MAX (cfg->arch.param_area_size, sp_offset); } void @@ -1657,24 +1722,42 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src) else { if (cfg->gsharedvt && mini_is_gsharedvt_klass (cfg, ins->klass)) { /* Pass by addr */ - MONO_INST_NEW (cfg, arg, OP_X86_PUSH); - arg->sreg1 = src->dreg; - MONO_ADD_INS (cfg->cbb, arg); + if (cfg->arch.no_pushes) { + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, src->dreg); + } else { + MONO_INST_NEW (cfg, arg, OP_X86_PUSH); + arg->sreg1 = src->dreg; + MONO_ADD_INS (cfg->cbb, arg); + } } else if (size <= 4) { - MONO_INST_NEW (cfg, arg, OP_X86_PUSH_MEMBASE); - arg->sreg1 = src->dreg; - - MONO_ADD_INS (cfg->cbb, arg); - } else if (size <= 20) { - MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SUB_IMM, X86_ESP, X86_ESP, ALIGN_TO (size, 4)); - mini_emit_memcpy (cfg, X86_ESP, 0, src->dreg, 0, size, 4); + if (cfg->arch.no_pushes) { + int dreg = mono_alloc_ireg (cfg); + MONO_EMIT_NEW_LOAD_MEMBASE (cfg, dreg, src->dreg, 0); + MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, X86_ESP, ainfo->offset, dreg); + } else { + MONO_INST_NEW (cfg, arg, OP_X86_PUSH_MEMBASE); + arg->sreg1 = src->dreg; + MONO_ADD_INS (cfg->cbb, arg); + } + } else if (size <= 20) { + if (cfg->arch.no_pushes) { + mini_emit_memcpy (cfg, X86_ESP, ainfo->offset, src->dreg, 0, size, 4); + } else { + MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SUB_IMM, X86_ESP, X86_ESP, ALIGN_TO (size, 4)); + mini_emit_memcpy (cfg, X86_ESP, 0, src->dreg, 0, size, 4); + } } else { - MONO_INST_NEW (cfg, arg, OP_X86_PUSH_OBJ); - arg->inst_basereg = src->dreg; - arg->inst_offset = 0; - arg->inst_imm = size; + if (cfg->arch.no_pushes) { + // FIXME: Code growth + mini_emit_memcpy (cfg, X86_ESP, ainfo->offset, src->dreg, 0, size, 4); + } else { + MONO_INST_NEW (cfg, arg, OP_X86_PUSH_OBJ); + arg->inst_basereg = src->dreg; + arg->inst_offset = 0; + arg->inst_imm = size; - MONO_ADD_INS (cfg->cbb, arg); + MONO_ADD_INS (cfg->cbb, arg); + } } } } @@ -2173,7 +2256,7 @@ emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int size, gboolean } static unsigned char* -mono_emit_stack_alloc (guchar *code, MonoInst* tree) +mono_emit_stack_alloc (MonoCompile *cfg, guchar *code, MonoInst* tree) { int sreg = tree->sreg1; int need_touch = FALSE; @@ -2217,7 +2300,10 @@ mono_emit_stack_alloc (guchar *code, MonoInst* tree) x86_push_reg (code, X86_EDI); x86_mov_reg_imm (code, X86_ECX, (0x1000 >> 2)); x86_alu_reg_reg (code, X86_XOR, X86_EAX, X86_EAX); - x86_lea_membase (code, X86_EDI, X86_ESP, 12); + if (cfg->param_area && cfg->arch.no_pushes) + x86_lea_membase (code, X86_EDI, X86_ESP, 12 + ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT)); + else + x86_lea_membase (code, X86_EDI, X86_ESP, 12); x86_cld (code); x86_prefix (code, X86_REP_PREFIX); x86_stosl (code); @@ -2264,7 +2350,10 @@ mono_emit_stack_alloc (guchar *code, MonoInst* tree) x86_mov_reg_reg (code, X86_ECX, sreg, 4); x86_alu_reg_reg (code, X86_XOR, X86_EAX, X86_EAX); - x86_lea_membase (code, X86_EDI, X86_ESP, offset); + if (cfg->param_area && cfg->arch.no_pushes) + x86_lea_membase (code, X86_EDI, X86_ESP, offset + ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT)); + else + x86_lea_membase (code, X86_EDI, X86_ESP, offset); x86_cld (code); x86_prefix (code, X86_REP_PREFIX); x86_stosl (code); @@ -3245,14 +3334,58 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_VCALL2: case OP_VOIDCALL: case OP_CALL: + case OP_FCALL_REG: + case OP_LCALL_REG: + case OP_VCALL_REG: + case OP_VCALL2_REG: + case OP_VOIDCALL_REG: + case OP_CALL_REG: + case OP_FCALL_MEMBASE: + case OP_LCALL_MEMBASE: + case OP_VCALL_MEMBASE: + case OP_VCALL2_MEMBASE: + case OP_VOIDCALL_MEMBASE: + case OP_CALL_MEMBASE: { + CallInfo *cinfo; + call = (MonoCallInst*)ins; - if (ins->flags & MONO_INST_HAS_METHOD) - code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, call->method); - else - code = emit_call (cfg, code, MONO_PATCH_INFO_ABS, call->fptr); + cinfo = (CallInfo*)call->call_info; + + switch (ins->opcode) { + case OP_FCALL: + case OP_LCALL: + case OP_VCALL: + case OP_VCALL2: + case OP_VOIDCALL: + case OP_CALL: + if (ins->flags & MONO_INST_HAS_METHOD) + code = emit_call (cfg, code, MONO_PATCH_INFO_METHOD, call->method); + else + code = emit_call (cfg, code, MONO_PATCH_INFO_ABS, call->fptr); + break; + case OP_FCALL_REG: + case OP_LCALL_REG: + case OP_VCALL_REG: + case OP_VCALL2_REG: + case OP_VOIDCALL_REG: + case OP_CALL_REG: + x86_call_reg (code, ins->sreg1); + break; + case OP_FCALL_MEMBASE: + case OP_LCALL_MEMBASE: + case OP_VCALL_MEMBASE: + case OP_VCALL2_MEMBASE: + case OP_VOIDCALL_MEMBASE: + case OP_CALL_MEMBASE: + x86_call_membase (code, ins->sreg1, ins->inst_offset); + break; + default: + g_assert_not_reached (); + break; + } ins->flags |= MONO_INST_GC_CALLSITE; ins->backend.pc_offset = code - cfg->native_code; - if (call->stack_usage && !CALLCONV_IS_STDCALL (call->signature)) { + if (call->stack_usage && !CALLCONV_IS_STDCALL (call->signature) && !cfg->arch.no_pushes) { /* a pop is one byte, while an add reg, imm is 3. So if there are 4 or 8 * bytes to pop, we want to use pops. GCC does this (note it won't happen * for P4 or i686 because gcc will avoid using pop push at all. But we aren't @@ -3273,56 +3406,27 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) } else { x86_alu_reg_imm (code, X86_ADD, X86_ESP, call->stack_usage); } + } else if (cinfo->callee_stack_pop && cfg->arch.no_pushes) { + /* Have to compensate for the stack space popped by the callee */ + x86_alu_reg_imm (code, X86_SUB, X86_ESP, cinfo->callee_stack_pop); } code = emit_move_return_value (cfg, ins, code); break; - case OP_FCALL_REG: - case OP_LCALL_REG: - case OP_VCALL_REG: - case OP_VCALL2_REG: - case OP_VOIDCALL_REG: - case OP_CALL_REG: - call = (MonoCallInst*)ins; - x86_call_reg (code, ins->sreg1); - ins->flags |= MONO_INST_GC_CALLSITE; - ins->backend.pc_offset = code - cfg->native_code; - if (call->stack_usage && !CALLCONV_IS_STDCALL (call->signature)) { - if (call->stack_usage == 4) - x86_pop_reg (code, X86_ECX); - else - x86_alu_reg_imm (code, X86_ADD, X86_ESP, call->stack_usage); - } - code = emit_move_return_value (cfg, ins, code); - break; - case OP_FCALL_MEMBASE: - case OP_LCALL_MEMBASE: - case OP_VCALL_MEMBASE: - case OP_VCALL2_MEMBASE: - case OP_VOIDCALL_MEMBASE: - case OP_CALL_MEMBASE: - call = (MonoCallInst*)ins; - - x86_call_membase (code, ins->sreg1, ins->inst_offset); - ins->flags |= MONO_INST_GC_CALLSITE; - ins->backend.pc_offset = code - cfg->native_code; - if (call->stack_usage && !CALLCONV_IS_STDCALL (call->signature)) { - if (call->stack_usage == 4) - x86_pop_reg (code, X86_ECX); - else - x86_alu_reg_imm (code, X86_ADD, X86_ESP, call->stack_usage); - } - code = emit_move_return_value (cfg, ins, code); - break; + } case OP_X86_PUSH: + g_assert (!cfg->arch.no_pushes); x86_push_reg (code, ins->sreg1); break; case OP_X86_PUSH_IMM: + g_assert (!cfg->arch.no_pushes); x86_push_imm (code, ins->inst_imm); break; case OP_X86_PUSH_MEMBASE: + g_assert (!cfg->arch.no_pushes); x86_push_membase (code, ins->inst_basereg, ins->inst_offset); break; case OP_X86_PUSH_OBJ: + g_assert (!cfg->arch.no_pushes); x86_alu_reg_imm (code, X86_SUB, X86_ESP, ins->inst_imm); x86_push_reg (code, X86_EDI); x86_push_reg (code, X86_ESI); @@ -3353,8 +3457,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) /* keep alignment */ x86_alu_reg_imm (code, X86_ADD, ins->sreg1, MONO_ARCH_LOCALLOC_ALIGNMENT - 1); x86_alu_reg_imm (code, X86_AND, ins->sreg1, ~(MONO_ARCH_LOCALLOC_ALIGNMENT - 1)); - code = mono_emit_stack_alloc (code, ins); + code = mono_emit_stack_alloc (cfg, code, ins); x86_mov_reg_reg (code, ins->dreg, X86_ESP, 4); + if (cfg->param_area && cfg->arch.no_pushes) + x86_alu_reg_imm (code, X86_ADD, ins->dreg, ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT)); break; case OP_LOCALLOC_IMM: { guint32 size = ins->inst_imm; @@ -3365,12 +3471,14 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) x86_mov_reg_imm (code, ins->dreg, size); ins->sreg1 = ins->dreg; - code = mono_emit_stack_alloc (code, ins); + code = mono_emit_stack_alloc (cfg, code, ins); x86_mov_reg_reg (code, ins->dreg, X86_ESP, 4); } else { x86_alu_reg_imm (code, X86_SUB, X86_ESP, size); x86_mov_reg_reg (code, ins->dreg, X86_ESP, 4); } + if (cfg->param_area && cfg->arch.no_pushes) + x86_alu_reg_imm (code, X86_ADD, ins->dreg, ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT)); break; } case OP_THROW: { @@ -3401,6 +3509,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) case OP_START_HANDLER: { MonoInst *spvar = mono_find_spvar_for_region (cfg, bb->region); x86_mov_membase_reg (code, spvar->inst_basereg, spvar->inst_offset, X86_ESP, 4); + if (cfg->param_area && cfg->arch.no_pushes) { + x86_alu_reg_imm (code, X86_SUB, X86_ESP, ALIGN_TO (cfg->param_area, MONO_ARCH_FRAME_ALIGNMENT)); + } break; } case OP_ENDFINALLY: { @@ -5246,6 +5357,11 @@ mono_arch_emit_prolog (MonoCompile *cfg) cfg->frame_reg = X86_ESP; } + if (cfg->arch.no_pushes) { + cfg->stack_offset += cfg->param_area; + cfg->stack_offset = ALIGN_TO (cfg->stack_offset, MONO_ARCH_FRAME_ALIGNMENT); + } + alloc_size = cfg->stack_offset; pos = 0; @@ -5561,8 +5677,8 @@ mono_arch_emit_epilog (MonoCompile *cfg) MonoJitArgumentInfo *arg_info = alloca (sizeof (MonoJitArgumentInfo) * (sig->param_count + 1)); stack_to_pop = mono_arch_get_argument_info (NULL, sig, sig->param_count, arg_info); - } else if (cinfo->vtype_retaddr) - stack_to_pop = 4; + } else if (cinfo->callee_stack_pop) + stack_to_pop = cinfo->callee_stack_pop; else stack_to_pop = 0; diff --git a/mono/mini/mini-x86.h b/mono/mini/mini-x86.h index 995686bf94b..2f7eaca37b6 100644 --- a/mono/mini/mini-x86.h +++ b/mono/mini/mini-x86.h @@ -74,6 +74,8 @@ struct sigcontext { #endif /* HAVE_WORKING_SIGALTSTACK */ #endif /* !HOST_WIN32 */ +/* #define MONO_X86_NO_PUSHES 1 */ + #define MONO_ARCH_SUPPORT_TASKLETS 1 #ifndef DISABLE_SIMD @@ -167,6 +169,7 @@ struct MonoLMF { typedef struct { gboolean need_stack_frame_inited; gboolean need_stack_frame; + gboolean no_pushes; int sp_fp_offset, param_area_size; } MonoCompileArch; diff --git a/mono/mini/mini.c b/mono/mini/mini.c index 035f975c9f8..679fdcda71a 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -4901,7 +4901,9 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl guint8 *ip; MonoCompile *cfg; int dfn, i, code_size_ratio; +#ifndef DISABLE_SSA gboolean deadce_has_run = FALSE; +#endif gboolean try_generic_shared, try_llvm = FALSE; MonoMethod *method_to_compile, *method_to_register; gboolean method_is_gshared = FALSE; diff --git a/mono/mini/mini.h b/mono/mini/mini.h index ff3d5537ad2..76cbdf32022 100644 --- a/mono/mini/mini.h +++ b/mono/mini/mini.h @@ -1060,6 +1060,11 @@ typedef struct { */ MonoContext orig_ex_ctx; gboolean orig_ex_ctx_set; + + /* + * Stores if we need to run a chained exception in Windows. + */ + gboolean mono_win_chained_exception_needs_run; } MonoJitTlsData; /* diff --git a/mono/profiler/decode.c b/mono/profiler/decode.c index 2a52c19f4d0..dff9d66a143 100644 --- a/mono/profiler/decode.c +++ b/mono/profiler/decode.c @@ -1433,7 +1433,7 @@ typedef struct _ThreadContext ThreadContext; typedef struct { FILE *file; #if defined (HAVE_SYS_ZLIB) - gzFile *gzfile; + gzFile gzfile; #endif unsigned char *buf; int size; diff --git a/mono/profiler/proflog.c b/mono/profiler/proflog.c index 9064535fbd1..2f3ef61ca5f 100644 --- a/mono/profiler/proflog.c +++ b/mono/profiler/proflog.c @@ -66,8 +66,7 @@ #include #endif -/* the architecture needs a memory fence */ -#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__) || defined(__arm__)) +#if defined(__linux__) #include #include #include "perf_event.h" @@ -384,7 +383,7 @@ struct _MonoProfiler { StatBuffer *stat_buffers; FILE* file; #if defined (HAVE_SYS_ZLIB) - gzFile *gzfile; + gzFile gzfile; #endif uint64_t startup_time; int pipe_output; diff --git a/mono/utils/atomic.c b/mono/utils/atomic.c index 7cd884e61d9..362bb8d3a08 100755 --- a/mono/utils/atomic.c +++ b/mono/utils/atomic.c @@ -12,26 +12,27 @@ #include #include +#include #if defined (WAPI_NO_ATOMIC_ASM) || defined (BROKEN_64BIT_ATOMICS_INTRINSIC) #include -static pthread_mutex_t spin = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t spin G_GNUC_UNUSED = PTHREAD_MUTEX_INITIALIZER; -#define NEED_64BIT_CMPXCHG_FALLBACK - -#endif - -#ifdef WAPI_NO_ATOMIC_ASM - -static mono_once_t spin_once=MONO_ONCE_INIT; +static mono_once_t spin_once G_GNUC_UNUSED = MONO_ONCE_INIT; static void spin_init(void) { g_warning("Using non-atomic functions! Expect race conditions when using process-shared handles!"); } +#define NEED_64BIT_CMPXCHG_FALLBACK + +#endif + +#ifdef WAPI_NO_ATOMIC_ASM + gint32 InterlockedCompareExchange(volatile gint32 *dest, gint32 exch, gint32 comp) { @@ -568,15 +569,26 @@ gint64 InterlockedCompareExchange64(volatile gint64 *dest, gint64 exch, gint64 comp) { gint64 old; + int ret; + + mono_once(&spin_once, spin_init); + + pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock, + (void *)&spin); + ret = pthread_mutex_lock(&spin); + g_assert (ret == 0); + + old= *dest; + if(old==comp) { + *dest=exch; + } + + ret = pthread_mutex_unlock(&spin); + g_assert (ret == 0); + + pthread_cleanup_pop (0); - pthread_mutex_lock (&spin); - - old = *dest; - if(old == comp) - *dest = exch; - - pthread_mutex_unlock (&spin); - return old; + return(old); } #endif diff --git a/mono/utils/mono-linked-list-set.c b/mono/utils/mono-linked-list-set.c index 3536d25d844..b7391962eaa 100644 --- a/mono/utils/mono-linked-list-set.c +++ b/mono/utils/mono-linked-list-set.c @@ -188,7 +188,7 @@ mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLink continue; /* The second CAS must happen before the first. */ mono_memory_write_barrier (); - if (InterlockedCompareExchangePointer ((volatile gpointer*)prev, next, cur) == cur) { + if (InterlockedCompareExchangePointer ((volatile gpointer*)prev, mono_lls_pointer_unmask (next), cur) == cur) { /* The CAS must happen before the hazard pointer clear. */ mono_memory_write_barrier (); mono_hazard_pointer_clear (hp, 1); diff --git a/mono/utils/mono-mmap.c b/mono/utils/mono-mmap.c index 402b82e2f95..5546c6b7cca 100644 --- a/mono/utils/mono-mmap.c +++ b/mono/utils/mono-mmap.c @@ -483,6 +483,8 @@ mono_mprotect (void *addr, size_t length, int flags) } #endif // HAVE_MMAP +#if defined(HAVE_SHM_OPEN) && !defined (DISABLE_SHARED_PERFCOUNTERS) + static int use_shared_area; static gboolean @@ -497,8 +499,6 @@ shared_area_disabled (void) return use_shared_area == -1; } -#if defined(HAVE_SHM_OPEN) && !defined (DISABLE_SHARED_PERFCOUNTERS) - static int mono_shared_area_instances_slow (void **array, int count, gboolean cleanup) { diff --git a/support/macros.c b/support/macros.c index d2cf5e7bcdb..8d455889d7c 100644 --- a/support/macros.c +++ b/support/macros.c @@ -100,6 +100,15 @@ char *helper_Mono_Posix_readdir(void *dir) { } #if HAVE_GETPWNAM_R +int helper_Mono_Posix_getpwnamuid (int mode, char *in_name, int in_uid, + char **account, + char **password, + int *uid, + int *gid, + char **name, + char **home, + char **shell); + int helper_Mono_Posix_getpwnamuid (int mode, char *in_name, int in_uid, char **account, char **password, diff --git a/support/minizip/zip.c b/support/minizip/zip.c index 5acf49f5861..ef81ecc032c 100644 --- a/support/minizip/zip.c +++ b/support/minizip/zip.c @@ -187,12 +187,13 @@ local void init_linkedlist(linkedlist_data *ll) ll->first_block = ll->last_block = NULL; } +/* local void free_linkedlist(linkedlist_data *ll) { free_datablock(ll->first_block); ll->first_block = ll->last_block = NULL; } - +*/ local int add_data_in_datablock(linkedlist_data *ll, const void *buf, uLong len) { diff --git a/support/supportw.c b/support/supportw.c index 49ed549c5d2..51b49697152 100644 --- a/support/supportw.c +++ b/support/supportw.c @@ -158,6 +158,9 @@ FindWindowExW (gpointer hwndParent, gpointer hwndChildAfter, const char *classw, return func (hwndParent, hwndChildAfter, classw, window); } +int +SetWindowPos (gpointer hwnd, gpointer hwndInsertAfter, int x, int y, int cx, int cy, unsigned int flags); + int SetWindowPos (gpointer hwnd, gpointer hwndInsertAfter, int x, int y, int cx, int cy, unsigned int flags) { @@ -165,6 +168,9 @@ SetWindowPos (gpointer hwnd, gpointer hwndInsertAfter, int x, int y, int cx, int return 1; } +int +SendMessageA (gpointer hwnd, unsigned int msg, gpointer wparam, gpointer lparam); + int SendMessageA (gpointer hwnd, unsigned int msg, gpointer wparam, gpointer lparam) { @@ -172,6 +178,9 @@ SendMessageA (gpointer hwnd, unsigned int msg, gpointer wparam, gpointer lparam) return 0; } +int +GetWindowLongA (gpointer hwnd, int a); + int GetWindowLongA (gpointer hwnd, int a) { diff --git a/support/sys-time.c b/support/sys-time.c index 1759ec0fcb8..1309f2a9753 100644 --- a/support/sys-time.c +++ b/support/sys-time.c @@ -70,6 +70,10 @@ Mono_Posix_Syscall_settimeofday ( } /* Remove this at some point in the future */ +gint32 +Mono_Posix_Syscall_utimes_bad (const char *filename, + struct Mono_Posix_Timeval *tv); + gint32 Mono_Posix_Syscall_utimes_bad (const char *filename, struct Mono_Posix_Timeval *tv) diff --git a/support/syslog.c b/support/syslog.c index 6fed2ad2059..2d8d7cbe800 100644 --- a/support/syslog.c +++ b/support/syslog.c @@ -47,6 +47,9 @@ Mono_Posix_Syscall_syslog (int priority, const char* message) #endif /* vararg version of syslog(3). */ +gint32 +Mono_Posix_Syscall_syslog2 (int priority, const char *format, ...); + gint32 Mono_Posix_Syscall_syslog2 (int priority, const char *format, ...) { diff --git a/support/x-struct-str.c b/support/x-struct-str.c index b71a9cca1f0..5124af71fc9 100644 --- a/support/x-struct-str.c +++ b/support/x-struct-str.c @@ -20,7 +20,7 @@ : lstr_at(p, n) \ ) -char* MPH_INTERNAL +char* _mph_copy_structure_strings ( void *to, const mph_string_offset_t *to_offsets, const void *from, const mph_string_offset_t *from_offsets, diff --git a/support/zlib-helper.c b/support/zlib-helper.c index 47adde38dbf..d0911fc0764 100644 --- a/support/zlib-helper.c +++ b/support/zlib-helper.c @@ -45,7 +45,7 @@ gint WriteZStream (ZStream *stream, guchar *buffer, gint length); static gint flush_internal (ZStream *stream, gboolean is_final); static void * -z_alloc (void *opaque, gsize nitems, gsize item_size) +z_alloc (void *opaque, unsigned int nitems, unsigned int item_size) { return g_malloc0 (nitems * item_size); }